(* Copyright (C) 1990, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* Last modified on Thu Jul 30 12:04:33 PDT 1992 by muller *) (* modified on Thu Feb 27 16:07:29 PST 1992 by kalsow *) UNSAFE MODULE RTLoader; (* BEWARE! Init is called before types are registered or main bodies are initialized (but after RTParams is ready). *) (***** NOTE: This module is DS3100/Ultrix specific... *) IMPORT RTParams, Ctypes, Unix, Uuio, RTMisc; CONST OverlayMagic = 8_407; TYPE AoutHeader = RECORD f_magic : Ctypes.unsigned_short; f_nscns : Ctypes.unsigned_short; f_timdat : Ctypes.long; f_symptr : Ctypes.long; f_nsyms : Ctypes.long; f_opthdr : Ctypes.unsigned_short; f_flags : Ctypes.unsigned_short; magic : Ctypes.short; vstamp : Ctypes.short; tsize : Ctypes.long; dsize : Ctypes.long; bsize : Ctypes.long; entry : Ctypes.long; text_start : Ctypes.long; data_start : Ctypes.long; bss_start : Ctypes.long; gprmask : Ctypes.long; cprmask : ARRAY [0..3] OF Ctypes.long; gp_value : Ctypes.long; END; TYPE SectionHeader = RECORD s_name : ARRAY [0..7] OF Ctypes.char; s_paddr : Ctypes.long; s_vaddr : Ctypes.long; s_size : Ctypes.long; s_scnptr : Ctypes.long; s_relptr : Ctypes.long; s_lnnoptr : Ctypes.long; s_nreloc : Ctypes.unsigned_short; s_nlnno : Ctypes.unsigned_short; s_flags : Ctypes.long; END; PROCEDURE Init () = VAR overlay := RTParams.RawValue ("overlay"); hdr : AoutHeader; fd : INTEGER; i : INTEGER; cnt : INTEGER; start : ADDRESS; finish : INTEGER; n_needed : INTEGER; BEGIN IF (overlay = NIL) THEN RETURN END; fd := Unix.open (overlay, Unix.O_RDONLY, 0); IF (fd < 0) THEN Die ("unable to open overlay file") END; (* if (fd == -1) { perror(pgm); _exit(1); }; *) (* read the a.out header *) i := Uuio.read (fd, ADR (hdr), BYTESIZE (hdr)); IF (i # BYTESIZE (hdr)) THEN Die ("overlay file header is too short") END; IF (hdr.magic # OverlayMagic) THEN Die ("Bad magic in overlay") END; (* seek to the beginning of the text segment *) i := BYTESIZE (hdr) + hdr.f_nscns * BYTESIZE (SectionHeader); i := (i + 15) DIV 16 * 16; EVAL Unix.lseek (fd, i, Unix.L_SET); (* compute the end points of the loaded overlay *) cnt := hdr.tsize + hdr.dsize; (* # bytes to read *) start := ADR (Unix.end); finish := LOOPHOLE (start, INTEGER) + cnt + hdr.bsize; (* allocate any more memory that we might need *) n_needed := finish - Unix.sbrk (0); IF (n_needed > 0) THEN i := Unix.sbrk (n_needed); IF (i + n_needed < finish) THEN Die ("Break messed up.") END; END; (* read the overlay's text and data into memory *) i := Uuio.read (fd, start, cnt); IF (i # cnt) THEN Die ("overlay text+data segment too short") END; (* close the overlay file *) EVAL Unix.close (fd); (* initialize the overlay's bss segment *) RTMisc.Zero (start+cnt, hdr.bsize); (* call the overlay's init code *) LOOPHOLE (start, PROCEDURE()) (); END Init; PROCEDURE Die (msg: TEXT) = BEGIN RTMisc.FatalError (NIL, 0, "dynamic loading failed: ", msg); END Die; BEGIN END RTLoader.