This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] Take 2: Adding new files for Interix port


Joel Brobecker <brobecker@gnat.com> writes:

> --BXVAT5kNtrzKuDFl
> Content-Type: text/plain; charset=us-ascii
> Content-Disposition: inline
> 
> Thanks to Mark's very valuable comments, I think I have brought the
> interix-specific files to a much better state. I also fixed the ARI
> regressions (I had to hack a bit Andrew's script, so some regressions
> may have been left behind, but most of them should have been dealt
> with).

I'm sorry to be such a nitpicker, but there are several places where
the use of whitespace in and capitalization of comments is still
slightly wrong:

* Comments should be full sentences if possible.

* A full stop (that's a dot at the end of a sentence) should be
  followed by two spaces, even at the end of a comment.

* There should only be a single space before the start of the text of
  a comment.

> The nm- and xm- files contains macros that you have never seen so far.
> They are part of some changes that were made in common parts of the GDB
> source. They are probably temporary, all the more so as I understand
> that we want to get rid of these files in the long run anyway.

I don't think we're going to tolerate those changes in most of the
common parts of GDB.  Therefore, what's the point of adding them now?

Anyway please use a uniform naming convention for these files; now you
have xm-i386interix.h and nm-interix.h, and you mention xm-interix.h
in your ChangeLog.

> One example of such macro is COFF_IMAGE_WITH_PE, which is used mostly
> in coffread to handle the little differences in the object format.
> There is probably a better way than using a macro, something like the
> procfs_ops vector, or the arch vector. I will take care of this macro
> at the same time I take of the changes in coffread.c.
> 
> Same for macros like NONZERO_LINK_BASE, or NAME_OF_MALLOC.
> 
> I am hoping that we are getting close to a state where I can check these
> files in, and work on the configury parts. Here is the ChangeLog:
> 
> 2002-08-15  Joel Brobecker  <brobecker@gnat.com>
> 
>         New interix-specific files:
>         * config/i386/nm-interix.h: New file.
>         * config/i386/xm-interix.h: New file.
>         * config/i386/interix.mh: New file.
>         * config/i386/interix.mt: New file.
>         * i386-interix-nat.c: New file.
>         * i386-interix-tdep.c: New file.
> 
> Ok to apply?
> 
> Thanks,
> -- 
> Joel
> 
> --BXVAT5kNtrzKuDFl
> Content-Type: text/plain; charset=us-ascii
> Content-Description: nm-interix.h
> Content-Disposition: attachment; filename="nm-interix.h"
> 
> /* Native-dependent definitions for Intel 386 running Interix, for GDB.
>    Copyright 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.  */
> 
> #ifndef NM_INTERIX_H
> #define NM_INTERIX_H
> 
> /* Be shared lib aware */
> #include "solib.h"
> 
> /* submodes of USE_PROC_FS */
> #define UNIXWARE
> 
> /* It's ALMOST coff; bfd does the same thing. Mostly used in coffread.c.  */
> #define COFF_IMAGE_WITH_PE
> 
> /* Turn on our own child_pid_to_exec_file. */
> #define CHILD_PID_TO_EXEC_FILE
> 
> #endif /* NM_INTERIX_H */
> 
> --BXVAT5kNtrzKuDFl
> Content-Type: text/plain; charset=us-ascii
> Content-Description: xm-i386interix.h
> Content-Disposition: attachment; filename="xm-i386interix.h"
> 
> /* Host-dependent definitions for i386 running Interix.
>    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 XM_I386INTERIX_H
> #define XM_I386INTERIX_H
> 
> /* FIXME: This file is only temporary, and the final intent is to get
>    rid of each macro defined here. This will be done later.  */
> 
> /* FIXME: configure should be taught about this. */
> #define PRINTF_HAS_LONG_LONG 1
> #ifdef __GNUC__
> #define BFD_HOST_64_BIT long long
> #define BFD_HOST_U_64_BIT unsigned long long
> #elif defined(_MSC_VER)
> #define BFD_HOST_64_BIT __int64
> #define BFD_HOST_U_64_BIT unsigned __int64
> #else
> #error... OK what compiler is this?
> #endif
> 
> /* FIXME: configure should be taught about this. */
> #undef LONGEST
> #define LONGEST BFD_HOST_64_BIT
> 
> /* FIXME: configure should be taught about this. */
> #undef ULONGEST
> #define ULONGEST BFD_HOST_U_64_BIT

This should really be addressed in BFD, not GDB.  I suspect that with
this approach you'll encounter problems when you build a 64-bit
enabled BFD.

> /* Interix has a minimal sbrk() (but not what's wanted for this usage),
>    and its relationship to environ[] is not what's usually expected
>    (as in, there is no specific relationship at all). Just pretend we don't
>    have an sbrk().  */
> #undef HAVE_SBRK
> 
> /*  Used in coffread.c to adjust the symbol offsets.  */
> #define ADJUST_OBJFILE_OFFSETS(objfile, type) \
>     pei_adjust_objfile_offsets(objfile, type)
> 
> extern CORE_ADDR bfd_getImageBase(bfd *abfd);
> #define NONZERO_LINK_BASE(abfd) bfd_getImageBase(abfd)
> 
> /*  Used in valops.c, to change the name of the malloc function when
>     trying to allocate memory in the inferior. On Interix, we need to
>     call _malloc.  Should this be added to the target vector?  */
> #define NAME_OF_MALLOC "_malloc"

This doesn't belong here.  Probably should be moved to your nm.h file.

> #endif /* XM_I386INTERIX_H */
> 
> 
> --BXVAT5kNtrzKuDFl
> Content-Type: text/plain; charset=us-ascii
> Content-Description: interix.mh
> Content-Disposition: attachment; filename="interix.mh"
> 
> # Host: Intel 386 running Interix
> XDEPFILES= 
> NATDEPFILES= corelow.o core-regset.o fork-child.o i386-interix-nat.o \
> 	procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o
> NAT_FILE= nm-interix.h
> XM_FILE= xm-i386interix.h
> # The below may be temporary; mmalloc relies on sbrk() at the moment
> MMALLOC=
> MMALLOC_CFLAGS=-DNO_MMALLOC
> 
> --BXVAT5kNtrzKuDFl
> Content-Type: text/plain; charset=us-ascii
> Content-Description: interix.mt
> Content-Disposition: attachment; filename="interix.mt"
> 
> # Target: Intel 386 running Interix
> TDEPFILES= i386-tdep.o i387-tdep.o i386-interix-tdep.o \
>         solib.o solib-pei.o
> TM_FILE= tm-i386.h
> 
> --BXVAT5kNtrzKuDFl
> Content-Type: text/plain; charset=us-ascii
> Content-Description: i386-interix-nat.c
> Content-Disposition: attachment; filename="i386-interix-nat.c"
> 
> /* Native-dependent code for Interix running on i386's, 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.  */
> 
> #include "defs.h"
> 
> #include <sys/procfs.h>
> #include <inferior.h>
> #include <fcntl.h>
> 
> #include <i386-tdep.h>
> #include "gdb_string.h"
> #include "gdbcore.h"
> #include "gregset.h"
> 
> typedef unsigned long greg_t;
> 
> /* This is a duplicate of the table in i386-linux-nat.c. */
> 
> static int regmap[] = {
>   EAX, ECX, EDX, EBX,
>   UESP, EBP, ESI, EDI,
>   EIP, EFL, CS, SS,
>   DS, ES, FS, GS,
> };
> 
> /* Forward declarations */
> extern void _initialize_core_interix (void);
> extern initialize_file_ftype _initialize_core_interix;
> 
> /*  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)
> {
>   int regi;
>   greg_t *regp = (greg_t *) & gregsetp->gregs;

Indent gets this wrong :-(.  Please remove the space after the ampersand.

>   for (regi = 0; regi < I386_NUM_GREGS; regi++)
>     {
>       supply_register (regi, (char *) (regp + regmap[regi]));
>     }
> }
> 
> /* Store GDB's value for REGNO in *GREGSETP.  If REGNO is -1, do all
>    of them.  */
> 
> void
> fill_gregset (gregset_t *gregsetp, int regno)
> {
>   int regi;
>   greg_t *regp = (greg_t *) gregsetp->gregs;
> 
>   for (regi = 0; regi < I386_NUM_GREGS; regi++)
>     if (regno == -1 || regi == regno)
>       regcache_collect (regi, (void *) (regp + regmap[regi]));
> }
> 
> /* Fill GDB's register file with the floating-point register values in
>    *FPREGSETP.  */
> 
> void
> supply_fpregset (fpregset_t *fpregsetp)
> {
>   i387_supply_fsave ((char *) fpregsetp);
> }
> 
> /* Given a pointer to a floating point register set in (fpregset_t *)
>    format, update all of the registers from gdb's idea of the current
>    floating point register set.  */
> 
> void
> fill_fpregset (fpregset_t *fpregsetp, int regno)
> {
>   i387_fill_fsave ((char *) fpregsetp, regno);
> }
> 
> /* 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.  */
> 
> static void
> fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
> 		      CORE_ADDR reg_addr)
> {
>   gdb_gregset_t gregset;
>   gdb_fpregset_t fpregset;
> 
>   if (which == 0)
>     {
>       if (core_reg_size != sizeof (gregset))
> 	{
> 	  warning ("wrong size gregset struct in core file");
> 	}
>       else
> 	{
> 	  memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset));
> 	  supply_gregset (&gregset);
> 	}
>     }
>   else if (which == 2)
>     {
>       if (core_reg_size != sizeof (fpregset))
> 	{
> 	  warning ("wrong size fpregset struct in core file");
> 	}
>       else
> 	{
> 	  memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset));
> 	  supply_fpregset (&fpregset);
> 	}
>     }
> }
> 
> #include <setjmp.h>
> 
> static struct core_fns interix_core_fns = {

Please move the bracket on to the next line.

>   bfd_target_coff_flavour,	/* core_flavour  (more or less) */
>   default_check_format,		/* check_format */
>   default_core_sniffer,		/* core_sniffer */
>   fetch_core_registers,		/* core_read_registers */
>   NULL				/* next */
> };
> 
> void
> _initialize_core_interix (void)
> {
>   add_core_fns (&interix_core_fns);
> }
> 
> /* We don't have a /proc/pid/file or /proc/pid/exe to read a link from,
>    so read it from the same place ps gets the name.  */
> 
> char *
> child_pid_to_exec_file (int pid)
> {
>   char *path;
>   char *buf;
>   int fd, c;
>   char *p;
> 
>   xasprintf (&path, "/proc/%d/stat", pid);
>   buf = xcalloc (MAXPATHLEN + 1, sizeof (char));
>   make_cleanup (xfree, path);
>   make_cleanup (xfree, buf);
> 
>   fd = open (path, O_RDONLY);
> 
>   if (fd < 0)
>     return NULL;
> 
>   /* Skip over "Argv0\t" */
>   lseek (fd, 6, SEEK_SET);
> 
>   c = read (fd, buf, MAXPATHLEN);
>   close (fd);
> 
>   if (c < 0)
>     return NULL;
> 
>   buf[c] = '\0';		/* Ensure null termintion. */
>   p = strchr (buf, '\n');
>   if (p != NULL)
>     *p = '\0';
> 
>   return buf;
> }
> 
> --BXVAT5kNtrzKuDFl
> Content-Type: text/plain; charset=us-ascii
> Content-Description: i386-interix-tdep.c
> Content-Disposition: attachment; filename="i386-interix-tdep.c"
> 
> /* Target-dependent code for Interix running on i386's, 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.  */
> 
> #include "defs.h"
> #include "arch-utils.h"
> 
> #include "frame.h"
> #include "gdb_string.h"
> #include "gdb-stabs.h"
> #include "gdbcore.h"
> #include "gdbtypes.h"
> #include "i386-tdep.h"
> #include "inferior.h"
> #include "libbfd.h"
> #include "objfiles.h"
> #include "osabi.h"
> 
> /* offsetof (mcontext_t, gregs.gregs[EBP]) */
> static const int mcontext_EBP_greg_offset = 180;
> 
> /* offsetof (mcontext_t, gregs.gregs[EIP]) */
> static const int mcontext_EIP_greg_offset = 184; 
> 
> /* offsetof (mcontext_t, gregs.gregs[UESP]) */
> static const int mcontext_UESP_greg_offset = 196;
> 
> /* offsetof (mcontext_t, gregs.reserved[1]) */
> static const int mcontext_syscall_greg_offset = 4;
> 
> /* offsetof (_JUMP_BUFFER, Eip) */
> static const int jump_buffer_Eip_offset = 20;
> 
> /* See procfs.c and *interix*.h in config/[alpha,i386] */
> /* ??? These should be static, but this needs a bit of work before this
>    can be done.  */
> CORE_ADDR tramp_start;
> CORE_ADDR tramp_end;
> CORE_ADDR null_start;
> CORE_ADDR null_end;
> int winver;			/* Windows NT version number */
> 
> /* Forward declarations */
> extern void _initialize_i386_interix_tdep (void);
> extern initialize_file_ftype _initialize_i386_interix_tdep;
> 
> /* Adjust the section offsets in an objfile structure so that it's correct
>    for the type of symbols being read (or undo it with the _restore
>    arguments).  
> 
>    If main programs ever start showing up at other than the default Image
>    Base, this is where that would likely be applied.  */
> 
> void
> pei_adjust_objfile_offsets (struct objfile *objfile,
> 			    enum objfile_adjusts type)
> {
>   int i;
>   CORE_ADDR symbols_offset;
> 
>   switch (type)
>     {
>     case adjust_for_symtab:
>       symbols_offset = NONZERO_LINK_BASE (objfile->obfd);
>       break;
>     case adjust_for_symtab_restore:
>       symbols_offset = -NONZERO_LINK_BASE (objfile->obfd);
>       break;
>     case adjust_for_stabs:
>     case adjust_for_stabs_restore:
>     case adjust_for_dwarf:
>     case adjust_for_dwarf_restore:
>     default:
>       return;
>     }
> 
>   for (i = 0; i < SECT_OFF_MAX; i++)
>     {
>       (objfile->section_offsets)->offsets[i] += symbols_offset;
>     }
> }
> 
> static int
> i386_interix_pc_in_sigtramp (CORE_ADDR pc, char *name)
> {
>   /* This is sufficient, where used, but is NOT a complete test; There
>      is more in INIT_EXTRA_FRAME_INFO (a.k.a. interix_back_one_frame) */
>   return (pc >= tramp_start && pc < tramp_end)
>     || (pc >= null_start && pc < null_end);

Please use an extra pair of braces to get the indentation right.

> }
> 
> static int
> i386_interix_in_solib_call_trampoline (CORE_ADDR pc, char *name)
> {
>   return skip_trampoline_code (pc, name);
> }

