LCOV - code coverage report
Current view: top level - arch/x86/um/os-Linux - registers.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 15 40 37.5 %
Date: 2023-08-24 13:40:31 Functions: 3 8 37.5 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2004 PathScale, Inc
       3             :  * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
       4             :  * Licensed under the GPL
       5             :  */
       6             : 
       7             : #include <errno.h>
       8             : #include <stdlib.h>
       9             : #include <sys/ptrace.h>
      10             : #ifdef __i386__
      11             : #include <sys/user.h>
      12             : #endif
      13             : #include <longjmp.h>
      14             : #include <sysdep/ptrace_user.h>
      15             : #include <sys/uio.h>
      16             : #include <asm/sigcontext.h>
      17             : #include <linux/elf.h>
      18             : #include <registers.h>
      19             : 
      20             : int have_xstate_support;
      21             : 
      22           0 : int save_i387_registers(int pid, unsigned long *fp_regs)
      23             : {
      24           0 :         if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0)
      25           0 :                 return -errno;
      26             :         return 0;
      27             : }
      28             : 
      29           1 : int save_fp_registers(int pid, unsigned long *fp_regs)
      30             : {
      31             : #ifdef PTRACE_GETREGSET
      32             :         struct iovec iov;
      33             : 
      34           1 :         if (have_xstate_support) {
      35           1 :                 iov.iov_base = fp_regs;
      36           1 :                 iov.iov_len = FP_SIZE * sizeof(unsigned long);
      37           1 :                 if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) < 0)
      38           0 :                         return -errno;
      39             :                 return 0;
      40             :         } else
      41             : #endif
      42           0 :                 return save_i387_registers(pid, fp_regs);
      43             : }
      44             : 
      45           0 : int restore_i387_registers(int pid, unsigned long *fp_regs)
      46             : {
      47           0 :         if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0)
      48           0 :                 return -errno;
      49             :         return 0;
      50             : }
      51             : 
      52           0 : int restore_fp_registers(int pid, unsigned long *fp_regs)
      53             : {
      54             : #ifdef PTRACE_SETREGSET
      55             :         struct iovec iov;
      56           0 :         if (have_xstate_support) {
      57           0 :                 iov.iov_base = fp_regs;
      58           0 :                 iov.iov_len = FP_SIZE * sizeof(unsigned long);
      59           0 :                 if (ptrace(PTRACE_SETREGSET, pid, NT_X86_XSTATE, &iov) < 0)
      60           0 :                         return -errno;
      61             :                 return 0;
      62             :         } else
      63             : #endif
      64           0 :                 return restore_i387_registers(pid, fp_regs);
      65             : }
      66             : 
      67             : #ifdef __i386__
      68             : int have_fpx_regs = 1;
      69             : int save_fpx_registers(int pid, unsigned long *fp_regs)
      70             : {
      71             :         if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0)
      72             :                 return -errno;
      73             :         return 0;
      74             : }
      75             : 
      76             : int restore_fpx_registers(int pid, unsigned long *fp_regs)
      77             : {
      78             :         if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0)
      79             :                 return -errno;
      80             :         return 0;
      81             : }
      82             : 
      83             : int get_fp_registers(int pid, unsigned long *regs)
      84             : {
      85             :         if (have_fpx_regs)
      86             :                 return save_fpx_registers(pid, regs);
      87             :         else
      88             :                 return save_fp_registers(pid, regs);
      89             : }
      90             : 
      91             : int put_fp_registers(int pid, unsigned long *regs)
      92             : {
      93             :         if (have_fpx_regs)
      94             :                 return restore_fpx_registers(pid, regs);
      95             :         else
      96             :                 return restore_fp_registers(pid, regs);
      97             : }
      98             : 
      99             : void arch_init_registers(int pid)
     100             : {
     101             :         struct user_fpxregs_struct fpx_regs;
     102             :         int err;
     103             : 
     104             :         err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs);
     105             :         if (!err)
     106             :                 return;
     107             : 
     108             :         if (errno != EIO)
     109             :                 panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
     110             :                       errno);
     111             : 
     112             :         have_fpx_regs = 0;
     113             : }
     114             : #else
     115             : 
     116           1 : int get_fp_registers(int pid, unsigned long *regs)
     117             : {
     118           1 :         return save_fp_registers(pid, regs);
     119             : }
     120             : 
     121           0 : int put_fp_registers(int pid, unsigned long *regs)
     122             : {
     123           0 :         return restore_fp_registers(pid, regs);
     124             : }
     125             : 
     126           1 : void arch_init_registers(int pid)
     127             : {
     128             : #ifdef PTRACE_GETREGSET
     129             :         void * fp_regs;
     130             :         struct iovec iov;
     131             : 
     132           1 :         fp_regs = malloc(FP_SIZE * sizeof(unsigned long));
     133           1 :         if(fp_regs == NULL)
     134           0 :                 return;
     135             : 
     136           1 :         iov.iov_base = fp_regs;
     137           1 :         iov.iov_len = FP_SIZE * sizeof(unsigned long);
     138           1 :         if (ptrace(PTRACE_GETREGSET, pid, NT_X86_XSTATE, &iov) == 0)
     139           1 :                 have_xstate_support = 1;
     140             : 
     141           1 :         free(fp_regs);
     142             : #endif
     143             : }
     144             : #endif
     145             : 
     146           0 : unsigned long get_thread_reg(int reg, jmp_buf *buf)
     147             : {
     148           0 :         switch (reg) {
     149             : #ifdef __i386__
     150             :         case HOST_IP:
     151             :                 return buf[0]->__eip;
     152             :         case HOST_SP:
     153             :                 return buf[0]->__esp;
     154             :         case HOST_BP:
     155             :                 return buf[0]->__ebp;
     156             : #else
     157             :         case HOST_IP:
     158           0 :                 return buf[0]->__rip;
     159             :         case HOST_SP:
     160           0 :                 return buf[0]->__rsp;
     161             :         case HOST_BP:
     162           0 :                 return buf[0]->__rbp;
     163             : #endif
     164             :         default:
     165           0 :                 printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n",
     166             :                        reg);
     167           0 :                 return 0;
     168             :         }
     169             : }

Generated by: LCOV version 1.14