|
|
1.1 root 1: /* l.out.c -- routines for manipulating l.out executable files. */
2:
3: #include <l.out.h>
4: #include <canon.h>
5: #include <sys/types.h>
6:
7: #include "tboot.h"
8:
9: /* Convert l.out to load table.
10: * Used to generate loading instructions for use by tboot main().
11: * Returns true on successful translation.
12: */
13:
14: int
15: lout2load(ip, table, data_seg)
16: struct inode *ip; /* input: File to read. */
17: struct load_segment table[]; /* output: How to read it. */
18: uint16 *data_seg; /* output: Where to point es. */
19: {
20: int i; /* Loop counter. */
21: struct ldheader imageheader; /* l.out header for boot image. */
22:
23: VERBOSE( puts("Reading the l.out header.\r\n"); );
24:
25: /* Read the header. */
26: iread(ip, &imageheader,
27: (fsize_t) 0, (uint16) sizeof(struct ldheader));
28:
29:
30: /* Canonicalize the header. */
31: canint(imageheader.l_magic);
32: canint(imageheader.l_flag);
33: canint(imageheader.l_machine);
34: canvaddr(imageheader.l_entry);
35: for(i = 0; i < NLSEG; ++i) {
36: cansize(imageheader.l_ssize[i]);
37: }
38:
39: /* Copy the l.out header info into table. */
40:
41: #define L_TEXT table[0]
42: #define L_DATA table[1]
43: /* Calculate remaining entries. */
44: if (imageheader.l_flag & LF_SEP) { /* if sep i/d executable */
45: VERBOSE( puts("Generating table for sep i/d l.out.\r\n"); );
46: L_TEXT.valid = (1==1);
47: L_TEXT.message = "\r\nLoading 286 COHERENT...\r\n";
48: /* Load the shared and private code segments as one. */
49: L_TEXT.load_toseg = sys_base; /* This is where we want the OS. */
50: L_TEXT.load_tooffset = 0;
51: L_TEXT.load_offset = sizeof(struct ldheader); /* Skip the header. */
52: L_TEXT.load_length = imageheader.l_ssize[L_SHRI] + /* Both segments as one. */
53: imageheader.l_ssize[L_PRVI];
54:
55:
56: L_DATA.valid = (1==1);
57: L_DATA.message = "\r\nLoading 286 COHERENT data...\r\n";
58: /* Load both data segments. */
59:
60: /* Round up to next 16 byte paragraph. */
61: L_DATA.load_toseg = (sys_base +
62: (imageheader.l_ssize[L_SHRI] + /* Shared code */
63: imageheader.l_ssize[L_PRVI] + /* Private code */
64: 15) / 16);
65: L_DATA.load_tooffset = 0;
66: L_DATA.load_offset = (fsize_t) sizeof(struct ldheader) + /* l.out header */
67: imageheader.l_ssize[L_SHRI] + /* Shared code */
68: imageheader.l_ssize[L_PRVI]; /* Private code */
69: L_DATA.load_length = imageheader.l_ssize[L_SHRD] + /* Both segments as one. */
70: imageheader.l_ssize[L_PRVD];
71:
72: table[2].valid = (1==2); /* Terminate the list. */
73:
74: *data_seg = (uint16) (sys_base +
75: (imageheader.l_ssize[L_SHRI] + /* Shared code */
76: imageheader.l_ssize[L_PRVI] + /* Private code */
77: 15) / 16); /* Rounded up a paragraph. */
78:
79: } else { /* if not sep i/d executable */
80: #define SEGMENT table[0]
81:
82: VERBOSE( puts("Generating table for non-sep i/d l.out.\r\n"); );
83:
84: SEGMENT.valid = (1==1);
85: SEGMENT.message = "\r\nLoading ancient COHERENT...\r\n";
86: /* Load the shared and private code segments as one. */
87: SEGMENT.load_toseg = sys_base; /* This is where we */
88: SEGMENT.load_tooffset = 0; /* want the OS. */
89: /* Skip the header. */
90: SEGMENT.load_offset = (fsize_t) sizeof(struct ldheader);
91: /* Load all segments as one. */
92: SEGMENT.load_length = imageheader.l_ssize[L_SHRI] +
93: imageheader.l_ssize[L_PRVI] +
94: imageheader.l_ssize[L_SHRD] +
95: imageheader.l_ssize[L_PRVD];
96:
97: table[1].valid = (1==2); /* Terminate the list. */
98:
99: /* Tiny model: ds = cs */
100: *data_seg = sys_base;
101: } /* if not sep i/d executable */
102:
103: return (1==1);
104: }
105:
106:
107: /*
108: * Wrapper for l_out_nlist() to make it look palitable.
109: */
110: unsigned int
111: wrap_l_out_nlist(filename, symbol)
112: char *filename;
113: char *symbol;
114: {
115: struct nlist nlp[2]; /* For talking with l_out_nlist(). */
116:
117: strcpy(nlp[0].n_name, symbol);
118: strcat(nlp[0].n_name, "_");
119: nlp[1].n_name[0] = '\0';
120: l_out_nlist(filename, nlp);
121: return( nlp[0].n_value );
122: }
123:
124: /*
125: * Get entries from l.out name list.
126: */
127: void
128: l_out_nlist(fn, nlp)
129: char *fn;
130: struct nlist *nlp;
131: {
132: register struct nlist *np;
133: register int ntodo = 0;
134: int lfp;
135: struct ldheader lh;
136: struct ldsym ste;
137: fsize_t symsize;
138: register int n;
139:
140: for (np = nlp; np->n_name[0] != '\0'; np++) {
141: np->n_type = np->n_value = 0;
142: ntodo++;
143: }
144:
145: if ((lfp = open(fn, 0)) == -1)
146: return;
147:
148:
149: n = read(lfp, &lh, sizeof lh);
150:
151: canint(lh.l_magic);
152: if (n!=sizeof(lh) || lh.l_magic!=L_MAGIC) {
153: puts("L.out bad MAGIC.\r\n");
154: close(lfp);
155: return;
156: }
157: for (n=0; n<=L_SYM; n++)
158: cansize(lh.l_ssize[n]);
159: symsize = sizeof lh + lh.l_ssize[L_SHRI] + lh.l_ssize[L_SHRD]
160: + lh.l_ssize[L_PRVI] + lh.l_ssize[L_PRVD] + lh.l_ssize[L_DEBUG];
161: lseek(lfp, symsize, 0);
162: symsize = lh.l_ssize[L_SYM];
163: for ( ; symsize>0 && ntodo; symsize -= sizeof ste) {
164: if (read(lfp, &ste, sizeof ste) != sizeof(ste))
165: break;
166: for (np = nlp; np->n_name[0] != '\0'; np++)
167: if (strncmp(np->n_name, ste.ls_id, NCPLN) == 0) {
168: canint(ste.ls_type);
169: canvaddr(ste.ls_addr);
170: np->n_type = ste.ls_type;
171: np->n_value = ste.ls_addr;
172: if (--ntodo == 0)
173: break;
174: }
175: }
176: close(lfp);
177: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.