Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/tools/testing/selftests/powerpc/ptrace/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 15 kB image not shown  

Quelle  ptrace.h   Sprache: C

 
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Ptrace interface test helper functions
 *
 * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
 */


#define __SANE_USERSPACE_TYPES__

#include <inttypes.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <errno.h>
#include <time.h>
#include <sys/ptrace.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/user.h>
#include <sys/syscall.h>
#include <linux/elf.h>
#include <linux/types.h>
#include <linux/auxvec.h>
#include "reg.h"
#include "utils.h"

#define TEST_PASS 0
#define TEST_FAIL 1

struct fpr_regs {
 __u64 fpr[32];
 __u64 fpscr;
};

struct tm_spr_regs {
 unsigned long tm_tfhar;
 unsigned long tm_texasr;
 unsigned long tm_tfiar;
};

#ifndef NT_PPC_TAR
#define NT_PPC_TAR 0x103
#define NT_PPC_PPR 0x104
#define NT_PPC_DSCR 0x105
#define NT_PPC_EBB 0x106
#define NT_PPC_PMU 0x107
#define NT_PPC_TM_CGPR 0x108
#define NT_PPC_TM_CFPR 0x109
#define NT_PPC_TM_CVMX 0x10a
#define NT_PPC_TM_CVSX 0x10b
#define NT_PPC_TM_SPR 0x10c
#define NT_PPC_TM_CTAR 0x10d
#define NT_PPC_TM_CPPR 0x10e
#define NT_PPC_TM_CDSCR 0x10f
#endif

/* Basic ptrace operations */
int start_trace(pid_t child)
{
 int ret;

 ret = ptrace(PTRACE_ATTACH, child, NULL, NULL);
 if (ret) {
  perror("ptrace(PTRACE_ATTACH) failed");
  return TEST_FAIL;
 }
 ret = waitpid(child, NULL, 0);
 if (ret != child) {
  perror("waitpid() failed");
  return TEST_FAIL;
 }
 return TEST_PASS;
}

int stop_trace(pid_t child)
{
 int ret;

 ret = ptrace(PTRACE_DETACH, child, NULL, NULL);
 if (ret) {
  perror("ptrace(PTRACE_DETACH) failed");
  return TEST_FAIL;
 }
 return TEST_PASS;
}

int cont_trace(pid_t child)
{
 int ret;

 ret = ptrace(PTRACE_CONT, child, NULL, NULL);
 if (ret) {
  perror("ptrace(PTRACE_CONT) failed");
  return TEST_FAIL;
 }
 return TEST_PASS;
}

int ptrace_read_regs(pid_t child, unsigned long type, unsigned long regs[],
       int n)
{
 struct iovec iov;
 long ret;

 FAIL_IF(start_trace(child));

 iov.iov_base = regs;
 iov.iov_len = n * sizeof(unsigned long);

 ret = ptrace(PTRACE_GETREGSET, child, type, &iov);
 if (ret)
  return ret;

 FAIL_IF(stop_trace(child));

 return TEST_PASS;
}

long ptrace_write_regs(pid_t child, unsigned long type, unsigned long regs[],
         int n)
{
 struct iovec iov;
 long ret;

 FAIL_IF(start_trace(child));

 iov.iov_base = regs;
 iov.iov_len = n * sizeof(unsigned long);

 ret = ptrace(PTRACE_SETREGSET, child, type, &iov);

 FAIL_IF(stop_trace(child));

 return ret;
}

/* TAR, PPR, DSCR */
int show_tar_registers(pid_t child, unsigned long *out)
{
 struct iovec iov;
 unsigned long *reg;
 int ret;

 reg = malloc(sizeof(unsigned long));
 if (!reg) {
  perror("malloc() failed");
  return TEST_FAIL;
 }
 iov.iov_base = (u64 *) reg;
 iov.iov_len = sizeof(unsigned long);

 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TAR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  goto fail;
 }
 if (out)
  out[0] = *reg;

 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_PPR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  goto fail;
 }
 if (out)
  out[1] = *reg;

 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_DSCR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  goto fail;
 }
 if (out)
  out[2] = *reg;

 free(reg);
 return TEST_PASS;
fail:
 free(reg);
 return TEST_FAIL;
}