Didn't you rename skip_trampoline_code?

> static CORE_ADDR
> i386_interix_skip_trampoline_code (CORE_ADDR pc)
> {
>   return skip_trampoline_code (pc, 0);
> }

Likewise.

> static void
> i386_interix_init_frame_pc (int fromleaf, struct frame_info *prev)
> {
>   /* Nothing to do on Interix */
> }
> 
> static int
> i386_interix_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
> {
>   /* In the context where this is used, we get the saved PC before we've
>      successfully unwound far enough to be sure what we've got (it may
>      be a signal handler caller).  If we're dealing with a signal
>      handler caller, this will return valid, which is fine.  If not,
>      it'll make the correct test. */
>   return thisframe->signal_handler_caller
>     || (chain != 0
> 	&& !inside_entry_file (read_memory_integer (thisframe->frame + 4,
> 						    4)));

Again, please use an extra pair of braces.

> }
> 
> /* We want to find the previous frame, which on Interix is tricky when signals
>    are involved; set frame->frame appropriately, and also get the pc
>    and tweak signal_handler_caller; this replaces a boatload of nested
>    macros, as well. */
> static void
> i386_interix_back_one_frame (int fromleaf, struct frame_info *frame)
> {
>   CORE_ADDR ra;
>   CORE_ADDR fm;
>   CORE_ADDR context;
>   long t;
> 
>   if (frame == NULL)
>     internal_error (__FILE__, __LINE__, "unexpected NULL frame");
> 
>   if (fromleaf)
>     {
>       frame->pc = SAVED_PC_AFTER_CALL (frame->next);
>       return;
>     }
> 
>   if (!frame->next)
>     {
>       frame->pc = read_pc ();
> 
>       /* part of the signal stuff... see below */
>       if (stopped_by_random_signal)
> 	{
> 	  /* we know we're in a system call mini-frame; was it
> 	     NullApi or something else? */
> 	  ra = SAVED_PC_AFTER_CALL (frame);
> 	  if (ra >= null_start && ra < null_end)
> 	    frame->signal_handler_caller = 1;
> 	  /* There might also be an indirect call to the mini-frame,
> 	     putting one more return address on the stack.  (XP only,
> 	     I think?)  This can't (reasonably) return the address of the 
> 	     signal handler caller unless it's that situation, so this
> 	     is safe. */
> 	  ra =
> 	    read_memory_unsigned_integer (read_register (SP_REGNUM) + 4, 4);
> 	  if (ra >= null_start && ra < null_end)
> 	    frame->signal_handler_caller = 1;
> 	}
>       return;
>     }
> 
>   if (!frame->next->signal_handler_caller)
>     {
>       frame->pc = read_memory_integer (frame->next->frame + 4, 4);
>       return;
>     }
> 
>   /* This is messy... (actually AWFUL) the "trampoline" might be 2, 3 
>      or all 5 entities on the frame. 
> 
>      Chunk 1 will be present when we're actually in a signal handler.
>      Chunk 2 will be present when an asynchronous signal (one that
>      didn't come in with a system call) is present.
>      We may not (yet) be in the handler, if we're just returning
>      from the call.
>      When we're actually in a handler taken from an asynchronous
>      signal, both will be present.
> 
>      Chunk 1:
>      PdxSignalDeliverer's frame 
>      + Context struct    -- not accounted for in any frame
> 
>      Chunk 2:
>      + PdxNullPosixApi's frame 
>      + PdxNullApiCaller's frame
>      + Context struct = 0x230  not accounted for in any frame
> 
>      The symbol names come from examining objdumps of psxdll.dll;
>      they don't appear in the runtime image.
> 
>      For gdb's purposes, we can pile all this into one frame.
>    */
> 
>   ra = frame->next->pc;
>   /* Are we already pointing at PdxNullPosixApi?  We are if
>      this is a signal frame, we're at next-to-top, and were stopped
>      by a random signal.  (If it wasn't the right address under
>      these circumstances, we wouldn't be here at all by tests above
>      on the prior frame.) */
>   if (frame->next->next == NULL && stopped_by_random_signal)
>     {
>       /* We're pointing at the frame FOR PdxNullApi */
>       fm = frame->frame;
>     }
>   else
>     {
>       /* No... we must be pointing at the frame that
>          was called by PdxSignalDeliverer; back up across the
>          whole mess */
> 
>       /* extract the frame for PdxSignalDeliverer; note...FRAME_CHAIN
>          used the "old" frame pointer because we were a deliverer.
>          Get the address of the context record that's on here frameless */
>       context = read_memory_integer (frame->frame, 4);	/* an Arg */
> 
>       /* Now extract the frame pointer contained in the context */
>       fm = read_memory_integer (context + mcontext_EBP_greg_offset, 4);
> 
>       ra = read_memory_integer (context + mcontext_EIP_greg_offset, 4);
> 
>       /* We need to know if we're in a system call because we'll be
>          in a syscall mini-frame, if so, and the rules are different.  */
>       t = (long) read_memory_integer (context + mcontext_syscall_greg_offset,
>                                       4);
>       /* t contains 0 if running free, 1 if blocked on a system call,
>          and 2 if blocked on an exception message (e.g. a trap);
>          we don't expect to get here with a 2. */
>       if (t != 1)
> 	{
> 	  /* not at a system call, therefore it can't be NullApi */
> 	  frame->pc = ra;
> 	  frame->frame = fm;
> 	  return;
> 	}
> 
>       /* It's a system call... mini frame, then look for NullApi */
>       /* Get the RA (on the stack) associated with this... it's
>          a system call mini-frame */
>       ra = read_memory_integer (context + mcontext_UESP_greg_offset, 4);
> 
>       if (winver >= 51)
> 	{
> 	  /* Newer versions of Windows NT interpose another return
> 	     address (but no other "stack frame" stuff) that we need
> 	     to simply ignore here. */
> 	  ra += 4;
> 	}
> 
>       ra = read_memory_integer (ra, 4);
> 
>       /* We might be done (no Null API if so) */
>       if (!(ra >= null_start && ra < null_end))
> 	{
> 	  /* No Null API present; we're done */
> 	  frame->pc = ra;
> 	  frame->frame = fm;
> 	  return;
> 	}
>     }
>   /* At this point, we're looking at the frame for PdxNullPosixApi,
>      in either case.
> 
>      PdxNullPosixApi is called by PdxNullApiCaller (which in turn
>      is called by _PdxNullApiCaller (note the _).)
>      PdxNullPosixApiCaller (no _) is a frameless function.
> 
>      The saved frame pointer is as fm, but it's not of interest
>      to us because it skips us over the saved context, which is
>      the wrong thing to do, because it skips the interrrupted
>      routine!  PdxNullApiCaller takes as its only argument the
>      address of the context of the interrupded function (which
>      is really in no frame, but jammed on the stack by the system)
> 
>      So: fm+0: saved bp
>      fm+4: return address to _PdxNullApiCaller
>      fm+8: arg to PdxNullApiCaller pushed by _Pdx...  */
> 
>   fm = read_memory_integer (fm + 0x8, 4);
> 
>   /* Extract the second context record */
> 
>   ra = read_memory_integer (fm + mcontext_EIP_greg_offset, 4);
>   fm = read_memory_integer (fm + mcontext_EBP_greg_offset, 4);
> 
>   frame->frame = fm;
>   frame->pc = ra;
> 
>   return;
> }
> 
> static CORE_ADDR
> i386_interix_frame_saved_pc (struct frame_info *fi)
> {
>   /* Assume that we've already unwound enough to have the caller's address
>      if we're dealing with a signal handler caller.  (And if that fails,
>      return 0.)  */
>   if (fi->signal_handler_caller)
>     return fi->next ? fi->next->pc : 0;
>   else
>     return read_memory_integer (fi->frame + 4, 4);
> }
> 
> static void
> i386_interix_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
> {
>   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> 
>   tdep->struct_return = reg_struct_return;
>   tdep->jb_pc_offset = jump_buffer_Eip_offset;
> 
>   set_gdbarch_decr_pc_after_break (gdbarch, 0);
>   set_gdbarch_pc_in_sigtramp (gdbarch, i386_interix_pc_in_sigtramp);
>   set_gdbarch_in_solib_call_trampoline (gdbarch,
> 					i386_interix_in_solib_call_trampoline);
>   set_gdbarch_skip_trampoline_code (gdbarch,
> 				    i386_interix_skip_trampoline_code);
>   set_gdbarch_init_extra_frame_info (gdbarch, i386_interix_back_one_frame);
>   set_gdbarch_init_frame_pc (gdbarch, i386_interix_init_frame_pc);
>   set_gdbarch_frame_chain_valid (gdbarch, i386_interix_frame_chain_valid);
>   set_gdbarch_frame_saved_pc (gdbarch, i386_interix_frame_saved_pc);
> }
> 
> static enum gdb_osabi
> i386_interix_osabi_sniffer (bfd * abfd)
> {
>   char *target_name = bfd_get_target (abfd);
> 
>   if (strcmp (target_name, "pei-i386") == 0)
>     return GDB_OSABI_INTERIX;
> 
>   return GDB_OSABI_UNKNOWN;
> }
> 
> void
> _initialize_i386_interix_tdep (void)
> {
>   gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
> 				  i386_interix_osabi_sniffer);
> 
>   gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_INTERIX,
> 			  i386_interix_init_abi);
> }


You'll have to add these GDB_OSABI constants to osabi.h first.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]