[comp.os.minix] help needed converting Aztec .exe to a.out

Leisner.Henr@xerox.com (Marty) (08/26/87)

I'm currently the process of trying to build a Minix boot disk from the
Aztec C compiler on MS-DOS.  There was some talk on the net about this a
few months ago, pointers would be welcome.

I'm using the aztec compiler, assembler and linker.


Is the my understanding of the 8088 implementation of minix correct for
split I&D?
	1) code (text) is readonly, sits in its on segment
	2) data is initialized, sits in the a separate click aligned data
segment
	3) bss sits above data.  Does it have to be click aligned?
	4) heap sits above bss.
	5) Stack sits above heap.  
	6) 2-5 sit in one 8088 segment, <=64k.

The dos2out program gets the bss size as:
	(d_ptr->min_free<<4) - d_ptr->sp_reg;	
I don't understand the above relationship.  How do I compute the amount
of bss for an .exe?  (Is it the min free mem field of the exe header?).

Anyway, the Aztec linker doesn't put much useful information in the exe
header (the startup
routine sets up the stack and clears the bss).  Looks like the easiest
think to do it get the
information out of a symbol table and have some option to establish the
stack/heap size (which both come from the dynamic memory allocation?).
Any other ways?

marty
GV:  leisner.henr
NS:  martin leisner:henr801c:xerox
 

rmtodd@uokmax.UUCP (09/16/87)