int write_tar_registers(pid_t child, unsigned long tar,
  unsigned long ppr, unsigned long dscr)
{
 struct iovec iov;
 unsigned long *reg;
 int ret;

 reg = malloc(sizeof(unsigned long));
 if (!reg) {
  perror("malloc() failed");
  return TEST_FAIL;
 }

 iov.iov_base = (u64 *) reg;
 iov.iov_len = sizeof(unsigned long);

 *reg = tar;
 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TAR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_SETREGSET) failed");
  goto fail;
 }

 *reg = ppr;
 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_PPR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_SETREGSET) failed");
  goto fail;
 }

 *reg = dscr;
 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_DSCR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_SETREGSET) failed");
  goto fail;
 }

 free(reg);
 return TEST_PASS;
fail:
 free(reg);
 return TEST_FAIL;
}

int show_tm_checkpointed_state(pid_t child, unsigned long *out)
{
 struct iovec iov;
 unsigned long *reg;
 int ret;

 reg = malloc(sizeof(unsigned long));
 if (!reg) {
  perror("malloc() failed");
  return TEST_FAIL;
 }

 iov.iov_base = (u64 *) reg;
 iov.iov_len = sizeof(unsigned long);

 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CTAR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  goto fail;
 }
 if (out)
  out[0] = *reg;

 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CPPR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  goto fail;
 }
 if (out)
  out[1] = *reg;

 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CDSCR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  goto fail;
 }
 if (out)
  out[2] = *reg;

 free(reg);
 return TEST_PASS;

fail:
 free(reg);
 return TEST_FAIL;
}

int write_ckpt_tar_registers(pid_t child, unsigned long tar,
  unsigned long ppr, unsigned long dscr)
{
 struct iovec iov;
 unsigned long *reg;
 int ret;

 reg = malloc(sizeof(unsigned long));
 if (!reg) {
  perror("malloc() failed");
  return TEST_FAIL;
 }

 iov.iov_base = (u64 *) reg;
 iov.iov_len = sizeof(unsigned long);

 *reg = tar;
 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CTAR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  goto fail;
 }

 *reg = ppr;
 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CPPR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  goto fail;
 }

 *reg = dscr;
 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CDSCR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  goto fail;
 }

 free(reg);
 return TEST_PASS;
fail:
 free(reg);
 return TEST_FAIL;
}

/* FPR */
int show_fpr(pid_t child, __u64 *fpr)
{
 struct fpr_regs *regs;
 int ret, i;

 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
 ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  return TEST_FAIL;
 }

 if (fpr) {
  for (i = 0; i < 32; i++)
   fpr[i] = regs->fpr[i];
 }
 return TEST_PASS;
}

int write_fpr(pid_t child, __u64 val)
{
 struct fpr_regs *regs;
 int ret, i;

 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
 ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  return TEST_FAIL;
 }

 for (i = 0; i < 32; i++)
  regs->fpr[i] = val;

 ret = ptrace(PTRACE_SETFPREGS, child, NULL, regs);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  return TEST_FAIL;
 }
 return TEST_PASS;
}

int show_ckpt_fpr(pid_t child, __u64 *fpr)
{
 struct fpr_regs *regs;
 struct iovec iov;
 int ret, i;

 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
 iov.iov_base = regs;
 iov.iov_len = sizeof(struct fpr_regs);

 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  return TEST_FAIL;
 }

 if (fpr) {
  for (i = 0; i < 32; i++)
   fpr[i] = regs->fpr[i];
 }

 return TEST_PASS;
}

int write_ckpt_fpr(pid_t child, unsigned long val)
{
 struct fpr_regs *regs;
 struct iovec iov;
 int ret, i;

 regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
 iov.iov_base = regs;
 iov.iov_len = sizeof(struct fpr_regs);

 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  return TEST_FAIL;
 }

 for (i = 0; i < 32; i++)
  regs->fpr[i] = val;

 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CFPR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  return TEST_FAIL;
 }
 return TEST_PASS;
}

/* GPR */
int show_gpr(pid_t child, unsigned long *gpr)
{
 struct pt_regs *regs;
 int ret, i;

 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
 if (!regs) {
  perror("malloc() failed");
  return TEST_FAIL;
 }

 ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  return TEST_FAIL;
 }

 if (gpr) {
  for (i = 14; i < 32; i++)
   gpr[i-14] = regs->gpr[i];
 }

 return TEST_PASS;
}

long sys_ptrace(enum __ptrace_request request, pid_t pid, unsigned long addr, unsigned long data)
{
 return syscall(__NR_ptrace, request, pid, (void *)addr, data);
}

// 33 because of FPSCR
#define PT_NUM_FPRS (33 * (sizeof(__u64) / sizeof(unsigned long)))

