Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Jun 2017 15:19:35 +0530
From:      karnajit wangkhem <karnajitw@gmail.com>
To:        freebsd-hackers@freebsd.org
Subject:   Undesirable FPU tag word value after PT_SETFPREGS on i386
Message-ID:  <CAB6rxaSiG9zJMAjjBEKBimK_j6GaNaVXWuxH0civ1n0C0ZXF1w@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
Hi All,

Please help me understand why NaN is reported after PT_SETFPREGS. As a
result of this, if the inferior process contains an float operations, they
result in NaN.
This behavior is not seen in case of 32/64 bit binary on amd64.

My env
kern.ostype: FreeBSD
kern.osrelease: 11.0-RELEASE-p1
kern.version: FreeBSD 11.0-RELEASE-p1 #0 r306420: Thu Sep 29 03:40:55 UTC
2016
    root@releng2.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC
hw.machine_arch: i386

Result of the below program on an i386 box
FPU TAG = ffff
FPU TAG = fe00  -> 11 11 11 10 00 00 00 00

---------------------------------------------------------------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/wait.h>

#include <machine/reg.h>

int main()
{
    pid_t child_pid = fork();
    if (child_pid == 0) {
        ptrace(PT_TRACE_ME, 0, NULL, 0);
        execl("/bin/ls", "ls", NULL);
        perror("Exec failed\n");
        exit(1);
    }
    int status;
    int options = 0;
    if (waitpid(child_pid, &status, options) < 0) {
        perror("Failed to wait for child process!\n");
        exit(1);
    }
    if (WIFSTOPPED(status)) {
        printf("Child has stopped...\n");
    } else {
        perror("Child suppose to stop\n");
        exit(1);
    }

    //****************************************************//
    struct fpreg fpregs;
    ptrace(PT_GETFPREGS, child_pid, (caddr_t)&fpregs, 0);
    printf("FPU TAG = %04x\n", fpregs.fpr_env[2]);
    ptrace(PT_SETFPREGS, child_pid, (caddr_t)&fpregs, 0);      // <------
    ptrace(PT_GETFPREGS, child_pid, (caddr_t)&fpregs, 0);
    printf("FPU TAG = %04x\n", fpregs.fpr_env[2]);
    //****************************************************//

    printf("Send continue to child process\n");
    ptrace(PT_CONTINUE, child_pid, (caddr_t)1, 0);

    if (waitpid(child_pid, &status, options) < 0) {
        perror("Failed to wait for child process!\n");
        exit(1);
    }
    if (WIFEXITED(status)) {
        printf("Child exited\n");
    } else {
        perror("Child suppose to exit\n");
        exit(1);
    }

    return 0;
}


Regards,
Karan



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAB6rxaSiG9zJMAjjBEKBimK_j6GaNaVXWuxH0civ1n0C0ZXF1w>