Coherent4.2.10/tboot/l.out.c
/* l.out.c -- routines for manipulating l.out executable files. */
#include <l.out.h>
#include <canon.h>
#include <sys/types.h>
#include "tboot.h"
/* Convert l.out to load table.
* Used to generate loading instructions for use by tboot main().
* Returns true on successful translation.
*/
int
lout2load(ip, table, data_seg)
struct inode *ip; /* input: File to read. */
struct load_segment table[]; /* output: How to read it. */
uint16 *data_seg; /* output: Where to point es. */
{
int i; /* Loop counter. */
struct ldheader imageheader; /* l.out header for boot image. */
VERBOSE( puts("Reading the l.out header.\r\n"); );
/* Read the header. */
iread(ip, &imageheader,
(fsize_t) 0, (uint16) sizeof(struct ldheader));
/* Canonicalize the header. */
canint(imageheader.l_magic);
canint(imageheader.l_flag);
canint(imageheader.l_machine);
canvaddr(imageheader.l_entry);
for(i = 0; i < NLSEG; ++i) {
cansize(imageheader.l_ssize[i]);
}
/* Copy the l.out header info into table. */
#define L_TEXT table[0]
#define L_DATA table[1]
/* Calculate remaining entries. */
if (imageheader.l_flag & LF_SEP) { /* if sep i/d executable */
VERBOSE( puts("Generating table for sep i/d l.out.\r\n"); );
L_TEXT.valid = (1==1);
L_TEXT.message = "\r\nLoading 286 COHERENT...\r\n";
/* Load the shared and private code segments as one. */
L_TEXT.load_toseg = sys_base; /* This is where we want the OS. */
L_TEXT.load_tooffset = 0;
L_TEXT.load_offset = sizeof(struct ldheader); /* Skip the header. */
L_TEXT.load_length = imageheader.l_ssize[L_SHRI] + /* Both segments as one. */
imageheader.l_ssize[L_PRVI];
L_DATA.valid = (1==1);
L_DATA.message = "\r\nLoading 286 COHERENT data...\r\n";
/* Load both data segments. */
/* Round up to next 16 byte paragraph. */
L_DATA.load_toseg = (sys_base +
(imageheader.l_ssize[L_SHRI] + /* Shared code */
imageheader.l_ssize[L_PRVI] + /* Private code */
15) / 16);
L_DATA.load_tooffset = 0;
L_DATA.load_offset = (fsize_t) sizeof(struct ldheader) + /* l.out header */
imageheader.l_ssize[L_SHRI] + /* Shared code */
imageheader.l_ssize[L_PRVI]; /* Private code */
L_DATA.load_length = imageheader.l_ssize[L_SHRD] + /* Both segments as one. */
imageheader.l_ssize[L_PRVD];
table[2].valid = (1==2); /* Terminate the list. */
*data_seg = (uint16) (sys_base +
(imageheader.l_ssize[L_SHRI] + /* Shared code */
imageheader.l_ssize[L_PRVI] + /* Private code */
15) / 16); /* Rounded up a paragraph. */
} else { /* if not sep i/d executable */
#define SEGMENT table[0]
VERBOSE( puts("Generating table for non-sep i/d l.out.\r\n"); );
SEGMENT.valid = (1==1);
SEGMENT.message = "\r\nLoading ancient COHERENT...\r\n";
/* Load the shared and private code segments as one. */
SEGMENT.load_toseg = sys_base; /* This is where we */
SEGMENT.load_tooffset = 0; /* want the OS. */
/* Skip the header. */
SEGMENT.load_offset = (fsize_t) sizeof(struct ldheader);
/* Load all segments as one. */
SEGMENT.load_length = imageheader.l_ssize[L_SHRI] +
imageheader.l_ssize[L_PRVI] +
imageheader.l_ssize[L_SHRD] +
imageheader.l_ssize[L_PRVD];
table[1].valid = (1==2); /* Terminate the list. */
/* Tiny model: ds = cs */
*data_seg = sys_base;
} /* if not sep i/d executable */
return (1==1);
}
/*
* Wrapper for l_out_nlist() to make it look palitable.
*/
unsigned int
wrap_l_out_nlist(filename, symbol)
char *filename;
char *symbol;
{
struct nlist nlp[2]; /* For talking with l_out_nlist(). */
strcpy(nlp[0].n_name, symbol);
strcat(nlp[0].n_name, "_");
nlp[1].n_name[0] = '\0';
l_out_nlist(filename, nlp);
return( nlp[0].n_value );
}
/*
* Get entries from l.out name list.
*/
void
l_out_nlist(fn, nlp)
char *fn;
struct nlist *nlp;
{
register struct nlist *np;
register int ntodo = 0;
int lfp;
struct ldheader lh;
struct ldsym ste;
fsize_t symsize;
register int n;
for (np = nlp; np->n_name[0] != '\0'; np++) {
np->n_type = np->n_value = 0;
ntodo++;
}
if ((lfp = open(fn, 0)) == -1)
return;
n = read(lfp, &lh, sizeof lh);
canint(lh.l_magic);
if (n!=sizeof(lh) || lh.l_magic!=L_MAGIC) {
puts("L.out bad MAGIC.\r\n");
close(lfp);
return;
}
for (n=0; n<=L_SYM; n++)
cansize(lh.l_ssize[n]);
symsize = sizeof lh + lh.l_ssize[L_SHRI] + lh.l_ssize[L_SHRD]
+ lh.l_ssize[L_PRVI] + lh.l_ssize[L_PRVD] + lh.l_ssize[L_DEBUG];
lseek(lfp, symsize, 0);
symsize = lh.l_ssize[L_SYM];
for ( ; symsize>0 && ntodo; symsize -= sizeof ste) {
if (read(lfp, &ste, sizeof ste) != sizeof(ste))
break;
for (np = nlp; np->n_name[0] != '\0'; np++)
if (strncmp(np->n_name, ste.ls_id, NCPLN) == 0) {
canint(ste.ls_type);
canvaddr(ste.ls_addr);
np->n_type = ste.ls_type;
np->n_value = ste.ls_addr;
if (--ntodo == 0)
break;
}
}
close(lfp);
}