home *** CD-ROM | disk | FTP | other *** search
- /*
- * read_vmunix.c -- read data from an a.out file (for kernel _version)
- * This is just awful!!
- *
- * Copyright (C) 1986, 1990 Philip L. Budne
- *
- * This file is part of "Phil's Finger Program".
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- */
-
- # ifndef lint
- static char *rcsid = "$Id: read_vmunix.c,v 3.0 90/07/06 13:11:37 budd Rel $";
- # endif /* lint not defined */
-
- # include "finger.h"
- # if Umax != 42 && !defined(USG)
-
- # include "args.h"
- # ifndef COFF /* good old a.out */
-
- # include <a.out.h>
-
- /*
- * N_SEGSIZ is only needed if the kernel is not an OMAGIC file.
- */
-
- # ifdef sun
-
- # define LMASK 0xfff /* crock, seems to work tho */
- /* for Sun2,3,4 */
- /*# define LOADADDR 0xff004000 /* sun4 */
- /*# define LOADADDR 0x0f004000 /* sun3 */
- /*# define LOADADDR 0x4000 /* sun2 */
- # endif /* sun defined */
-
- # ifdef accel
- # define LMASK 0xffff
- # define INCLUDE_HEADERS
- # endif /* accel defined */
-
- # ifndef N_SEGSIZ /* a sun-ism */
- # include <sys/param.h> /* get CLBYTES */
- # define N_SEGSIZ(a) (CLBYTES) /* simulate sun macro */
- # endif /* N_SEGSIZ not defined */
-
- # ifdef vax
- # define LOADADDR 0x80000000 /* kernel load address */
- # endif /* vax defined */
-
- # ifdef ibm032 /* RT under AOS/ACIS 4.3 */
- # define LOADADDR 0xe0000000 /* kernel load address */
- # endif /* ibm032 defined */
-
- # ifdef sony_news /* only tested for News-800 */
- # define LOADADDR 0x80001000 /* crocked by 4k? */
- # endif /* sony_news defined */
-
- # ifdef sequent /* only tested for S3 */
- # define LOADADDR 0
- # endif /* sequent defined */
-
- GLOBAL BOOL
- read_vmunix( file, off, str, len )
- char *file; /* file name */
- long off; /* virtual address */
- char *str; /* dest buffer */
- int len; /* chars to read */
- {
- int f;
- long pos, base, data, koffset;
- struct exec ex;
-
- if( off == 0L ) /* bogus offset */
- return( FALSE ); /* lose quickly */
-
- if( (f = open( file, 0 )) < 0 ) /* open /vmunix */
- return( FALSE ); /* you lose */
-
- if( read( f, &ex, sizeof( ex ) ) != sizeof( ex ) ) { /* read header */
- close( f ); /* short read */
- return( FALSE ); /* quit */
- }
-
- base = N_TXTOFF( ex ); /* get start of meaningfullness */
-
- # ifdef LOADADDR
- koffset = LOADADDR; /* offset into image */
- # else /* LOADADDR not defined */
- # ifdef LMASK
- koffset = ex.a_entry & ~LMASK;
- # else /* LMASK not defined */
- # include <ERROR: must have one of LOADADDR and LMASK>
- # endif /* LMASK not defined */
- # endif /* LOADADDR not defined */
-
- off -= koffset; /* remove kernel offset */
- if( ex.a_magic == OMAGIC
- # ifdef NMAGIC /* sequent lacks NMAGIC! */
- || (off < ex.a_text && ex.a_magic == NMAGIC)
- # endif /* NMAGIC defined */
- # ifdef SMAGIC /* sequent standalone */
- || ex.a_magic == SMAGIC
- # endif /* SMAGIC defined */
- ) /* OMAGIC or NMAGIC text */
- data = 0; /* no data offset */
- # ifdef NMAGIC
- else if( ex.a_magic == NMAGIC ) { /* NMAGIC data loaded on seg boundry */
- int segs; /* segment size */
- segs = N_SEGSIZ(ex) - 1; /* round to "segment" after text*/
- data = (ex.a_text + segs - 1) & ~segs;
- data -= ex.a_text; /* just get needed offset */
- }
- # endif /* NMAGIC defined */
- # ifdef SOME_DAY_OVER_THE_RAINBOW
- else if( ex.a_magic == ZMAGIC ) { /* never seen a ZMAGIC kernel!! */
- base = N_SEGSIZ(ex); /* text starts on page boundry */
- if( off >= ex.a_text ) {
- /* something like for NMAGIC above... */
- }
- } /* ZMAGIC */
- # endif /* SOME_DAY_OVER_THE_RAINBOW defined */
- else {
- # ifdef DEBUGSW
- if( sw_debug )
- printf("Unknown %s magic %#x %#o\n", KERNEL_FILE,
- ex.a_magic, ex.a_magic );
- # endif /* DEBUGSW defined */
- return( FALSE ); /* (bad magic falls here too) */
- }
-
- pos = off + base - data;
- # ifdef DEBUGSW
- if( sw_debug )
- printf("read_vmunix: pos %#x off %#x base %#x data %#x\n",
- pos, off, base, data );
- # endif /* DEBUGSW defined */
-
- if( lseek( f, pos, 0 ) == pos && /* seek to position */
- read( f, str, len ) == len ) { /* and read bytes */
- close( f ); /* ok!! */
- return( TRUE ); /* return good status */
- } /* lseek and read OK */
- close( f );
- return( FALSE );
- } /* read_vmunix */
-
- # else /* COFF defined */
-
- /*
- * BSD systems using COFF end up here
- * ie; DECstation3100 and Sun 386i
- *
- * *TODO* needs work!
- */
-
- # include <stdio.h>
- # include <filehdr.h>
- # include <syms.h> /* works for DS3100. 386i?? */
- # include <ldfcn.h>
-
- # ifndef ISCOFF
- /* UGH! This happens only on Umax 4.3 */
- # define ISCOFF(m) ((m) >= 0500 && (m) <= 0577)
- # endif /* ISCOFF not defined */
-
- GLOBAL BOOL
- read_vmunix( file, off, str, len ) /* Hacking cough... */
- char *file; /* file name */
- long off; /* virtual address */
- char *str; /* dest buffer */
- int len; /* chars to read */
- {
- LDFILE *ld;
-
- # ifdef DEBUGSW
- if( sw_debug )
- printf("read_vmunix('%s', %x, ... , %d)\n", file, off, len );
- # endif /* DEBUGSW defined */
-
- if( (ld = ldopen(file, NULL)) == NULL )
- return( FALSE );
-
- for( ; ; ) { /* bogus loop */
- if( !ISCOFF( HEADER(ld).f_magic ) )
- break;
-
- # ifdef DEBUGSW
- if( sw_debug )
- puts("got here");
- # endif /* DEBUGSW defined */
-
- /* more good stuff here! */
-
- break; /* break bogus loop! */
- } /* bogus for loop */
- ldclose( ld );
- return( FALSE );
- } /* read_vmunix */
- # endif /* COFF defined */
-
- # endif /* Umax != 42 && !defined(USG) */
-
- /*
- * Local variables:
- * comment-column: 40
- * End:
- */
-