*BSD News Article 17121


Return to BSD News archive

Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!agate!soda.berkeley.edu!wjolitz
From: wjolitz@soda.berkeley.edu (William F. Jolitz)
Newsgroups: comp.os.386bsd.bugs
Subject: Catching References to address 0
Date: 14 Jun 1993 17:37:24 GMT
Organization: U.C. Berkeley, CS Undergraduate Association
Lines: 67
Message-ID: <1vid0k$p4n@agate.berkeley.edu>
NNTP-Posting-Host: soda.berkeley.edu


I noticed that someone had posted a kernel mod to catch indirections
through 0 as a different file format. I've had strong disagreements
with that approach when Donn Seely created it at BSDI, since it's
unnecessarily overly specific for a new object file format.

There's nothing worse than N different versions of the same stupid
object file format, straining a.out a little bit more in yet another
direction. This is as usual short sighted, and only useful as a quick
hack. BSD suffers from too many of such quick hacks.

May I suggest a different approach. Don't rush to change the kernel
when you can exploit the features of user mode to the same end. Here's
an example:

Let's say you want a debugging feature to catch indirections through 0,
and other absolute references.  Why not use the system's existing
memory management facilities?

How? Why not bump up the size of the run time start-up, and protect it
from access by the program. This can be done with two lines in the run
time start-off, creating a "hcrt0.o" or "hole" C run time start off:

*** crt0.c	Thu Jul  2 17:17:40 1992
--- hcrt0.c	Sat Jun 12 19:41:54 1993
***************
*** 49,55 ****
  int	errno = 0;
  
  asm(".text");
! asm(".long 0xc000c000");
  
  extern	unsigned char	etext;
  extern	unsigned char	eprol asm ("eprol");
--- 49,55 ----
  int	errno = 0;
  
  asm(".text");
! asm(" jmp start ; .space 4096 ");
  
  extern	unsigned char	etext;
  extern	unsigned char	eprol asm ("eprol");
***************
*** 79,84 ****
--- 79,85 ----
  	/* just above the saved frame pointer */
  	asm ("lea 4(%%ebp), %0" : "=r" (kfp) );
  #endif not lint
+ 	(void)mprotect (0, 4096, 0);
  	for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
  		/* void */ ;
  	if (targv >= (char **)(*argv))

Note that in some cases with large data structures (like databases and
window systems), you can have structure references that span the 4096
byte size of a page. It's possible to alter this larger on demand for
such occasions. Also, I've found that absolute program references of
addresses from low valued integer constants sometimes do occur, so
mapping really high can be useful.

If one still feels the need for better executable file format (and
a.out leaves much to be desired), may I suggest that one spend time
either implementing ELF or something like it and doing "real" work
instead of short term hacks. They are better dealt with by exploiting
what is already present in the system.

Bill.