__u64 *peek_fprs(pid_t child)
{
 unsigned long *fprs, *p, addr;
 long ret;
 int i;

 fprs = malloc(sizeof(unsigned long) * PT_NUM_FPRS);
 if (!fprs) {
  perror("malloc() failed");
  return NULL;
 }

 for (i = 0, p = fprs; i < PT_NUM_FPRS; i++, p++) {
  addr = sizeof(unsigned long) * (PT_FPR0 + i);
  ret = sys_ptrace(PTRACE_PEEKUSER, child, addr, (unsigned long)p);
  if (ret) {
   perror("ptrace(PTRACE_PEEKUSR) failed");
   return NULL;
  }
 }

 addr = sizeof(unsigned long) * (PT_FPR0 + i);
 ret = sys_ptrace(PTRACE_PEEKUSER, child, addr, (unsigned long)&addr);
 if (!ret) {
  printf("ptrace(PTRACE_PEEKUSR) succeeded unexpectedly!\n");
  return NULL;
 }

 return (__u64 *)fprs;
}

int poke_fprs(pid_t child, unsigned long *fprs)
{
 unsigned long *p, addr;
 long ret;
 int i;

 for (i = 0, p = fprs; i < PT_NUM_FPRS; i++, p++) {
  addr = sizeof(unsigned long) * (PT_FPR0 + i);
  ret = sys_ptrace(PTRACE_POKEUSER, child, addr, *p);
  if (ret) {
   perror("ptrace(PTRACE_POKEUSR) failed");
   return -1;
  }
 }

 addr = sizeof(unsigned long) * (PT_FPR0 + i);
 ret = sys_ptrace(PTRACE_POKEUSER, child, addr, addr);
 if (!ret) {
  printf("ptrace(PTRACE_POKEUSR) succeeded unexpectedly!\n");
  return -1;
 }

 return 0;
}

int write_gpr(pid_t child, unsigned long val)
{
 struct pt_regs *regs;
 int i, ret;

 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
 if (!regs) {
  perror("malloc() failed");
  return TEST_FAIL;
 }

 ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  return TEST_FAIL;
 }

 for (i = 14; i < 32; i++)
  regs->gpr[i] = val;

 ret = ptrace(PTRACE_SETREGS, child, NULL, regs);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  return TEST_FAIL;
 }
 return TEST_PASS;
}

int show_ckpt_gpr(pid_t child, unsigned long *gpr)
{
 struct pt_regs *regs;
 struct iovec iov;
 int ret, i;

 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
 if (!regs) {
  perror("malloc() failed");
  return TEST_FAIL;
 }

 iov.iov_base = (u64 *) regs;
 iov.iov_len = sizeof(struct pt_regs);

 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  return TEST_FAIL;
 }

 if (gpr) {
  for (i = 14; i < 32; i++)
   gpr[i-14] = regs->gpr[i];
 }

 return TEST_PASS;
}

int write_ckpt_gpr(pid_t child, unsigned long val)
{
 struct pt_regs *regs;
 struct iovec iov;
 int ret, i;

 regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
 if (!regs) {
  perror("malloc() failed\n");
  return TEST_FAIL;
 }
 iov.iov_base = (u64 *) regs;
 iov.iov_len = sizeof(struct pt_regs);

 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  return TEST_FAIL;
 }

 for (i = 14; i < 32; i++)
  regs->gpr[i] = val;

 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CGPR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  return TEST_FAIL;
 }
 return TEST_PASS;
}

/* VMX */
int show_vmx(pid_t child, unsigned long vmx[][2])
{
 int ret;

 ret = ptrace(PTRACE_GETVRREGS, child, 0, vmx);
 if (ret) {
  perror("ptrace(PTRACE_GETVRREGS) failed");
  return TEST_FAIL;
 }
 return TEST_PASS;
}

int show_vmx_ckpt(pid_t child, unsigned long vmx[][2])
{
 unsigned long regs[34][2];
 struct iovec iov;
 int ret;

 iov.iov_base = (u64 *) regs;
 iov.iov_len = sizeof(regs);
 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVMX, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVMX) failed");
  return TEST_FAIL;
 }
 memcpy(vmx, regs, sizeof(regs));
 return TEST_PASS;
}


int write_vmx(pid_t child, unsigned long vmx[][2])
{
 int ret;

 ret = ptrace(PTRACE_SETVRREGS, child, 0, vmx);
 if (ret) {
  perror("ptrace(PTRACE_SETVRREGS) failed");
  return TEST_FAIL;
 }
 return TEST_PASS;
}

