home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2612 < prev    next >
Encoding:
Internet Message Format  |  1991-01-26  |  43.1 KB

  1. From: pgd@bbt.se
  2. Newsgroups: alt.sources
  3. Subject: Xenixshlib - Shared libraries for xenix (part 1 of 3)
  4. Message-ID: <1991Jan25.145317.25461@bbt.se>
  5. Date: 25 Jan 91 14:53:17 GMT
  6.  
  7. This is my package to make shared libraries on the Xenix/386 operating
  8. system. It is specially geared toward the X-Windows user, and included
  9. is a makefile to make X11R4 shared libraries.
  10.  
  11. ---- Cut Here and unpack ----
  12. #!/bin/sh
  13. # This is Xenixshlib, a shell archive (shar 3.32)
  14. # made 01/25/1991 10:47 UTC by pgd@compuram.bbt.se
  15. # Source directory /u/pgd/coff
  16. #
  17. # existing files WILL be overwritten
  18. #
  19. # This shar contains:
  20. # length  mode       name
  21. # ------ ---------- ------------------------------------------
  22. #   7205 -rw-r----- README
  23. #   7778 -rw-r--r-- Makefile
  24. #  10959 -rw-rw---- makestub.c
  25. #  13743 -rw-rw---- convcoff.c
  26. #   6906 -r--r--r-- hash.c
  27. #   1686 -r--r--r-- hash.h
  28. #   1049 -rw-rw---- libX11_start.c
  29. #   2479 -rw-rw---- libc_jump.s
  30. #  10793 -rw-rw---- libX11_jump.s
  31. #   2027 -rw-rw---- libXmu_jump.s
  32. #   8376 -rw-rw---- libXt_jump.s
  33. #   2653 -rw-rw---- libXaw_jump.s
  34. #   1475 -rw-rw---- libXext_jump.s
  35. #    296 -rw-rw---- Scrt0.s
  36. #    418 -rw-rw---- libX11_s.c
  37. #     99 -rw-rw---- hello.c
  38. #   4277 -rw-rw---- coffhdr.c
  39. #   1516 -rw-rw---- xcc.c
  40. #    993 -rw-rw---- coffstrip.c
  41. #  10837 -rw------- malloc.c
  42. #     30 -rw-rw---- libX11_ver.c
  43. #    323 -rw-rw---- libXaw_s.c
  44. #   4678 -rw-rw---- xenix.cf
  45. #   2158 -rw-rw---- Project.example
  46. #
  47. if touch 2>&1 | fgrep 'amc' > /dev/null
  48.  then TOUCH=touch
  49.  else TOUCH=true
  50. fi
  51. # ============= README ==============
  52. echo "x - extracting README (Text)"
  53. sed 's/^X//' << 'SHAR_EOF' > README &&
  54. X           SHARED LIBRARY PACKAGE FOR XENIX
  55. X           --------------------------------
  56. X
  57. XAuthor: P.Garbha (pgd@compuram.bbt.se)        22-Jan-91
  58. X
  59. X
  60. XHere is my shared library package for xenix.
  61. XIt allows you to build your own shared libraries, and build
  62. Xprograms that use them.
  63. X
  64. XIn the package are the following programs:
  65. X
  66. X    convcoff   - convert a x.out file to a coff file
  67. X    coffhdr    - Prints out the coff header (like hdr)
  68. X    coffstrip  - strip for coff files
  69. X    xcc        - cc command for building X-windows
  70. X    makestub   - Make the stub sources for a library.
  71. X             Normally only used by the Makefile
  72. X    libX11_s   - Shared library for X11 (created)
  73. X    libX11_s.a - Stub library using libX11_s (created)
  74. X    libXaw_s   - Shared library for Xaw including Xt (created)
  75. X    libXaw_s.a - Stub library for libXaw_s
  76. X    libXc.a    - Special version of the libc.a library due to
  77. X             problems with the Xenix ld program.
  78. X    hello      - A test program with example build in the Makefile
  79. X    Scrt0.o    - Run-time startup to be used when the shared library
  80. X    hash.*     - hash routines written by ???
  81. X    malloc.c   - malloc routine from bsd-reno, since the Xenix one
  82. X             does not work when put in a library.
  83. X    xenix.cf   - Example X11R4 configuration file for using
  84. X             shared libraries.
  85. X    Project.example - Example of patches to Project.tmpl
  86. X
  87. XYou really need gcc and gas. (and masm to build a library until
  88. Xsomeone fixes the bug in gas).
  89. X
  90. XThe implementation is using a double jump table, because i was not
  91. Xable to make ld link properly when linking directly with the shared
  92. Xlibrary.  Therefore all the junk which is coming from libX11_s.a
  93. X
  94. X
  95. XInstallation:
  96. X-------------
  97. XUnpack the sharchive in an empty directory and type "make". That will
  98. Xautomatically produce the libX11 shared library and stub archive.
  99. XIgnore the warning messages, from makestub, given during build.
  100. XA "make install" will install the libraries. But check out the makefile
  101. Xfirst, it might not do what you want.
  102. X
  103. XFiles created (installed):
  104. X    libX11_s    (/shlib/libX11_s)
  105. X    libXaw_s    (/shlib/libXaw_s)
  106. X    libX11_s.a    (/lib/386/libX11_s.a)
  107. X    libXaw_s.a    (/lib/386/libXaw_s.a)
  108. X    libXc.a        (/lib/386/libXc.a)
  109. X
  110. XNote that the Xt library is included in the libXaw_s library. This is
  111. Xbecause there is a limitation of two shared libraries for Xenix, and
  112. Xprobably some program would load Xaw anyway, so that way Xt is "free".
  113. XBy building a separate Xt shared library, more system memory would be
  114. Xused. 
  115. X
  116. XThe Xenix (microsoft) linker will include the wrong object modules if
  117. Xit has two modules with the same symbols to choose from. (arrggh), so
  118. Xtherefore it has to be presented with a pre-digested library for
  119. X"libc.a". That library is called "libXc.a", and include all parts of
  120. Xlibc that is not included in libX11. So in all programs using the
  121. XlibX11_s library, -lXc has to be specified instead of -lc. Whenever
  122. XSCO fixes this bug, the libXc library can be removed.
  123. X
  124. X
  125. XWhat is the Makefile doing?
  126. X---------------------------
  127. X
  128. XThe Makefile builds a shared library for X-windows, called "libX11_s",
  129. Xand one for Xt and Xaw, called libXaw_s.  The library files should be
  130. Xput somewhere, for example in /shlib, the stub libraries "libX11_s.a"
  131. Xand "libXaw_s.a" are most convenient to put in /lib/386.  "Make
  132. Xinstall" will put them there. After that
  133. Xyou just include the stub library in your program builds.
  134. XUnfortunately the Scrt0.o file has to be replaced with the one in the
  135. Xpackage, which means you have to type in the ld command directly, and
  136. Xcannot depend on cc. You can also use the -nostdlib option to gcc.
  137. X
  138. XYou also have to convert the executable file to a coff file, and tell
  139. Xit which library to use.  This is done with the convcoff program. 
  140. X
  141. XExample:
  142. XLet's say your program is called hello.c (it is in the package)
  143. XTo compile you type:
  144. X
  145. X    gcc -nostdlib Scrt0.o /lib/386/Sseg.o hello.o libX11_s.a -lXc
  146. X    convcoff -l`pwd`/libX11_s a.out hello
  147. X
  148. XThe `pwd` is because you have to give the absolute path to the -l
  149. Xswitch. If the library is installed in /shlib, you instead type:
  150. X    convcoff -l /shlib/libX11_s a.out hello
  151. X
  152. XThe convcoff program has two options:
  153. X    -l libname        - Tell it to load the given shared
  154. X                library. You have to give the whole
  155. X                path from root.
  156. X    -s            - Strip symbols
  157. X
  158. XThe convcoff now automatically includes the correct shared libraries
  159. Xif you specify the stub library with the -L switch. To be able to make
  160. XX-windows, without massiv editing of the Imakefiles, I finally created
  161. Xthe "xcc" command, which does this automatically.
  162. XSo you can compile a program with:
  163. X
  164. X    xcc hello.c -LX11_s -lXc -o hello
  165. X
  166. X
  167. XHow to make another shared library
  168. X----------------------------------
  169. XThe Makefile is setup to build a X-windows library.  to build
  170. Xsomething else, the easiest is just to modify the Makefile, to fit the
  171. Xnew library. There are comments in it. Mainly you have to change the
  172. Xlibrary name, the list of jump-tables, and the list of libraries to
  173. Xinclude. To make a jump-table, do a "nm -S" on the library, sort the
  174. Xoutput, edit it with a text editor so that only the text definitions
  175. Xare left. (Those starting with 0001:xxxxx) After that do a
  176. X"delete-rectangle" (if you are using emacs), so only the names are
  177. Xleft, and putin a "\tjmp\t" before each. You might also have to
  178. Xexamine the list by hand to see if you really want to include all
  179. Xsymbols. You might also want to include the symbols from referenced
  180. Xlibraries. That is a little bit tougher. The easiest is probably to
  181. Xcapture the warning messages for "makestub" about "missing jump table
  182. Xentries", and include them in the jump table. You have to judge
  183. Xyourself which should be included, and which should be missing.
  184. XIn general, symbol that is never referenced outside the library, does
  185. Xnot need to be in the jump table.
  186. X
  187. X
  188. XBuilding X-windows for shared libraries
  189. X---------------------------------------
  190. XLook in the supplied xenix.cf file for hints on what to define for
  191. Xshared libraries. Don't try to use this file directly, since it will
  192. Xfor sure not fit your x-windows port.
  193. XYou also need some patches to Project.tmpl. Look in "Project.example"
  194. Xfor what what to do. (You can actually paste in this file directly
  195. Xinto Project.tmpl).
  196. X
  197. XYou now cannot do a "make World", since the building of the shared
  198. Xlibraries are not incorporated into the X11 build process. I suggest
  199. Xthat you first defined "#define    HasSharedLibraries NO" in xenix.cf,
  200. Xand do the "make World". When X-windows works nicely, you can do a
  201. X"make install" on the shared library package, after which you go back
  202. Xand edit xenix.cf to "HasSharedLibraries YES", go to mit/clients. Do a
  203. X"make clean", "make Makefiles" and finally "make". After this you go
  204. Xto "mit" and do a "make install".
  205. X
  206. XThis is just a general outline of the process. This since the posted
  207. XX11 port does not use shared libraries, and until someone incorporates
  208. Xthem, you have to do it yourself. I am using another X11 port (color
  209. Xvga), and since I don't have disk space for two, i have never tried to
  210. Xposted one. 
  211. X
  212. XI have successfully built all libraries and clients from "core". I
  213. Xhave also built some contributed clients, and the shared library
  214. Xconfiguration seems to work without a glitch.  The core clients +
  215. Xserver occupy less than 3MB in the /usr/lib/X11 library.
  216. X
  217. X
  218. XP Garbha (pgd@compuram.bbt.se)
  219. SHAR_EOF
  220. $TOUCH -am 0125114691 README &&
  221. chmod 0640 README ||
  222. echo "restore of README failed"
  223. set `wc -c README`;Wc_c=$1
  224. if test "$Wc_c" != "7205"; then
  225.     echo original size 7205, current size $Wc_c
  226. fi
  227. # ============= Makefile ==============
  228. echo "x - extracting Makefile (Text)"
  229. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  230. X#
  231. X# Build file for X-windows shared libraries for Xenix
  232. X#
  233. X# This file will build libX11_s, libXt_s and libXaw_s
  234. X# where libXt and libXaw also needs libX11
  235. X#
  236. X# Author: P.Garbha (pgd@compuram.bbt.se), 22-Jan-91
  237. X# 
  238. X
  239. X#
  240. X# Name of the libraries
  241. X#
  242. XLIBX11 = libX11
  243. XLIBXT = libXt
  244. XLIBXAW = libXaw
  245. X
  246. X#
  247. X# Path of the system libraries.
  248. X#
  249. XLIBPATH=/lib/386/S
  250. X
  251. X#
  252. X# Path of the X11 tree root
  253. X#
  254. XX11ROOT=/X
  255. X
  256. X#
  257. X# Jump tables to be used for build of library
  258. X# The order in this list is significant.
  259. X#
  260. XLIBX11_JUMPS = libc_jump.o libX11_jump.o 
  261. XLIBXT_JUMPS = libXt_jump.o
  262. XLIBXAW_JUMPS = libXaw_jump.o libXt_jump.o libXmu_jump.o
  263. X
  264. X#
  265. X# versions of the shared libraries
  266. X#
  267. XLIBX11_VERSION=0x00010001
  268. X
  269. X#
  270. X# libraries to search for symbols when building library
  271. X# If you get any undefined symbols you can add your favourite library
  272. X# here, without making any incompabilites in the library.
  273. X# If you don't use any socket (emulation) code, you definitively need
  274. X# to replace libsocket.a with something else.
  275. X#
  276. XLIBX11_LIBS = $(X11ROOT)/mit/lib/X11.o malloc.o \
  277. X    $(LIBPATH)libcfp.a $(LIBPATH)libc.a \
  278. X    $(LIBPATH)libm.a $(LIBPATH)libsocket.a $(LIBPATH)libgnu.a
  279. X
  280. XLIBXT_LIBS = $(X11ROOT)/mit/lib/Xt.o $(LIBX11)_s.a $(LIBPATH)libgnu.a
  281. X
  282. XLIBXAW_LIBS = $(X11ROOT)/mit/lib/Xaw.o $(LIBX11)_s.a \
  283. X        $(X11ROOT)/mit/lib/Xmu/libXmu.a \
  284. X        $(X11ROOT)/mit/extensions/lib/libXext.a \
  285. X        $(X11ROOT)/mit/lib/Xt/libXt.a $(LIBPATH)libgnu.a
  286. X
  287. X#
  288. X# Define text and data address for the library (in hex)
  289. X#
  290. X# Xenix kernel restrictions on addresses:
  291. X#
  292. X# text segment address range: a000000 .. c000000
  293. X# data segment address range: 8000000 .. c000000
  294. X#
  295. X# Actually the data segment can start of 20000000, but there is
  296. X# a bug in xenix so that such a file is not loaded properly.
  297. X#
  298. XLIBX11_TEXTADDR = B0000000
  299. XLIBX11_DATAADDR = B0800000
  300. XLIBXT_TEXTADDR  = B1000000
  301. XLIBXT_DATAADDR  = B1800000
  302. XLIBXAW_TEXTADDR = B2000000
  303. XLIBXAW_DATAADDR = B2800000
  304. X
  305. X#
  306. X# You will need the gnu c-compiler, gas, and also masm.
  307. X# This is because there is a bug in gas so that you cannot
  308. X# assemble the stub libraries with it.
  309. X#
  310. XCC = gcc
  311. XCFLAGS =
  312. XAS = gas
  313. XMASM = masm
  314. X
  315. X#
  316. X# The rest are the rules for building the library
  317. X#
  318. X
  319. X#
  320. X# List of all source files
  321. X#
  322. XALLSOURCES = makestub.c convcoff.c hash.c hash.h libX11_start.c \
  323. X    libc_jump.s libX11_jump.s libXmu_jump.s libXt_jump.s libXaw_jump.s \
  324. X    libXext_jump.s Scrt0.s libX11_s.c hello.c coffhdr.c xcc.c coffstrip.c \
  325. X    malloc.c libX11_ver.c libXaw_s.c xenix.cf Project.example
  326. X
  327. XALLPROGRAMS = makestub convcoff coffhdr xcc coffstrip
  328. X
  329. Xall : $(ALLPROGRAMS) $(LIBX11)_s.a $(LIBXAW)_s.a
  330. X
  331. X# libXt left out, since it is now included in libXaw
  332. X# $(LIBXT)_s.a 
  333. X
  334. X#
  335. X# Rules for libX11_s
  336. X#
  337. X$(LIBX11) : $(LIBX11)_s.o $(LIBX11_JUMPS) $(LIBX11_LIBS) $(LIBX11)_ver.o
  338. X    ld -Rt $(LIBX11_TEXTADDR) -Rd $(LIBX11_DATAADDR) -m $(LIBX11).map \
  339. X     -o $(LIBX11) $(LIBX11_JUMPS) $(LIBX11)_s.o $(LIBX11)_ver.o $(LIBX11_LIBS)
  340. X
  341. X$(LIBX11)_s : $(LIBX11) convcoff
  342. X    convcoff -s $(LIBX11) $(LIBX11)_s
  343. X
  344. X$(LIBX11).nm : $(LIBX11)_s
  345. X    nm -go $(LIBX11_LIBS) | egrep " A | C " >$(LIBX11).nm
  346. X
  347. X$(LIBX11)_s.a : $(LIBX11)_s $(LIBX11)_start.o $(LIBX11).nm makestub
  348. X    -mkdir tmp
  349. X    (cd tmp && ls | xargs rm)
  350. X    echo "Processing stub library. This will take a while..."
  351. X    for fi in `(cd tmp ; ../makestub -m ../$(LIBX11).nm ../$(LIBX11))` ;\
  352. X        do \
  353. X        (cd tmp ; $(MASM) $$fi ; rm $$fi ); \
  354. X    done
  355. X    -rm $(LIBX11)_s.a
  356. X    ar cu $(LIBX11)_s.a $(LIBX11)_start.o
  357. X    ( cd tmp ; ls | xargs ar u ../$(LIBX11)_s.a )
  358. X    ( cd tmp && ls | xargs rm )
  359. X    ranlib $(LIBX11)_s.a
  360. X
  361. X$(LIBX11)_start.o : $(LIBX11)_start.c
  362. X    $(CC) -c -DVERSION=$(LIBX11_VERSION) $(LIBX11)_start.c
  363. X
  364. X$(LIBX11)_ver.o : $(LIBX11)_ver.c
  365. X    $(CC) -c -DVERSION=$(LIBX11_VERSION) $(LIBX11)_ver.c
  366. X
  367. Xinstall_$(LIBX11) : $(LIBX11)_s $(LIBX11)_s.a
  368. X    cp $(LIBX11)_s /shlib && chmod 755 /shlib/$(LIBX11)_s
  369. X    cp $(LIBX11)_s.a $(LIBPATH)$(LIBX11)_s.a && chmod 755 $(LIBPATH)$(LIBX11)_s.a
  370. X
  371. X$(X11ROOT)/mit/lib/X11.o :
  372. X    (cd $(X11ROOT)/mit/lib/X ; \
  373. X    ld -r *.o -o ../X11.o )
  374. X
  375. X$(X11ROOT)/mit/lib/Xmu.o :
  376. X    (cd $(X11ROOT)/mit/lib/Xmu ; \
  377. X    ld -r *.o -o ../Xmu.o )
  378. X
  379. X#
  380. X# Rules for LIBXT_s
  381. X#
  382. X$(LIBXT) : $(LIBXT)_s.o $(LIBXT_JUMPS) $(LIBXT_LIBS)
  383. X    ld -Rt $(LIBXT_TEXTADDR) -Rd $(LIBXT_DATAADDR) -m $(LIBXT).map \
  384. X     -o $(LIBXT) $(LIBXT_JUMPS) $(LIBXT)_s.o $(LIBXT_LIBS)
  385. X
  386. X$(LIBXT)_s : $(LIBXT) convcoff
  387. X    convcoff -s $(LIBXT) $(LIBXT)_s
  388. X
  389. X$(LIBXT).nm : $(LIBXT)_s
  390. X    nm -go $(LIBXT_LIBS) | egrep " A | C " >$(LIBXT).nm
  391. X
  392. X$(LIBXT)_s.a : $(LIBXT)_s $(LIBXT).nm makestub
  393. X    -mkdir tmp
  394. X    (cd tmp && ls | xargs rm)
  395. X    echo "Processing stub library. This will take a while..."
  396. X    for fi in `(cd tmp ; ../makestub -m ../$(LIBXT).nm ../$(LIBXT))` ;\
  397. X        do \
  398. X        (cd tmp ; $(MASM) $$fi ; rm $$fi ); \
  399. X    done
  400. X    -rm $(LIBXT)_s.a
  401. X    ( cd tmp ; ls | xargs ar u ../$(LIBXT)_s.a )
  402. X    ( cd tmp && ls | xargs rm )
  403. X    ranlib $(LIBXT)_s.a
  404. X
  405. Xinstall_$(LIBXT) : $(LIBXT)_s $(LIBXT)_s.a
  406. X    cp $(LIBXT)_s /shlib && chmod 755 /shlib/$(LIBXT)_s
  407. X    cp $(LIBXT)_s.a $(LIBPATH)$(LIBXT)_s.a && chmod 755 $(LIBPATH)$(LIBXT)_s.a
  408. X
  409. X$(X11ROOT)/mit/lib/Xt.o :
  410. X    (cd $(X11ROOT)/mit/lib/Xt ; \
  411. X    ld -r *.o -o ../Xt.o )
  412. X
  413. X
  414. X#
  415. X# Rules for LIBXAW_s
  416. X#
  417. X$(LIBXAW) : $(LIBXAW)_s.o $(LIBXAW_JUMPS) $(LIBXAW_LIBS)
  418. X    ld -Rt $(LIBXAW_TEXTADDR) -Rd $(LIBXAW_DATAADDR) -m $(LIBXAW).map \
  419. X     -o $(LIBXAW) $(LIBXAW_JUMPS) $(LIBXAW)_s.o $(LIBXAW_LIBS)
  420. X
  421. X$(LIBXAW)_s : $(LIBXAW) convcoff
  422. X    convcoff -s $(LIBXAW) $(LIBXAW)_s
  423. X
  424. X$(LIBXAW).nm : $(LIBXAW)_s
  425. X    nm -go $(LIBXAW_LIBS) | egrep " A | C " >$(LIBXAW).nm
  426. X
  427. X$(LIBXAW)_s.a : $(LIBXAW)_s $(LIBXAW).nm makestub
  428. X    -mkdir tmp
  429. X    (cd tmp && ls | xargs rm)
  430. X    echo "Processing stub library. This will take a while..."
  431. X    for fi in `(cd tmp ; ../makestub -m ../$(LIBXAW).nm ../$(LIBXAW))` ;\
  432. X        do \
  433. X        (cd tmp ; $(MASM) $$fi ; rm $$fi ); \
  434. X    done
  435. X    -rm $(LIBXAW)_s.a
  436. X    ( cd tmp ; ls | xargs ar u ../$(LIBXAW)_s.a )
  437. X    ( cd tmp && ls | xargs rm )
  438. X    ranlib $(LIBXAW)_s.a
  439. X
  440. Xinstall_$(LIBXAW) : $(LIBXAW)_s $(LIBXAW)_s.a
  441. X    cp $(LIBXAW)_s /shlib && chmod 755 /shlib/$(LIBXAW)_s
  442. X    cp $(LIBXAW)_s.a $(LIBPATH)$(LIBXAW)_s.a && chmod 755 $(LIBPATH)$(LIBXAW)_s.a
  443. X
  444. X$(X11ROOT)/mit/lib/Xaw.o:
  445. X    (cd $(X11ROOT)/mit/lib/Xaw ; \
  446. X    ld -r *.o -o ../Xaw.o )
  447. X
  448. X#
  449. X# A small test program.
  450. X#
  451. Xhello : hello.x libX11_s convcoff
  452. X    convcoff -l `pwd`/libX11_s hello.x hello
  453. X
  454. Xhello.x : hello.o libX11_s.a Scrt0.o
  455. X    gcc -nostdlib Scrt0.o /lib/386/Sseg.o hello.o libX11_s.a -lc -o hello.x
  456. X
  457. XScrt0.o: Scrt0.s
  458. X    gas Scrt0.s -o Scrt0.o
  459. X
  460. Xmakestub : makestub.o hash.o
  461. X    $(CC) -g -o makestub makestub.o hash.o
  462. X
  463. Xconvcoff : convcoff.c
  464. X    $(CC) -g -o convcoff convcoff.c
  465. X
  466. Xinstall_programs: convcoff coffhdr coffstrip xcc
  467. X    cp convcoff /usr/local/convcoff && chmod 755 /usr/local/convcoff
  468. X    cp coffhdr /usr/local/coffhdr && chmod 755 /usr/local/coffhdr
  469. X    cp coffstrip /usr/local/coffstrip && chmod 755 /usr/local/coffstrip
  470. X    cp xcc /usr/local/xcc && chmod 755 /usr/local/xcc
  471. X
  472. Xclean::
  473. X    -rm *.o *.map *.nm $(LIBX11) hello a.out hello.x $(LIBXT) $(LIBXAW)
  474. X    -rm -fr tmp
  475. X
  476. Xremove::
  477. X    -rm /shlib/libX11_s /shlib/libXt_s /shlib/libXaw_s
  478. X    -rm $(LIBPATH)libX11_s.a $(LIBPATH)libXt_s.a $(LIBPATH)libXaw_s.a
  479. X    -rm libX11 libXt libXaw libX11_s libXt_s libXaw_s
  480. X    -rm libX11_s.a libXt_s.a libXaw_s.a
  481. X
  482. Xshar::
  483. X    shar -a -f -n Xenixshlib -l50 -o Xenixshlib -c -f README Makefile $(ALLSOURCES)
  484. X
  485. Xinstall:: install_$(LIBX11) install_$(LIBXT) install_$(LIBXAW) install_programs install_libXc
  486. X
  487. X#
  488. X# junk
  489. X#
  490. X
  491. X$(LIBX11)_s.nm : $(LIBX11)_s.a
  492. X    nm -go $(LIBX11)_s.a >$(LIBX11)_s.nm
  493. X
  494. X#
  495. X# This library is needed since the microsoft linker is brain-damaged and
  496. X# loads the wrong object files. The libXc library is a copy of libc, but
  497. X# with all modules includes in libX11_s deleted
  498. X#
  499. XlibXc.a : $(LIBPATH)libc.a $(LIBX11)_s.nm 
  500. X    cp $(LIBPATH)libc.a libXc.a
  501. X    nm -go $(LIBX11)_s.a | egrep " A | C " | awk "{print \$$2;}" | tr -d ":" | sort | uniq | xargs ar d libXc.a
  502. X    ranlib libXc.a
  503. X
  504. Xinstall_libXc : libXc.a
  505. X    cp libXc.a $(LIBPATH)libXc.a
  506. X    chmod 544 $(LIBPATH)libXc.a
  507. X
  508. Xcoffstrip : coffstrip.c
  509. X    $(CC) coffstrip.c -lx -o coffstrip
  510. SHAR_EOF
  511. $TOUCH -am 0122180791 Makefile &&
  512. chmod 0644 Makefile ||
  513. echo "restore of Makefile failed"
  514. set `wc -c Makefile`;Wc_c=$1
  515. if test "$Wc_c" != "7778"; then
  516.     echo original size 7778, current size $Wc_c
  517. fi
  518. # ============= makestub.c ==============
  519. echo "x - extracting makestub.c (Text)"
  520. sed 's/^X//' << 'SHAR_EOF' > makestub.c &&
  521. X/*
  522. X * Make stub files from a nm listing of a library
  523. X *
  524. X * Author: P.Garbha pgd@compuram.bbt.se 9-Jan-91
  525. X */
  526. X
  527. X#include <stdio.h>
  528. X#include <string.h>
  529. X#include <sys/types.h>
  530. X#include <sys/a.out.h>
  531. X#include <sys/relsym.h>
  532. X#include <fcntl.h>
  533. X#include "hash.h"
  534. X
  535. X#define    SYMMAX    2000
  536. X#define    MSYMMAX    2000
  537. X#define    MAXSEG    10
  538. X
  539. Xstruct hashtab *symhash;
  540. Xstruct hashtab *mastab;
  541. Xstruct hashtab *filetab;
  542. Xstruct hashtab *addrhash;
  543. X
  544. Xstruct symbol {
  545. X    char    *name;
  546. X    char    type;
  547. X    int    addr;        /* Real routine address */
  548. X    int    jaddr;        /* Jump table index */
  549. X} symtab[SYMMAX];
  550. X
  551. Xint symcount;
  552. X
  553. X#define    DONE    0200
  554. X
  555. Xstruct master {
  556. X    char    *fname;        /* File name */
  557. X    char    *name;        /* Symbol name */
  558. X    char    type;        /* Symbol type */
  559. X} master[MSYMMAX];
  560. Xint mastcount;
  561. X
  562. X/*
  563. X * x.out header structure
  564. X */
  565. Xstruct xexec xhdr;
  566. Xstruct xext ehdr;
  567. Xstruct xseg xsegs[MAXSEG];    /*  */
  568. Xint xsegcount, xtextseg, xdataseg, textbase, database;
  569. X
  570. Xchar *libname;
  571. Xchar *progname = "makestub";
  572. XFILE *sfp;
  573. X
  574. Xchar filedef[] =     "    TITLE    %s\n\n    .386\n\
  575. XDGROUP    GROUP    _DSTUB\n";
  576. Xchar pubdef[] =        "    PUBLIC    %s\nL%d    DD    0%xH\n";
  577. Xchar datadef[] =    "    PUBLIC    %s\n%s    EQU    0%xH\n";
  578. Xchar textstart1[] =    "_TEXT    SEGMENT    DWORD USE32 PUBLIC 'CODE'\n";
  579. Xchar textstart2[] =    "_TEXT    SEGMENT\n";
  580. Xchar textend[] =    "_TEXT    ENDS\n";
  581. Xchar datastart1[] =    "_DSTUB    SEGMENT    DWORD USE32 PUBLIC 'DSTUB'\n";
  582. Xchar datastart2[] =     "_DSTUB    SEGMENT\n";
  583. Xchar dataend[] =    "_DSTUB ENDS\n";
  584. Xchar fileend[] =    "END\n";
  585. Xchar jumpdef[] =    "%s    EQU    $\n    jmp    L%d\n";
  586. X            
  587. X
  588. X
  589. Xmain(argc, argv)
  590. X    int argc;
  591. X    char **argv;
  592. X{
  593. X    int seg, addr, type;
  594. X    char name[80];
  595. X    char sfname[20];
  596. X    char *ofname = NULL;
  597. X    char fname[40];
  598. X    int i;
  599. X    int six;
  600. X    int intext, indata;
  601. X    int tsflag, dsflag;
  602. X    int seq;
  603. X    char *cp;
  604. X
  605. X    symhash = ht_new("symhash");
  606. X    mastab = ht_new("master");
  607. X    filetab = ht_new("filetab");
  608. X    addrhash = ht_new("addrhash");
  609. X
  610. X    while (argc > 1 && argv[1][0] == '-') {
  611. X        switch (argv[1][1]) {
  612. X        case 'm':
  613. X            loadmaster(argv[2]);
  614. X            argc--;
  615. X            argv++;
  616. X            break;
  617. X        default:
  618. X            fprintf(stderr, "Illegal option: %s\n", argv[1]);
  619. X        }
  620. X        argv++;
  621. X        argc--;
  622. X    }
  623. X    if (argc != 2) {
  624. X        fprintf(stderr, "Usage: makestub {-m masterfile} libname\n");
  625. X        exit(1);
  626. X    }
  627. X    cp = strrchr(argv[1], '/');
  628. X    if (cp)
  629. X        libname = cp+1;
  630. X    else
  631. X        libname = argv[1];
  632. X
  633. X    loadlibdata(argv[1]);
  634. X
  635. X    if (mastcount) {
  636. X        /*
  637. X         * Split into different files
  638. X         */
  639. X        intext = indata = tsflag = dsflag = seq = 0;
  640. X        for (i = 0; i < mastcount; i++) {
  641. X            six = (int)ht_nget(symhash, master[i].name) - 1;
  642. X            if (six == -1)
  643. X                continue;
  644. X            if (symtab[six].type != 'T' || (symtab[six].type & DONE))
  645. X                continue;
  646. X            if (symtab[six].jaddr == 0)
  647. X                continue;
  648. X            if (ofname == NULL || strcmp(ofname, master[i].fname)) {
  649. X                if (ofname) {
  650. X                    fprintf(sfp, fileend);
  651. X                    fclose(sfp);
  652. X                }
  653. X                ofname = master[i].fname;
  654. X                strcpy(sfname, ofname);
  655. X                sfname[strlen(sfname)-1] = 's';
  656. X                if (ht_nins(filetab, sfname, (char *)1)) {
  657. X                    int cntr = 'A';
  658. X                    fprintf(stderr, "Duplicate file: %s",
  659. X                        sfname);
  660. X                    do {
  661. X                        sfname[0] = cntr;
  662. X                    } while (ht_nins(filetab, sfname, (char *)1));
  663. X                    fprintf(stderr, " new name: %s\n",
  664. X                        sfname);
  665. X                }
  666. X                sfp = fopen(sfname, "w");
  667. X                if (sfp == NULL) {
  668. X                    perror(sfname);
  669. X                    exit(1);
  670. X                }
  671. X                puts(sfname);
  672. X                fprintf(sfp, filedef, sfname);
  673. X                intext = indata = tsflag = dsflag = seq = 0;
  674. X            }
  675. X            fprintf(sfp, dsflag ? datastart2 : datastart1);
  676. X            dsflag = 1;
  677. X            seq++;
  678. X            fprintf(sfp, pubdef,
  679. X                symtab[six].name, seq, symtab[six].jaddr);
  680. X            fprintf(sfp, dataend);
  681. X            fprintf(sfp, tsflag ? textstart2 : textstart1);
  682. X            tsflag = 1;
  683. X            fprintf(sfp, jumpdef, symtab[six].name, seq);
  684. X            fprintf(sfp, textend);
  685. X            symtab[six].type |= DONE;
  686. X            symtab[six].addr = seq;
  687. X        }
  688. X        if (ofname) {
  689. X            fprintf(sfp, fileend);
  690. X            fclose(sfp);
  691. X        }
  692. X    }
  693. X    /*
  694. X     * Now emit global symbols, and symbols not found
  695. X     * in the master index
  696. X     */
  697. X    sprintf(sfname, "%s_stub.s", libname);
  698. X    sfp = fopen(sfname, "w");
  699. X    if (sfp == NULL) {
  700. X        perror(sfname);
  701. X        exit(1);
  702. X    }
  703. X    puts(sfname);
  704. X    fprintf(sfp, filedef, libname);
  705. X    fprintf(sfp, datastart1);
  706. X    seq = 0;
  707. X    for (i = 0; i < symcount; i++) {
  708. X        switch (symtab[i].type) {
  709. X        case 'T':
  710. X            if (symtab[i].jaddr) {
  711. X                fprintf(sfp, pubdef,
  712. X                    symtab[i].name, i, symtab[i].jaddr);
  713. X                symtab[i].addr = ++seq;
  714. X            } else if (strcmp(symtab[i].name, "___JumpTabEnd"))
  715. X                fprintf(stderr, "Warning: Symbol %s not in jump table\n", symtab[i].name);
  716. X            break;
  717. X            
  718. X        case 'D':
  719. X        case 'B':
  720. X            fprintf(sfp, datadef,
  721. X                symtab[i].name, symtab[i].name,
  722. X                symtab[i].addr);
  723. X            break;
  724. X        }
  725. X    }
  726. X    fprintf(sfp, dataend);
  727. X    fprintf(sfp, textstart1);
  728. X    for (i = 0; i < symcount; i++)
  729. X        if (symtab[i].type == 'T' && symtab[i].jaddr)
  730. X            fprintf(sfp, jumpdef, symtab[i].name, symtab[i].addr);
  731. X    fprintf(sfp, textend);
  732. X    fprintf(sfp, fileend);
  733. X    fclose(sfp);
  734. X    exit(0);
  735. X}
  736. X
  737. X/*
  738. X * load master index
  739. X */
  740. Xloadmaster(mfname)
  741. X    char *mfname;
  742. X{
  743. X    FILE *fp;
  744. X    char line[100];
  745. X    char *cp;
  746. X    char fname[20], *fnp;
  747. X    int addr, type;
  748. X    char name[40];
  749. X
  750. X    fnp = NULL;
  751. X    fp = fopen(mfname, "r");
  752. X    if (fp == NULL) {
  753. X        perror(mfname); exit(1);
  754. X    }
  755. X    while (fgets(line, sizeof(line) - 1, fp) != NULL) {
  756. X        cp = strchr(line, ':');
  757. X        if (strchr(cp+1, ':'))
  758. X            cp++;
  759. X        else
  760. X            cp = line;
  761. X        while (*cp == ' ')
  762. X            cp++;
  763. X        if (sscanf(cp, "%s %x %c %s\n", &fname, &addr, &type, &name) !=4) {
  764. X            fprintf(stderr, "Malformed line in %s:\n%s",
  765. X                mfname, line);
  766. X            exit(1);
  767. X        }
  768. X        cp = &fname[strlen(fname)-1];
  769. X        if (*cp != ':') {
  770. X            fprintf(stderr, "Malformed filename: %s\n", fname);
  771. X            exit(1);
  772. X        }
  773. X        *cp = '\0';
  774. X        if (mastcount == MSYMMAX) {
  775. X            fprintf(stderr, "Master symbol table overflow\n");
  776. X            exit(1);
  777. X        }
  778. X        if (fnp == NULL || strcmp(fname, fnp) != 0)
  779. X            fnp = strdup(fname);
  780. X        master[mastcount].fname = fnp;
  781. X        master[mastcount].name = strdup(name);
  782. X        master[mastcount].type = type;
  783. X        if (ht_nins(mastab, master[mastcount].name, (char *)(mastcount+1)))
  784. X            fprintf(stderr, "Warning: Cannot enter master symbol: %s\n", name);
  785. X        mastcount++;
  786. X    }
  787. X}
  788. X
  789. X
  790. X/*
  791. X * Load data from library file (in x.out format)
  792. X */
  793. Xloadlibdata(xfname)
  794. X    char *xfname;
  795. X{
  796. X    register int i;
  797. X    short magic;
  798. X    int xfd;
  799. X
  800. X    xfd = open(xfname, O_RDONLY);
  801. X    if (xfd == -1) {
  802. X        perror(xfname); exit(1);
  803. X    }
  804. X    loadxhdr(xfd, xfname);
  805. X    loadxsyms(xfd, xfname);
  806. X    fixjumptab(xfd, xfname);
  807. X    close(xfd);
  808. X}
  809. X
  810. X/*
  811. X * Read library x.out header
  812. X */
  813. Xloadxhdr(xfd, xfname)
  814. X    int xfd;
  815. X    char *xfname;
  816. X{
  817. X    int seg;
  818. X
  819. X    if (read(xfd, (char *)&xhdr, sizeof xhdr) != sizeof xhdr) {
  820. X        perror(xfname);
  821. X        return 0;
  822. X    }
  823. X    if (xhdr.x_magic != X_MAGIC) {
  824. X        fprintf(stderr, "Not a x.out file: %s\n", xfname);
  825. X        return 0;
  826. X    }
  827. X    if (read(xfd, (char *)&ehdr, sizeof ehdr) != sizeof ehdr) {
  828. X        perror(xfname);
  829. X        return 0;
  830. X    }
  831. X    if ((xhdr.x_cpu & XC_CPU) != XC_386) {
  832. X        fprintf(stderr, "Not a 80386 executable file:%s\n", xfname);
  833. X        return 0;
  834. X    }
  835. X    if ((xhdr.x_renv & XE_SEG) == 0) {
  836. X        fprintf(stderr, "Not a Xenix segmented file: %s\n", xfname);
  837. X        return 0;
  838. X    }
  839. X    lseek(xfd, ehdr.xe_segpos, 0);
  840. X    xsegcount = ehdr.xe_segsize / sizeof(struct xseg);
  841. X    if (xsegcount > MAXSEG) {
  842. X        fprintf(stderr, "Too many segments: %d\n", xsegcount);
  843. X        return -1;
  844. X    }
  845. X    if (read(xfd, (char *)xsegs, xsegcount * sizeof(struct xseg)) != xsegcount * sizeof(struct xseg)) {
  846. X        perror(xfname);
  847. X        return 0;
  848. X    }
  849. X
  850. X    /*
  851. X     * Locate the segments
  852. X     */
  853. X    for (seg = 0; seg < xsegcount; seg++)
  854. X        if (xsegs[seg].xs_type == XS_TTEXT)
  855. X            break;
  856. X    if (seg == xsegcount) {
  857. X        fprintf(stderr, "library file has no text segment\n");
  858. X        return 0;
  859. X    }
  860. X    xtextseg = seg;
  861. X    textbase = xsegs[seg].xs_rbase;
  862. X
  863. X    for (seg = 0; seg < xsegcount; seg++)
  864. X        if (xsegs[seg].xs_type == XS_TDATA)
  865. X            break;
  866. X    if (seg == xsegcount) {
  867. X        fprintf(stderr, "library file has no data segment\n");
  868. X        return 0;
  869. X    }
  870. X    xdataseg = seg;
  871. X    database = xsegs[seg].xs_rbase;
  872. X    return 1;
  873. X}
  874. X
  875. X/* 
  876. X * Read the x.out symbol table into memory
  877. X */
  878. Xloadxsyms(xfd, xfname)
  879. X    int xfd;
  880. X    char *xfname;
  881. X{
  882. X    struct sym *xsymtab, *symp;
  883. X    int type, seg, value;
  884. X    char *name;
  885. X    int i;
  886. X    char *p;
  887. X
  888. X    for (seg = 0; seg < xsegcount; seg++)
  889. X        if (xsegs[seg].xs_type == XS_TSYMS && xsegs[seg].xs_attr == XS_SXSEG)
  890. X            break;
  891. X    if (seg == xsegcount) {
  892. X        fprintf(stderr, "Library %s has no symbol table segment\n", xfname);
  893. X        exit(1);
  894. X    }
  895. X    xsymtab = (struct sym *)malloc(xsegs[seg].xs_psize);
  896. X    if (xsymtab == NULL) {
  897. X        fprintf(stderr, "Out of memory"); exit(1);
  898. X    }
  899. X    lseek(xfd, xsegs[seg].xs_filpos, 0);
  900. X    if (read(xfd, (char *)xsymtab, xsegs[seg].xs_psize) != xsegs[seg].xs_psize) {
  901. X        perror("symbol"); exit(1);
  902. X    }
  903. X
  904. X    /*
  905. X     * Enter the symbols into the symbol table
  906. X     */
  907. X    symcount = 0;
  908. X    for (p = (char *)xsymtab; p < (char *)xsymtab+xhdr.x_syms; ) {
  909. X        symp = (struct sym *)p;
  910. X        p += sizeof(struct sym);
  911. X        name = (char *)p;
  912. X        switch (symp->s_type & S_TYPE) {
  913. X        case S_TEXT:    /* A routine address */
  914. X            symtab[symcount].type = 'T';
  915. X            goto enter;
  916. X        case S_DATA:
  917. X            symtab[symcount].type = 'D';
  918. X            goto enter;
  919. X        case S_BSS:
  920. X            symtab[symcount].type = 'B';
  921. X            goto enter;
  922. X        enter:
  923. X/*            if (strcmp(name, "__nd_") == 0)
  924. X                name = "_shlib__nd_"; */
  925. X            symtab[symcount].name = strdup(name);
  926. X            symtab[symcount].addr = symp->s_value;
  927. X            symtab[symcount].jaddr = 0;
  928. X            if (ht_nins(symhash, symtab[symcount].name, (char *)(symcount+1)))
  929. X                fprintf(stderr, "Error entering symbol %s\n",
  930. X                    name);
  931. X            if (ht_iins(addrhash, symtab[symcount].addr, (char *)(symcount+1)))
  932. X                fprintf(stderr, "Error inserting address %x (%s)\n", symtab[symcount].addr, symtab[symcount].name);
  933. X            symcount++;
  934. X            break;
  935. X        }
  936. X        p += strlen(p) + 1;
  937. X    }
  938. X    free(xsymtab);
  939. X    return 1;
  940. X}
  941. X
  942. X
  943. X/*
  944. X * Fixup all symbol values for jumptable offset
  945. X */
  946. Xfixjumptab(xfd, xfname)
  947. X    int xfd;
  948. X    char *xfname;
  949. X{
  950. X    register int i;
  951. X    int jumptabend, jumptabsize, noentries, six;
  952. X    char *jumpaddr;
  953. X    unsigned char *jumptab;
  954. X    int cc;
  955. X    unsigned int off;
  956. X
  957. X    /*
  958. X     * Locate the end of the jump table
  959. X     */
  960. X    six = (int)ht_nget(symhash, "___JumpTabEnd") - 1;
  961. X    if (six == -1) {
  962. X        fprintf(stderr, "Library does not have a valid jump table\n");
  963. X        fprintf(stderr, "(Jump table end symbol missing)\n");
  964. X        exit(1);
  965. X    }
  966. X    jumptabend = symtab[six].addr;
  967. X    jumptabsize = jumptabend - textbase;
  968. X    jumptab = (unsigned char *)malloc(sizeof(char *) * jumptabsize);
  969. X    if (jumptab == NULL) {
  970. X        perror("Allocating jump table");
  971. X        exit(1);
  972. X    }
  973. X    /*
  974. X     * Read jump table into memory
  975. X     */
  976. X    lseek(xfd, xsegs[xtextseg].xs_filpos, 0);
  977. X    cc = read(xfd, jumptab, jumptabsize);
  978. X    if (cc != jumptabsize) {
  979. X        fprintf(stderr, "Something wrong with library file\n");
  980. X        exit(1);
  981. X    }
  982. X
  983. X    /*
  984. X     * Go through all entries in the jump table, and
  985. X     * insert the jump table index into the symbol table
  986. X     */
  987. X    for (i = 0; i < jumptabsize; ) {
  988. X        if (jumptab[i] == 0) {
  989. X            i++;
  990. X            continue;
  991. X        }
  992. X        if (jumptab[i] != 0xe9) {
  993. X            fprintf(stderr, "Illegal jump table (no jump)\n");
  994. X            exit(1);
  995. X        }
  996. X        jumpaddr = *(char **)&jumptab[i+1] + i+5 + textbase;
  997. X        six = (int)ht_iget(addrhash, jumpaddr) - 1;
  998. X        if (six == -1) {
  999. X            fprintf(stderr, "Cannot find symbol for jump table entry %d (addr = %x)\n", i, jumpaddr);
  1000. X        } else if (symtab[six].jaddr) {
  1001. X            fprintf(stderr, "Symbol %s has multiple jump table entries\n", symtab[six].name);
  1002. X        } else
  1003. X            symtab[six].jaddr = i + textbase;
  1004. X        i += 5;
  1005. X    }
  1006. X}
  1007. SHAR_EOF
  1008. $TOUCH -am 0110080491 makestub.c &&
  1009. chmod 0660 makestub.c ||
  1010. echo "restore of makestub.c failed"
  1011. set `wc -c makestub.c`;Wc_c=$1
  1012. if test "$Wc_c" != "10959"; then
  1013.     echo original size 10959, current size $Wc_c
  1014. fi
  1015. # ============= convcoff.c ==============
  1016. echo "x - extracting convcoff.c (Text)"
  1017. sed 's/^X//' << 'SHAR_EOF' > convcoff.c &&
  1018. X/*
  1019. X * Program to convert a Xenix x-out file to a coff file
  1020. X *
  1021. X * Author: P.Garbha pgd@compuram.bbt.se
  1022. X */
  1023. X
  1024. X#include <stdio.h>
  1025. X#include <sys/types.h>
  1026. X#include <sys/fcntl.h>
  1027. X#include <sys/coff.h>
  1028. X#include <sys/a.out.h>
  1029. X#include <string.h>
  1030. X#include <memory.h>
  1031. X#include <time.h>
  1032. X#include <malloc.h>
  1033. X#include <sys/relsym.h>
  1034. X
  1035. X/*
  1036. X * COFF symbol entry
  1037. X */
  1038. X#pragma pack(1)
  1039. Xstruct symbol {
  1040. X    char n_name[8];            /* symbol name */
  1041. X    unsigned long n_value;        /* symbol value */
  1042. X    unsigned short n_scnum;        /* section number */
  1043. X    unsigned short n_type;
  1044. X    unsigned char n_sclass;
  1045. X    unsigned char n_numaux;        /* no of aux entries */
  1046. X};
  1047. X#pragma pack()
  1048. X
  1049. Xstruct symbol *symtab;
  1050. Xint symcount;
  1051. X
  1052. Xchar *fname;
  1053. X
  1054. X#define    MAXSEG        10
  1055. X#define    PAGESIZE    0x1000
  1056. X
  1057. X#define    TEXT_SEGMENT    0x3f
  1058. X#define    DATA_SEGMENT    0x47
  1059. X/*
  1060. X * Max number of shared libraries. (kernel restriction. see user.h)
  1061. X */
  1062. X#define    SHLBMAX    2
  1063. X
  1064. X/*
  1065. X * Coff header structure
  1066. X */
  1067. X#define    TEXT    0
  1068. X#define    DATA    1
  1069. X#define    BSS    2
  1070. X#define    LIB    3
  1071. X
  1072. Xstruct filehdr fhdr;        /* coff file header */
  1073. Xstruct aouthdr ahdr;        /* a.out header */
  1074. Xstruct scnhdr shdr[MAXSEG];    /* section headers */
  1075. X
  1076. Xstruct {
  1077. X    long    size;        /* size of lib section in words */
  1078. X    long    hdrsize;    /* no of words in header */
  1079. X    char    path[80];    /* Path of library */
  1080. X} libsect1, libsect2;
  1081. X
  1082. Xint cfd;                /* coff file id */
  1083. Xint tseg, dseg, bseg;
  1084. Xint coffscns;
  1085. Xint xtextfilpos, xdatafilpos;        /* file position for text and data */
  1086. Xchar *textp, *datap;
  1087. Xint textsize, datasize;
  1088. Xint sflag;            /* Stripping flag */
  1089. X
  1090. X/*
  1091. X * x.out header structure
  1092. X */
  1093. Xstruct xexec xhdr;
  1094. Xstruct xext ehdr;
  1095. Xstruct xseg xsegs[MAXSEG];    /*  */
  1096. Xint xfd, cfd;
  1097. Xint xsegcount;
  1098. Xint xtextseg, xdataseg;
  1099. X
  1100. Xchar *xfname, *cfname;
  1101. X
  1102. Xint nshlibs;            /* Number of shared libraries */
  1103. Xchar *shlibpaths[SHLBMAX];    /* Name of shared libraries */
  1104. X
  1105. Xmain(argc, argv)
  1106. X    int argc;
  1107. X    char **argv;
  1108. X{
  1109. X    while (argc > 1 && argv[1][0] == '-') {
  1110. X        switch (argv[1][1]) {
  1111. X        case 's':
  1112. X            sflag = 1;
  1113. X            break;
  1114. X        case 'l':        /* Use shared library */
  1115. X            addshlib(argv[2]);
  1116. X            argc--;
  1117. X            argv++;
  1118. X            break;
  1119. X            
  1120. X        default:
  1121. X            fprintf(stderr, "Illegal option: %s\n", argv[1]);
  1122. X        }
  1123. X        argv++;
  1124. X        argc--;
  1125. X    }
  1126. X    if (argc != 3) {
  1127. X        fprintf(stderr, "Usage: convcoff infile outfile\n");
  1128. X        exit(1);
  1129. X    }
  1130. X    xfname = argv[1];
  1131. X    cfname = argv[2];
  1132. X    xfd = open(xfname, O_RDONLY);
  1133. X    if (xfd == -1) {
  1134. X        perror(xfname); exit(1);
  1135. X    }
  1136. X    if (!loadxhdr())
  1137. X        exit(1);
  1138. X    (void)loadxsyms();
  1139. X    if (!cvtcoffhdr())
  1140. X        exit(1);
  1141. X    if (!loadximage())
  1142. X        exit(1);
  1143. X    cfd = open(cfname, O_WRONLY|O_CREAT|O_TRUNC, 0700);
  1144. X    if (cfd == -1) {
  1145. X        perror(cfname); exit(1);
  1146. X    }
  1147. X    if (!dumpcoff()) {
  1148. X        close(cfd); unlink(cfname);
  1149. X        exit(1);
  1150. X    }
  1151. X    close(xfd);
  1152. X    close(cfd);
  1153. X    exit(0);
  1154. X}
  1155. X
  1156. X/*
  1157. X * Load a x.out header
  1158. X */
  1159. Xloadxhdr()
  1160. X{
  1161. X    register int i;
  1162. X    short magic;
  1163. X
  1164. X    if (read(xfd, (char *)&xhdr, sizeof xhdr) != sizeof xhdr) {
  1165. X        perror(xfname);
  1166. X        return 0;
  1167. X    }
  1168. X    if (xhdr.x_magic != X_MAGIC) {
  1169. X        fprintf(stderr, "Not a x.out file: %s\n", xfname);
  1170. X        return 0;
  1171. X    }
  1172. X    if (read(xfd, (char *)&ehdr, sizeof ehdr) != sizeof ehdr) {
  1173. X        perror(fname);
  1174. X        return 0;
  1175. X    }
  1176. X    if ((xhdr.x_cpu & XC_CPU) != XC_386) {
  1177. X        fprintf(stderr, "Not a 80386 executable file:%s\n", xfname);
  1178. X        return 0;
  1179. X    }
  1180. X    if ((xhdr.x_renv & XE_SEG) == 0) {
  1181. X        fprintf(stderr, "Not a Xenix segmented file: %s\n", xfname);
  1182. X        return 0;
  1183. X    }
  1184. X    lseek(xfd, ehdr.xe_segpos, 0);
  1185. X    xsegcount = ehdr.xe_segsize / sizeof(struct xseg);
  1186. X    if (xsegcount > MAXSEG) {
  1187. X        fprintf(stderr, "Too many segments: %d\n", xsegcount);
  1188. X        return -1;
  1189. X    }
  1190. X    if (read(xfd, (char *)xsegs, xsegcount * sizeof(struct xseg)) != xsegcount * sizeof(struct xseg)) {
  1191. X        perror(xfname);
  1192. X        return 0;
  1193. X    }
  1194. X    return 1;
  1195. X}
  1196. X
  1197. X/*
  1198. X * Load coff header
  1199. X */
  1200. Xint
  1201. Xloadcoffhdr(fname, fhdr, ahdr, shdrs)
  1202. X    char *fname;
  1203. X    struct filehdr *fhdr;
  1204. X    struct aouthdr *ahdr;
  1205. X    struct scnhdr **shdrs;
  1206. X{
  1207. X    int fd;
  1208. X
  1209. X    fd = open(fname, O_RDONLY);
  1210. X    if (fd == -1) {
  1211. X        perror(fname); return 0;
  1212. X    }
  1213. X    if (read(fd, fhdr, sizeof fhdr) != sizeof fhdr) {
  1214. X        perror(fname); close(fd); return 0;
  1215. X    }
  1216. X    if (fhdr->f_magic == X_MAGIC) {
  1217. X        fprintf(stderr, "file %s is not of coff type\n", fname);
  1218. X        close(fd);
  1219. X        return 0;
  1220. X    }
  1221. X    if (fhdr->f_magic != I386MAGIC) {
  1222. X        fprintf(stderr, "File %s is not a coff exec file\n", fname);
  1223. X        close(fd); return 0;
  1224. X    }
  1225. X    if (read(fd, ahdr, sizeof ahdr) != sizeof ahdr) {
  1226. X        perror("aouthdr"); close(fd); return 0;
  1227. X    }
  1228. X    if (fhdr->f_nscns) {
  1229. X        *shdrs = (struct scnhdr *)calloc(sizeof(struct scnhdr), fhdr->f_nscns);
  1230. X        if (*shdrs == NULL) {
  1231. X            perror(fname); close(fd);
  1232. X            return 0;
  1233. X        }
  1234. X        if (read(fd, (char *)*shdrs, fhdr->f_nscns * sizeof(struct scnhdr)) == -1) {
  1235. X            perror(fname); close(fd);
  1236. X            return 0;
  1237. X        }
  1238. X    } else
  1239. X        *shdrs = NULL;
  1240. X    close(fd);
  1241. X    return 1;
  1242. X}
  1243. X
  1244. X
  1245. X
  1246. X/*
  1247. X * Convert a x.out header structure, to coff header
  1248. X */
  1249. Xint
  1250. Xcvtcoffhdr()
  1251. X{
  1252. X    int filpos = 0;
  1253. X    int seg;
  1254. X
  1255. X    /*
  1256. X     * Make filehdr
  1257. X     */
  1258. X    fhdr.f_magic = I386MAGIC;
  1259. X    fhdr.f_nscns = 0;        /* Number of sections */
  1260. X    fhdr.f_timdat = time(NULL);    /* Current date and time */
  1261. X    fhdr.f_symptr = 0;        /* Symbol table pointer */
  1262. X    fhdr.f_nsyms = symcount;     /* Symbol count */
  1263. X    fhdr.f_opthdr = sizeof(ahdr);
  1264. X    fhdr.f_flags = F_RELFLG|F_EXEC|F_LNNO|F_AR32WR;
  1265. X
  1266. X    /*
  1267. X     * Make aout header extension
  1268. X     */
  1269. X    ahdr.magic = 0;            /* magic */
  1270. X    ahdr.vstamp = 0;        /* version stamp */
  1271. X    ahdr.tsize = xhdr.x_text;    /* Text segment size */
  1272. X    ahdr.dsize = xhdr.x_data;    /* Data segment size */
  1273. X    ahdr.bsize = xhdr.x_bss;    /* bss segment size */
  1274. X    ahdr.entry = xhdr.x_entry;    /* entry address */
  1275. X    ahdr.text_start = 0;        /* text relcoation */
  1276. X    ahdr.data_start = 0;        /* data relocation */
  1277. X
  1278. X    tseg = dseg = bseg = 0;
  1279. X
  1280. X    /*
  1281. X     * Make coff text segment
  1282. X     */
  1283. X    for (seg = 0; seg < xsegcount; seg++)
  1284. X        if (xsegs[seg].xs_type == XS_TTEXT)
  1285. X            break;
  1286. X    if (seg == xsegcount) {
  1287. X        fprintf(stderr, "x.out file has no text segment\n");
  1288. X        return 0;
  1289. X    }
  1290. X    if (xsegs[seg].xs_seg != TEXT_SEGMENT) {
  1291. X        fprintf(stderr, "Text segment must be %#02x\n", TEXT_SEGMENT);
  1292. X        return 0;
  1293. X    }
  1294. X    xtextseg = seg;
  1295. X    memset((char *)&shdr[TEXT].s_name, 0, sizeof(shdr[TEXT].s_name));
  1296. X    strcpy(shdr[TEXT].s_name, ".text");
  1297. X    ahdr.text_start = shdr[TEXT].s_paddr = shdr[TEXT].s_vaddr = xsegs[seg].xs_rbase;
  1298. X    shdr[TEXT].s_size =  xsegs[seg].xs_psize;
  1299. X    shdr[TEXT].s_scnptr = PAGESIZE;
  1300. X    shdr[TEXT].s_relptr = 0;
  1301. X    shdr[TEXT].s_lnnoptr = 0;
  1302. X    shdr[TEXT].s_nreloc = 0;
  1303. X    shdr[TEXT].s_nlnno = 0;
  1304. X    shdr[TEXT].s_flags = STYP_TEXT;
  1305. X    xtextfilpos = xsegs[seg].xs_filpos;
  1306. X    filpos = (PAGESIZE + xsegs[seg].xs_psize + (PAGESIZE-1)) & ~(PAGESIZE-1);
  1307. X
  1308. X    /*
  1309. X     * Make coff data segment
  1310. X     */
  1311. X    for (seg = 0; seg < xsegcount; seg++)
  1312. X        if (xsegs[seg].xs_type == XS_TDATA)
  1313. X            break;
  1314. X    if (seg == xsegcount) {
  1315. X        fprintf(stderr, "x.out file has no data segment\n");
  1316. X        return 0;
  1317. X    }
  1318. X    xdataseg = seg;
  1319. X    if (xsegs[seg].xs_seg != DATA_SEGMENT) {
  1320. X        fprintf(stderr, "Data segment must be %#02x\n", DATA_SEGMENT);
  1321. X        return 0;
  1322. X    }
  1323. X    memset((char *)&shdr[DATA].s_name, 0, sizeof(shdr[DATA].s_name));
  1324. X    strcpy(shdr[DATA].s_name, ".data");
  1325. X    ahdr.data_start = shdr[DATA].s_paddr = shdr[DATA].s_vaddr = xsegs[seg].xs_rbase;
  1326. X    shdr[DATA].s_size =  xsegs[seg].xs_psize;
  1327. X    shdr[DATA].s_scnptr = filpos;
  1328. X    shdr[DATA].s_relptr = 0;
  1329. X    shdr[DATA].s_lnnoptr = 0;
  1330. X    shdr[DATA].s_nreloc = 0;
  1331. X    shdr[DATA].s_nlnno = 0;
  1332. X    shdr[DATA].s_flags = STYP_DATA;
  1333. X    xdatafilpos = xsegs[seg].xs_filpos;
  1334. X    filpos += shdr[DATA].s_size;
  1335. X
  1336. X    /*
  1337. X     * Make coff bss segment
  1338. X     */
  1339. X    memset((char *)&shdr[BSS].s_name, 0, sizeof(shdr[BSS].s_name));
  1340. X    strcpy(shdr[BSS].s_name, ".bss");
  1341. X    shdr[BSS].s_paddr = shdr[BSS].s_vaddr = shdr[DATA].s_paddr + shdr[DATA].s_size;
  1342. X    shdr[BSS].s_size =  xhdr.x_bss;
  1343. X    shdr[BSS].s_scnptr = 0;
  1344. X    shdr[BSS].s_relptr = 0;
  1345. X    shdr[BSS].s_lnnoptr = 0;
  1346. X    shdr[BSS].s_nreloc = 0;
  1347. X    shdr[BSS].s_nlnno = 0;
  1348. X    shdr[BSS].s_flags = STYP_BSS;
  1349. X    coffscns = 3;
  1350. X
  1351. X    /*
  1352. X     * Make library segment
  1353. X     */
  1354. X    if (nshlibs) {
  1355. X        strcpy(shdr[LIB].s_name, ".lib");
  1356. X        shdr[LIB].s_nlib = nshlibs;
  1357. X        shdr[LIB].s_vaddr = 0;
  1358. X        shdr[LIB].s_size = 0;
  1359. X        shdr[LIB].s_scnptr = filpos;
  1360. X        shdr[LIB].s_relptr = 0;
  1361. X        shdr[LIB].s_lnnoptr = 0;
  1362. X        shdr[LIB].s_nreloc = 0;
  1363. X        shdr[LIB].s_nlnno = 0;
  1364. X        shdr[LIB].s_flags = STYP_LIB;
  1365. X        coffscns++;
  1366. X
  1367. X        memset((char *)&libsect1, 0, sizeof(libsect1));
  1368. X        libsect1.size = 2 + ((strlen(shlibpaths[0]) + 1 + 3) >> 2);
  1369. X        libsect1.hdrsize = 2;
  1370. X        strcpy(libsect1.path, shlibpaths[0]);
  1371. X        shdr[LIB].s_size += libsect1.size << 2;
  1372. X        if (nshlibs > 1) {
  1373. X            memset((char *)&libsect2, 0, sizeof(libsect2));
  1374. X            libsect2.size = 2 + ((strlen(shlibpaths[1])+1+3) >> 2);
  1375. X            libsect2.hdrsize = 2;
  1376. X            strcpy(libsect2.path, shlibpaths[1]);
  1377. X            shdr[LIB].s_size += libsect2.size << 2;
  1378. X        }
  1379. X        filpos += shdr[LIB].s_size;
  1380. X    }
  1381. X
  1382. X    /*
  1383. X     * Fix up the last pointers
  1384. X     */
  1385. X    fhdr.f_symptr = filpos;
  1386. X    fhdr.f_nscns = coffscns;
  1387. X    return 1;
  1388. X}
  1389. X
  1390. X
  1391. X/* 
  1392. X * Read the x.out symbol table into memory
  1393. X */
  1394. Xloadxsyms()
  1395. X{
  1396. X    struct sym *xsymtab;
  1397. X    int type, seg, value;
  1398. X    char *name;
  1399. X    int i, xsymcount;
  1400. X    char *p;
  1401. X
  1402. X    for (seg = 0; seg < xsegcount; seg++)
  1403. X        if (xsegs[seg].xs_type == XS_TSYMS && xsegs[seg].xs_attr == XS_SXSEG)
  1404. X            break;
  1405. X    if (seg == xsegcount) {
  1406. X        fprintf(stderr, "warning: %s has no symbol table segment\n", xfname);
  1407. X        return 0;
  1408. X    }
  1409. X    xsymtab = (struct sym *)malloc(xsegs[seg].xs_psize);
  1410. X    if (xsymtab == NULL) {
  1411. X        fprintf(stderr, "Out of memory"); exit(1);
  1412. X    }
  1413. X    lseek(xfd, xsegs[seg].xs_filpos, 0);
  1414. X    if (read(xfd, (char *)xsymtab, xsegs[seg].xs_psize) != xsegs[seg].xs_psize) {
  1415. X        perror("symbol"); exit(1);
  1416. X    }
  1417. X
  1418. X    /*
  1419. X     * Count the symbols
  1420. X     */
  1421. X    xsymcount = 0;
  1422. X    for (p = (char *)xsymtab; p < (char *)xsymtab+xhdr.x_syms; ) {
  1423. X        p += sizeof(struct sym);
  1424. X        if (p[0] == '_' && p[1] == '_' && p[2] == '_'
  1425. X                    && strncmp(p, "___SHLIB__", 10) == 0) {
  1426. X            char path[40];
  1427. X            /*
  1428. X             * An autoload symbol
  1429. X             */
  1430. X            sprintf(path, "/shlib/%s", p+10);
  1431. X            addshlib(path);
  1432. X        }
  1433. X        p += strlen(p) + 1;
  1434. X        xsymcount++;
  1435. X    }
  1436. X    
  1437. X    /*
  1438. X     * Merge it in with the coff symbol table
  1439. X     * unless stripping flag is on.
  1440. X     */
  1441. X    if (sflag)
  1442. X        return 1;
  1443. X
  1444. X    if (symcount == 0)
  1445. X        symtab = (struct symbol *)malloc(symcount + xsymcount * sizeof(struct symbol));
  1446. X    else
  1447. X        symtab = (struct symbol *)realloc((char *)symtab, symcount + xsymcount * sizeof(struct symbol));
  1448. X    if (symtab == NULL) {
  1449. X        perror("Out of memory"); exit(1);
  1450. X    }
  1451. X    for (p = (char *)xsymtab; p < (char *)xsymtab+xhdr.x_syms; ) {
  1452. X        if (((struct sym *)p)->s_seg == TEXT_SEGMENT) {
  1453. X            symtab[symcount].n_scnum = TEXT+1;
  1454. X            symtab[symcount].n_sclass = 2;
  1455. X        } else if (((struct sym *)p)->s_seg == DATA_SEGMENT) {
  1456. X            if (((struct sym *)p)->s_value >= xsegs[xdataseg].xs_rbase
  1457. X                + xsegs[xdataseg].xs_vsize)
  1458. X                symtab[symcount].n_scnum = BSS+1;
  1459. X            else
  1460. X                symtab[symcount].n_scnum = DATA+1;
  1461. X            symtab[symcount].n_sclass = 3;
  1462. X        } else {
  1463. X            p += sizeof(struct sym);
  1464. X            p += strlen(p) + 1;
  1465. X            continue;
  1466. X        }
  1467. X        symtab[symcount].n_value = ((struct sym *)p)->s_value;
  1468. X        symtab[symcount].n_type = 0;
  1469. X        symtab[symcount].n_numaux = 0;
  1470. X        p += sizeof(struct sym);
  1471. X        strncpy(symtab[symcount].n_name, p, 8);
  1472. X        p += strlen(p) + 1;
  1473. X        symcount++;
  1474. X    }
  1475. X    free(xsymtab);
  1476. X    return 1;
  1477. X}
  1478. X
  1479. X/*
  1480. X * Read a coff symbol table
  1481. X */
  1482. Xloadcoffsyms(fd)
  1483. X    int fd;
  1484. X{
  1485. X    int cc;
  1486. X
  1487. X    if (lseek(fd, fhdr.f_symptr, 0) == -1) {
  1488. X        perror("loadsyms"); exit(1);
  1489. X    }
  1490. X    if (symtab == NULL)
  1491. X        symtab = (struct symbol *)malloc(sizeof(struct symbol) * fhdr.f_nsyms);
  1492. X    else
  1493. X        symtab = (struct symbol *)realloc((char *)symtab, sizeof(struct symbol) * (fhdr.f_nsyms + symcount));
  1494. X    if (symtab == NULL) {
  1495. X        perror("loadsyms"); exit(1);
  1496. X    }
  1497. X    cc = read(fd, (char *)&symtab[symcount], fhdr.f_nsyms * sizeof(struct symbol));
  1498. X    if (cc == -1) {
  1499. X        perror("loadsyms"); exit(1);
  1500. X    }
  1501. X    if (cc != fhdr.f_nsyms * sizeof(struct symbol)) {
  1502. X        fprintf(stderr, "File too short\n");
  1503. X        exit(1);
  1504. X    }
  1505. X    symcount += fhdr.f_nsyms;
  1506. X}
  1507. X
  1508. X/*
  1509. X * Load the image of a x.out file into memory
  1510. X */
  1511. Xloadximage()
  1512. X{
  1513. X    int cc;
  1514. X
  1515. X    textsize = xsegs[xtextseg].xs_psize;
  1516. X    textp = malloc(textsize);
  1517. X    if (textp == NULL) {
  1518. X        perror("convcoff"); return 0;
  1519. X    }
  1520. X    datasize = xsegs[xdataseg].xs_psize;
  1521. X    datap = malloc(datasize);
  1522. X    if (datap == NULL) {
  1523. X        perror("convcoff"); return 0;
  1524. X    }
  1525. X    lseek(xfd, xsegs[xtextseg].xs_filpos, 0);
  1526. X    cc = read(xfd, textp, textsize);
  1527. X    if (cc != textsize) {
  1528. X        if (cc == -1)
  1529. X            perror(xfname);
  1530. X        else
  1531. X            fprintf(stderr, "Invalid exec file: %s\n", xfname);
  1532. X        return 0;
  1533. X    }
  1534. X    lseek(xfd, xsegs[xdataseg].xs_filpos, 0);
  1535. X    cc = read(xfd, datap, datasize);
  1536. X    if (cc != datasize) {
  1537. X        if (cc == -1)
  1538. X            perror(xfname);
  1539. X        else
  1540. X            fprintf(stderr, "Invalid exec file: %s\n", xfname);
  1541. X        return 0;
  1542. X    }
  1543. X    return 1;
  1544. X}
  1545. X
  1546. X/*
  1547. X * Dump coff header
  1548. X */
  1549. Xdumpcoff()
  1550. X{
  1551. X    int cc, j, padding;
  1552. X    char block[PAGESIZE];
  1553. X
  1554. X    memset(block, 0, PAGESIZE);
  1555. X    memcpy(block, (char *)&fhdr, sizeof(fhdr));
  1556. X    memcpy(block+sizeof(fhdr), (char *)&ahdr, sizeof(ahdr));
  1557. X    memcpy(block+sizeof(fhdr)+sizeof(ahdr), (char *)shdr, sizeof(struct scnhdr)*coffscns);
  1558. X    lseek(cfd, 0L, 0);
  1559. X    cc = write(cfd, block, PAGESIZE);
  1560. X    if (cc != PAGESIZE) {
  1561. X        perror(cfname); return 0;
  1562. X    }
  1563. X    memset(block, 0, PAGESIZE);
  1564. X    cc = write(cfd, textp, textsize);
  1565. X    if (cc != textsize) {
  1566. X        perror(cfname); return 0;
  1567. X    }
  1568. X    padding = shdr[DATA].s_scnptr - (PAGESIZE + textsize);
  1569. X    cc = write(cfd, block, padding);
  1570. X    if (cc != padding) {
  1571. X        perror(cfname); return 0;
  1572. X    }
  1573. X    cc = write(cfd, datap, datasize);
  1574. X    if (cc != datasize) {
  1575. X        perror(cfname); return 0;
  1576. X    }
  1577. X    if (nshlibs) {
  1578. X        cc = write(cfd, (char *)&libsect1, libsect1.size << 2);
  1579. X        if (cc == -1) {
  1580. X            perror(cfname); return 0;
  1581. X        }
  1582. X        if (nshlibs > 1) {
  1583. X            cc = write(cfd, (char *)&libsect2, libsect2.size << 2);
  1584. X            if (cc == -1) {
  1585. X                perror(cfname); return 0;
  1586. X            }
  1587. X        }
  1588. X    }
  1589. X    cc = write(cfd, (char *)symtab, symcount * sizeof(struct symbol));
  1590. X    if (cc == -1) {
  1591. X        perror(cfname); return 0;
  1592. X    }
  1593. X    return 1;
  1594. X}
  1595. X
  1596. Xaddshlib(path)
  1597. X    char *path;
  1598. X{
  1599. X    int i;
  1600. X    char *basep, *cp;
  1601. X
  1602. X    if (basep = strrchr(path, '/'))
  1603. X        basep++;
  1604. X    else
  1605. X        basep = path;
  1606. X    for (i = 0; i < nshlibs; i++) {
  1607. X        cp = strrchr(shlibpaths[i], '/');
  1608. X        if (cp)
  1609. X            cp++;
  1610. X        else
  1611. X            cp = shlibpaths[i];
  1612. X        if (strcmp(basep, cp) == 0)
  1613. X            return;
  1614. X    }
  1615. X    if (nshlibs == SHLBMAX) {
  1616. X        fprintf(stderr, "Xenix only allows %d shared libraries\n", SHLBMAX);
  1617. X        exit(1);
  1618. X    }
  1619. X    shlibpaths[nshlibs++] = strdup(path);
  1620. X}
  1621. SHAR_EOF
  1622. $TOUCH -am 0118105591 convcoff.c &&
  1623. chmod 0660 convcoff.c ||
  1624. echo "restore of convcoff.c failed"
  1625. set `wc -c convcoff.c`;Wc_c=$1
  1626. if test "$Wc_c" != "13743"; then
  1627.     echo original size 13743, current size $Wc_c
  1628. fi
  1629. echo "End of part 1, continue with part 2"
  1630. exit 0
  1631.