In article <455@louie.udel.EDU> Leisner.Henr@xerox.com (Marty) writes:
>Is the my understanding of the 8088 implementation of minix correct for
>split I&D?
>	1) code (text) is readonly, sits in its on segment
>	2) data is initialized, sits in the a separate click aligned data
>segment
>	3) bss sits above data.  Does it have to be click aligned?
>	4) heap sits above bss.
>	5) Stack sits above heap.  
>	6) 2-5 sit in one 8088 segment, <=64k.
>
>The dos2out program gets the bss size as:
>	(d_ptr->min_free<<4) - d_ptr->sp_reg;	
>I don't understand the above relationship.  How do I compute the amount
>of bss for an .exe?  (Is it the min free mem field of the exe header?).
I don't remember the exact details, but I did get dos2out and build to
work on Aztec C-created files.  (The problem with build is that build
expects the first data to be at addr. 0 of the data segment, whereas
Aztec C's ln starts putting your data at addr. 2 of the data seg.
>Anyway, the Aztec linker doesn't put much useful information in the exe
>header (the startup
>routine sets up the stack and clears the bss).  Looks like the easiest
>think to do it get the
>information out of a symbol table and have some option to establish the
>stack/heap size (which both come from the dynamic memory allocation?).
>Any other ways?
It's possible to get some info out of the header fields.  As I recall,
the best you can do is get start of bss and end of bss values rounded
up to the next click.  This means that the crtso.asm must include some
'dead space' at start of bss so that none of your uninit. data ends up
in a place where MINIX won't clear it.
  Anyway, below is the message that I've usually been sending people who
wanted to compile stuff for MINIX with Aztec C.  It contains everything
you need.  I decided to post it since there seem to be quite a few
people out there with Aztec.  Here it is:
  This message contains a shar file with the *.asm files, as well as a 
context diff for patching the original-distribution build.c and dos2out.c
to work correctly with Aztec C.  Unpack the shar, patch dos2out.c and build.c
and transfer build.c to MINIX and compile it there.  (You only need build.c
if you plan to recompile parts of the OS with MINIX.)  Compile dos2out.c
with Aztec C and link it to form an executable of dos2out.  
Copy the C source files of the library and the header files
from /h and /include to your MSDOS disk. Set up three subdirectories, LIB,
H, and INCLUDE, and put the relevant files into the relevant directories.
Set up a batch file to set the INCLUDE environment variable to point to
your include directory for MINIX cross-compilations (the directory mentioned
above) and set the CLIB environment variable to point to your library
directory.  You will need to execute this batch file before any compilation
intended for MINIX, so that cc and ln will look for the MINIX versions of the
library and include files, instead of the Aztec versions.  Put all the
*.asm files in the LIB directory.  Assemble them and compile the C files
of the library.  Use lb to extract the modules you will need for long
arithmetic, switch code, and setjmp (in v3.40, they are setjmp.o, cswt.o,
cswit.o, and lsubs.o) from the Aztec C small-memory-model library c.lib.
Build the library using the command
	lb minix.lib -f list
where 'list' is the ordered list of the files that will make up the library.
(List is include in the shar here.)  Then you can delete all the .o files
except for crtso.o and head.o.
  To compile a program for MINIX, execute your batch file to set the 
environment variables.  Compile the modules of your program as you
usually would with cc.  To link your program's *.o files, type
	ln -o whatever.exe -S 1 crtso.o <your object files> -lminix
The -S 1 must be there for dos2out to determine the sizes correctly.  crtso.o
must precede all your object files on the command line.  (If you are compiling
mm or fs, you must use head.o instead of crtso.o).  Then use dos2out to
convert the executable to MINIX format and copy it over to MINIX.  
You may need to diddle with the stack-size allocation once the output is
on MINIX.


# Shell archive created with Richard Todd's makeshar on Sat Jun  6 21:27:24 1987
echo x - brksize.asm
sed 's/^X//' >brksize.asm << 'EOF'
Xdataseg segment para public 'data'
X	extrn _Uend_:byte
X	public brksize_
Xbrksize_ dw	_Uend_+2
Xdataseg ends
X	end
'EOF'
echo x - catchsig.asm
sed 's/^X//' >catchsig.asm << 'EOF'
X	public begsig_	
Xmtype equ 2			; M+mtype = &M.m_type
Xcodeseg segment para public 'code'
Xdataseg segment para public 'data'
X	extrn vectab_:word,M_:word
Xdataseg ends
X	assume	cs:codeseg, ds:dataseg, es:dataseg, ss:dataseg
Xbegsig_	proc	near
X	push ax			; after interrupt, save all regs
X	push bx
X	push cx
X	push dx
X	push si
X	push di
X	push bp
X	push ds
X	push es
X	mov bx,sp
X	mov bx,18[bx]		; bx = signal number
X	mov ax,bx		; ax = signal number
X	dec bx			; vectab[0] is for sig 1
X	add bx,bx		; pointers are two bytes on 8088
X	mov bx,vectab_[bx]	; bx = address of routine to call
X	push M_+mtype		; push status of last system call
X	push ax			; func called with signal number as arg
X	call bx
Xback:
X	pop ax			; get signal number off stack
X	pop M_+mtype		; restore status of previous system call
X	pop es			; signal handling finished
X	pop ds
X	pop bp
X	pop di
X	pop si
X	pop dx
X	pop cx
X	pop bx
X	pop ax
X	pop dummy		; remove signal number from stack
X	iret
Xcodeseg ends
Xdataseg segment para public 'data'
Xdummy	dw	 0
Xdataseg ends
X
'EOF'
echo x - crtso.asm
sed 's/^X//' >crtso.asm << 'EOF'
X; This is the C run-time start-off routine.  It's job is to take the
X; arguments as put on the stack by EXEC, and to parse them and set them up the
X; way _main expects them.
X;begtext,begdata, etc. stuff removed--Aztec linker automatically puts
X;in equivalents _Corg_,_Dorg_,_Uorg_
Xcodeseg segment para public 'code'
X	extrn	main_:near, exit_:near
Xdataseg	segment para public 'data'
Xdataseg	ends
X	assume	cs:codeseg,ds:dataseg,es:dataseg,ss:dataseg	
X	public environ_
X	public $begin
X$begin:	mov	ax,dataseg
X	mov	bx,sp
X	mov	cx,[bx]
X	add	bx,2
X	mov	ax,cx
X	inc	ax
X	shl	ax,1
X	add	ax,bx
X	mov	environ_,ax	; save envp in environ
X	push	ax	; push environ
X	push	bx	; push argv
X	push	cx	; push argc
X	call	main_
X	add	sp,6
X	push	ax	; push exit status
X	call	exit_
Xdataseg	segment para public 'data'
Xenviron_ dw 0
X	bss	junk:byte,16 ; junk region at beginning of bss because
X;dos2out can't determine the data&bss sizes w/o rounding up to the nearest
X;paragraph.  We want to ensure that the paragraph on the boundary is never
X;used because it may not be properly initialized.
Xdataseg	ends
X	end	$begin
'EOF'
echo x - getutil.asm
sed 's/^X//' >getutil.asm << 'EOF'
X	public get_base_, get_size_, get_tot_mem_
Xcodeseg segment para public 'code'
Xdataseg segment para public 'data'
X	extrn	_Uend_:byte
Xdataseg	ends
X;*========================================================================*
X;                           utilities                                     *
X;*========================================================================*
Xget_base_:			; return click at which prog starts
X	mov ax,ds
X	ret
X
Xget_size_:			; return prog size in bytes (text+data+bss)
X	mov ax,offset _Uend_	; end is compiler label at end of bss
X	ret
X
X; Find out how much memory the machine has, including vectors, kernel MM, etc.
Xget_tot_mem_:
X	cli
X	push es
X	push di
X	mov ax,8192		; start search at 128K (8192 clicks)
X	sub di,di
XL1:	mov es,ax
X	mov es:[di],0A5A4H	; write random bit pattern to memory
X	xor bx,bx
X	mov bx,es:[di]		; read back pattern just written
X	cmp bx,0A5A4H		; compare with expected value
X	jne L2			; if different, no memory present
X	add ax,4096		; advance counter by 64K
X	cmp ax,0A000H		; stop seaching at 640K
X	jne L1
XL2:	pop di
X	pop es
X	sti
X	ret
Xcodeseg	ends
X	end
X
'EOF'
echo x - head.asm
sed 's/^X//' >head.asm << 'EOF'
X	public main_,exit_,data_org_,$begin
Xcodeseg segment para public 'code'
Xdataseg segment para public 'data'
X	extrn	stackpt_:word
Xdataseg	ends
X	assume cs:codeseg,ds:dataseg,es:dataseg,ss:dataseg
X;begtext, begdata, begbss stuff removed--Aztec ln automatically creates
X;labels _Corg_,_Dorg_,_Uorg_
X$begin:
X	jmp short L0
X	dw	8 dup (0)	; kernel uses this area as stack for inital IRET
XL0:	mov sp,stackpt_
X	call main_
XL1:	jmp L1			; this will never be executed
Xexit_:	jmp exit_		; this will never be executed either
X	mov	ax,dataseg
Xcodeseg ends
Xdataseg segment para public 'data'
Xdata_org_ equ 0			; fs needs to know where build stuffed table
X;can't use obvious 'data_org_:' construction because Aztec ln automatically
X;puts a zero word at beginning of dataseg, and if build puts the table
X;in the usual position relative to the DADA, the tail end of the table gets
X;stomped by the initial stack.  Thus we put data_org at address 0 and have
X;build put the table in locations 4,6,8, even though the magic number is
X;two units further down.
X	dw  0DADAH,0,0,0,0,0,0,0	; first 8 words of MM, FS, INIT are for stack
X				; 0xDADA is magic number for build
X	bss	junk:byte,16 ; junk region at beginning of bss because
X;dos2out can't determine the data&bss sizes w/o rounding up to the nearest
X;paragraph.  We want to ensure that the paragraph on the boundary is never
X;used because it may not be properly initialized.
Xdataseg	ends
X	end	$begin
X
'EOF'
echo x - sendrec.asm
sed 's/^X//' >sendrec.asm << 'EOF'
X; See ../h/com.h for C definitions
XSEND = 1
XRECEIVE = 2
XBOTH = 3
XSYSVEC = 32
X
Xcodeseg segment para public 'code'
Xdataseg segment para public 'data'
Xdataseg ends
X	assume cs:codeseg,ds:dataseg,ss:dataseg,es:dataseg
X
X;*========================================================================*
X;                           send and receive                              *
X;*========================================================================*
X; send(), receive(), sendrec() all save bp, but destroy ax, bx, and cx.
X	public	send_,receive_,sendrec_
Xsend_:	mov cx,SEND		; send(dest, ptr)
X	jmp L0
X
Xreceive_:
X	mov cx,RECEIVE		; receive(src, ptr)
X	jmp L0
X
Xsendrec_:
X	mov cx,BOTH		; sendrec(srcdest, ptr)
X	jmp L0
X
X  L0:	push bp			; save bp
X	mov bp,sp		; can't index off sp
X	mov ax,4[bp]		; ax = dest-src
X	mov bx,6[bp]		; bx = message pointer
X	int SYSVEC		; trap to the kernel
X	pop bp			; restore bp
X	ret			; return
Xcodeseg	ends
X	end
X
'EOF'
echo x - diff
sed 's/^X//' >diff << 'EOF'
X*** build.c.orig	Sat Jun  6 15:52:54 1987
X--- build.c.new	Sat Jun  6 21:18:08 1987
X***************
X*** 39,44
X   *      build bootblok kernel mm fs init fsck image
X   *
X   * to get the resulting image onto the file "image".
X   */
X  
X  
X
X--- 39,50 -----
X   *      build bootblok kernel mm fs init fsck image
X   *
X   * to get the resulting image onto the file "image".
X+  * Revision by rmtodd:
X+  * Since Aztec ln insists on putting a zero word at the beginning of
X+  * data space before the program's data, we have to change the magic number
X+  * searches slightly for Aztec-generated programs.  Since they have 'FFFF'
X+  * at byte offset 6 in the header, as opposed for 0 for Minix-gen. progs,
X+  * we can tell the difference.
X   */
X  
X  
X***************
X*** 61,66
X  #define HEADER2 48              /* long form header size */
X  #define SEP_POS 1               /* tells where sep I & D bit is */
X  #define HDR_LEN 2               /* tells where header length is */
X  #define TEXT_POS 0              /* where is text size in header */
X  #define DATA_POS 1              /* where is data size in header */
X  #define BSS_POS 2               /* where is bss size in header */
X
X--- 67,73 -----
X  #define HEADER2 48              /* long form header size */
X  #define SEP_POS 1               /* tells where sep I & D bit is */
X  #define HDR_LEN 2               /* tells where header length is */
X+ #define CREATED_BY 3
X  #define TEXT_POS 0              /* where is text size in header */
X  #define DATA_POS 1              /* where is data size in header */
X  #define BSS_POS 2               /* where is bss size in header */
X***************
X*** 86,91
X    unsigned data_size;           /* size in bytes */
X    unsigned bss_size;            /* size in bytes */
X    int sep_id;                   /* 1 if separate, 0 if not */
X  } sizes[PROGRAMS];
X  
X  char *name[] = {"\nkernel", "mm    ", "fs    ", "init  ", "fsck  "};
X
X--- 93,99 -----
X    unsigned data_size;           /* size in bytes */
X    unsigned bss_size;            /* size in bytes */
X    int sep_id;                   /* 1 if separate, 0 if not */
X+   int aztec_made;		/* 1 if aztec-generated, 0 if not */
X  } sizes[PROGRAMS];
X  
X  char *name[] = {"\nkernel", "mm    ", "fs    ", "init  ", "fsck  "};
X***************
X*** 162,168
X   * when separate I & D space is used.
X   */
X  
X!   int fd, sepid, bytes_read, count;
X    unsigned text_bytes, data_bytes, bss_bytes, tot_bytes, rest, filler;
X    unsigned left_to_read;
X    char inbuf[READ_UNIT];
X
X--- 170,176 -----
X   * when separate I & D space is used.
X   */
X  
X!   int fd, sepid, aztec, bytes_read, count;
X    unsigned text_bytes, data_bytes, bss_bytes, tot_bytes, rest, filler;
X    unsigned left_to_read;
X    char inbuf[READ_UNIT];
X***************
X*** 170,176
X    if ( (fd = open(file_name, BREAD)) < 0) pexit("can't open ", file_name);
X  
X    /* Read the header to see how big the segments are. */
X!   read_header(fd, &sepid, &text_bytes, &data_bytes, &bss_bytes, file_name);
X  
X    /* Pad the total size to a 16-byte multiple, if needed. */
X    if (sepid && ((text_bytes % 16) != 0) ) {
X
X--- 178,184 -----
X    if ( (fd = open(file_name, BREAD)) < 0) pexit("can't open ", file_name);
X  
X    /* Read the header to see how big the segments are. */
X!   read_header(fd, &sepid, &aztec, &text_bytes, &data_bytes, &bss_bytes, file_name);
X  
X    /* Pad the total size to a 16-byte multiple, if needed. */
X    if (sepid && ((text_bytes % 16) != 0) ) {
X***************
X*** 190,195
X    sizes[num].data_size = data_bytes;
X    sizes[num].bss_size  = bss_bytes;
X    sizes[num].sep_id    = sepid;
X  
X    /* Print a message giving the program name and size, except for fsck. */
X    if (num < FSCK) { 
X
X--- 198,204 -----
X    sizes[num].data_size = data_bytes;
X    sizes[num].bss_size  = bss_bytes;
X    sizes[num].sep_id    = sepid;
X+   sizes[num].aztec_made= aztec;
X  
X    /* Print a message giving the program name and size, except for fsck. */
X    if (num < FSCK) { 
X***************
X*** 193,199
X  
X    /* Print a message giving the program name and size, except for fsck. */
X    if (num < FSCK) { 
X!         printf("%s  text=%5u  data=%5u  bss=%5u  tot=%5u  hex=%4x  %s\n",
X                  name[num], text_bytes, data_bytes, bss_bytes, tot_bytes,
X                  tot_bytes, (sizes[num].sep_id ? "Separate I & D" : ""));
X    }
X
X--- 202,208 -----
X  
X    /* Print a message giving the program name and size, except for fsck. */
X    if (num < FSCK) { 
X!         printf("%s  text=%5u  data=%5u  bss=%5u  tot=%5u  hex=%4x %s %s\n",
X                  name[num], text_bytes, data_bytes, bss_bytes, tot_bytes,
X                  tot_bytes, (sizes[num].sep_id ? "Separate I&D" : ""),
X  		(sizes[num].aztec_made ? "Azt" : ""));
X***************
X*** 195,201
X    if (num < FSCK) { 
X          printf("%s  text=%5u  data=%5u  bss=%5u  tot=%5u  hex=%4x  %s\n",
X                  name[num], text_bytes, data_bytes, bss_bytes, tot_bytes,
X!                 tot_bytes, (sizes[num].sep_id ? "Separate I & D" : ""));
X    }
X  
X  
X
X--- 204,211 -----
X    if (num < FSCK) { 
X          printf("%s  text=%5u  data=%5u  bss=%5u  tot=%5u  hex=%4x %s %s\n",
X                  name[num], text_bytes, data_bytes, bss_bytes, tot_bytes,
X!                 tot_bytes, (sizes[num].sep_id ? "Separate I&D" : ""),
X! 		(sizes[num].aztec_made ? "Azt" : ""));
X    }
X  
X  
X***************
X*** 219,226
X  }
X  
X  
X! read_header(fd, sepid, text_bytes, data_bytes, bss_bytes, file_name)
X! int fd, *sepid;
X  unsigned *text_bytes, *data_bytes, *bss_bytes;
X  char *file_name;
X  {
X
X--- 229,236 -----
X  }
X  
X  
X! read_header(fd, sepid, aztec, text_bytes, data_bytes, bss_bytes, file_name)
X! int fd, *sepid, *aztec;
X  unsigned *text_bytes, *data_bytes, *bss_bytes;
X  char *file_name;
X  {
X***************
X*** 253,258
X    /* Extract separate I & D bit. */
X    *sepid = hd[SEP_POS] & SEP_ID_BIT;
X  
X    /* Read the rest of the header and extract the sizes. */
X    if ((n = read(fd, head, header_len - 8)) != header_len - 8)
X          pexit("header too short: ", file_name);
X
X--- 263,270 -----
X    /* Extract separate I & D bit. */
X    *sepid = hd[SEP_POS] & SEP_ID_BIT;
X  
X+   /* Extract DOS (Aztec)-origin field -- non-0 is DOS */
X+   *aztec = hd[CREATED_BY] !=0 ;
X    /* Read the rest of the header and extract the sizes. */
X    if ((n = read(fd, head, header_len - 8)) != header_len - 8)
X          pexit("header too short: ", file_name);
X***************
X*** 372,377
X  
X    /* See if the magic number is where it should be in the kernel. */
X    data_offset = 512L + (long)sizes[KERN].text_size;    /* start of kernel data */
X    i = (get_byte(data_offset+1L) << 8) + get_byte(data_offset);
X    if (i != KERNEL_D_MAGIC)  {
X  	pexit("kernel data space: no magic #","");
X
X--- 384,390 -----
X  
X    /* See if the magic number is where it should be in the kernel. */
X    data_offset = 512L + (long)sizes[KERN].text_size;    /* start of kernel data */
X+   if (sizes[KERN].aztec_made) data_offset += 2L;
X    i = (get_byte(data_offset+1L) << 8) + get_byte(data_offset);
X    if (i != KERNEL_D_MAGIC)  {
X  	pexit("kernel data space: no magic #","");
X***************
X*** 419,424
X    init_org += sizes[KERN].text_size+sizes[KERN].data_size+sizes[KERN].bss_size;
X    mm_data = init_org - PROG_ORG +512L;	/* offset of mm in file */
X    mm_data += (long) sizes[MM].text_size;
X    init_org += sizes[MM].text_size + sizes[MM].data_size + sizes[MM].bss_size;
X    fs_org = init_org - PROG_ORG + 512L;   /* offset of fs-text into file */
X    fs_org +=  (long) sizes[FS].text_size;
X
X--- 432,438 -----
X    init_org += sizes[KERN].text_size+sizes[KERN].data_size+sizes[KERN].bss_size;
X    mm_data = init_org - PROG_ORG +512L;	/* offset of mm in file */
X    mm_data += (long) sizes[MM].text_size;
X+   if (sizes[MM].aztec_made) mm_data += 2L;
X    init_org += sizes[MM].text_size + sizes[MM].data_size + sizes[MM].bss_size;
X    fs_org = init_org - PROG_ORG + 512L;   /* offset of fs-text into file */
X    fs_org +=  (long) sizes[FS].text_size;
X***************
X*** 422,427
X    init_org += sizes[MM].text_size + sizes[MM].data_size + sizes[MM].bss_size;
X    fs_org = init_org - PROG_ORG + 512L;   /* offset of fs-text into file */
X    fs_org +=  (long) sizes[FS].text_size;
X    init_org += sizes[FS].text_size + sizes[FS].data_size + sizes[FS].bss_size;
X    init_text_size = sizes[INIT].text_size;
X    init_data_size = sizes[INIT].data_size + sizes[INIT].bss_size;
X
X--- 436,442 -----
X    init_org += sizes[MM].text_size + sizes[MM].data_size + sizes[MM].bss_size;
X    fs_org = init_org - PROG_ORG + 512L;   /* offset of fs-text into file */
X    fs_org +=  (long) sizes[FS].text_size;
X+   if (sizes[FS].aztec_made) fs_org +=2L;
X    init_org += sizes[FS].text_size + sizes[FS].data_size + sizes[FS].bss_size;
X    init_text_size = sizes[INIT].text_size;
X    init_data_size = sizes[INIT].data_size + sizes[INIT].bss_size;
X***************
X*** 449,454
X    if (mag != FS_D_MAGIC) pexit("mm data space: no magic #","");
X    mag = (get_byte(fbase+1L) << 8) + get_byte(fbase+0L);
X    if (mag != FS_D_MAGIC) pexit("fs data space: no magic #","");
X  
X    put_byte(fbase+4L, b0);
X    put_byte(fbase+5L, b1);
X
X--- 464,474 -----
X    if (mag != FS_D_MAGIC) pexit("mm data space: no magic #","");
X    mag = (get_byte(fbase+1L) << 8) + get_byte(fbase+0L);
X    if (mag != FS_D_MAGIC) pexit("fs data space: no magic #","");
X+   /* if fs was made by Aztec C, we want to patch starting at the usual loc.
X+   ** in the dataseg, even though the DADA magic number is shifted down 2
X+   ** bytes.
X+   */
X+   if (sizes[FS].aztec_made) fbase -= 2L;
X  
X    put_byte(fbase+4L, b0);
X    put_byte(fbase+5L, b1);
X*** dos2out.c.orig	Sat Jun  6 15:53:21 1987
X--- dos2out.c.new	Sat Jun  6 20:06:31 1987
X***************
X*** 97,103
X  #define A_WLR(cputype)	((cputype&0x02)!=0)  /* TRUE if words left-to-right */
X  
X  
X! #include "/lib/C86/stdio.h"
X  
X  
X  #define PH_SECTSIZE	512		/* size of a disk-block */
X
X--- 97,104 -----
X  #define A_WLR(cputype)	((cputype&0x02)!=0)  /* TRUE if words left-to-right */
X  
X  
X! #include <stdio.h>
X! #include <fcntl.h>
X  
X  
X  
X***************
X*** 100,105
X  #include "/lib/C86/stdio.h"
X  
X  
X  #define PH_SECTSIZE	512		/* size of a disk-block */
X  #define NOT_A_HDR_LEN	(PH_SECTSIZE-A_HDR_LEN)	/* complement */
X  #define FNAME		 32		/* length of filename/path +1 */
X
X--- 101,107 -----
X  #include <fcntl.h>
X  
X  
X+ 
X  #define PH_SECTSIZE	512		/* size of a disk-block */
X  #define NOT_A_HDR_LEN	(PH_SECTSIZE-A_HDR_LEN)	/* complement */
X  #define FNAME		 32		/* length of filename/path +1 */
X***************
X*** 177,183
X      } /* end switch */
X  
X      /* open & create files */
X!     if ((inf=open(in_name,BREAD)) <0) {
X         printf ("input file %s not found\n",in_name);
X         exit(2);
X      }
X
X--- 179,185 -----
X      } /* end switch */
X  
X      /* open & create files */
X!     if ((inf=open(in_name,O_RDONLY)) <0) {
X         printf ("input file %s not found\n",in_name);
X         exit(2);
X      }
X***************
X*** 207,213
X  
X  
X      /* input file is ok, open output (possibly destroy existing file) */
X!     if ((outf=creat(out_name,BWRITE)) <0) {
X  	printf ("cannot open output %s\n",out_name);
X  	exit(2);
X      }
X
X--- 209,215 -----
X  
X  
X      /* input file is ok, open output (possibly destroy existing file) */
X!     if ((outf=creat(out_name,0666)) <0) {
X  	printf ("cannot open output %s\n",out_name);
X  	exit(2);
X      }
X***************
X*** 237,243
X  
X      /* reposition file */
X      close (inf);
X!     inf=open(in_name,BREAD);
X      in_cnt=read(inf,inbuf2,PH_SECTSIZE);
X  
X      /* make a.out header */
X
X--- 239,245 -----
X  
X      /* reposition file */
X      close (inf);
X!     inf=open(in_name,O_RDONLY);
X      in_cnt=read(inf,inbuf2,PH_SECTSIZE);
X  
X      /* make a.out header */
X***************
X*** 251,257
X      a_ptr->a_version  = DOS;
X      a_ptr->a_data     = d_size;
X      a_ptr->a_text     = t_size;
X!     a_ptr->a_bss      = (d_ptr->min_free<<4) - d_ptr->sp_reg;
X      a_ptr->a_entry    = d_ptr->ip_reg;
X      a_ptr->a_totb     = a_ptr->a_text + a_ptr->a_bss + 
X  			a_ptr->a_data + d_ptr->sp_reg;
X
X--- 253,259 -----
X      a_ptr->a_version  = DOS;
X      a_ptr->a_data     = d_size;
X      a_ptr->a_text     = t_size;
X!     a_ptr->a_bss      = d_ptr->sp_reg - d_size;
X      a_ptr->a_entry    = d_ptr->ip_reg;
X      a_ptr->a_totb     = a_ptr->a_text + a_ptr->a_bss + 
X  			a_ptr->a_data + 4096; /* default 4K stack */
X***************
X*** 254,260
X      a_ptr->a_bss      = (d_ptr->min_free<<4) - d_ptr->sp_reg;
X      a_ptr->a_entry    = d_ptr->ip_reg;
X      a_ptr->a_totb     = a_ptr->a_text + a_ptr->a_bss + 
X! 			a_ptr->a_data + d_ptr->sp_reg;
X  
X      if (print) printinfo();
X  
X
X--- 256,262 -----
X      a_ptr->a_bss      = d_ptr->sp_reg - d_size;
X      a_ptr->a_entry    = d_ptr->ip_reg;
X      a_ptr->a_totb     = a_ptr->a_text + a_ptr->a_bss + 
X! 			a_ptr->a_data + 4096; /* default 4K stack */
X  
X      if (print) printinfo();
X  
'EOF'
echo x - liblist
sed 's/^X//' >liblist << 'EOF'
Xsetjmp.o
Xabort.o
Xabs.o
Xaccess.o
Xatol.o
Xbrk2.o
Xchdir.o
Xchmod.o
Xchown.o
Xchroot.o
Xcleanup.o
Xcrypt.o
Xctype.o
Xdup.o
Xdup2.o
Xexec.o
Xexit.o
Xfgets.o
Xfork.o
Xfprintf.o
Xfputs.o
Xfread.o
Xfreopen.o
Xfclose.o
Xfopen.o
Xcreat.o
Xfseek.o
Xfflush.o
Xftell.o
Xfwrite.o
Xgetegid.o
Xgetenv.o
Xgeteuid.o
Xgetgid.o
Xgetgrent.o
Xgetpass.o
Xgetpwent.o
Xatoi.o
Xclose.o
Xgets.o
Xgetuid.o
Xgetutil.o
Xioctl.o
Xisatty.o
Xfstat.o
Xitoa.o
Xkill.o
Xlink.o
Xlseek.o
Xmknod.o
Xmktemp.o
Xgetpid.o
Xmount.o
Xopen.o
Xperror.o
Xpipe.o
Xprintk.o
Xprints.o
Xrand.o
Xregexp.o
Xindex.o
Xregsub.o
Xrindex.o
Xscanf.o
Xprintdat.o
Xgetc.o
Xread.o
Xsetbuf.o
Xmalloc.o
Xbcopy.o
Xbrk.o
Xbrksize.o
Xsetgid.o
Xsetuid.o
Xsleep.o
Xalarm.o
Xpause.o
Xsignal.o
Xcatchsig.o
Xsprintf.o
Xdoprintf.o
Xputc.o
Xstat.o
Xstb.o
Xstderr.o
Xstime.o
Xstrcat.o
Xstrcmp.o
Xstrcpy.o
Xstrlen.o
Xstrncat.o
Xstrncmp.o
Xstrncpy.o
Xsync.o
Xsyslib.o
Xtime.o
Xtimes.o
Xumask.o
Xumount.o
Xungetc.o
Xunlink.o
Xutime.o
Xwait.o
Xwrite.o
Xcall.o
Xmessage.o
Xsendrec.o
Xcswt.o
Xcswit.o
Xlsubs.o
'EOF'