Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/arch/x86/um/os-Linux/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 7 kB image not shown  

Quelle  mcontext.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
#define __FRAME_OFFSETS
#include <linux/errno.h>
#include <linux/string.h>
#include <sys/ucontext.h>
#include <asm/ptrace.h>
#include <asm/sigcontext.h>
#include <sysdep/ptrace.h>
#include <sysdep/mcontext.h>
#include <arch.h>

void get_regs_from_mc(struct uml_pt_regs *regs, mcontext_t *mc)
{
#ifdef __i386__
#define COPY2(X,Y) regs->gp[X] = mc->gregs[REG_##Y]
#define COPY(X) regs->gp[X] = mc->gregs[REG_##X]
#define COPY_SEG(X) regs->gp[X] = mc->gregs[REG_##X] & 0xffff;
#define COPY_SEG_CPL3(X) regs->gp[X] = (mc->gregs[REG_##X] & 0xffff) | 3;
 COPY_SEG(GS); COPY_SEG(FS); COPY_SEG(ES); COPY_SEG(DS);
 COPY(EDI); COPY(ESI); COPY(EBP);
 COPY2(UESP, ESP); /* sic */
 COPY(EBX); COPY(EDX); COPY(ECX); COPY(EAX);
 COPY(EIP); COPY_SEG_CPL3(CS); COPY(EFL); COPY_SEG_CPL3(SS);
#undef COPY2
#undef COPY
#undef COPY_SEG
#undef COPY_SEG_CPL3
#else
#define COPY2(X,Y) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##Y]
#define COPY(X) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##X]
 COPY(R8); COPY(R9); COPY(R10); COPY(R11);
 COPY(R12); COPY(R13); COPY(R14); COPY(R15);
 COPY(RDI); COPY(RSI); COPY(RBP); COPY(RBX);
 COPY(RDX); COPY(RAX); COPY(RCX); COPY(RSP);
 COPY(RIP);
 COPY2(EFLAGS, EFL);
 COPY2(CS, CSGSFS);
 regs->gp[SS / sizeof(unsigned long)] = mc->gregs[REG_CSGSFS] >> 48;
#undef COPY2
#undef COPY
#endif
}

void mc_set_rip(void *_mc, void *target)
{
 mcontext_t *mc = _mc;

#ifdef __i386__
 mc->gregs[REG_EIP] = (unsigned long)target;
#else
 mc->gregs[REG_RIP] = (unsigned long)target;
#endif
}

/* Same thing, but the copy macros are turned around. */
void get_mc_from_regs(struct uml_pt_regs *regs, mcontext_t *mc, int single_stepping)
{
#ifdef __i386__
#define COPY2(X,Y) mc->gregs[REG_##Y] = regs->gp[X]
#define COPY(X) mc->gregs[REG_##X] = regs->gp[X]
#define COPY_SEG(X) mc->gregs[REG_##X] = regs->gp[X] & 0xffff;
#define COPY_SEG_CPL3(X) mc->gregs[REG_##X] = (regs->gp[X] & 0xffff) | 3;
 COPY_SEG(GS); COPY_SEG(FS); COPY_SEG(ES); COPY_SEG(DS);
 COPY(EDI); COPY(ESI); COPY(EBP);
 COPY2(UESP, ESP); /* sic */
 COPY(EBX); COPY(EDX); COPY(ECX); COPY(EAX);
 COPY(EIP); COPY_SEG_CPL3(CS); COPY(EFL); COPY_SEG_CPL3(SS);
#else
#define COPY2(X,Y) mc->gregs[REG_##Y] = regs->gp[X/sizeof(unsigned long)]
#define COPY(X) mc->gregs[REG_##X] = regs->gp[X/sizeof(unsigned long)]
 COPY(R8); COPY(R9); COPY(R10); COPY(R11);
 COPY(R12); COPY(R13); COPY(R14); COPY(R15);
 COPY(RDI); COPY(RSI); COPY(RBP); COPY(RBX);
 COPY(RDX); COPY(RAX); COPY(RCX); COPY(RSP);
 COPY(RIP);
 COPY2(EFLAGS, EFL);
 mc->gregs[REG_CSGSFS] = mc->gregs[REG_CSGSFS] & 0xffffffffffffl;
 mc->gregs[REG_CSGSFS] |= (regs->gp[SS / sizeof(unsigned long)] & 0xffff) << 48;
#endif

 if (single_stepping)
  mc->gregs[REG_EFL] |= X86_EFLAGS_TF;
 else
  mc->gregs[REG_EFL] &= ~X86_EFLAGS_TF;
}

#ifdef CONFIG_X86_32
struct _xstate_64 {
 struct _fpstate_64  fpstate;
 struct _header   xstate_hdr;
 struct _ymmh_state  ymmh;
 /* New processor state extensions go here: */
};

/* Not quite the right structures as these contain more information */
int um_i387_from_fxsr(struct _fpstate_32 *i387,
        const struct _fpstate_64 *fxsave);
int um_fxsr_from_i387(struct _fpstate_64 *fxsave,
        const struct _fpstate_32 *from);
#else
#define _xstate_64 _xstate
#endif

