From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12069 invoked by alias); 9 Mar 2003 17:51:53 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 12061 invoked from network); 9 Mar 2003 17:51:53 -0000 Received: from unknown (HELO hub.ott.qnx.com) (209.226.137.76) by 172.16.49.205 with SMTP; 9 Mar 2003 17:51:53 -0000 Received: from smtp.ott.qnx.com (smtp.ott.qnx.com [10.0.2.158]) by hub.ott.qnx.com (8.9.3/8.9.3) with ESMTP id MAA29454; Sun, 9 Mar 2003 12:38:37 -0500 Received: from dash ([192.168.20.27]) by smtp.ott.qnx.com (8.8.8/8.6.12) with SMTP id MAA08948; Sun, 9 Mar 2003 12:51:49 -0500 Message-ID: <002501c2e665$150a09e0$2a00a8c0@dash> From: "Kris Warkentin" To: "Mark Kettenis" Cc: References: <200303081344.h28DiNvi040785@elgar.kettenis.dyndns.org> <004001c2e584$65814690$2a00a8c0@dash> <200303090013.h290DnBU000820@elgar.kettenis.dyndns.org> Subject: Re: [RFC] QNX Neutrino/i386 support Date: Sun, 09 Mar 2003 17:51:00 -0000 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0022_01C2E63B.2B921C90" X-Priority: 3 X-MSMail-Priority: Normal X-MIMEOLE: Produced By Microsoft MimeOLE V6.00.2800.1106 X-SW-Source: 2003-03/txt/msg00206.txt.bz2 This is a multi-part message in MIME format. ------=_NextPart_000_0022_01C2E63B.2B921C90 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-length: 407 > Here are my comments about the i386-nto-tdep.c file. Some general > stuff first (which probably applies to the other files as well): Hi Mark, I've done the cleaning that you proposed and attached the revised files. I'm not really fond of the branch and merging idea so if you really don't want to put all of this stuff in, we'll rip everything out, start with the minimum and work up from there. Kris ------=_NextPart_000_0022_01C2E63B.2B921C90 Content-Type: application/octet-stream; name="nto-tdep.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="nto-tdep.c" Content-length: 9997 /* nto-tdep.c - general QNX Neutrino target functionality */=0A= =0A= /* Copyright 2003 Free Software Foundation */=0A= =0A= /* Contributed by QNX Software Systems Ltd. */=0A= =0A= #include =0A= #include "nto-tdep.h"=0A= #include "top.h"=0A= #include "cli/cli-decode.h"=0A= #include "cli/cli-cmds.h"=0A= #include "inferior.h"=0A= #include "gdbarch.h"=0A= #include "bfd.h"=0A= #include "elf-bfd.h"=0A= #include "solib-svr4.h"=0A= #include "gdbcore.h"=0A= =0A= #ifdef __CYGWIN__=0A= #include =0A= #endif=0A= =0A= #ifdef __CYGWIN__=0A= static char default_nto_target[] =3D "C:\\QNXsdk\\target\\qnx6";=0A= #elif defined(__sun__) || defined(linux)=0A= static char default_nto_target[] =3D "/opt/QNXsdk/target/qnx6";=0A= #else=0A= static char default_nto_target[] =3D "";=0A= #endif=0A= =0A= /* Maintenance debugging flag */=0A= int nto_internal_debugging;=0A= =0A= /* Filled in cpu info structure and flag to indicate its validity.=20=0A= * This is initialized in procfs_attach or nto_start_remote depending on=0A= * our host/target. It would only be invalid if we were talking to an=0A= * older pdebug which didn't support the cpuinfo message. */=0A= unsigned nto_cpuinfo_flags;=0A= int nto_cpuinfo_valid;=0A= =0A= static char *=0A= nto_target (void)=0A= {=0A= char *p =3D getenv ("QNX_TARGET");=0A= =0A= #ifdef __CYGWIN__=0A= static char buf[PATH_MAX];=0A= if (p)=0A= cygwin_conv_to_posix_path (p, buf);=0A= else=0A= cygwin_conv_to_posix_path (default_nto_target, buf);=0A= return buf;=0A= #else=0A= return p ? p : default_nto_target;=0A= #endif=0A= }=0A= =0A= /* Take a string such as i386, rs6000, etc. and map it onto CPUTYPE_X86,=0A= CPUTYPE_PPC, etc. as defined in nto-share/dsmsgs.h. */=0A= int=0A= nto_map_arch_to_cputype(const char *arch)=0A= {=0A= if(!strcmp(arch, "i386") || !strcmp(arch, "x86"))=0A= return CPUTYPE_X86;=0A= if(!strcmp(arch, "rs6000") || !strcmp(arch, "ppc"))=0A= return CPUTYPE_PPC;=0A= if(!strcmp(arch, "mips"))=0A= return CPUTYPE_MIPS;=0A= if(!strcmp(arch, "arm"))=0A= return CPUTYPE_ARM;=0A= if(!strcmp(arch, "sh"))=0A= return CPUTYPE_SH;=0A= return CPUTYPE_UNKNOWN;=0A= }=0A= =0A= int=0A= nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathnam= e)=0A= {=0A= char *buf, arch_path[PATH_MAX], *nto_root, *endian;=0A= const char *arch;=0A= char *path_fmt =3D "%s/lib:%s/usr/lib:%s/usr/photon/lib\=0A= :%s/usr/photon/dll:%s/lib/dll";=0A= =0A= nto_root =3D nto_target ();=0A= if (strcmp (TARGET_ARCHITECTURE->arch_name, "i386") =3D=3D 0)=0A= {=0A= arch =3D "x86";=0A= endian =3D "";=0A= }=0A= else if (strcmp (TARGET_ARCHITECTURE->arch_name, "rs6000") =3D=3D 0)=0A= {=0A= arch =3D "ppc";=0A= endian =3D "be";=0A= }=0A= else=0A= {=0A= arch =3D TARGET_ARCHITECTURE->arch_name;=0A= endian =3D TARGET_BYTE_ORDER =3D=3D BFD_ENDIAN_BIG ? "be" : "le";=0A= }=0A= =0A= sprintf (arch_path, "%s/%s%s", nto_root, arch, endian);=0A= =0A= buf =3D alloca (strlen(path_fmt) + strlen(arch_path) * 5 + 1);=0A= sprintf (buf, path_fmt, arch_path, arch_path, arch_path, arch_path, arch_= path);=0A= =0A= return openp(buf, 1, solib, o_flags, 0, temp_pathname);=0A= }=0A= =0A= void=0A= nto_init_solib_absolute_prefix (void)=0A= {=0A= char buf[PATH_MAX * 2], arch_path[PATH_MAX];=0A= char *nto_root, *endian;=0A= const char *arch;=0A= =0A= nto_root =3D nto_target ();=0A= if (strcmp (TARGET_ARCHITECTURE->arch_name, "i386") =3D=3D 0)=0A= {=0A= arch =3D "x86";=0A= endian =3D "";=0A= }=0A= else if (strcmp (TARGET_ARCHITECTURE->arch_name, "rs6000") =3D=3D 0)=0A= {=0A= arch =3D "ppc";=0A= endian =3D "be";=0A= }=0A= else=0A= {=0A= arch =3D TARGET_ARCHITECTURE->arch_name;=0A= endian =3D TARGET_BYTE_ORDER =3D=3D BFD_ENDIAN_BIG ? "be" : "le";=0A= }=0A= =0A= sprintf (arch_path, "%s/%s%s", nto_root, arch, endian);=0A= =0A= sprintf (buf, "set solib-absolute-prefix %s", arch_path);=0A= execute_command (buf, 0);=0A= }=0A= =0A= char **=0A= nto_parse_redirection (char *pargv[], char **pin, char **pout, char **perr)= =0A= {=0A= char **argv;=0A= char *in, *out, *err, *p;=0A= int argc, i, n;=0A= =0A= for (n =3D 0; pargv[n]; n++);=0A= if (n =3D=3D 0)=0A= return NULL;=0A= in =3D "";=0A= out =3D "";=0A= err =3D "";=0A= =0A= argv =3D xcalloc (n + 1, sizeof argv[0]);=0A= argc =3D n;=0A= for (i =3D 0, n =3D 0; n < argc; n++)=0A= {=0A= p =3D pargv[n];=0A= if (*p =3D=3D '>')=0A= {=0A= p++;=0A= if (*p)=0A= out =3D p;=0A= else=0A= out =3D pargv[++n];=0A= }=0A= else if (*p =3D=3D '<')=0A= {=0A= p++;=0A= if (*p)=0A= in =3D p;=0A= else=0A= in =3D pargv[++n];=0A= }=0A= else if (*p++ =3D=3D '2' && *p++ =3D=3D '>')=0A= {=0A= if (*p =3D=3D '&' && *(p + 1) =3D=3D '1')=0A= err =3D out;=0A= else if (*p)=0A= err =3D p;=0A= else=0A= err =3D pargv[++n];=0A= }=0A= else=0A= argv[i++] =3D pargv[n];=0A= }=0A= *pin =3D in;=0A= *pout =3D out;=0A= *perr =3D err;=0A= return argv;=0A= }=0A= =0A= void=0A= nto_source_extra_gdbinit (char *file)=0A= {=0A= char *homedir, *homeinit;=0A= struct stat statbuf;=0A= =0A= homedir =3D getenv ("HOME");=0A= =0A= if (homedir && !inhibit_gdbinit)=0A= {=0A= homeinit =3D (char *) alloca (strlen (homedir) + strlen (file) + 10);= =0A= sprintf (homeinit, "%s/%s", homedir, file);=0A= if (stat (homeinit, &statbuf) =3D=3D 0)=0A= catch_command_errors (source_command, homeinit, 0, RETURN_MASK_ALL);=0A= }=0A= }=0A= =0A= /* struct lm_info, LM_ADDR, and nto_truncate_ptr are copied from=0A= solib-svr4.c to support nto_relocate_section_addresses=0A= which is different from the svr4 version. */=0A= =0A= struct lm_info=0A= {=0A= /* Pointer to copy of link map from inferior. The type is char *=0A= rather than void *, so that we may use byte offsets to find the=0A= various fields without the need for a cast. */=0A= char *lm;=0A= };=0A= =0A= static CORE_ADDR=0A= LM_ADDR (struct so_list *so)=0A= {=0A= struct link_map_offsets *lmo =3D nto_fetch_link_map_offsets ();=0A= =0A= return (CORE_ADDR) extract_signed_integer (so->lm_info->lm +=0A= lmo->l_addr_offset,=0A= lmo->l_addr_size);=0A= }=0A= =0A= static CORE_ADDR=0A= nto_truncate_ptr (CORE_ADDR addr)=0A= {=0A= if (TARGET_PTR_BIT =3D=3D sizeof (CORE_ADDR) * 8)=0A= /* We don't need to truncate anything, and the bit twiddling below=0A= will fail due to overflow problems. */=0A= return addr;=0A= else=0A= return addr & (((CORE_ADDR) 1 << TARGET_PTR_BIT) - 1);=0A= }=0A= =0A= Elf_Internal_Phdr *=0A= find_load_phdr (bfd *abfd)=0A= {=0A= Elf_Internal_Phdr *phdr;=0A= unsigned int i;=0A= =0A= if (!elf_tdata (abfd))=0A= return NULL;=0A= =0A= phdr =3D elf_tdata (abfd)->phdr;=0A= for (i =3D 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)=0A= {=0A= if (phdr->p_type =3D=3D PT_LOAD && (phdr->p_flags & PF_X))=0A= return phdr;=0A= }=0A= return NULL;=0A= }=0A= =0A= void=0A= nto_relocate_section_addresses (struct so_list *so, struct section_table *s= ec)=0A= {=0A= /* Neutrino treats the l_addr base address field in link.h as different t= han=0A= the base address in the System V ABI and so the offset needs to be=0A= calculated and applied to relocations. */=0A= Elf_Internal_Phdr *phdr =3D find_load_phdr (sec->bfd);=0A= unsigned vaddr =3D phdr ? phdr->p_vaddr : 0;=0A= =0A= sec->addr =3D nto_truncate_ptr (sec->addr + LM_ADDR (so) - vaddr);=0A= sec->endaddr =3D nto_truncate_ptr (sec->endaddr + LM_ADDR (so) - vaddr);= =0A= }=0A= =0A= static void=0A= fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,=0A= int which, CORE_ADDR reg_addr)=0A= {=0A= nto_gregset_t gregset;=0A= nto_fpregset_t fpregset;=0A= =0A= nto_init_solib_absolute_prefix ();=0A= =0A= if (which =3D=3D 0)=0A= {=0A= memcpy ((char *) &gregset, core_reg_sect,=0A= min (core_reg_size, sizeof (gregset)));=0A= nto_supply_gregset (&gregset);=0A= }=0A= else if (which =3D=3D 2)=0A= {=0A= memcpy ((char *) &fpregset, core_reg_sect,=0A= min (core_reg_size, sizeof (fpregset)));=0A= nto_supply_fpregset (&fpregset);=0A= }=0A= }=0A= =0A= /* Register that we are able to handle ELF file formats using standard=0A= procfs "regset" structures. */=0A= =0A= static struct core_fns regset_core_fns =3D {=0A= bfd_target_elf_flavour, /* core_flavour */=0A= default_check_format, /* check_format */=0A= default_core_sniffer, /* core_sniffer */=0A= fetch_core_registers, /* core_read_registers */=0A= NULL /* next */=0A= };=0A= =0A= void=0A= _initialize_nto_tdep ()=0A= {=0A= add_show_from_set (add_set_cmd ("nto-debug", class_maintenance, var_zinte= ger, (char *) &nto_internal_debugging, "Set QNX NTO internal debugging.\n\= =0A= When non-zero, nto specific debug info is\n\=0A= displayed. Different information is displayed\n\=0A= for different positive values.", &setdebuglist),=0A= &showdebuglist);=0A= =0A= /* We use SIG45 for pulses, or something, so nostop, noprint=0A= and pass them. */=0A= signal_stop_update (target_signal_from_name ("SIG45"), 0);=0A= signal_print_update (target_signal_from_name ("SIG45"), 0);=0A= signal_pass_update (target_signal_from_name ("SIG45"), 1);=0A= =0A= /* By default we don't want to stop on these two, but we do want to pass.= */=0A= #if defined(SIGSELECT)=0A= signal_stop_update (SIGSELECT, 0);=0A= signal_print_update (SIGSELECT, 0);=0A= signal_pass_update (SIGSELECT, 1);=0A= #endif=0A= =0A= #if defined(SIGPHOTON)=0A= signal_stop_update (SIGPHOTON, 0);=0A= signal_print_update (SIGPHOTON, 0);=0A= signal_pass_update (SIGPHOTON, 1);=0A= #endif=0A= =0A= /* Register core file support. */=0A= add_core_fns (®set_core_fns);=0A= }=0A= ------=_NextPart_000_0022_01C2E63B.2B921C90 Content-Type: application/octet-stream; name="nto-tdep.h" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="nto-tdep.h" Content-length: 2095 /* nto-tdep.h - QNX Neutrino target header */=0A= =0A= /* Copyright 2003 Free Software Foundation */=0A= =0A= /* Contributed by QNX Software Systems Ltd. */=0A= =0A= #ifndef _NTO_TDEP_H=0A= #define _NTO_TDEP_H=0A= =0A= #include "defs.h"=0A= #include "nto-share/debug.h"=0A= #include "solist.h"=0A= =0A= /* Generic functions in nto-tdep.c. */=0A= =0A= extern void nto_init_solib_absolute_prefix PARAMS ((void));=0A= =0A= char **nto_parse_redirection=0A= PARAMS ((char *start_argv[], char **in, char **out, char **err));=0A= =0A= int proc_iterate_over_mappings PARAMS ((int (*func) (int, CORE_ADDR)));=0A= =0A= void nto_source_extra_gdbinit PARAMS ((char *));=0A= =0A= void nto_relocate_section_addresses=0A= PARAMS ((struct so_list *, struct section_table *));=0A= =0A= int nto_map_arch_to_cputype PARAMS((const char *));=0A= =0A= int nto_find_and_open_solib PARAMS((char *, unsigned, char **));=0A= =0A= /* Functions exported from all Neutrino targets (-nto-tdep.c). */= =0A= =0A= unsigned nto_get_regset_id PARAMS ((int regno));=0A= =0A= void nto_cpu_regset_fetch PARAMS ((int endian, int regset, void *data));=0A= =0A= unsigned nto_get_regset_area PARAMS ((unsigned regset, char *subcmd));=0A= =0A= unsigned nto_cpu_register_area=0A= PARAMS ((unsigned first_regno, unsigned last_regno, unsigned char *subcmd,= =0A= unsigned *off, unsigned *len));=0A= =0A= int nto_cpu_register_store=0A= PARAMS ((int endian, unsigned first_regno, unsigned last_regno, void *data)= );=0A= =0A= void nto_supply_gregset PARAMS ((union _debug_gregs *));=0A= =0A= void nto_supply_fpregset PARAMS ((union _debug_fpregs *));=0A= =0A= struct link_map_offsets *nto_fetch_link_map_offsets PARAMS ((void));=0A= =0A= /* Globals. */=0A= =0A= /* For 'maintenance debug nto-debug' command. */=0A= extern int nto_internal_debugging;=0A= =0A= /* The CPUINFO flags from the remote. Currently used by=0A= i386 for fxsave but future proofing other hosts */=0A= extern unsigned nto_cpuinfo_flags;=0A= =0A= /* True if successfully retrieved cpuinfo from remote */=0A= extern int nto_cpuinfo_valid;=0A= =0A= #endif=0A= ------=_NextPart_000_0022_01C2E63B.2B921C90 Content-Type: application/octet-stream; name="i386-nto-tdep.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="i386-nto-tdep.c" Content-length: 10637 /* i386-nto-tdep.c - i386 specific functionality for QNX Neutrino */=0A= =0A= /* Copyright 2003 Free Software Foundation */=0A= =0A= /* Contributed by QNX Software Systems Ltd. */=0A= =0A= #include "defs.h"=0A= #include "frame.h"=0A= #include "target.h"=0A= #include "regcache.h"=0A= #include "solib-svr4.h"=0A= #include "i386-tdep.h"=0A= #include "nto-tdep.h"=0A= #include "osabi.h"=0A= #include "nto-share/debug.h"=0A= #include "i387-tdep.h"=0A= =0A= #define NUM_GPREGS 13=0A= static int gdb_to_nto[NUM_GPREGS] =3D=0A= { 7, 6, 5, 4, 11, 2, 1, 0, 8, 10, 9, 12, -1 };=0A= =0A= #define GDB_TO_OS(x) ((x >=3D 0 && x < NUM_GPREGS) ? gdb_to_nto[x] : -1)=0A= =0A= #ifndef X86_CPU_FXSR=0A= #define X86_CPU_FXSR (1L << 12)=0A= #endif=0A= =0A= enum QNX_REGS=0A= {=0A= QNX_REGS_GP =3D 0,=0A= QNX_REGS_FP =3D 1,=0A= QNX_REGS_END =3D 2=0A= };=0A= =0A= /* Given a register, return an id that represents the Neutrino=0A= regset it came from. If reg =3D=3D -1 update all regsets. */=0A= unsigned=0A= nto_get_regset_id (int regno)=0A= {=0A= if (regno =3D=3D -1)=0A= return QNX_REGS_END;=0A= else if (regno < FP0_REGNUM)=0A= return QNX_REGS_GP;=0A= else if (regno < FPC_REGNUM)=0A= return QNX_REGS_FP;=0A= =0A= return -1; /* error */=0A= }=0A= =0A= /* Tell GDB about the regset contained in the 'data' buffer. */=0A= static void=0A= gp_regset_fetch (char *data)=0A= {=0A= unsigned first_regno;=0A= =0A= for (first_regno =3D 0; first_regno < FP0_REGNUM; first_regno++)=0A= {=0A= int regno =3D GDB_TO_OS (first_regno);=0A= int const blank =3D 0;=0A= =0A= if (data =3D=3D NULL || regno =3D=3D -1)=0A= supply_register (first_regno, (char *) &blank);=0A= else=0A= supply_register (first_regno, &data[regno * 4]);=0A= }=0A= }=0A= =0A= /* Get 8087 data. */=0A= static void=0A= fp_regset_fetch (char *data)=0A= {=0A= if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)=0A= i387_supply_fxsave (data);=0A= else=0A= i387_supply_fsave (data);=0A= }=0A= =0A= void=0A= nto_cpu_regset_fetch (int endian, int regset, void *data)=0A= {=0A= endian =3D endian; /* For i386, we don't care about endian. */=0A= =0A= switch (regset)=0A= {=0A= case QNX_REGS_GP: /* QNX has different ordering of GP regs than GDB. *= /=0A= gp_regset_fetch ((char *) data);=0A= break;=0A= case QNX_REGS_FP:=0A= fp_regset_fetch ((char *) data);=0A= break;=0A= }=0A= }=0A= =0A= /* Get regset characteristics. */=0A= unsigned=0A= nto_get_regset_area (unsigned regset, char *subcmd)=0A= {=0A= unsigned length =3D 0;=0A= switch (regset)=0A= {=0A= case QNX_REGS_GP:=0A= *subcmd =3D NTO_REG_GENERAL;=0A= length =3D NUM_GPREGS * sizeof (unsigned);=0A= break;=0A= case QNX_REGS_FP:=0A= *subcmd =3D NTO_REG_FLOAT;=0A= /* FIXME: should we calculate based on fxsave/fsave? */=0A= length =3D 512;=0A= break;=0A= default:=0A= length =3D 0;=0A= }=0A= return length;=0A= }=0A= =0A= /* Given the first and last register number, figure out the size/len=0A= of the Neutrino register save area to ask for/tell about. Also set=0A= the register set that's being dealt with in *subcmd. Watch out for=0A= the range crossing a register set boundry. */=0A= unsigned=0A= nto_cpu_register_area (unsigned first_regno, unsigned last_regno,=20=0A= unsigned char *subcmd, unsigned *off, unsigned *len)=0A= {=0A= int regno =3D -1;=0A= =0A= if (first_regno < FP0_REGNUM)=0A= {=0A= if (last_regno >=3D FP0_REGNUM)=0A= last_regno =3D FP0_REGNUM - 1;=0A= *subcmd =3D NTO_REG_GENERAL;=0A= regno =3D GDB_TO_OS (first_regno);=0A= *off =3D regno * sizeof (unsigned);=0A= if (regno =3D=3D -1)=0A= *len =3D 0;=0A= else=0A= *len =3D (last_regno - first_regno + 1) * sizeof (unsigned);=0A= }=0A= else if (first_regno =3D=3D FP_REGNUM)=0A= {=0A= /* Frame Pointer Psuedo-register */=0A= *off =3D SP_REGNUM * sizeof (unsigned);=0A= *len =3D sizeof (unsigned);=0A= return FP_REGNUM;=0A= }=0A= else if (first_regno >=3D FP0_REGNUM && first_regno < FPC_REGNUM)=0A= {=0A= unsigned off_adjust, regsize;=0A= =0A= if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)=0A= {=0A= off_adjust =3D 32;=0A= regsize =3D 16;=0A= }=0A= else=0A= {=0A= off_adjust =3D 28;=0A= regsize =3D 10;=0A= }=0A= =0A= if (last_regno >=3D FPC_REGNUM)=0A= last_regno =3D FPC_REGNUM - 1;=0A= *subcmd =3D NTO_REG_FLOAT;=0A= *off =3D (first_regno - FP0_REGNUM) * regsize + off_adjust;=0A= *len =3D (last_regno - first_regno + 1) * 10;=0A= /* Why 10? GDB only stores 10 bytes per FP register so if we're=0A= sending a register back to the target, we only want pdebug to writ= e=0A= 10 bytes so as not to clobber the reserved 6 bytes in the fxsave= =0A= structure. The astute reader will note that this will fail if we= =0A= try to send a range of fpregs rather than 1 at a time but, as far= =0A= as I know, there is no way to send more than one fpreg at a time= =0A= anyway. If this turns out to be wrong, we may need to put more co= de=0A= in pdebug to deal with this - perhaps by masking off part of the= =0A= register when it writes it in.*/=0A= }=0A= else=0A= {=0A= *len =3D 0;=0A= return last_regno;=0A= }=0A= return last_regno;=0A= }=0A= =0A= /* Build the Neutrino register set info into the 'data' buffer. */=0A= int=0A= nto_cpu_register_store (int endian, unsigned first_regno,=0A= unsigned last_regno, void *data)=0A= {=0A= /* Mostly (always?) you're only storing one at a time. */=0A= if (first_regno =3D=3D last_regno)=0A= {=0A= regcache_collect (first_regno, data);=0A= return 1;=0A= }=0A= /* Floating point is the same for gdb and target */=0A= if (first_regno >=3D FP0_REGNUM)=0A= {=0A= for (; first_regno <=3D last_regno; first_regno++)=0A= {=0A= regcache_collect (first_regno, data);=0A= (char *) data +=3D REGISTER_RAW_SIZE (first_regno);=0A= }=0A= return 1;=0A= }=0A= /* GP registers are mapped differently for NTO than GDB */=0A= for (; first_regno <=3D last_regno; first_regno++)=0A= {=0A= int regnum =3D GDB_TO_OS (first_regno);=0A= if (regnum =3D=3D -1)=0A= continue;=0A= regcache_collect (first_regno,=0A= (char *) data + sizeof (unsigned) * regnum);=0A= }=0A= return 1;=0A= }=0A= =0A= void=0A= nto_supply_gregset (nto_gregset_t *gregsetp)=0A= {=0A= int regi, i =3D 0;=0A= unsigned *regp =3D (unsigned *) gregsetp;=0A= =0A= for (regi =3D 0; regi < (NUM_REGS - FP0_REGNUM); regi++)=0A= {=0A= i =3D GDB_TO_OS (regi);=0A= supply_register (regi, (char *) ®p[i]);=0A= }=0A= }=0A= =0A= void=0A= nto_supply_fpregset (nto_fpregset_t *fpregsetp)=0A= {=0A= if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)=0A= i387_supply_fxsave ((char *) fpregsetp);=0A= else=0A= i387_supply_fsave ((char *) fpregsetp);=0A= }=0A= =0A= /* Fetch (and possibly build) an appropriate link_map_offsets=0A= structure for native x86 targets using the struct offsets=0A= defined in link.h (but without actual reference to that file).=0A= =0A= This makes it possible to access x86 shared libraries from a GDB=0A= that was not built on an x86 host (for cross debugging). */=0A= =0A= static struct link_map_offsets *=0A= i386_nto_svr4_fetch_link_map_offsets (void)=0A= {=0A= static struct link_map_offsets lmo;=0A= static struct link_map_offsets *lmp =3D NULL;=0A= =0A= if (lmp =3D=3D NULL)=0A= {=0A= lmp =3D &lmo;=0A= =0A= lmo.r_debug_size =3D 8; /* The actual size is 20 bytes, but=0A= this is all we need. */=0A= lmo.r_map_offset =3D 4;=0A= lmo.r_map_size =3D 4;=0A= =0A= lmo.link_map_size =3D 20; /* The actual size is 552 bytes, but=0A= this is all we need. */=0A= lmo.l_addr_offset =3D 0;=0A= lmo.l_addr_size =3D 4;=0A= =0A= lmo.l_name_offset =3D 4;=0A= lmo.l_name_size =3D 4;=0A= =0A= lmo.l_next_offset =3D 12;=0A= lmo.l_next_size =3D 4;=0A= =0A= lmo.l_prev_offset =3D 16;=0A= lmo.l_prev_size =3D 4;=0A= }=0A= =0A= return lmp;=0A= }=0A= =0A= struct link_map_offsets *=0A= nto_fetch_link_map_offsets (void)=0A= {=0A= return i386_nto_svr4_fetch_link_map_offsets ();=0A= }=0A= =0A= static int=0A= i386_nto_pc_in_sigtramp (CORE_ADDR pc, char *name)=0A= {=0A= return name && strcmp ("__signalstub", name) =3D=3D 0;=0A= }=0A= =0A= static CORE_ADDR=0A= i386_nto_sigcontext_addr (struct frame_info *frame)=0A= {=0A= int sigcontext_offset =3D 136;=0A= =0A= if (get_next_frame (frame))=0A= return get_frame_base (get_next_frame (frame)) + sigcontext_offset;=0A= =0A= return read_register (SP_REGNUM) + sigcontext_offset;=0A= }=0A= =0A= static void=0A= i386_nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)=0A= {=0A= struct gdbarch_tdep *tdep =3D gdbarch_tdep (gdbarch);=0A= =0A= /* NTO uses ELF. */=0A= i386_elf_init_abi (info, gdbarch);=0A= =0A= /* neutrino rewinds to look more normal */=0A= set_gdbarch_decr_pc_after_break (gdbarch, 0);=0A= =0A= /* NTO has shared libraries. */=0A= set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);=0A= set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);= =0A= =0A= set_gdbarch_pc_in_sigtramp (gdbarch, i386_nto_pc_in_sigtramp);=0A= tdep->sigcontext_addr =3D i386_nto_sigcontext_addr;=0A= tdep->sc_pc_offset =3D 56;=0A= tdep->sc_sp_offset =3D 68;=0A= =0A= /* setjmp()'s return PC saved in EDX (5) */=0A= tdep->jb_pc_offset =3D 20; /* 5x32 bit ints in. */=0A= =0A= set_solib_svr4_fetch_link_map_offsets (gdbarch,=0A= i386_nto_svr4_fetch_link_map_offsets);=0A= =0A= /* Our loader handles solib relocations slightly differently than svr4 */= =0A= TARGET_SO_RELOCATE_SECTION_ADDRESSES =3D nto_relocate_section_addresses;= =0A= =0A= /* Supply a nice function to find our solibs */=0A= TARGET_SO_FIND_AND_OPEN_SOLIB =3D nto_find_and_open_solib;=0A= =0A= /* After a watchpoint trap, the PC points to the instruction after=0A= the one that caused the trap. Therefore we don't need to step over it.= =0A= But we do need to reset the status register to avoid another trap. */= =0A= HAVE_CONTINUABLE_WATCHPOINT =3D 1;=0A= }=0A= =0A= void=0A= _initialize_i386_nto_tdep (void)=0A= {=0A= gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_QNXNTO,=0A= i386_nto_init_abi);=0A= }=0A= ------=_NextPart_000_0022_01C2E63B.2B921C90--