[BACK]Return to fork05.c CVS log [TXT][DIR] Up to [Development] / projects / ltp / tests

File: [Development] / projects / ltp / tests / fork05.c (download)

Revision 1.4, Wed Feb 28 17:42:00 2001 UTC (16 years, 7 months ago) by nstraz
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +3 -1 lines

I've applied most of the patch that Urban Widmark <urban@teststation.com>
contributed.  It turns on the "all warnings" compiler options and fixes a lot
of the warnings.

/*
 * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
 * Portions Copyright (c) 2000 Ulrich Drepper
 * 
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it would be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * 
 * Further, this software is distributed without any warranty that it is
 * free of the rightful claim of any third person regarding infringement
 * or the like.  Any license provided herein, whether implied or
 * otherwise, applies only to this software file.  Patent licenses, if
 * any, provided herein do not apply to combinations of this program with
 * other software, or any other product whatsoever.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc., 59
 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
 * 
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
 * Mountain View, CA  94043, or:
 * 
 * http://www.sgi.com 
 * 
 * For further information regarding this notice, see: 
 * 
 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
 */
/* $Id: fork05.c,v 1.4 2001/02/28 17:42:00 nstraz Exp $ */
/**********************************************************
 *
 *    Linux Test Project - Silicon Graphics, Inc.
 *    
 *    TEST IDENTIFIER	: fork05
 *
 *    EXECUTED BY	: anyone
 *
 *    TEST TITLE	: Make sure LDT is propagated correctly
 *
 *    TEST CASE TOTAL	: 1
 *
 *    CPU TYPES		: i386
 *
 *    AUTHORS		: Ulrich Drepper
 *			  Nate Straz
 *
 *On Sat, Aug 12, 2000 at 12:47:31PM -0700, Ulrich Drepper wrote:
 *> Ever since the %gs handling was fixed in the 2.3.99 series the
 *> appended test program worked.  Now with 2.4.0-test6 it's not working
 *> again.  Looking briefly over the patch from test5 to test6 I haven't
 *> seen an immediate candidate for the breakage.  It could be missing
 *> propagation of the LDT to the new process (and therefore an invalid
 *> segment descriptor) or simply clearing %gs.
 *> 
 *> Anyway, this is what you should see and what you get with test5:
 *> 
 *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *> a = 42
 *> %gs = 0x0007
 *> %gs = 0x0007
 *> a = 99
 *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *> 
 *> This is what you get with test6:
 *> 
 *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *> a = 42
 *> %gs = 0x0007
 *> %gs = 0x0000
 *> <SEGFAULT>
 *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *> 
 *> If somebody is actually creating a test suite for the kernel, please
 *> add this program.  It's mostly self-contained.  The correct handling
 *> of %gs is really important since glibc 2.2 will make heavy use of it.
 *> 
 *> - -- 
 *> - ---------------.                          ,-.   1325 Chesapeake Terrace
 *> Ulrich Drepper  \    ,-------------------'   \  Sunnyvale, CA 94089 USA
 *> Red Hat          `--' drepper at redhat.com   `------------------------
 *> 
 *> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *
 *********************************************************/
#include <stdio.h>

#if defined(linux) && defined(__i386__)
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

struct modify_ldt_ldt_s
{
  unsigned int entry_number;
  unsigned long int base_addr;
  unsigned int limit;
  unsigned int seg_32bit:1;
  unsigned int contents:2;
  unsigned int read_exec_only:1;
  unsigned int limit_in_pages:1;
  unsigned int seg_not_present:1;
  unsigned int useable:1;
  unsigned int empty:25;
};

void modify_ldt(int, struct modify_ldt_ldt_s *, int);
asm("	.type modify_ldt,@function
modify_ldt:
	push   %ebx
	mov    0x10(%esp,1),%edx
	mov    0xc(%esp,1),%ecx
	mov    0x8(%esp,1),%ebx
	mov    $0x7b,%eax
	int    $0x80
	pop    %ebx
	ret");

int a = 42;

int
main ()
{
  struct modify_ldt_ldt_s ldt0;
  int lo;
  pid_t pid;
  int res;

  ldt0.entry_number = 0;
  ldt0.base_addr = (long) &a;
  ldt0.limit = 4;
  ldt0.seg_32bit = 1;
  ldt0.contents = 0;
  ldt0.read_exec_only = 0;
  ldt0.limit_in_pages = 0;
  ldt0.seg_not_present = 0;
  ldt0.useable = 1;
  ldt0.empty = 0;

  modify_ldt (1, &ldt0, sizeof (ldt0));

  asm ("movw %w0, %%gs" : : "q" (7));

  asm ("movl %%gs:0, %0" : "=r" (lo));
  printf ("a = %d\n", lo);

  asm ("pushl %%gs; popl %0" : "=q" (lo));
  printf ("%%gs = %#06hx\n", lo);

  asm ("movl %0, %%gs:0" : : "r" (99));

  pid = fork ();

  if (pid == 0) {
      asm ("pushl %%gs; popl %0" : "=q" (lo));
      printf ("%%gs = %#06hx\n", lo);

      asm ("movl %%gs:0, %0" : "=r" (lo));
      printf ("a = %d\n", lo);

      exit (lo != 99);
  } else {
      waitpid (pid, &res, 0);
  }

  return WIFSIGNALED(res);
}

#else /* if defined(linux) && defined(__i386__) */

int
main()
{
  printf("%%gs test only for ix86\n");

  /*
   * should be successful on all non-ix86 platforms.
   */
  return(0);
}

#endif /* if defined(linux) && defined(__i386__) */