|
|
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: #ifdef VERBOSE ! 24: puts("Reading the l.out header.\r\n"); ! 25: #endif /* VERBOSE */ ! 26: ! 27: /* Read the header. */ ! 28: iread(ip, &imageheader, ! 29: (fsize_t) 0, (uint16) sizeof(struct ldheader)); ! 30: ! 31: ! 32: /* Canonicalize the header. */ ! 33: canint(imageheader.l_magic); ! 34: canint(imageheader.l_flag); ! 35: canint(imageheader.l_machine); ! 36: canvaddr(imageheader.l_entry); ! 37: for(i = 0; i < NLSEG; ++i) { ! 38: cansize(imageheader.l_ssize[i]); ! 39: } ! 40: ! 41: /* Copy the l.out header info into table. */ ! 42: ! 43: #define L_TEXT table[0] ! 44: #define L_DATA table[1] ! 45: /* Calculate remaining entries. */ ! 46: if (imageheader.l_flag & LF_SEP) { /* if sep i/d executable */ ! 47: #ifdef VERBOSE ! 48: puts("Generating table for sep i/d l.out.\r\n"); ! 49: #endif /* VERBOSE */ ! 50: L_TEXT.valid = (1==1); ! 51: L_TEXT.message = "\r\nLoading l.out code segments...\r\n"; ! 52: /* Load the shared and private code segments as one. */ ! 53: L_TEXT.load_toseg = sys_base; /* This is where we want the OS. */ ! 54: L_TEXT.load_tooffset = 0; ! 55: L_TEXT.load_offset = sizeof(struct ldheader); /* Skip the header. */ ! 56: L_TEXT.load_length = imageheader.l_ssize[L_SHRI] + /* Both segments as one. */ ! 57: imageheader.l_ssize[L_PRVI]; ! 58: ! 59: ! 60: L_DATA.valid = (1==1); ! 61: L_DATA.message = "\r\nLoading l.out data segments...\r\n"; ! 62: /* Load both data segments. */ ! 63: ! 64: /* Round up to next 16 byte paragraph. */ ! 65: L_DATA.load_toseg = (sys_base + ! 66: (imageheader.l_ssize[L_SHRI] + /* Shared code */ ! 67: imageheader.l_ssize[L_PRVI] + /* Private code */ ! 68: 15) / 16); ! 69: L_DATA.load_tooffset = 0; ! 70: L_DATA.load_offset = (fsize_t) sizeof(struct ldheader) + /* l.out header */ ! 71: imageheader.l_ssize[L_SHRI] + /* Shared code */ ! 72: imageheader.l_ssize[L_PRVI]; /* Private code */ ! 73: L_DATA.load_length = imageheader.l_ssize[L_SHRD] + /* Both segments as one. */ ! 74: imageheader.l_ssize[L_PRVD]; ! 75: ! 76: table[2].valid = (1==2); /* Terminate the list. */ ! 77: ! 78: *data_seg = (uint16) (sys_base + ! 79: (imageheader.l_ssize[L_SHRI] + /* Shared code */ ! 80: imageheader.l_ssize[L_PRVI] + /* Private code */ ! 81: 15) / 16); /* Rounded up a paragraph. */ ! 82: ! 83: } else { /* if not sep i/d executable */ ! 84: #define SEGMENT table[0] ! 85: ! 86: #ifdef VERBOSE ! 87: puts("Generating table for non-sep i/d l.out.\r\n"); ! 88: #endif /* VERBOSE */ ! 89: ! 90: SEGMENT.valid = (1==1); ! 91: SEGMENT.message = "\r\nLoading all l.out segments...\r\n"; ! 92: /* Load the shared and private code segments as one. */ ! 93: SEGMENT.load_toseg = sys_base; /* This is where we */ ! 94: SEGMENT.load_tooffset = 0; /* want the OS. */ ! 95: /* Skip the header. */ ! 96: SEGMENT.load_offset = (fsize_t) sizeof(struct ldheader); ! 97: /* Load all segments as one. */ ! 98: SEGMENT.load_length = imageheader.l_ssize[L_SHRI] + ! 99: imageheader.l_ssize[L_PRVI] + ! 100: imageheader.l_ssize[L_SHRD] + ! 101: imageheader.l_ssize[L_PRVD]; ! 102: ! 103: table[1].valid = (1==2); /* Terminate the list. */ ! 104: ! 105: /* Tiny model: ds = cs */ ! 106: *data_seg = sys_base; ! 107: } /* if not sep i/d executable */ ! 108: ! 109: return (1==1); ! 110: } ! 111: ! 112: ! 113: /* ! 114: * Get entries from l.out name list. ! 115: */ ! 116: ! 117: void ! 118: l_out_nlist(fn, nlp) ! 119: char *fn; ! 120: struct nlist *nlp; ! 121: { ! 122: register struct nlist *np; ! 123: register int ntodo = 0; ! 124: int lfp; ! 125: struct ldheader lh; ! 126: struct ldsym ste; ! 127: fsize_t symsize; ! 128: register int n; ! 129: ! 130: for (np = nlp; np->n_name[0] != '\0'; np++) { ! 131: np->n_type = np->n_value = 0; ! 132: ntodo++; ! 133: } ! 134: ! 135: if ((lfp = open(fn, 0)) == -1) ! 136: return; ! 137: ! 138: ! 139: n = read(lfp, &lh, sizeof lh); ! 140: ! 141: canint(lh.l_magic); ! 142: if (n!=sizeof(lh) || lh.l_magic!=L_MAGIC) { ! 143: puts("L.out bad MAGIC.\r\n"); ! 144: close(lfp); ! 145: return; ! 146: } ! 147: for (n=0; n<=L_SYM; n++) ! 148: cansize(lh.l_ssize[n]); ! 149: symsize = sizeof lh + lh.l_ssize[L_SHRI] + lh.l_ssize[L_SHRD] ! 150: + lh.l_ssize[L_PRVI] + lh.l_ssize[L_PRVD] + lh.l_ssize[L_DEBUG]; ! 151: lseek(lfp, symsize, 0); ! 152: symsize = lh.l_ssize[L_SYM]; ! 153: for ( ; symsize>0 && ntodo; symsize -= sizeof ste) { ! 154: if (read(lfp, &ste, sizeof ste) != sizeof(ste)) ! 155: break; ! 156: for (np = nlp; np->n_name[0] != '\0'; np++) ! 157: if (strncmp(np->n_name, ste.ls_id, NCPLN) == 0) { ! 158: canint(ste.ls_type); ! 159: canvaddr(ste.ls_addr); ! 160: np->n_type = ste.ls_type; ! 161: np->n_value = ste.ls_addr; ! 162: if (--ntodo == 0) ! 163: break; ! 164: } ! 165: } ! 166: close(lfp); ! 167: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.