Bug 92110 - setcontext restore the carry flag
Summary: setcontext restore the carry flag
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: David Xu
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-01-21 20:30 UTC by akr
Modified: 2010-04-21 12:20 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description akr 2006-01-21 20:30:03 UTC
On Pentium, getcontext saves EFLAGS and setcontext restores it.
When CF is set in EFLAGS, setcontext treats it as an system call error.

How-To-Repeat: % cat t.c
#include <stdlib.h>
#include <stdio.h>
#include <ucontext.h>

ucontext_t c;
int first;

volatile int carry_set;

int main()
{
  first = 1;

  carry_set = ~0;
  carry_set += 1;
  if (getcontext(&c) != 0) {
    perror("getcontext");
    exit(1);
  }

  printf("first:%d\n", first);

  if (first == 0)
    exit(0);

  first = 0;

  if (setcontext(&c) != 0) {
    perror("setcontext");
    exit(1);
  }

  printf("setcontext returns\n");
  exit(1);
}

% gcc -march=pentium4 t.c      
% ./a.out 
first:1
setcontext: Unknown error: 0

If "carry_set += 1" is changed to "carry_set -= 1", it works fine:

% ./a.out 
first:1
first:0
Comment 1 David Xu freebsd_committer freebsd_triage 2006-02-03 02:35:58 UTC
I have committed a fix in -HEAD,  please try it
if you have time.

David Xu
Comment 2 Mark Linimon freebsd_committer freebsd_triage 2006-02-03 04:48:54 UTC
State Changed
From-To: open->patched

Set as MFC reminder. 


Comment 3 Mark Linimon freebsd_committer freebsd_triage 2006-02-03 04:48:54 UTC
Responsible Changed
From-To: freebsd-bugs->davidxu
Comment 4 David Xu freebsd_committer freebsd_triage 2006-04-25 12:13:38 UTC
State Changed
From-To: patched->closed

Fixed in RELENG_5, RELENG_6 and HEAD.
Comment 5 dfilter service freebsd_committer freebsd_triage 2010-04-21 12:17:30 UTC
Author: kib
Date: Wed Apr 21 11:17:16 2010
New Revision: 206992
URL: http://svn.freebsd.org/changeset/base/206992

Log:
  As was done in r155238 for i386 and in r155239 for amd64, clear the carry
  flag for ia32 binary executed on amd64 host in get_mcontext().
  
  PR:	kern/92110 (one more time)
  Reported by:	stas
  MFC after:	1 week

Modified:
  head/sys/amd64/ia32/ia32_signal.c

Modified: head/sys/amd64/ia32/ia32_signal.c
==============================================================================
--- head/sys/amd64/ia32/ia32_signal.c	Wed Apr 21 11:11:11 2010	(r206991)
+++ head/sys/amd64/ia32/ia32_signal.c	Wed Apr 21 11:17:16 2010	(r206992)
@@ -141,9 +141,11 @@ ia32_get_mcontext(struct thread *td, str
 	mcp->mc_esi = tp->tf_rsi;
 	mcp->mc_ebp = tp->tf_rbp;
 	mcp->mc_isp = tp->tf_rsp;
+	mcp->mc_eflags = tp->tf_rflags;
 	if (flags & GET_MC_CLEAR_RET) {
 		mcp->mc_eax = 0;
 		mcp->mc_edx = 0;
+		mcp->mc_eflags &= ~PSL_C;
 	} else {
 		mcp->mc_eax = tp->tf_rax;
 		mcp->mc_edx = tp->tf_rdx;
@@ -152,7 +154,6 @@ ia32_get_mcontext(struct thread *td, str
 	mcp->mc_ecx = tp->tf_rcx;
 	mcp->mc_eip = tp->tf_rip;
 	mcp->mc_cs = tp->tf_cs;
-	mcp->mc_eflags = tp->tf_rflags;
 	mcp->mc_esp = tp->tf_rsp;
 	mcp->mc_ss = tp->tf_ss;
 	mcp->mc_len = sizeof(*mcp);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"