Re: final i386.floating.record.patch

paawan oza
2009-08-21T16:31:12Z

[-- Attachment #1: Type: text/plain, Size: 15616 bytes --]

Hu Hui,
please find the ChageLog and floating point patch attached as you suggested.
Sorry for not pasting it in email-body becasue of space and tabs issues.
Do we need to update wiki?
Regards,
Oza.

--- On Wed, 8/19/09, Hui Zhu <teawater@gmail.com> wrote:

> From: Hui Zhu <teawater@gmail.com>
> Subject: Re: final i386.floating.record.patch
> To: "paawan oza" <paawan1982@yahoo.com>
> Cc: "Michael Snyder" <msnyder@vmware.com>, "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>, "Mark Kettenis" <mark.kettenis@xs4all.nl>
> Date: Wednesday, August 19, 2009, 7:47 AM
> Oops, this is not the bug in fp
> patch.  Sorry for it.
>
> After patch http://sourceware.org/ml/gdb-patches/2009-08/msg00272.html
>
> Everything is OK.
>
> I post a new patch that remove space in the tail.
> I think you need write a changelog.  You can get a
> example from
> src/ChangeLog.  Please Let each line doesn't bigger
> than 72.
>
> Thanks,
> Hui
>
> On Wed, Aug 19, 2009 at 09:13, Hui Zhu<teawater@gmail.com>
> wrote:
> > Could you try cvs-head?
> >
> > On Tue, Aug 18, 2009 at 21:48, paawan oza<paawan1982@yahoo.com>
> wrote:
> >> Hi,
> >>
> >> Another analysis and observation is:
> >>
> >> I used gdb-6.8.50.20090803 and everything seemed
> okay.
> >> Hui used gdb-6.8.50.20090817 and patch was still
> the same and gdb threw these error.
> >> was there any thing major changed in gdb ?
> >>
> >> and gdb throws error in
> >> ../../src/gdb/utils.c:1200:
> >>
> >> which looks like somebody has allocated memory too
> much or something has gone wrong in error checking.
> >>
> >>
> >> the floating-point-patch is still the same, if it
> works fine with gdb-6.8.50.20090803, it is high unlikely
> that why should it throw memory allocation error with
> gdb-6.8.50.20090817 (unless system is dangerously low in
> virtual memory, swap space is full).
> >>
> >> Regards,
> >> Oza.
> >>
> >>
> >>
> >> --- On Mon, 8/17/09, paawan oza <paawan1982@yahoo.com>
> wrote:
> >>
> >>> From: paawan oza <paawan1982@yahoo.com>
> >>> Subject: Re: final i386.floating.record.patch
> >>> To: "Michael Snyder" <msnyder@vmware.com>,
> "Hui Zhu" <teawater@gmail.com>
> >>> Cc: "gdb-patches@sourceware.org"
> <gdb-patches@sourceware.org>,
> "Mark Kettenis" <mark.kettenis@xs4all.nl>
> >>> Date: Monday, August 17, 2009, 9:40 PM
> >>> Hi Hui,
> >>>
> >>> I test the same and it seems working fine.
> Another thing I
> >>> observe is, vertual memory is low problem and
> may be gdb's
> >>> virtual address space gets exhausted or any
> other limit!
> >>> highly unlikely though.
> >>>
> >>> please see the atached log.
> >>>
> >>>
> linux-p94d:/home/oza/mk_patch/take_diff/gdb_current/gdb-6.8.50.20090803/gdb
> >>> # ./gdb ./test_floats
> >>> GNU gdb (GDB) 6.8.50.20090803
> >>> Copyright (C) 2009 Free Software Foundation,
> Inc.
> >>> License GPLv3+: GNU GPL version 3 or later
> <http://gnu.org/licenses/gpl.html>
> >>> This is free software: you are free to change
> and
> >>> redistribute it.
> >>> There is NO WARRANTY, to the extent permitted
> by law.
> >>> Type "show copying"
> >>> and "show warranty" for details.
> >>> This GDB was configured as
> "i686-pc-linux-gnu".
> >>> For bug reporting instructions, please see:
> >>> <http://www.gnu.org/software/gdb/bugs/>...
> >>> Setting up the environment for debugging gdb.
> >>> Function "internal_error" not defined.
> >>> Make breakpoint pending on future shared
> library load? (y
> >>> or [n]) [answered N; input not from terminal]
> >>> Function "info_command" not defined.
> >>> Make breakpoint pending on future shared
> library load? (y
> >>> or [n]) [answered N; input not from terminal]
> >>>
> /home/oza/mk_patch/take_diff/gdb_current/gdb-6.8.50.20090803/gdb/.gdbinit:8:
> >>> Error in sourced command file:
> >>> No breakpoint number 0.
> >>> (gdb) start
> >>> Temporary breakpoint 1 at 0x8048c94: file
> ./test_floats.c,
> >>> line 196.
> >>> Starting program:
> >>>
> /home/oza/mk_patch/take_diff/gdb_current/gdb-6.8.50.20090803/gdb/test_floats
> >>>
> >>> Temporary breakpoint 1, main () at
> ./test_floats.c:196
> >>> 196         init_floats();
> >>> (gdb) record
> >>> (gdb) c
> >>> Continuing.
> >>> result is 369.438751
> >>> result is 10.320001
> >>> result is 23.008301
> >>> result is 0.000000
> >>> result is 10.450000
> >>> result is 10.776012
> >>> result is 495830.968750
> >>> result is -181.778748
> >>> result is 12.525923
> >>> result is 2.195619
> >>> result is 5.055601
> >>> result is inf
> >>> result is inf
> >>> result is -0.988032
> >>> result is 0.154251
> >>> result is -6.405331
> >>> result is 1.537475
> >>> The next instruction is syscall exit_group.
> It will
> >>> make the program exit.  Do you want to stop
> the
> >>> program?([y] or n) y
> >>> Process record: inferior program stopped.
> >>>
> >>> Program received signal SIGTRAP,
> Trace/breakpoint trap.
> >>> 0xffffe405 in __kernel_vsyscall ()
> >>> (gdb)
> >>>
> >>> Regards,
> >>> Oza.
> >>>
> >>>
> >>>
> >>>
> >>> --- On Mon, 8/17/09, Hui Zhu <teawater@gmail.com>
> >>> wrote:
> >>>
> >>> > From: Hui Zhu <teawater@gmail.com>
> >>> > Subject: Re: final
> i386.floating.record.patch
> >>> > To: "Michael Snyder" <msnyder@vmware.com>
> >>> > Cc: "paawan oza" <paawan1982@yahoo.com>,
> >>> "gdb-patches@sourceware.org"
> >>> <gdb-patches@sourceware.org>,
> >>> "Mark Kettenis" <mark.kettenis@xs4all.nl>
> >>> > Date: Monday, August 17, 2009, 12:06 PM
> >>> > Get some error with this patch.
> >>> > cat fp.c
> >>> > #include <stdio.h>
> >>> > #include <math.h>
> >>> > #include <stdlib.h>
> >>> >
> >>> > /* the test intends to test following
> insns.
> >>> > flds faddp fstps fstpl fldl fxch fabs
> fdivrp fmulp
> >>> fsubrp
> >>> > fucomp fnstsw fsqrt
> >>> > fchs f2xm1 fyl2x fxtract fprem1 fld
> fdecstp fld1
> >>> fldl2t
> >>> > fldl2e FLDPI
> >>> > FLDLG2 FLDLN2
> >>> > FLDZ fincstp ffree fptan fpatan fincstp
> fsincos
> >>> frndint
> >>> > fscale fsin fcos fcmovb
> >>> > fcmovbe fcmove fcmovu fcmovnb fcmovnbe
> fsave frstor
> >>> fstsw
> >>> > */
> >>> >
> >>> > float no1,no2,no3,no4,no5,no6,no7;
> >>> > double x = 100.345, y = 25.7789;
> >>> > long double ldx =
> 88888888888888888888.88, ldy =
> >>> > 9999999999999999999.99;
> >>> > float result,resultd,resultld;
> >>> > float *float_memory;
> >>> >
> >>> > /* initialization of floats */
> >>> > void init_floats()
> >>> > {
> >>> >  no1 = 10.45;
> >>> >  no2 = 20.77;
> >>> >  no3 = 156.89874646;
> >>> >  no4 = 14.56;
> >>> >  no5 = 11.11;
> >>> >  no6 = 66.77;
> >>> >  no7 = 88.88;
> >>> >  float_memory = malloc(sizeof(float) *
> 4);
> >>> >  *float_memory = 256.256;
> >>> >  *(float_memory + 1) = 356.356;
> >>> >  *(float_memory + 2) = 456.456;
> >>> >  *(float_memory + 3) = 556.556;
> >>> > }
> >>> >
> >>> > /* marks FPU stack as empty */
> >>> > void empty_fpu_stack()
> >>> > {
> >>> >  asm ("ffree %st(1) \n\t"
> >>> >       "ffree %st(2) \n\t"
> >>> >       "ffree %st(3) \n\t"
> >>> >       "ffree %st(4) \n\t"
> >>> >       "ffree %st(5) \n\t"
> >>> >       "ffree %st(6) \n\t"
> >>> >       "ffree %st(7)");
> >>> > }
> >>> >
> >>> > /* tests floating point arithmatic */
> >>> > void test_arith_floats()
> >>> > {
> >>> >  result = no1 + no2 + no3 + no4 + no5 +
> no6 +
> >>> no7;
> >>> >  printf("result is %f\n",result);
> >>> >
> >>> >  result = fmodf(no2,no1);
> >>> >  printf("result is %f\n",result);
> >>> >
> >>> >  resultd = fmod(x,y);
> >>> >  printf("result is %f\n",resultd);
> >>> >
> >>> >  resultld = fmodl(ldy,ldy);
> >>> >  printf("result is %f\n",resultld);
> >>> >
> >>> >  result = fabsf(no1);
> >>> >  printf("result is %f\n",result);
> >>> >
> >>> >  result = no3 / no4;
> >>> >  printf("result is %f\n",result);
> >>> >
> >>> >  result = no1 * no2 * no3 * no4;
> >>> >  printf("result is %f\n",result);
> >>> >
> >>> >  result = no1 - no2 - no3 - no4;
> >>> >  printf("result is %f\n",result);
> >>> >
> >>> >
> >>> >  asm ("fld %0" : :"m"(*float_memory));
> >>> >  asm ("fchs");
> >>> >
> >>> >  /* test for f2xm1 */
> >>> >  asm ("fld %0" : :"m"(*float_memory));
> >>> >  asm ("f2xm1");
> >>> >
> >>> >  asm ("fyl2x");
> >>> >
> >>> >  asm ("fld %0" : :"m"(*float_memory));
> >>> >  asm ("fxtract");
> >>> >
> >>> >  asm ("fld %0" : :"m"(*float_memory));
> >>> >  asm ("fprem1");
> >>> >
> >>> >  /* decrement fpu stack pointer only
> status
> >>> register should
> >>> > get affected */
> >>> >  asm ("fld %0" : :"m"(*float_memory));
> >>> >
> >>> >  empty_fpu_stack();
> >>> >
> >>> >  asm ("fld1");
> >>> >  asm ("fldl2t");
> >>> >  asm ("fldl2e");
> >>> >  asm ("fldpi");
> >>> >  asm ("fldlg2");
> >>> >  asm ("fldln2");
> >>> >  asm ("fldz");
> >>> >
> >>> >  empty_fpu_stack();
> >>> >  /* finishing emptying the stack */
> >>> >
> >>> >  result = sqrt(no3);
> >>> >  printf("result is %f\n",result);
> >>> > }
> >>> >
> >>> > void test_log_exp_floats()
> >>> > {
> >>> >  result = log10(no3);
> >>> >  printf("result is %f\n",result);
> >>> >
> >>> >  result = log(no3);
> >>> >  printf("result is %f\n",result);
> >>> >
> >>> >  result = exp10(no3);
> >>> >  printf("result is %f\n",result);
> >>> >
> >>> >  result = exp(no3);
> >>> >  printf("result is %f\n",result);
> >>> > }
> >>> >
> >>> > void test_trigo_floats()
> >>> > {
> >>> >  result = sin(30);
> >>> >  printf("result is %f\n",result);
> >>> >
> >>> >  result = cos(30);
> >>> >  printf("result is %f\n",result);
> >>> >
> >>> >  result = tan(30);
> >>> >  printf("result is %f\n",result);
> >>> >
> >>> >  result = atan(30);
> >>> >  printf("result is %f\n",result);
> >>> >
> >>> >  asm ("fld %0" : :"m"(*float_memory));
> >>> >  asm ("fptan");
> >>> >
> >>> >  /* changes st1 and popping register
> stack */
> >>> >  asm ("fpatan");
> >>> >
> >>> >  asm("fincstp");
> >>> >  asm ("fld %0" : :"m"(float_memory));
> >>> >  asm ("fsincos");
> >>> >
> >>> >  asm ("fld %0" : :"m"(*float_memory));
> >>> >  asm ("frndint");
> >>> >
> >>> >  asm ("fld %0" : :"m"(*float_memory));
> >>> >  asm ("fld %0" :
> :"m"(*(float_memory+1)));
> >>> >  asm ("fscale");
> >>> >
> >>> >  empty_fpu_stack();
> >>> >
> >>> >  asm ("fld %0" : :"m"(*float_memory));
> >>> >  asm ("fsin");
> >>> >  asm ("fcos");
> >>> >
> >>> >  /* currently we assume condition likely
> and
> >>> always record
> >>> > the registers
> >>> >  code could be optimized only if the
> flag is set
> >>> then
> >>> > record */
> >>> >  asm ("fld %0" : :"m"(*float_memory));
> >>> >  asm ("fld %0" :
> :"m"(*(float_memory+1)));
> >>> >  asm ("fcmovb %st(1), %st");
> >>> >  asm ("fcmovbe %st(1), %st");
> >>> >  asm ("fcmove %st(1), %st");
> >>> >  asm ("fcmovu %st(1), %st");
> >>> >  asm ("fcmovnb %st(1), %st");
> >>> >  asm ("fcmovnbe %st(1), %st");
> >>> >
> >>> >  empty_fpu_stack();
> >>> >  /* finished emtyping the stack */
> >>> > }
> >>> >
> >>> > void test_compare_floats()
> >>> > {
> >>> >    ldy = 88888888888888888888.88;
> >>> >    if (ldx == ldy)
> >>> >      ldy =
> >>> > 7777777777777777777777777777.777;
> >>> >    else
> >>> >      ldy =
> >>> > 666666666666666666666666666.666;
> >>> > }
> >>> >
> >>> > /* test loading and saving of FPU
> environment */
> >>> > void test_fpu_env()
> >>> > {
> >>> >  asm ("fsave %0" : "=m"(*float_memory) :
> );
> >>> >  asm ("frstor %0" : :
> "m"(*float_memory));
> >>> >  asm ("fstsw %ax");
> >>> > }
> >>> >
> >>> > int main()
> >>> > {
> >>> >    init_floats();
> >>> >    test_arith_floats();
> >>> >    test_log_exp_floats();
> >>> >    test_trigo_floats();
> >>> >    test_compare_floats();
> >>> >    test_fpu_env();
> >>> > }
> >>> >
> >>> >
> >>> >
> >>> > ./gdb ./a.out
> >>> > GNU gdb (GDB) 6.8.50.20090817-cvs
> >>> > Copyright (C) 2009 Free Software
> Foundation, Inc.
> >>> > License GPLv3+: GNU GPL version 3 or
> later <http://gnu.org/licenses/gpl.html>
> >>> > This is free software: you are free to
> change and
> >>> > redistribute it.
> >>> > There is NO WARRANTY, to the extent
> permitted by
> >>> law.
> >>> > Type "show copying"
> >>> > and "show warranty" for details.
> >>> > This GDB was configured as
> "i686-pc-linux-gnu".
> >>> > For bug reporting instructions, please
> see:
> >>> > <http://www.gnu.org/software/gdb/bugs/>...
> >>> > Setting up the environment for debugging
> gdb.
> >>> > Function "internal_error" not defined.
> >>> > Make breakpoint pending on future shared
> library load?
> >>> (y
> >>> > or [n])
> >>> > [answered N; input not from terminal]
> >>> > Function "info_command" not defined.
> >>> > Make breakpoint pending on future shared
> library load?
> >>> (y
> >>> > or [n])
> >>> > [answered N; input not from terminal]
> >>> > /home/teawater/gdb/bgdbno/gdb/.gdbinit:8:
> Error in
> >>> sourced
> >>> > command file:
> >>> > No breakpoint number 0.
> >>> > (gdb) start
> >>> > During symbol reading, DW_AT_name missing
> from
> >>> > DW_TAG_base_type.
> >>> > Temporary breakpoint 1 at 0x8048c74: file
> fp.c, line
> >>> 196.
> >>> > Starting program:
> /home/teawater/gdb/bgdbno/gdb/a.out
> >>> >
> >>> > Temporary breakpoint 1, main () at
> fp.c:196
> >>> > 196       init_floats();
> >>> > (gdb) record
> >>> > (gdb) c
> >>> > Continuing.
> >>> > ../../src/gdb/utils.c:1200:
> internal-error: virtual
> >>> memory
> >>> > exhausted.
> >>> > A problem internal to GDB has been
> detected,
> >>> > further debugging may prove unreliable.
> >>> > Quit this debugging session? (y or n) n
> >>> > ../../src/gdb/utils.c:1200:
> internal-error: virtual
> >>> memory
> >>> > exhausted.
> >>> > A problem internal to GDB has been
> detected,
> >>> > further debugging may prove unreliable.
> >>> > Create a core file of GDB? (y or n) n
> >>> >
> >>> > Program received signal SIGTRAP,
> Trace/breakpoint
> >>> trap.
> >>> > 0xb7eba9bc in memcpy () from
> >>> /lib/tls/i686/cmov/libc.so.6
> >>> > (gdb) quit
> >>> > A debugging session is active.
> >>> >
> >>> >     Inferior 1 [process 15657] will
> be
> >>> > killed.
> >>> >
> >>> > Quit anyway? (y or n) y
> >>> >
> >>> >
> >>> > Thanks,
> >>> > Hui
> >>> >
> >>> > On Mon, Aug 17, 2009 at 05:16, Michael
> Snyder<msnyder@vmware.com>
> >>> > wrote:
> >>> > > paawan oza wrote:
> >>> > >>
> >>> > >> Hi Hui & Michael,
> >>> > >> Now we revert status registers
> also.
> >>> > >> please find the patch attached.
> >>> > >> I am sorry, if I am not pasting
> the patch in
> >>> > email-body due to tabs&spaces
> >>> > >> problem faced by Michael last
> time.
> >>> > >> Regards,
> >>> > >> Oza.
> >>> > >
> >>> > > Looking good!
> >>> > >
> >>> > > There were some conflicts between
> your changes
> >>> and a
> >>> > check-in that
> >>> > > happened after your submission  --
>  I've taken
> >>> the
> >>> > liberty of merging
> >>> > > your changes with the cvs head,
> fixing up the
> >>> > conflicts.  Hope you
> >>> > > don't mind  --  merged patch
> attached.
> >>> > >
> >>> > > I'll review your tests next.
> >>> > >
> >>> > > Can you write up a change log entry
> for this
> >>> patch?
> >>> > >
> >>> > > Hui, Mark, any more comments?
> >>> > >
> >>> > > Cheers,
> >>> > > Michael
> >>> > >
> >>> > >
> >>> > >
> >>> > >
> >>> > >
> >>> >
> >>>
> >>>
> >>>
> >>>
> >>
> >>
> >>
> >>
> >
>

[-- Attachment #2: i386.record.float.aug-21.patch --]
[-- Type: application/octet-stream, Size: 14363 bytes --]

---
i386-tdep.c | 389 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 369 insertions(+), 20 deletions(-)

--- a/i386-tdep.c
+++ b/i386-tdep.c
@@ -3196,6 +3196,74 @@ i386_record_push (struct i386_record_s *
return 0;
}

+
+/* Defines contents to record. */
+#define I386_SAVE_FPU_REGS 0xfffd
+#define I386_SAVE_FPU_ENV 0xfffe
+#define I386_SAVE_FPU_ENV_REG_STACK 0xffff
+
+/* Record the value of floating point registers which will be changed by the
+ current instruction to "record_arch_list". Return -1 if something is wrong.
+*/
+
+static int i386_record_floats (struct gdbarch *gdbarch,
+ struct i386_record_s *ir,
+ uint32_t iregnum)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int i;
+
+ /* Oza: Because of floating point insn push/pop of fpu stack is going to
+ happen. Currently we store st0-st7 registers, but we need not store all
+ registers all the time, in future we use ftag register and record only
+ those who are not marked as an empty. */
+
+ if (I386_SAVE_FPU_REGS == iregnum)
+ {
+ for (i = I387_ST0_REGNUM (tdep); i <= I387_ST0_REGNUM (tdep) + 7; i++)
+ {
+ if (record_arch_list_add_reg (ir->regcache, i))
+ return -1;
+ }
+ }
+ else if (I386_SAVE_FPU_ENV == iregnum)
+ {
+ for (i = I387_FCTRL_REGNUM (tdep); i <= I387_FOP_REGNUM (tdep); i++)
+ {
+ if (record_arch_list_add_reg (ir->regcache, i))
+ return -1;
+ }
+ }
+ else if (I386_SAVE_FPU_ENV_REG_STACK == iregnum)
+ {
+ for (i = I387_ST0_REGNUM (tdep); i <= I387_FOP_REGNUM (tdep); i++)
+ {
+ if (record_arch_list_add_reg (ir->regcache, i))
+ return -1;
+ }
+ }
+ else if ((iregnum >= I387_ST0_REGNUM (tdep)) &&
+ (iregnum <= I387_FOP_REGNUM (tdep)))
+ {
+ if (record_arch_list_add_reg (ir->regcache,iregnum))
+ return -1;
+ }
+ else
+ {
+ /* Parameter error. */
+ return -1;
+ }
+ if(I386_SAVE_FPU_ENV != iregnum)
+ {
+ for (i = I387_FCTRL_REGNUM (tdep); i <= I387_FOP_REGNUM (tdep); i++)
+ {
+ if (record_arch_list_add_reg (ir->regcache, i))
+ return -1;
+ }
+ }
+ return 0;
+}
+
/* Parse the current instruction and record the values of the registers and
memory that will be changed in current instruction to "record_arch_list".
Return -1 if something wrong. */
@@ -3214,6 +3282,7 @@ i386_process_record (struct gdbarch *gdb
ULONGEST tmpulongest;
uint32_t opcode;
struct i386_record_s ir;
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int rex = 0;
uint8_t rex_w = -1;
uint8_t rex_r = 0;
@@ -4260,8 +4329,7 @@ reswitch:
}
break;

- /* floats */
- /* It just record the memory change of instrcution. */
+ /* Floats. */
case 0xd8:
case 0xd9:
case 0xda:
@@ -4275,45 +4343,56 @@ reswitch:
ir.reg |= ((opcode & 7) << 3);
if (ir.mod != 3)
{
- /* memory */
+ /* Memory. */
uint64_t tmpu64;

if (i386_record_lea_modrm_addr (&ir, &tmpu64))
return -1;
switch (ir.reg)
{
- case 0x00:
- case 0x01:
case 0x02:
+ case 0x12:
+ case 0x22:
+ case 0x32:
+ /* For fcom, ficom nothing to do. */
+ break;
case 0x03:
+ case 0x13:
+ case 0x23:
+ case 0x33:
+ /* For fcomp, ficomp pop FPU stack, store all. */
+ if (i386_record_floats (gdbarch, &ir, I386_SAVE_FPU_REGS))
+ return -1;
+ break;
+ case 0x00:
+ case 0x01:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x10:
case 0x11:
- case 0x12:
- case 0x13:
case 0x14:
case 0x15:
case 0x16:
case 0x17:
case 0x20:
case 0x21:
- case 0x22:
- case 0x23:
case 0x24:
case 0x25:
case 0x26:
case 0x27:
case 0x30:
case 0x31:
- case 0x32:
- case 0x33:
case 0x34:
case 0x35:
case 0x36:
case 0x37:
+ /* For fadd, fmul, fsub, fsubr, fdiv, fdivr, fiadd, fimul,
+ fisub, fisubr, fidiv, fidivr, modR/M.reg is an extension
+ of code, always affects st(0) register. */
+ if (i386_record_floats (gdbarch, &ir, I387_ST0_REGNUM (tdep)))
+ return -1;
break;
case 0x08:
case 0x0a:
@@ -4322,6 +4401,7 @@ reswitch:
case 0x19:
case 0x1a:
case 0x1b:
+ case 0x1d:
case 0x28:
case 0x29:
case 0x2a:
@@ -4330,9 +4410,14 @@ reswitch:
case 0x39:
case 0x3a:
case 0x3b:
+ case 0x3c:
+ case 0x3d:
switch (ir.reg & 7)
{
case 0:
+ /* Handling fld, fild. */
+ if (i386_record_floats (gdbarch, &ir, I386_SAVE_FPU_REGS))
+ return -1;
break;
case 1:
switch (ir.reg >> 4)
@@ -4346,6 +4431,7 @@ reswitch:
return -1;
break;
case 3:
+ break;
default:
if (record_arch_list_add_mem (tmpu64, 2))
return -1;
@@ -4356,15 +4442,49 @@ reswitch:
switch (ir.reg >> 4)
{
case 0:
+ if (record_arch_list_add_mem (tmpu64, 4))
+ return -1;
+ if (3 == (ir.reg & 7))
+ {
+ /* For fstp m32fp. */
+ if (i386_record_floats (gdbarch, &ir,
+ I386_SAVE_FPU_REGS))
+ return -1;
+ }
+ break;
case 1:
if (record_arch_list_add_mem (tmpu64, 4))
return -1;
+ if ((3 == (ir.reg & 7))
+ || (5 == (ir.reg & 7))
+ || (7 == (ir.reg & 7)))
+ {
+ /* For fstp insn. */
+ if (i386_record_floats (gdbarch, &ir,
+ I386_SAVE_FPU_REGS))
+ return -1;
+ }
break;
case 2:
if (record_arch_list_add_mem (tmpu64, 8))
return -1;
+ if (3 == (ir.reg & 7))
+ {
+ /* For fstp m64fp. */
+ if (i386_record_floats (gdbarch, &ir,
+ I386_SAVE_FPU_REGS))
+ return -1;
+ }
break;
case 3:
+ if ((3 <= (ir.reg & 7)) && (6 <= (ir.reg & 7)))
+ {
+ /* For fistp, fbld, fild, fbstp. */
+ if (i386_record_floats (gdbarch, &ir,
+ I386_SAVE_FPU_REGS))
+ return -1;
+ }
+ /* Fall through */
default:
if (record_arch_list_add_mem (tmpu64, 2))
return -1;
@@ -4374,11 +4494,21 @@ reswitch:
}
break;
case 0x0c:
+ /* Insn fldenv. */
+ if (i386_record_floats (gdbarch, &ir,
+ I386_SAVE_FPU_ENV_REG_STACK))
+ return -1;
+ break;
case 0x0d:
- case 0x1d:
+ /* Insn fldcw. */
+ if (i386_record_floats (gdbarch, &ir, I387_FCTRL_REGNUM (tdep)))
+ return -1;
+ break;
case 0x2c:
- case 0x3c:
- case 0x3d:
+ /* Insn frstor. */
+ if (i386_record_floats (gdbarch, &ir,
+ I386_SAVE_FPU_ENV_REG_STACK))
+ return -1;
break;
case 0x0e:
if (ir.dflag)
@@ -4396,6 +4526,9 @@ reswitch:
case 0x2f:
if (record_arch_list_add_mem (tmpu64, 2))
return -1;
+ /* Insn fstp, fbstp. */
+ if (i386_record_floats (gdbarch, &ir, I386_SAVE_FPU_REGS))
+ return -1;
break;
case 0x1f:
case 0x3e:
@@ -4417,10 +4550,17 @@ reswitch:
}
if (record_arch_list_add_mem (tmpu64, 80))
return -1;
+ /* Insn fsave. */
+ if (i386_record_floats (gdbarch, &ir,
+ I386_SAVE_FPU_ENV_REG_STACK))
+ return -1;
break;
case 0x3f:
if (record_arch_list_add_mem (tmpu64, 8))
return -1;
+ /* Insn fistp. */
+ if (i386_record_floats (gdbarch, &ir, I386_SAVE_FPU_REGS))
+ return -1;
break;
default:
ir.addr -= 2;
@@ -4429,8 +4569,211 @@ reswitch:
break;
}
}
+ /* Opcode is an extension of modR/M byte. */
+ else
+ {
+ switch (opcode)
+ {
+ case 0xd8:
+ if (i386_record_floats (gdbarch, &ir, I387_ST0_REGNUM (tdep)))
+ return -1;
+ break;
+ case 0xd9:
+ if (0x0c == (ir.modrm >> 4))
+ {
+ if ((ir.modrm & 0x0f) <= 7)
+ {
+ if (i386_record_floats (gdbarch, &ir,
+ I386_SAVE_FPU_REGS))
+ return -1;
+ }
+ else
+ {
+ if (i386_record_floats (gdbarch, &ir,
+ I387_ST0_REGNUM (tdep)))
+ return -1;
+ /* If only st(0) is changing, then we have already
+ recorded. */
+ if ((ir.modrm & 0x0f) - 0x08)
+ {
+ if (i386_record_floats (gdbarch, &ir,
+ I387_ST0_REGNUM (tdep) +
+ ((ir.modrm & 0x0f) - 0x08)))
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ switch (ir.modrm)
+ {
+ case 0xe0:
+ case 0xe1:
+ case 0xf0:
+ case 0xf5:
+ case 0xf8:
+ case 0xfa:
+ case 0xfc:
+ case 0xfe:
+ case 0xff:
+ if (i386_record_floats (gdbarch, &ir,
+ I387_ST0_REGNUM (tdep)))
+ return -1;
+ break;
+ case 0xf1:
+ case 0xf2:
+ case 0xf3:
+ case 0xf4:
+ case 0xf6:
+ case 0xf7:
+ case 0xe8:
+ case 0xe9:
+ case 0xea:
+ case 0xeb:
+ case 0xec:
+ case 0xed:
+ case 0xee:
+ case 0xf9:
+ case 0xfb:
+ if (i386_record_floats (gdbarch, &ir,
+ I386_SAVE_FPU_REGS))
+ return -1;
+ break;
+ case 0xfd:
+ if (i386_record_floats (gdbarch, &ir,
+ I387_ST0_REGNUM (tdep)))
+ return -1;
+ if (i386_record_floats (gdbarch, &ir,
+ I387_ST0_REGNUM (tdep) + 1))
+ return -1;
+ break;
+ }
+ }
+ break;
+ case 0xda:
+ if (0xe9 == ir.modrm)
+ {
+ if (i386_record_floats (gdbarch, &ir, I386_SAVE_FPU_REGS))
+ return -1;
+ }
+ else if ((0x0c == ir.modrm >> 4) || (0x0d == ir.modrm >> 4))
+ {
+ if (i386_record_floats (gdbarch, &ir,
+ I387_ST0_REGNUM (tdep)))
+ return -1;
+ if (((ir.modrm & 0x0f) > 0) && ((ir.modrm & 0x0f) <= 7))
+ {
+ if (i386_record_floats (gdbarch, &ir,
+ I387_ST0_REGNUM (tdep) +
+ (ir.modrm & 0x0f)))
+ return -1;
+ }
+ else if ((ir.modrm & 0x0f) - 0x08)
+ {
+ if (i386_record_floats (gdbarch, &ir,
+ I387_ST0_REGNUM (tdep) +
+ ((ir.modrm & 0x0f) - 0x08)))
+ return -1;
+ }
+ }
+ break;
+ case 0xdb:
+ if (0xe3 == ir.modrm)
+ {
+ if (i386_record_floats (gdbarch, &ir, I386_SAVE_FPU_ENV))
+ return -1;
+ }
+ else if ((0x0c == ir.modrm >> 4) || (0x0d == ir.modrm >> 4))
+ {
+ if (i386_record_floats (gdbarch, &ir,
+ I387_ST0_REGNUM (tdep)))
+ return -1;
+ if (((ir.modrm & 0x0f) > 0) && ((ir.modrm & 0x0f) <= 7))
+ {
+ if (i386_record_floats (gdbarch, &ir,
+ I387_ST0_REGNUM (tdep) +
+ (ir.modrm & 0x0f)))
+ return -1;
+ }
+ else if ((ir.modrm & 0x0f) - 0x08)
+ {
+ if (i386_record_floats (gdbarch, &ir,
+ I387_ST0_REGNUM (tdep) +
+ ((ir.modrm & 0x0f) - 0x08)))
+ return -1;
+ }
+ }
+ break;
+ case 0xdc:
+ if ((0x0c == ir.modrm >> 4)
+ || (0x0d == ir.modrm >> 4)
+ || (0x0f == ir.modrm >> 4))
+ {
+ if ((ir.modrm & 0x0f) <= 7)
+ {
+ if (i386_record_floats (gdbarch, &ir,
+ I387_ST0_REGNUM (tdep) +
+ (ir.modrm & 0x0f)))
+ return -1;
+ }
+ else
+ {
+ if (i386_record_floats (gdbarch, &ir,
+ I387_ST0_REGNUM (tdep) +
+ ((ir.modrm & 0x0f) - 0x08)))
+ return -1;
+ }
+ }
+ break;
+ case 0xdd:
+ if (0x0c == ir.modrm >> 4)
+ {
+ if (i386_record_floats (gdbarch, &ir,
+ I387_FTAG_REGNUM (tdep)))
+ return -1;
+ }
+ else if ((0x0d == ir.modrm >> 4) || (0x0e == ir.modrm >> 4))
+ {
+ if ((ir.modrm & 0x0f) <= 7)
+ {
+ if (i386_record_floats (gdbarch, &ir,
+ I387_ST0_REGNUM (tdep) +
+ (ir.modrm & 0x0f)))
+ return -1;
+ }
+ else
+ {
+ if (i386_record_floats (gdbarch, &ir,
+ I386_SAVE_FPU_REGS))
+ return -1;
+ }
+ }
+ break;
+ case 0xde:
+ if ((0x0c == ir.modrm >> 4)
+ || (0x0e == ir.modrm >> 4)
+ || (0x0f == ir.modrm >> 4)
+ || (0xd9 == ir.modrm))
+ {
+ if (i386_record_floats (gdbarch, &ir, I386_SAVE_FPU_REGS))
+ return -1;
+ }
+ break;
+ case 0xdf:
+ if (0xe0 == ir.modrm)
+ {
+ if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
+ return -1;
+ }
+ else if ((0x0f == ir.modrm >> 4) || (0x0e == ir.modrm >> 4))
+ {
+ if (i386_record_floats (gdbarch, &ir, I386_SAVE_FPU_REGS))
+ return -1;
+ }
+ break;
+ }
+ }
break;
-
/* string ops */
/* movsS */
case 0xa4:
@@ -4835,12 +5178,18 @@ reswitch:
break;

/* fwait */
- /* XXX */
case 0x9b:
- printf_unfiltered (_("Process record doesn't support instruction "
- "fwait.\n"));
- ir.addr -= 1;
- goto no_support;
+ if (target_read_memory (ir.addr, &tmpu8, 1))
+ {
+ if (record_debug)
+ printf_unfiltered (_("Process record: error reading memory at "
+ "addr 0x%s len = 1.\n"),
+ paddress (gdbarch, ir.addr));
+ return -1;
+ }
+ opcode = (uint32_t) tmpu8;
+ ir.addr++;
+ goto reswitch;
break;

/* int3 */

[-- Attachment #3: floating.ChangeLog.patch --]
[-- Type: application/octet-stream, Size: 453 bytes --]

--- gdb.orig/ChangeLog 2009-08-21 21:37:18.000000000 -0400
+++ gdb.new/floating.ChangeLog 2009-08-21 21:37:13.000000000 -0400
@@ -1,3 +1,9 @@
+2009-08-21 Oza Pawandeep <paawan1982@yahoo.com>
+
+ * i386-tdep.c: Support for floating point recording.
+ Records and Replay the i386 floating point registers,
+ of i387 FPU.
+
2009-08-19 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>

* configure.ac: Call AC_DISABLE_OPTION_CHECKING.