int write_vmx_ckpt(pid_t child, unsigned long vmx[][2])
{
 unsigned long regs[34][2];
 struct iovec iov;
 int ret;

 memcpy(regs, vmx, sizeof(regs));
 iov.iov_base = (u64 *) regs;
 iov.iov_len = sizeof(regs);
 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVMX, &iov);
 if (ret) {
  perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVMX) failed");
  return TEST_FAIL;
 }
 return TEST_PASS;
}

/* VSX */
int show_vsx(pid_t child, unsigned long *vsx)
{
 int ret;

 ret = ptrace(PTRACE_GETVSRREGS, child, 0, vsx);
 if (ret) {
  perror("ptrace(PTRACE_GETVSRREGS) failed");
  return TEST_FAIL;
 }
 return TEST_PASS;
}

int show_vsx_ckpt(pid_t child, unsigned long *vsx)
{
 unsigned long regs[32];
 struct iovec iov;
 int ret;

 iov.iov_base = (u64 *) regs;
 iov.iov_len = sizeof(regs);
 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVSX, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVSX) failed");
  return TEST_FAIL;
 }
 memcpy(vsx, regs, sizeof(regs));
 return TEST_PASS;
}

int write_vsx(pid_t child, unsigned long *vsx)
{
 int ret;

 ret = ptrace(PTRACE_SETVSRREGS, child, 0, vsx);
 if (ret) {
  perror("ptrace(PTRACE_SETVSRREGS) failed");
  return TEST_FAIL;
 }
 return TEST_PASS;
}

int write_vsx_ckpt(pid_t child, unsigned long *vsx)
{
 unsigned long regs[32];
 struct iovec iov;
 int ret;

 memcpy(regs, vsx, sizeof(regs));
 iov.iov_base = (u64 *) regs;
 iov.iov_len = sizeof(regs);
 ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVSX, &iov);
 if (ret) {
  perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVSX) failed");
  return TEST_FAIL;
 }
 return TEST_PASS;
}

/* TM SPR */
int show_tm_spr(pid_t child, struct tm_spr_regs *out)
{
 struct tm_spr_regs *regs;
 struct iovec iov;
 int ret;

 regs = (struct tm_spr_regs *) malloc(sizeof(struct tm_spr_regs));
 if (!regs) {
  perror("malloc() failed");
  return TEST_FAIL;
 }

 iov.iov_base = (u64 *) regs;
 iov.iov_len = sizeof(struct tm_spr_regs);

 ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_SPR, &iov);
 if (ret) {
  perror("ptrace(PTRACE_GETREGSET) failed");
  return TEST_FAIL;
 }

 if (out)
  memcpy(out, regs, sizeof(struct tm_spr_regs));

 return TEST_PASS;
}



/* Analyse TEXASR after TM failure */
inline unsigned long get_tfiar(void)
{
 return mfspr(SPRN_TFIAR);
}

void analyse_texasr(unsigned long texasr)
{
 printf("TEXASR: %16lx\t", texasr);

 if (texasr & TEXASR_FP)
  printf("TEXASR_FP ");

 if (texasr & TEXASR_DA)
  printf("TEXASR_DA ");

 if (texasr & TEXASR_NO)
  printf("TEXASR_NO ");

 if (texasr & TEXASR_FO)
  printf("TEXASR_FO ");

 if (texasr & TEXASR_SIC)
  printf("TEXASR_SIC ");

 if (texasr & TEXASR_NTC)
  printf("TEXASR_NTC ");

 if (texasr & TEXASR_TC)
  printf("TEXASR_TC ");

 if (texasr & TEXASR_TIC)
  printf("TEXASR_TIC ");

 if (texasr & TEXASR_IC)
  printf("TEXASR_IC ");

 if (texasr & TEXASR_IFC)
  printf("TEXASR_IFC ");

 if (texasr & TEXASR_ABT)
  printf("TEXASR_ABT ");

 if (texasr & TEXASR_SPD)
  printf("TEXASR_SPD ");

 if (texasr & TEXASR_HV)
  printf("TEXASR_HV ");

 if (texasr & TEXASR_PR)
  printf("TEXASR_PR ");

 if (texasr & TEXASR_FS)
  printf("TEXASR_FS ");

 if (texasr & TEXASR_TE)
  printf("TEXASR_TE ");

 if (texasr & TEXASR_ROT)
  printf("TEXASR_ROT ");

 printf("TFIAR :%lx\n", get_tfiar());
}

void store_gpr(unsigned long *addr);

Messung V0.5
C=93 H=95 G=93

¤ Dauer der Verarbeitung: 0.7 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.