static struct _fpstate *get_fpstate(struct stub_data *data,
        mcontext_t *mcontext,
        int *fp_size)
{
 struct _fpstate *res;

 /* Assume floating point registers are on the same page */
 res = (void *)(((unsigned long)mcontext->fpregs &
   (UM_KERN_PAGE_SIZE - 1)) +
         (unsigned long)&data->sigstack[0]);

 if ((void *)res + sizeof(struct _fpstate) >
     (void *)data->sigstack + sizeof(data->sigstack))
  return NULL;

 if (res->sw_reserved.magic1 != FP_XSTATE_MAGIC1) {
  *fp_size = sizeof(struct _fpstate);
 } else {
  char *magic2_addr;

  magic2_addr = (void *)res;
  magic2_addr += res->sw_reserved.extended_size;
  magic2_addr -= FP_XSTATE_MAGIC2_SIZE;

  /* We still need to be within our stack */
  if ((void *)magic2_addr >
      (void *)data->sigstack + sizeof(data->sigstack))
   return NULL;

  /* If we do not read MAGIC2, then we did something wrong */
  if (*(__u32 *)magic2_addr != FP_XSTATE_MAGIC2)
   return NULL;

  /* Remove MAGIC2 from the size, we do not save/restore it */
  *fp_size = res->sw_reserved.extended_size -
      FP_XSTATE_MAGIC2_SIZE;
 }

 return res;
}

int get_stub_state(struct uml_pt_regs *regs, struct stub_data *data,
     unsigned long *fp_size_out)
{
 mcontext_t *mcontext;
 struct _fpstate *fpstate_stub;
 struct _xstate_64 *xstate_stub;
 int fp_size, xstate_size;

 /* mctx_offset is verified by wait_stub_done_seccomp */
 mcontext = (void *)&data->sigstack[data->mctx_offset];

 get_regs_from_mc(regs, mcontext);

 fpstate_stub = get_fpstate(data, mcontext, &fp_size);
 if (!fpstate_stub)
  return -EINVAL;

#ifdef CONFIG_X86_32
 xstate_stub = (void *)&fpstate_stub->_fxsr_env;
 xstate_size = fp_size - offsetof(struct _fpstate_32, _fxsr_env);
#else
 xstate_stub = (void *)fpstate_stub;
 xstate_size = fp_size;
#endif

 if (fp_size_out)
  *fp_size_out = xstate_size;

 if (xstate_size > host_fp_size)
  return -ENOSPC;

 memcpy(®s->fp, xstate_stub, xstate_size);

 /* We do not need to read the x86_64 FS_BASE/GS_BASE registers as
 * we do not permit userspace to set them directly.
 */


#ifdef CONFIG_X86_32
 /* Read the i387 legacy FP registers */
 if (um_fxsr_from_i387((void *)®s->fp, fpstate_stub))
  return -EINVAL;
#endif

 return 0;
}

/* Copied because we cannot include regset.h here. */
struct task_struct;
struct user_regset;
struct membuf {
 void *p;
 size_t left;
};

int fpregs_legacy_get(struct task_struct *target,
        const struct user_regset *regset,
        struct membuf to);

int set_stub_state(struct uml_pt_regs *regs, struct stub_data *data,
     int single_stepping)
{
 mcontext_t *mcontext;
 struct _fpstate *fpstate_stub;
 struct _xstate_64 *xstate_stub;
 int fp_size, xstate_size;

 /* mctx_offset is verified by wait_stub_done_seccomp */
 mcontext = (void *)&data->sigstack[data->mctx_offset];

 if ((unsigned long)mcontext < (unsigned long)data->sigstack ||
     (unsigned long)mcontext >
   (unsigned long) data->sigstack +
   sizeof(data->sigstack) - sizeof(*mcontext))
  return -EINVAL;

 get_mc_from_regs(regs, mcontext, single_stepping);

 fpstate_stub = get_fpstate(data, mcontext, &fp_size);
 if (!fpstate_stub)
  return -EINVAL;

#ifdef CONFIG_X86_32
 xstate_stub = (void *)&fpstate_stub->_fxsr_env;
 xstate_size = fp_size - offsetof(struct _fpstate_32, _fxsr_env);
#else
 xstate_stub = (void *)fpstate_stub;
 xstate_size = fp_size;
#endif

 memcpy(xstate_stub, ®s->fp, xstate_size);

#ifdef __i386__
 /*
 * On x86, the GDT entries are updated by arch_set_tls.
 */


 /* Store the i387 legacy FP registers which the host will use */
 if (um_i387_from_fxsr(fpstate_stub, (void *)®s->fp))
  return -EINVAL;
#else
 /*
 * On x86_64, we need to sync the FS_BASE/GS_BASE registers using the
 * arch specific data.
 */

 if (data->arch_data.fs_base != regs->gp[FS_BASE / sizeof(unsigned long)]) {
  data->arch_data.fs_base = regs->gp[FS_BASE / sizeof(unsigned long)];
  data->arch_data.sync |= STUB_SYNC_FS_BASE;
 }
 if (data->arch_data.gs_base != regs->gp[GS_BASE / sizeof(unsigned long)]) {
  data->arch_data.gs_base = regs->gp[GS_BASE / sizeof(unsigned long)];
  data->arch_data.sync |= STUB_SYNC_GS_BASE;
 }
#endif

 return 0;
}

Messung V0.5
C=96 H=99 G=97

¤ Dauer der Verarbeitung: 0.4 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.