Xenixshlib - Shared libraries for xenix (part 1 of 3)
pgd at bbt.se
pgd at bbt.se
Sat Jan 26 01:53:17 AEST 1991
This is my package to make shared libraries on the Xenix/386 operating
system. It is specially geared toward the X-Windows user, and included
is a makefile to make X11R4 shared libraries.
---- Cut Here and unpack ----
#!/bin/sh
# This is Xenixshlib, a shell archive (shar 3.32)
# made 01/25/1991 10:47 UTC by pgd at compuram.bbt.se
# Source directory /u/pgd/coff
#
# existing files WILL be overwritten
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 7205 -rw-r----- README
# 7778 -rw-r--r-- Makefile
# 10959 -rw-rw---- makestub.c
# 13743 -rw-rw---- convcoff.c
# 6906 -r--r--r-- hash.c
# 1686 -r--r--r-- hash.h
# 1049 -rw-rw---- libX11_start.c
# 2479 -rw-rw---- libc_jump.s
# 10793 -rw-rw---- libX11_jump.s
# 2027 -rw-rw---- libXmu_jump.s
# 8376 -rw-rw---- libXt_jump.s
# 2653 -rw-rw---- libXaw_jump.s
# 1475 -rw-rw---- libXext_jump.s
# 296 -rw-rw---- Scrt0.s
# 418 -rw-rw---- libX11_s.c
# 99 -rw-rw---- hello.c
# 4277 -rw-rw---- coffhdr.c
# 1516 -rw-rw---- xcc.c
# 993 -rw-rw---- coffstrip.c
# 10837 -rw------- malloc.c
# 30 -rw-rw---- libX11_ver.c
# 323 -rw-rw---- libXaw_s.c
# 4678 -rw-rw---- xenix.cf
# 2158 -rw-rw---- Project.example
#
if touch 2>&1 | fgrep 'amc' > /dev/null
then TOUCH=touch
else TOUCH=true
fi
# ============= README ==============
echo "x - extracting README (Text)"
sed 's/^X//' << 'SHAR_EOF' > README &&
X SHARED LIBRARY PACKAGE FOR XENIX
X --------------------------------
X
XAuthor: P.Garbha (pgd at compuram.bbt.se) 22-Jan-91
X
X
XHere is my shared library package for xenix.
XIt allows you to build your own shared libraries, and build
Xprograms that use them.
X
XIn the package are the following programs:
X
X convcoff - convert a x.out file to a coff file
X coffhdr - Prints out the coff header (like hdr)
X coffstrip - strip for coff files
X xcc - cc command for building X-windows
X makestub - Make the stub sources for a library.
X Normally only used by the Makefile
X libX11_s - Shared library for X11 (created)
X libX11_s.a - Stub library using libX11_s (created)
X libXaw_s - Shared library for Xaw including Xt (created)
X libXaw_s.a - Stub library for libXaw_s
X libXc.a - Special version of the libc.a library due to
X problems with the Xenix ld program.
X hello - A test program with example build in the Makefile
X Scrt0.o - Run-time startup to be used when the shared library
X hash.* - hash routines written by ???
X malloc.c - malloc routine from bsd-reno, since the Xenix one
X does not work when put in a library.
X xenix.cf - Example X11R4 configuration file for using
X shared libraries.
X Project.example - Example of patches to Project.tmpl
X
XYou really need gcc and gas. (and masm to build a library until
Xsomeone fixes the bug in gas).
X
XThe implementation is using a double jump table, because i was not
Xable to make ld link properly when linking directly with the shared
Xlibrary. Therefore all the junk which is coming from libX11_s.a
X
X
XInstallation:
X-------------
XUnpack the sharchive in an empty directory and type "make". That will
Xautomatically produce the libX11 shared library and stub archive.
XIgnore the warning messages, from makestub, given during build.
XA "make install" will install the libraries. But check out the makefile
Xfirst, it might not do what you want.
X
XFiles created (installed):
X libX11_s (/shlib/libX11_s)
X libXaw_s (/shlib/libXaw_s)
X libX11_s.a (/lib/386/libX11_s.a)
X libXaw_s.a (/lib/386/libXaw_s.a)
X libXc.a (/lib/386/libXc.a)
X
XNote that the Xt library is included in the libXaw_s library. This is
Xbecause there is a limitation of two shared libraries for Xenix, and
Xprobably some program would load Xaw anyway, so that way Xt is "free".
XBy building a separate Xt shared library, more system memory would be
Xused.
X
XThe Xenix (microsoft) linker will include the wrong object modules if
Xit has two modules with the same symbols to choose from. (arrggh), so
Xtherefore it has to be presented with a pre-digested library for
X"libc.a". That library is called "libXc.a", and include all parts of
Xlibc that is not included in libX11. So in all programs using the
XlibX11_s library, -lXc has to be specified instead of -lc. Whenever
XSCO fixes this bug, the libXc library can be removed.
X
X
XWhat is the Makefile doing?
X---------------------------
X
XThe Makefile builds a shared library for X-windows, called "libX11_s",
Xand one for Xt and Xaw, called libXaw_s. The library files should be
Xput somewhere, for example in /shlib, the stub libraries "libX11_s.a"
Xand "libXaw_s.a" are most convenient to put in /lib/386. "Make
Xinstall" will put them there. After that
Xyou just include the stub library in your program builds.
XUnfortunately the Scrt0.o file has to be replaced with the one in the
Xpackage, which means you have to type in the ld command directly, and
Xcannot depend on cc. You can also use the -nostdlib option to gcc.
X
XYou also have to convert the executable file to a coff file, and tell
Xit which library to use. This is done with the convcoff program.
X
XExample:
XLet's say your program is called hello.c (it is in the package)
XTo compile you type:
X
X gcc -nostdlib Scrt0.o /lib/386/Sseg.o hello.o libX11_s.a -lXc
X convcoff -l`pwd`/libX11_s a.out hello
X
XThe `pwd` is because you have to give the absolute path to the -l
Xswitch. If the library is installed in /shlib, you instead type:
X convcoff -l /shlib/libX11_s a.out hello
X
XThe convcoff program has two options:
X -l libname - Tell it to load the given shared
X library. You have to give the whole
X path from root.
X -s - Strip symbols
X
XThe convcoff now automatically includes the correct shared libraries
Xif you specify the stub library with the -L switch. To be able to make
XX-windows, without massiv editing of the Imakefiles, I finally created
Xthe "xcc" command, which does this automatically.
XSo you can compile a program with:
X
X xcc hello.c -LX11_s -lXc -o hello
X
X
XHow to make another shared library
X----------------------------------
XThe Makefile is setup to build a X-windows library. to build
Xsomething else, the easiest is just to modify the Makefile, to fit the
Xnew library. There are comments in it. Mainly you have to change the
Xlibrary name, the list of jump-tables, and the list of libraries to
Xinclude. To make a jump-table, do a "nm -S" on the library, sort the
Xoutput, edit it with a text editor so that only the text definitions
Xare left. (Those starting with 0001:xxxxx) After that do a
X"delete-rectangle" (if you are using emacs), so only the names are
Xleft, and putin a "\tjmp\t" before each. You might also have to
Xexamine the list by hand to see if you really want to include all
Xsymbols. You might also want to include the symbols from referenced
Xlibraries. That is a little bit tougher. The easiest is probably to
Xcapture the warning messages for "makestub" about "missing jump table
Xentries", and include them in the jump table. You have to judge
Xyourself which should be included, and which should be missing.
XIn general, symbol that is never referenced outside the library, does
Xnot need to be in the jump table.
X
X
XBuilding X-windows for shared libraries
X---------------------------------------
XLook in the supplied xenix.cf file for hints on what to define for
Xshared libraries. Don't try to use this file directly, since it will
Xfor sure not fit your x-windows port.
XYou also need some patches to Project.tmpl. Look in "Project.example"
Xfor what what to do. (You can actually paste in this file directly
Xinto Project.tmpl).
X
XYou now cannot do a "make World", since the building of the shared
Xlibraries are not incorporated into the X11 build process. I suggest
Xthat you first defined "#define HasSharedLibraries NO" in xenix.cf,
Xand do the "make World". When X-windows works nicely, you can do a
X"make install" on the shared library package, after which you go back
Xand edit xenix.cf to "HasSharedLibraries YES", go to mit/clients. Do a
X"make clean", "make Makefiles" and finally "make". After this you go
Xto "mit" and do a "make install".
X
XThis is just a general outline of the process. This since the posted
XX11 port does not use shared libraries, and until someone incorporates
Xthem, you have to do it yourself. I am using another X11 port (color
Xvga), and since I don't have disk space for two, i have never tried to
Xposted one.
X
XI have successfully built all libraries and clients from "core". I
Xhave also built some contributed clients, and the shared library
Xconfiguration seems to work without a glitch. The core clients +
Xserver occupy less than 3MB in the /usr/lib/X11 library.
X
X
XP Garbha (pgd at compuram.bbt.se)
SHAR_EOF
$TOUCH -am 0125114691 README &&
chmod 0640 README ||
echo "restore of README failed"
set `wc -c README`;Wc_c=$1
if test "$Wc_c" != "7205"; then
echo original size 7205, current size $Wc_c
fi
# ============= Makefile ==============
echo "x - extracting Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
X#
X# Build file for X-windows shared libraries for Xenix
X#
X# This file will build libX11_s, libXt_s and libXaw_s
X# where libXt and libXaw also needs libX11
X#
X# Author: P.Garbha (pgd at compuram.bbt.se), 22-Jan-91
X#
X
X#
X# Name of the libraries
X#
XLIBX11 = libX11
XLIBXT = libXt
XLIBXAW = libXaw
X
X#
X# Path of the system libraries.
X#
XLIBPATH=/lib/386/S
X
X#
X# Path of the X11 tree root
X#
XX11ROOT=/X
X
X#
X# Jump tables to be used for build of library
X# The order in this list is significant.
X#
XLIBX11_JUMPS = libc_jump.o libX11_jump.o
XLIBXT_JUMPS = libXt_jump.o
XLIBXAW_JUMPS = libXaw_jump.o libXt_jump.o libXmu_jump.o
X
X#
X# versions of the shared libraries
X#
XLIBX11_VERSION=0x00010001
X
X#
X# libraries to search for symbols when building library
X# If you get any undefined symbols you can add your favourite library
X# here, without making any incompabilites in the library.
X# If you don't use any socket (emulation) code, you definitively need
X# to replace libsocket.a with something else.
X#
XLIBX11_LIBS = $(X11ROOT)/mit/lib/X11.o malloc.o \
X $(LIBPATH)libcfp.a $(LIBPATH)libc.a \
X $(LIBPATH)libm.a $(LIBPATH)libsocket.a $(LIBPATH)libgnu.a
X
XLIBXT_LIBS = $(X11ROOT)/mit/lib/Xt.o $(LIBX11)_s.a $(LIBPATH)libgnu.a
X
XLIBXAW_LIBS = $(X11ROOT)/mit/lib/Xaw.o $(LIBX11)_s.a \
X $(X11ROOT)/mit/lib/Xmu/libXmu.a \
X $(X11ROOT)/mit/extensions/lib/libXext.a \
X $(X11ROOT)/mit/lib/Xt/libXt.a $(LIBPATH)libgnu.a
X
X#
X# Define text and data address for the library (in hex)
X#
X# Xenix kernel restrictions on addresses:
X#
X# text segment address range: a000000 .. c000000
X# data segment address range: 8000000 .. c000000
X#
X# Actually the data segment can start of 20000000, but there is
X# a bug in xenix so that such a file is not loaded properly.
X#
XLIBX11_TEXTADDR = B0000000
XLIBX11_DATAADDR = B0800000
XLIBXT_TEXTADDR = B1000000
XLIBXT_DATAADDR = B1800000
XLIBXAW_TEXTADDR = B2000000
XLIBXAW_DATAADDR = B2800000
X
X#
X# You will need the gnu c-compiler, gas, and also masm.
X# This is because there is a bug in gas so that you cannot
X# assemble the stub libraries with it.
X#
XCC = gcc
XCFLAGS =
XAS = gas
XMASM = masm
X
X#
X# The rest are the rules for building the library
X#
X
X#
X# List of all source files
X#
XALLSOURCES = makestub.c convcoff.c hash.c hash.h libX11_start.c \
X libc_jump.s libX11_jump.s libXmu_jump.s libXt_jump.s libXaw_jump.s \
X libXext_jump.s Scrt0.s libX11_s.c hello.c coffhdr.c xcc.c coffstrip.c \
X malloc.c libX11_ver.c libXaw_s.c xenix.cf Project.example
X
XALLPROGRAMS = makestub convcoff coffhdr xcc coffstrip
X
Xall : $(ALLPROGRAMS) $(LIBX11)_s.a $(LIBXAW)_s.a
X
X# libXt left out, since it is now included in libXaw
X# $(LIBXT)_s.a
X
X#
X# Rules for libX11_s
X#
X$(LIBX11) : $(LIBX11)_s.o $(LIBX11_JUMPS) $(LIBX11_LIBS) $(LIBX11)_ver.o
X ld -Rt $(LIBX11_TEXTADDR) -Rd $(LIBX11_DATAADDR) -m $(LIBX11).map \
X -o $(LIBX11) $(LIBX11_JUMPS) $(LIBX11)_s.o $(LIBX11)_ver.o $(LIBX11_LIBS)
X
X$(LIBX11)_s : $(LIBX11) convcoff
X convcoff -s $(LIBX11) $(LIBX11)_s
X
X$(LIBX11).nm : $(LIBX11)_s
X nm -go $(LIBX11_LIBS) | egrep " A | C " >$(LIBX11).nm
X
X$(LIBX11)_s.a : $(LIBX11)_s $(LIBX11)_start.o $(LIBX11).nm makestub
X -mkdir tmp
X (cd tmp && ls | xargs rm)
X echo "Processing stub library. This will take a while..."
X for fi in `(cd tmp ; ../makestub -m ../$(LIBX11).nm ../$(LIBX11))` ;\
X do \
X (cd tmp ; $(MASM) $$fi ; rm $$fi ); \
X done
X -rm $(LIBX11)_s.a
X ar cu $(LIBX11)_s.a $(LIBX11)_start.o
X ( cd tmp ; ls | xargs ar u ../$(LIBX11)_s.a )
X ( cd tmp && ls | xargs rm )
X ranlib $(LIBX11)_s.a
X
X$(LIBX11)_start.o : $(LIBX11)_start.c
X $(CC) -c -DVERSION=$(LIBX11_VERSION) $(LIBX11)_start.c
X
X$(LIBX11)_ver.o : $(LIBX11)_ver.c
X $(CC) -c -DVERSION=$(LIBX11_VERSION) $(LIBX11)_ver.c
X
Xinstall_$(LIBX11) : $(LIBX11)_s $(LIBX11)_s.a
X cp $(LIBX11)_s /shlib && chmod 755 /shlib/$(LIBX11)_s
X cp $(LIBX11)_s.a $(LIBPATH)$(LIBX11)_s.a && chmod 755 $(LIBPATH)$(LIBX11)_s.a
X
X$(X11ROOT)/mit/lib/X11.o :
X (cd $(X11ROOT)/mit/lib/X ; \
X ld -r *.o -o ../X11.o )
X
X$(X11ROOT)/mit/lib/Xmu.o :
X (cd $(X11ROOT)/mit/lib/Xmu ; \
X ld -r *.o -o ../Xmu.o )
X
X#
X# Rules for LIBXT_s
X#
X$(LIBXT) : $(LIBXT)_s.o $(LIBXT_JUMPS) $(LIBXT_LIBS)
X ld -Rt $(LIBXT_TEXTADDR) -Rd $(LIBXT_DATAADDR) -m $(LIBXT).map \
X -o $(LIBXT) $(LIBXT_JUMPS) $(LIBXT)_s.o $(LIBXT_LIBS)
X
X$(LIBXT)_s : $(LIBXT) convcoff
X convcoff -s $(LIBXT) $(LIBXT)_s
X
X$(LIBXT).nm : $(LIBXT)_s
X nm -go $(LIBXT_LIBS) | egrep " A | C " >$(LIBXT).nm
X
X$(LIBXT)_s.a : $(LIBXT)_s $(LIBXT).nm makestub
X -mkdir tmp
X (cd tmp && ls | xargs rm)
X echo "Processing stub library. This will take a while..."
X for fi in `(cd tmp ; ../makestub -m ../$(LIBXT).nm ../$(LIBXT))` ;\
X do \
X (cd tmp ; $(MASM) $$fi ; rm $$fi ); \
X done
X -rm $(LIBXT)_s.a
X ( cd tmp ; ls | xargs ar u ../$(LIBXT)_s.a )
X ( cd tmp && ls | xargs rm )
X ranlib $(LIBXT)_s.a
X
Xinstall_$(LIBXT) : $(LIBXT)_s $(LIBXT)_s.a
X cp $(LIBXT)_s /shlib && chmod 755 /shlib/$(LIBXT)_s
X cp $(LIBXT)_s.a $(LIBPATH)$(LIBXT)_s.a && chmod 755 $(LIBPATH)$(LIBXT)_s.a
X
X$(X11ROOT)/mit/lib/Xt.o :
X (cd $(X11ROOT)/mit/lib/Xt ; \
X ld -r *.o -o ../Xt.o )
X
X
X#
X# Rules for LIBXAW_s
X#
X$(LIBXAW) : $(LIBXAW)_s.o $(LIBXAW_JUMPS) $(LIBXAW_LIBS)
X ld -Rt $(LIBXAW_TEXTADDR) -Rd $(LIBXAW_DATAADDR) -m $(LIBXAW).map \
X -o $(LIBXAW) $(LIBXAW_JUMPS) $(LIBXAW)_s.o $(LIBXAW_LIBS)
X
X$(LIBXAW)_s : $(LIBXAW) convcoff
X convcoff -s $(LIBXAW) $(LIBXAW)_s
X
X$(LIBXAW).nm : $(LIBXAW)_s
X nm -go $(LIBXAW_LIBS) | egrep " A | C " >$(LIBXAW).nm
X
X$(LIBXAW)_s.a : $(LIBXAW)_s $(LIBXAW).nm makestub
X -mkdir tmp
X (cd tmp && ls | xargs rm)
X echo "Processing stub library. This will take a while..."
X for fi in `(cd tmp ; ../makestub -m ../$(LIBXAW).nm ../$(LIBXAW))` ;\
X do \
X (cd tmp ; $(MASM) $$fi ; rm $$fi ); \
X done
X -rm $(LIBXAW)_s.a
X ( cd tmp ; ls | xargs ar u ../$(LIBXAW)_s.a )
X ( cd tmp && ls | xargs rm )
X ranlib $(LIBXAW)_s.a
X
Xinstall_$(LIBXAW) : $(LIBXAW)_s $(LIBXAW)_s.a
X cp $(LIBXAW)_s /shlib && chmod 755 /shlib/$(LIBXAW)_s
X cp $(LIBXAW)_s.a $(LIBPATH)$(LIBXAW)_s.a && chmod 755 $(LIBPATH)$(LIBXAW)_s.a
X
X$(X11ROOT)/mit/lib/Xaw.o:
X (cd $(X11ROOT)/mit/lib/Xaw ; \
X ld -r *.o -o ../Xaw.o )
X
X#
X# A small test program.
X#
Xhello : hello.x libX11_s convcoff
X convcoff -l `pwd`/libX11_s hello.x hello
X
Xhello.x : hello.o libX11_s.a Scrt0.o
X gcc -nostdlib Scrt0.o /lib/386/Sseg.o hello.o libX11_s.a -lc -o hello.x
X
XScrt0.o: Scrt0.s
X gas Scrt0.s -o Scrt0.o
X
Xmakestub : makestub.o hash.o
X $(CC) -g -o makestub makestub.o hash.o
X
Xconvcoff : convcoff.c
X $(CC) -g -o convcoff convcoff.c
X
Xinstall_programs: convcoff coffhdr coffstrip xcc
X cp convcoff /usr/local/convcoff && chmod 755 /usr/local/convcoff
X cp coffhdr /usr/local/coffhdr && chmod 755 /usr/local/coffhdr
X cp coffstrip /usr/local/coffstrip && chmod 755 /usr/local/coffstrip
X cp xcc /usr/local/xcc && chmod 755 /usr/local/xcc
X
Xclean::
X -rm *.o *.map *.nm $(LIBX11) hello a.out hello.x $(LIBXT) $(LIBXAW)
X -rm -fr tmp
X
Xremove::
X -rm /shlib/libX11_s /shlib/libXt_s /shlib/libXaw_s
X -rm $(LIBPATH)libX11_s.a $(LIBPATH)libXt_s.a $(LIBPATH)libXaw_s.a
X -rm libX11 libXt libXaw libX11_s libXt_s libXaw_s
X -rm libX11_s.a libXt_s.a libXaw_s.a
X
Xshar::
X shar -a -f -n Xenixshlib -l50 -o Xenixshlib -c -f README Makefile $(ALLSOURCES)
X
Xinstall:: install_$(LIBX11) install_$(LIBXT) install_$(LIBXAW) install_programs install_libXc
X
X#
X# junk
X#
X
X$(LIBX11)_s.nm : $(LIBX11)_s.a
X nm -go $(LIBX11)_s.a >$(LIBX11)_s.nm
X
X#
X# This library is needed since the microsoft linker is brain-damaged and
X# loads the wrong object files. The libXc library is a copy of libc, but
X# with all modules includes in libX11_s deleted
X#
XlibXc.a : $(LIBPATH)libc.a $(LIBX11)_s.nm
X cp $(LIBPATH)libc.a libXc.a
X nm -go $(LIBX11)_s.a | egrep " A | C " | awk "{print \$$2;}" | tr -d ":" | sort | uniq | xargs ar d libXc.a
X ranlib libXc.a
X
Xinstall_libXc : libXc.a
X cp libXc.a $(LIBPATH)libXc.a
X chmod 544 $(LIBPATH)libXc.a
X
Xcoffstrip : coffstrip.c
X $(CC) coffstrip.c -lx -o coffstrip
SHAR_EOF
$TOUCH -am 0122180791 Makefile &&
chmod 0644 Makefile ||
echo "restore of Makefile failed"
set `wc -c Makefile`;Wc_c=$1
if test "$Wc_c" != "7778"; then
echo original size 7778, current size $Wc_c
fi
# ============= makestub.c ==============
echo "x - extracting makestub.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > makestub.c &&
X/*
X * Make stub files from a nm listing of a library
X *
X * Author: P.Garbha pgd at compuram.bbt.se 9-Jan-91
X */
X
X#include <stdio.h>
X#include <string.h>
X#include <sys/types.h>
X#include <sys/a.out.h>
X#include <sys/relsym.h>
X#include <fcntl.h>
X#include "hash.h"
X
X#define SYMMAX 2000
X#define MSYMMAX 2000
X#define MAXSEG 10
X
Xstruct hashtab *symhash;
Xstruct hashtab *mastab;
Xstruct hashtab *filetab;
Xstruct hashtab *addrhash;
X
Xstruct symbol {
X char *name;
X char type;
X int addr; /* Real routine address */
X int jaddr; /* Jump table index */
X} symtab[SYMMAX];
X
Xint symcount;
X
X#define DONE 0200
X
Xstruct master {
X char *fname; /* File name */
X char *name; /* Symbol name */
X char type; /* Symbol type */
X} master[MSYMMAX];
Xint mastcount;
X
X/*
X * x.out header structure
X */
Xstruct xexec xhdr;
Xstruct xext ehdr;
Xstruct xseg xsegs[MAXSEG]; /* */
Xint xsegcount, xtextseg, xdataseg, textbase, database;
X
Xchar *libname;
Xchar *progname = "makestub";
XFILE *sfp;
X
Xchar filedef[] = " TITLE %s\n\n .386\n\
XDGROUP GROUP _DSTUB\n";
Xchar pubdef[] = " PUBLIC %s\nL%d DD 0%xH\n";
Xchar datadef[] = " PUBLIC %s\n%s EQU 0%xH\n";
Xchar textstart1[] = "_TEXT SEGMENT DWORD USE32 PUBLIC 'CODE'\n";
Xchar textstart2[] = "_TEXT SEGMENT\n";
Xchar textend[] = "_TEXT ENDS\n";
Xchar datastart1[] = "_DSTUB SEGMENT DWORD USE32 PUBLIC 'DSTUB'\n";
Xchar datastart2[] = "_DSTUB SEGMENT\n";
Xchar dataend[] = "_DSTUB ENDS\n";
Xchar fileend[] = "END\n";
Xchar jumpdef[] = "%s EQU $\n jmp L%d\n";
X
X
X
Xmain(argc, argv)
X int argc;
X char **argv;
X{
X int seg, addr, type;
X char name[80];
X char sfname[20];
X char *ofname = NULL;
X char fname[40];
X int i;
X int six;
X int intext, indata;
X int tsflag, dsflag;
X int seq;
X char *cp;
X
X symhash = ht_new("symhash");
X mastab = ht_new("master");
X filetab = ht_new("filetab");
X addrhash = ht_new("addrhash");
X
X while (argc > 1 && argv[1][0] == '-') {
X switch (argv[1][1]) {
X case 'm':
X loadmaster(argv[2]);
X argc--;
X argv++;
X break;
X default:
X fprintf(stderr, "Illegal option: %s\n", argv[1]);
X }
X argv++;
X argc--;
X }
X if (argc != 2) {
X fprintf(stderr, "Usage: makestub {-m masterfile} libname\n");
X exit(1);
X }
X cp = strrchr(argv[1], '/');
X if (cp)
X libname = cp+1;
X else
X libname = argv[1];
X
X loadlibdata(argv[1]);
X
X if (mastcount) {
X /*
X * Split into different files
X */
X intext = indata = tsflag = dsflag = seq = 0;
X for (i = 0; i < mastcount; i++) {
X six = (int)ht_nget(symhash, master[i].name) - 1;
X if (six == -1)
X continue;
X if (symtab[six].type != 'T' || (symtab[six].type & DONE))
X continue;
X if (symtab[six].jaddr == 0)
X continue;
X if (ofname == NULL || strcmp(ofname, master[i].fname)) {
X if (ofname) {
X fprintf(sfp, fileend);
X fclose(sfp);
X }
X ofname = master[i].fname;
X strcpy(sfname, ofname);
X sfname[strlen(sfname)-1] = 's';
X if (ht_nins(filetab, sfname, (char *)1)) {
X int cntr = 'A';
X fprintf(stderr, "Duplicate file: %s",
X sfname);
X do {
X sfname[0] = cntr;
X } while (ht_nins(filetab, sfname, (char *)1));
X fprintf(stderr, " new name: %s\n",
X sfname);
X }
X sfp = fopen(sfname, "w");
X if (sfp == NULL) {
X perror(sfname);
X exit(1);
X }
X puts(sfname);
X fprintf(sfp, filedef, sfname);
X intext = indata = tsflag = dsflag = seq = 0;
X }
X fprintf(sfp, dsflag ? datastart2 : datastart1);
X dsflag = 1;
X seq++;
X fprintf(sfp, pubdef,
X symtab[six].name, seq, symtab[six].jaddr);
X fprintf(sfp, dataend);
X fprintf(sfp, tsflag ? textstart2 : textstart1);
X tsflag = 1;
X fprintf(sfp, jumpdef, symtab[six].name, seq);
X fprintf(sfp, textend);
X symtab[six].type |= DONE;
X symtab[six].addr = seq;
X }
X if (ofname) {
X fprintf(sfp, fileend);
X fclose(sfp);
X }
X }
X /*
X * Now emit global symbols, and symbols not found
X * in the master index
X */
X sprintf(sfname, "%s_stub.s", libname);
X sfp = fopen(sfname, "w");
X if (sfp == NULL) {
X perror(sfname);
X exit(1);
X }
X puts(sfname);
X fprintf(sfp, filedef, libname);
X fprintf(sfp, datastart1);
X seq = 0;
X for (i = 0; i < symcount; i++) {
X switch (symtab[i].type) {
X case 'T':
X if (symtab[i].jaddr) {
X fprintf(sfp, pubdef,
X symtab[i].name, i, symtab[i].jaddr);
X symtab[i].addr = ++seq;
X } else if (strcmp(symtab[i].name, "___JumpTabEnd"))
X fprintf(stderr, "Warning: Symbol %s not in jump table\n", symtab[i].name);
X break;
X
X case 'D':
X case 'B':
X fprintf(sfp, datadef,
X symtab[i].name, symtab[i].name,
X symtab[i].addr);
X break;
X }
X }
X fprintf(sfp, dataend);
X fprintf(sfp, textstart1);
X for (i = 0; i < symcount; i++)
X if (symtab[i].type == 'T' && symtab[i].jaddr)
X fprintf(sfp, jumpdef, symtab[i].name, symtab[i].addr);
X fprintf(sfp, textend);
X fprintf(sfp, fileend);
X fclose(sfp);
X exit(0);
X}
X
X/*
X * load master index
X */
Xloadmaster(mfname)
X char *mfname;
X{
X FILE *fp;
X char line[100];
X char *cp;
X char fname[20], *fnp;
X int addr, type;
X char name[40];
X
X fnp = NULL;
X fp = fopen(mfname, "r");
X if (fp == NULL) {
X perror(mfname); exit(1);
X }
X while (fgets(line, sizeof(line) - 1, fp) != NULL) {
X cp = strchr(line, ':');
X if (strchr(cp+1, ':'))
X cp++;
X else
X cp = line;
X while (*cp == ' ')
X cp++;
X if (sscanf(cp, "%s %x %c %s\n", &fname, &addr, &type, &name) !=4) {
X fprintf(stderr, "Malformed line in %s:\n%s",
X mfname, line);
X exit(1);
X }
X cp = &fname[strlen(fname)-1];
X if (*cp != ':') {
X fprintf(stderr, "Malformed filename: %s\n", fname);
X exit(1);
X }
X *cp = '\0';
X if (mastcount == MSYMMAX) {
X fprintf(stderr, "Master symbol table overflow\n");
X exit(1);
X }
X if (fnp == NULL || strcmp(fname, fnp) != 0)
X fnp = strdup(fname);
X master[mastcount].fname = fnp;
X master[mastcount].name = strdup(name);
X master[mastcount].type = type;
X if (ht_nins(mastab, master[mastcount].name, (char *)(mastcount+1)))
X fprintf(stderr, "Warning: Cannot enter master symbol: %s\n", name);
X mastcount++;
X }
X}
X
X
X/*
X * Load data from library file (in x.out format)
X */
Xloadlibdata(xfname)
X char *xfname;
X{
X register int i;
X short magic;
X int xfd;
X
X xfd = open(xfname, O_RDONLY);
X if (xfd == -1) {
X perror(xfname); exit(1);
X }
X loadxhdr(xfd, xfname);
X loadxsyms(xfd, xfname);
X fixjumptab(xfd, xfname);
X close(xfd);
X}
X
X/*
X * Read library x.out header
X */
Xloadxhdr(xfd, xfname)
X int xfd;
X char *xfname;
X{
X int seg;
X
X if (read(xfd, (char *)&xhdr, sizeof xhdr) != sizeof xhdr) {
X perror(xfname);
X return 0;
X }
X if (xhdr.x_magic != X_MAGIC) {
X fprintf(stderr, "Not a x.out file: %s\n", xfname);
X return 0;
X }
X if (read(xfd, (char *)&ehdr, sizeof ehdr) != sizeof ehdr) {
X perror(xfname);
X return 0;
X }
X if ((xhdr.x_cpu & XC_CPU) != XC_386) {
X fprintf(stderr, "Not a 80386 executable file:%s\n", xfname);
X return 0;
X }
X if ((xhdr.x_renv & XE_SEG) == 0) {
X fprintf(stderr, "Not a Xenix segmented file: %s\n", xfname);
X return 0;
X }
X lseek(xfd, ehdr.xe_segpos, 0);
X xsegcount = ehdr.xe_segsize / sizeof(struct xseg);
X if (xsegcount > MAXSEG) {
X fprintf(stderr, "Too many segments: %d\n", xsegcount);
X return -1;
X }
X if (read(xfd, (char *)xsegs, xsegcount * sizeof(struct xseg)) != xsegcount * sizeof(struct xseg)) {
X perror(xfname);
X return 0;
X }
X
X /*
X * Locate the segments
X */
X for (seg = 0; seg < xsegcount; seg++)
X if (xsegs[seg].xs_type == XS_TTEXT)
X break;
X if (seg == xsegcount) {
X fprintf(stderr, "library file has no text segment\n");
X return 0;
X }
X xtextseg = seg;
X textbase = xsegs[seg].xs_rbase;
X
X for (seg = 0; seg < xsegcount; seg++)
X if (xsegs[seg].xs_type == XS_TDATA)
X break;
X if (seg == xsegcount) {
X fprintf(stderr, "library file has no data segment\n");
X return 0;
X }
X xdataseg = seg;
X database = xsegs[seg].xs_rbase;
X return 1;
X}
X
X/*
X * Read the x.out symbol table into memory
X */
Xloadxsyms(xfd, xfname)
X int xfd;
X char *xfname;
X{
X struct sym *xsymtab, *symp;
X int type, seg, value;
X char *name;
X int i;
X char *p;
X
X for (seg = 0; seg < xsegcount; seg++)
X if (xsegs[seg].xs_type == XS_TSYMS && xsegs[seg].xs_attr == XS_SXSEG)
X break;
X if (seg == xsegcount) {
X fprintf(stderr, "Library %s has no symbol table segment\n", xfname);
X exit(1);
X }
X xsymtab = (struct sym *)malloc(xsegs[seg].xs_psize);
X if (xsymtab == NULL) {
X fprintf(stderr, "Out of memory"); exit(1);
X }
X lseek(xfd, xsegs[seg].xs_filpos, 0);
X if (read(xfd, (char *)xsymtab, xsegs[seg].xs_psize) != xsegs[seg].xs_psize) {
X perror("symbol"); exit(1);
X }
X
X /*
X * Enter the symbols into the symbol table
X */
X symcount = 0;
X for (p = (char *)xsymtab; p < (char *)xsymtab+xhdr.x_syms; ) {
X symp = (struct sym *)p;
X p += sizeof(struct sym);
X name = (char *)p;
X switch (symp->s_type & S_TYPE) {
X case S_TEXT: /* A routine address */
X symtab[symcount].type = 'T';
X goto enter;
X case S_DATA:
X symtab[symcount].type = 'D';
X goto enter;
X case S_BSS:
X symtab[symcount].type = 'B';
X goto enter;
X enter:
X/* if (strcmp(name, "__nd_") == 0)
X name = "_shlib__nd_"; */
X symtab[symcount].name = strdup(name);
X symtab[symcount].addr = symp->s_value;
X symtab[symcount].jaddr = 0;
X if (ht_nins(symhash, symtab[symcount].name, (char *)(symcount+1)))
X fprintf(stderr, "Error entering symbol %s\n",
X name);
X if (ht_iins(addrhash, symtab[symcount].addr, (char *)(symcount+1)))
X fprintf(stderr, "Error inserting address %x (%s)\n", symtab[symcount].addr, symtab[symcount].name);
X symcount++;
X break;
X }
X p += strlen(p) + 1;
X }
X free(xsymtab);
X return 1;
X}
X
X
X/*
X * Fixup all symbol values for jumptable offset
X */
Xfixjumptab(xfd, xfname)
X int xfd;
X char *xfname;
X{
X register int i;
X int jumptabend, jumptabsize, noentries, six;
X char *jumpaddr;
X unsigned char *jumptab;
X int cc;
X unsigned int off;
X
X /*
X * Locate the end of the jump table
X */
X six = (int)ht_nget(symhash, "___JumpTabEnd") - 1;
X if (six == -1) {
X fprintf(stderr, "Library does not have a valid jump table\n");
X fprintf(stderr, "(Jump table end symbol missing)\n");
X exit(1);
X }
X jumptabend = symtab[six].addr;
X jumptabsize = jumptabend - textbase;
X jumptab = (unsigned char *)malloc(sizeof(char *) * jumptabsize);
X if (jumptab == NULL) {
X perror("Allocating jump table");
X exit(1);
X }
X /*
X * Read jump table into memory
X */
X lseek(xfd, xsegs[xtextseg].xs_filpos, 0);
X cc = read(xfd, jumptab, jumptabsize);
X if (cc != jumptabsize) {
X fprintf(stderr, "Something wrong with library file\n");
X exit(1);
X }
X
X /*
X * Go through all entries in the jump table, and
X * insert the jump table index into the symbol table
X */
X for (i = 0; i < jumptabsize; ) {
X if (jumptab[i] == 0) {
X i++;
X continue;
X }
X if (jumptab[i] != 0xe9) {
X fprintf(stderr, "Illegal jump table (no jump)\n");
X exit(1);
X }
X jumpaddr = *(char **)&jumptab[i+1] + i+5 + textbase;
X six = (int)ht_iget(addrhash, jumpaddr) - 1;
X if (six == -1) {
X fprintf(stderr, "Cannot find symbol for jump table entry %d (addr = %x)\n", i, jumpaddr);
X } else if (symtab[six].jaddr) {
X fprintf(stderr, "Symbol %s has multiple jump table entries\n", symtab[six].name);
X } else
X symtab[six].jaddr = i + textbase;
X i += 5;
X }
X}
SHAR_EOF
$TOUCH -am 0110080491 makestub.c &&
chmod 0660 makestub.c ||
echo "restore of makestub.c failed"
set `wc -c makestub.c`;Wc_c=$1
if test "$Wc_c" != "10959"; then
echo original size 10959, current size $Wc_c
fi
# ============= convcoff.c ==============
echo "x - extracting convcoff.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > convcoff.c &&
X/*
X * Program to convert a Xenix x-out file to a coff file
X *
X * Author: P.Garbha pgd at compuram.bbt.se
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/fcntl.h>
X#include <sys/coff.h>
X#include <sys/a.out.h>
X#include <string.h>
X#include <memory.h>
X#include <time.h>
X#include <malloc.h>
X#include <sys/relsym.h>
X
X/*
X * COFF symbol entry
X */
X#pragma pack(1)
Xstruct symbol {
X char n_name[8]; /* symbol name */
X unsigned long n_value; /* symbol value */
X unsigned short n_scnum; /* section number */
X unsigned short n_type;
X unsigned char n_sclass;
X unsigned char n_numaux; /* no of aux entries */
X};
X#pragma pack()
X
Xstruct symbol *symtab;
Xint symcount;
X
Xchar *fname;
X
X#define MAXSEG 10
X#define PAGESIZE 0x1000
X
X#define TEXT_SEGMENT 0x3f
X#define DATA_SEGMENT 0x47
X/*
X * Max number of shared libraries. (kernel restriction. see user.h)
X */
X#define SHLBMAX 2
X
X/*
X * Coff header structure
X */
X#define TEXT 0
X#define DATA 1
X#define BSS 2
X#define LIB 3
X
Xstruct filehdr fhdr; /* coff file header */
Xstruct aouthdr ahdr; /* a.out header */
Xstruct scnhdr shdr[MAXSEG]; /* section headers */
X
Xstruct {
X long size; /* size of lib section in words */
X long hdrsize; /* no of words in header */
X char path[80]; /* Path of library */
X} libsect1, libsect2;
X
Xint cfd; /* coff file id */
Xint tseg, dseg, bseg;
Xint coffscns;
Xint xtextfilpos, xdatafilpos; /* file position for text and data */
Xchar *textp, *datap;
Xint textsize, datasize;
Xint sflag; /* Stripping flag */
X
X/*
X * x.out header structure
X */
Xstruct xexec xhdr;
Xstruct xext ehdr;
Xstruct xseg xsegs[MAXSEG]; /* */
Xint xfd, cfd;
Xint xsegcount;
Xint xtextseg, xdataseg;
X
Xchar *xfname, *cfname;
X
Xint nshlibs; /* Number of shared libraries */
Xchar *shlibpaths[SHLBMAX]; /* Name of shared libraries */
X
Xmain(argc, argv)
X int argc;
X char **argv;
X{
X while (argc > 1 && argv[1][0] == '-') {
X switch (argv[1][1]) {
X case 's':
X sflag = 1;
X break;
X case 'l': /* Use shared library */
X addshlib(argv[2]);
X argc--;
X argv++;
X break;
X
X default:
X fprintf(stderr, "Illegal option: %s\n", argv[1]);
X }
X argv++;
X argc--;
X }
X if (argc != 3) {
X fprintf(stderr, "Usage: convcoff infile outfile\n");
X exit(1);
X }
X xfname = argv[1];
X cfname = argv[2];
X xfd = open(xfname, O_RDONLY);
X if (xfd == -1) {
X perror(xfname); exit(1);
X }
X if (!loadxhdr())
X exit(1);
X (void)loadxsyms();
X if (!cvtcoffhdr())
X exit(1);
X if (!loadximage())
X exit(1);
X cfd = open(cfname, O_WRONLY|O_CREAT|O_TRUNC, 0700);
X if (cfd == -1) {
X perror(cfname); exit(1);
X }
X if (!dumpcoff()) {
X close(cfd); unlink(cfname);
X exit(1);
X }
X close(xfd);
X close(cfd);
X exit(0);
X}
X
X/*
X * Load a x.out header
X */
Xloadxhdr()
X{
X register int i;
X short magic;
X
X if (read(xfd, (char *)&xhdr, sizeof xhdr) != sizeof xhdr) {
X perror(xfname);
X return 0;
X }
X if (xhdr.x_magic != X_MAGIC) {
X fprintf(stderr, "Not a x.out file: %s\n", xfname);
X return 0;
X }
X if (read(xfd, (char *)&ehdr, sizeof ehdr) != sizeof ehdr) {
X perror(fname);
X return 0;
X }
X if ((xhdr.x_cpu & XC_CPU) != XC_386) {
X fprintf(stderr, "Not a 80386 executable file:%s\n", xfname);
X return 0;
X }
X if ((xhdr.x_renv & XE_SEG) == 0) {
X fprintf(stderr, "Not a Xenix segmented file: %s\n", xfname);
X return 0;
X }
X lseek(xfd, ehdr.xe_segpos, 0);
X xsegcount = ehdr.xe_segsize / sizeof(struct xseg);
X if (xsegcount > MAXSEG) {
X fprintf(stderr, "Too many segments: %d\n", xsegcount);
X return -1;
X }
X if (read(xfd, (char *)xsegs, xsegcount * sizeof(struct xseg)) != xsegcount * sizeof(struct xseg)) {
X perror(xfname);
X return 0;
X }
X return 1;
X}
X
X/*
X * Load coff header
X */
Xint
Xloadcoffhdr(fname, fhdr, ahdr, shdrs)
X char *fname;
X struct filehdr *fhdr;
X struct aouthdr *ahdr;
X struct scnhdr **shdrs;
X{
X int fd;
X
X fd = open(fname, O_RDONLY);
X if (fd == -1) {
X perror(fname); return 0;
X }
X if (read(fd, fhdr, sizeof fhdr) != sizeof fhdr) {
X perror(fname); close(fd); return 0;
X }
X if (fhdr->f_magic == X_MAGIC) {
X fprintf(stderr, "file %s is not of coff type\n", fname);
X close(fd);
X return 0;
X }
X if (fhdr->f_magic != I386MAGIC) {
X fprintf(stderr, "File %s is not a coff exec file\n", fname);
X close(fd); return 0;
X }
X if (read(fd, ahdr, sizeof ahdr) != sizeof ahdr) {
X perror("aouthdr"); close(fd); return 0;
X }
X if (fhdr->f_nscns) {
X *shdrs = (struct scnhdr *)calloc(sizeof(struct scnhdr), fhdr->f_nscns);
X if (*shdrs == NULL) {
X perror(fname); close(fd);
X return 0;
X }
X if (read(fd, (char *)*shdrs, fhdr->f_nscns * sizeof(struct scnhdr)) == -1) {
X perror(fname); close(fd);
X return 0;
X }
X } else
X *shdrs = NULL;
X close(fd);
X return 1;
X}
X
X
X
X/*
X * Convert a x.out header structure, to coff header
X */
Xint
Xcvtcoffhdr()
X{
X int filpos = 0;
X int seg;
X
X /*
X * Make filehdr
X */
X fhdr.f_magic = I386MAGIC;
X fhdr.f_nscns = 0; /* Number of sections */
X fhdr.f_timdat = time(NULL); /* Current date and time */
X fhdr.f_symptr = 0; /* Symbol table pointer */
X fhdr.f_nsyms = symcount; /* Symbol count */
X fhdr.f_opthdr = sizeof(ahdr);
X fhdr.f_flags = F_RELFLG|F_EXEC|F_LNNO|F_AR32WR;
X
X /*
X * Make aout header extension
X */
X ahdr.magic = 0; /* magic */
X ahdr.vstamp = 0; /* version stamp */
X ahdr.tsize = xhdr.x_text; /* Text segment size */
X ahdr.dsize = xhdr.x_data; /* Data segment size */
X ahdr.bsize = xhdr.x_bss; /* bss segment size */
X ahdr.entry = xhdr.x_entry; /* entry address */
X ahdr.text_start = 0; /* text relcoation */
X ahdr.data_start = 0; /* data relocation */
X
X tseg = dseg = bseg = 0;
X
X /*
X * Make coff text segment
X */
X for (seg = 0; seg < xsegcount; seg++)
X if (xsegs[seg].xs_type == XS_TTEXT)
X break;
X if (seg == xsegcount) {
X fprintf(stderr, "x.out file has no text segment\n");
X return 0;
X }
X if (xsegs[seg].xs_seg != TEXT_SEGMENT) {
X fprintf(stderr, "Text segment must be %#02x\n", TEXT_SEGMENT);
X return 0;
X }
X xtextseg = seg;
X memset((char *)&shdr[TEXT].s_name, 0, sizeof(shdr[TEXT].s_name));
X strcpy(shdr[TEXT].s_name, ".text");
X ahdr.text_start = shdr[TEXT].s_paddr = shdr[TEXT].s_vaddr = xsegs[seg].xs_rbase;
X shdr[TEXT].s_size = xsegs[seg].xs_psize;
X shdr[TEXT].s_scnptr = PAGESIZE;
X shdr[TEXT].s_relptr = 0;
X shdr[TEXT].s_lnnoptr = 0;
X shdr[TEXT].s_nreloc = 0;
X shdr[TEXT].s_nlnno = 0;
X shdr[TEXT].s_flags = STYP_TEXT;
X xtextfilpos = xsegs[seg].xs_filpos;
X filpos = (PAGESIZE + xsegs[seg].xs_psize + (PAGESIZE-1)) & ~(PAGESIZE-1);
X
X /*
X * Make coff data segment
X */
X for (seg = 0; seg < xsegcount; seg++)
X if (xsegs[seg].xs_type == XS_TDATA)
X break;
X if (seg == xsegcount) {
X fprintf(stderr, "x.out file has no data segment\n");
X return 0;
X }
X xdataseg = seg;
X if (xsegs[seg].xs_seg != DATA_SEGMENT) {
X fprintf(stderr, "Data segment must be %#02x\n", DATA_SEGMENT);
X return 0;
X }
X memset((char *)&shdr[DATA].s_name, 0, sizeof(shdr[DATA].s_name));
X strcpy(shdr[DATA].s_name, ".data");
X ahdr.data_start = shdr[DATA].s_paddr = shdr[DATA].s_vaddr = xsegs[seg].xs_rbase;
X shdr[DATA].s_size = xsegs[seg].xs_psize;
X shdr[DATA].s_scnptr = filpos;
X shdr[DATA].s_relptr = 0;
X shdr[DATA].s_lnnoptr = 0;
X shdr[DATA].s_nreloc = 0;
X shdr[DATA].s_nlnno = 0;
X shdr[DATA].s_flags = STYP_DATA;
X xdatafilpos = xsegs[seg].xs_filpos;
X filpos += shdr[DATA].s_size;
X
X /*
X * Make coff bss segment
X */
X memset((char *)&shdr[BSS].s_name, 0, sizeof(shdr[BSS].s_name));
X strcpy(shdr[BSS].s_name, ".bss");
X shdr[BSS].s_paddr = shdr[BSS].s_vaddr = shdr[DATA].s_paddr + shdr[DATA].s_size;
X shdr[BSS].s_size = xhdr.x_bss;
X shdr[BSS].s_scnptr = 0;
X shdr[BSS].s_relptr = 0;
X shdr[BSS].s_lnnoptr = 0;
X shdr[BSS].s_nreloc = 0;
X shdr[BSS].s_nlnno = 0;
X shdr[BSS].s_flags = STYP_BSS;
X coffscns = 3;
X
X /*
X * Make library segment
X */
X if (nshlibs) {
X strcpy(shdr[LIB].s_name, ".lib");
X shdr[LIB].s_nlib = nshlibs;
X shdr[LIB].s_vaddr = 0;
X shdr[LIB].s_size = 0;
X shdr[LIB].s_scnptr = filpos;
X shdr[LIB].s_relptr = 0;
X shdr[LIB].s_lnnoptr = 0;
X shdr[LIB].s_nreloc = 0;
X shdr[LIB].s_nlnno = 0;
X shdr[LIB].s_flags = STYP_LIB;
X coffscns++;
X
X memset((char *)&libsect1, 0, sizeof(libsect1));
X libsect1.size = 2 + ((strlen(shlibpaths[0]) + 1 + 3) >> 2);
X libsect1.hdrsize = 2;
X strcpy(libsect1.path, shlibpaths[0]);
X shdr[LIB].s_size += libsect1.size << 2;
X if (nshlibs > 1) {
X memset((char *)&libsect2, 0, sizeof(libsect2));
X libsect2.size = 2 + ((strlen(shlibpaths[1])+1+3) >> 2);
X libsect2.hdrsize = 2;
X strcpy(libsect2.path, shlibpaths[1]);
X shdr[LIB].s_size += libsect2.size << 2;
X }
X filpos += shdr[LIB].s_size;
X }
X
X /*
X * Fix up the last pointers
X */
X fhdr.f_symptr = filpos;
X fhdr.f_nscns = coffscns;
X return 1;
X}
X
X
X/*
X * Read the x.out symbol table into memory
X */
Xloadxsyms()
X{
X struct sym *xsymtab;
X int type, seg, value;
X char *name;
X int i, xsymcount;
X char *p;
X
X for (seg = 0; seg < xsegcount; seg++)
X if (xsegs[seg].xs_type == XS_TSYMS && xsegs[seg].xs_attr == XS_SXSEG)
X break;
X if (seg == xsegcount) {
X fprintf(stderr, "warning: %s has no symbol table segment\n", xfname);
X return 0;
X }
X xsymtab = (struct sym *)malloc(xsegs[seg].xs_psize);
X if (xsymtab == NULL) {
X fprintf(stderr, "Out of memory"); exit(1);
X }
X lseek(xfd, xsegs[seg].xs_filpos, 0);
X if (read(xfd, (char *)xsymtab, xsegs[seg].xs_psize) != xsegs[seg].xs_psize) {
X perror("symbol"); exit(1);
X }
X
X /*
X * Count the symbols
X */
X xsymcount = 0;
X for (p = (char *)xsymtab; p < (char *)xsymtab+xhdr.x_syms; ) {
X p += sizeof(struct sym);
X if (p[0] == '_' && p[1] == '_' && p[2] == '_'
X && strncmp(p, "___SHLIB__", 10) == 0) {
X char path[40];
X /*
X * An autoload symbol
X */
X sprintf(path, "/shlib/%s", p+10);
X addshlib(path);
X }
X p += strlen(p) + 1;
X xsymcount++;
X }
X
X /*
X * Merge it in with the coff symbol table
X * unless stripping flag is on.
X */
X if (sflag)
X return 1;
X
X if (symcount == 0)
X symtab = (struct symbol *)malloc(symcount + xsymcount * sizeof(struct symbol));
X else
X symtab = (struct symbol *)realloc((char *)symtab, symcount + xsymcount * sizeof(struct symbol));
X if (symtab == NULL) {
X perror("Out of memory"); exit(1);
X }
X for (p = (char *)xsymtab; p < (char *)xsymtab+xhdr.x_syms; ) {
X if (((struct sym *)p)->s_seg == TEXT_SEGMENT) {
X symtab[symcount].n_scnum = TEXT+1;
X symtab[symcount].n_sclass = 2;
X } else if (((struct sym *)p)->s_seg == DATA_SEGMENT) {
X if (((struct sym *)p)->s_value >= xsegs[xdataseg].xs_rbase
X + xsegs[xdataseg].xs_vsize)
X symtab[symcount].n_scnum = BSS+1;
X else
X symtab[symcount].n_scnum = DATA+1;
X symtab[symcount].n_sclass = 3;
X } else {
X p += sizeof(struct sym);
X p += strlen(p) + 1;
X continue;
X }
X symtab[symcount].n_value = ((struct sym *)p)->s_value;
X symtab[symcount].n_type = 0;
X symtab[symcount].n_numaux = 0;
X p += sizeof(struct sym);
X strncpy(symtab[symcount].n_name, p, 8);
X p += strlen(p) + 1;
X symcount++;
X }
X free(xsymtab);
X return 1;
X}
X
X/*
X * Read a coff symbol table
X */
Xloadcoffsyms(fd)
X int fd;
X{
X int cc;
X
X if (lseek(fd, fhdr.f_symptr, 0) == -1) {
X perror("loadsyms"); exit(1);
X }
X if (symtab == NULL)
X symtab = (struct symbol *)malloc(sizeof(struct symbol) * fhdr.f_nsyms);
X else
X symtab = (struct symbol *)realloc((char *)symtab, sizeof(struct symbol) * (fhdr.f_nsyms + symcount));
X if (symtab == NULL) {
X perror("loadsyms"); exit(1);
X }
X cc = read(fd, (char *)&symtab[symcount], fhdr.f_nsyms * sizeof(struct symbol));
X if (cc == -1) {
X perror("loadsyms"); exit(1);
X }
X if (cc != fhdr.f_nsyms * sizeof(struct symbol)) {
X fprintf(stderr, "File too short\n");
X exit(1);
X }
X symcount += fhdr.f_nsyms;
X}
X
X/*
X * Load the image of a x.out file into memory
X */
Xloadximage()
X{
X int cc;
X
X textsize = xsegs[xtextseg].xs_psize;
X textp = malloc(textsize);
X if (textp == NULL) {
X perror("convcoff"); return 0;
X }
X datasize = xsegs[xdataseg].xs_psize;
X datap = malloc(datasize);
X if (datap == NULL) {
X perror("convcoff"); return 0;
X }
X lseek(xfd, xsegs[xtextseg].xs_filpos, 0);
X cc = read(xfd, textp, textsize);
X if (cc != textsize) {
X if (cc == -1)
X perror(xfname);
X else
X fprintf(stderr, "Invalid exec file: %s\n", xfname);
X return 0;
X }
X lseek(xfd, xsegs[xdataseg].xs_filpos, 0);
X cc = read(xfd, datap, datasize);
X if (cc != datasize) {
X if (cc == -1)
X perror(xfname);
X else
X fprintf(stderr, "Invalid exec file: %s\n", xfname);
X return 0;
X }
X return 1;
X}
X
X/*
X * Dump coff header
X */
Xdumpcoff()
X{
X int cc, j, padding;
X char block[PAGESIZE];
X
X memset(block, 0, PAGESIZE);
X memcpy(block, (char *)&fhdr, sizeof(fhdr));
X memcpy(block+sizeof(fhdr), (char *)&ahdr, sizeof(ahdr));
X memcpy(block+sizeof(fhdr)+sizeof(ahdr), (char *)shdr, sizeof(struct scnhdr)*coffscns);
X lseek(cfd, 0L, 0);
X cc = write(cfd, block, PAGESIZE);
X if (cc != PAGESIZE) {
X perror(cfname); return 0;
X }
X memset(block, 0, PAGESIZE);
X cc = write(cfd, textp, textsize);
X if (cc != textsize) {
X perror(cfname); return 0;
X }
X padding = shdr[DATA].s_scnptr - (PAGESIZE + textsize);
X cc = write(cfd, block, padding);
X if (cc != padding) {
X perror(cfname); return 0;
X }
X cc = write(cfd, datap, datasize);
X if (cc != datasize) {
X perror(cfname); return 0;
X }
X if (nshlibs) {
X cc = write(cfd, (char *)&libsect1, libsect1.size << 2);
X if (cc == -1) {
X perror(cfname); return 0;
X }
X if (nshlibs > 1) {
X cc = write(cfd, (char *)&libsect2, libsect2.size << 2);
X if (cc == -1) {
X perror(cfname); return 0;
X }
X }
X }
X cc = write(cfd, (char *)symtab, symcount * sizeof(struct symbol));
X if (cc == -1) {
X perror(cfname); return 0;
X }
X return 1;
X}
X
Xaddshlib(path)
X char *path;
X{
X int i;
X char *basep, *cp;
X
X if (basep = strrchr(path, '/'))
X basep++;
X else
X basep = path;
X for (i = 0; i < nshlibs; i++) {
X cp = strrchr(shlibpaths[i], '/');
X if (cp)
X cp++;
X else
X cp = shlibpaths[i];
X if (strcmp(basep, cp) == 0)
X return;
X }
X if (nshlibs == SHLBMAX) {
X fprintf(stderr, "Xenix only allows %d shared libraries\n", SHLBMAX);
X exit(1);
X }
X shlibpaths[nshlibs++] = strdup(path);
X}
SHAR_EOF
$TOUCH -am 0118105591 convcoff.c &&
chmod 0660 convcoff.c ||
echo "restore of convcoff.c failed"
set `wc -c convcoff.c`;Wc_c=$1
if test "$Wc_c" != "13743"; then
echo original size 13743, current size $Wc_c
fi
echo "End of part 1, continue with part 2"
exit 0
More information about the Alt.sources
mailing list