Main Page   Compound List   File List   Compound Members   File Members  

coff2noff.c

Go to the documentation of this file.
00001 /* coff2noff.c 
00002  *
00003  * This program reads in a COFF format file, and outputs a NOFF format file.
00004  * The NOFF format is essentially just a simpler version of the COFF file,
00005  * recording where each segment is in the NOFF file, and where it is to
00006  * go in the virtual address space.
00007  * 
00008  * Assumes coff file is linked with either
00009  *      gld with -N -Ttext 0 
00010  *      ld with  -N -T 0
00011  * to make sure the object file has no shared text.
00012  *
00013  * Also assumes that the COFF file has at most 3 segments:
00014  *      .text   -- read-only executable instructions 
00015  *      .data   -- initialized data
00016  *      .bss/.sbss -- uninitialized data (should be zero'd on program startup)
00017  *
00018  * Copyright (c) 1992-1993 The Regents of the University of California.
00019  * All rights reserved.  See copyright.h for copyright notice and limitation 
00020  * of liability and disclaimer of warranty provisions.
00021  */
00022 
00023 #define MAIN
00024 #include "copyright.h" 
00025 #undef MAIN
00026 
00027 #include <sys/types.h>
00028 #include <sys/stat.h>
00029 #include <fcntl.h>
00030 #include <limits.h>
00031 #include <stdio.h>
00032 
00033 #include "coff.h"
00034 #include "noff.h"
00035 
00036 /* Routines for converting words and short words to and from the
00037  * simulated machine's format of little endian.  These end up
00038  * being NOPs when the host machine is little endian.
00039  */
00040 
00041 unsigned int
00042 WordToHost(unsigned int word) {
00043 #ifdef HOST_IS_BIG_ENDIAN
00044          register unsigned long result;
00045          result = (word >> 24) & 0x000000ff;
00046          result |= (word >> 8) & 0x0000ff00;
00047          result |= (word << 8) & 0x00ff0000;
00048          result |= (word << 24) & 0xff000000;
00049          return result;
00050 #else 
00051          return word;
00052 #endif /* HOST_IS_BIG_ENDIAN */
00053 }
00054 
00055 unsigned short
00056 ShortToHost(unsigned short shortword) {
00057 #if HOST_IS_BIG_ENDIAN
00058          register unsigned short result;
00059          result = (shortword << 8) & 0xff00;
00060          result |= (shortword >> 8) & 0x00ff;
00061          return result;
00062 #else 
00063          return shortword;
00064 #endif /* HOST_IS_BIG_ENDIAN */
00065 }
00066 
00067 #define ReadStruct(f,s)         Read(f,(char *)&s,sizeof(s))
00068 
00069 extern char *malloc();
00070 char *noffFileName = NULL;
00071 
00072 /* read and check for error */
00073 void Read(int fd, char *buf, int nBytes)
00074 {
00075     if (read(fd, buf, nBytes) != nBytes) {
00076         fprintf(stderr, "File is too short\n");
00077         unlink(noffFileName);
00078         exit(1);
00079     }
00080 }
00081 
00082 /* write and check for error */
00083 void Write(int fd, char *buf, int nBytes)
00084 {
00085     if (write(fd, buf, nBytes) != nBytes) {
00086         fprintf(stderr, "Unable to write file\n");
00087         unlink(noffFileName);
00088         exit(1);
00089     }
00090 }
00091 
00092 main (int argc, char **argv)
00093 {
00094     int fdIn, fdOut, numsections, i, inNoffFile;
00095     struct filehdr fileh;
00096     struct aouthdr systemh;
00097     struct scnhdr *sections;
00098     char *buffer;
00099     NoffHeader noffH;
00100 
00101     if (argc < 2) {
00102         fprintf(stderr, "Usage: %s <coffFileName> <noffFileName>\n", argv[0]);
00103         exit(1);
00104     }
00105     
00106 /* open the COFF file (input) */
00107     fdIn = open(argv[1], O_RDONLY, 0);
00108     if (fdIn == -1) {
00109         perror(argv[1]);
00110         exit(1);
00111     }
00112 
00113 /* open the NOFF file (output) */
00114     fdOut = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC , 0666);
00115     if (fdIn == -1) {
00116         perror(argv[2]);
00117         exit(1);
00118     }
00119     noffFileName = argv[2];
00120     
00121 /* Read in the file header and check the magic number. */
00122     ReadStruct(fdIn,fileh);
00123     fileh.f_magic = ShortToHost(fileh.f_magic);
00124     fileh.f_nscns = ShortToHost(fileh.f_nscns); 
00125     if (fileh.f_magic != MIPSELMAGIC) {
00126         fprintf(stderr, "File is not a MIPSEL COFF file\n");
00127         unlink(noffFileName);
00128         exit(1);
00129     }
00130     
00131 /* Read in the system header and check the magic number */
00132     ReadStruct(fdIn,systemh);
00133     systemh.magic = ShortToHost(systemh.magic);
00134     if (systemh.magic != OMAGIC) {
00135         fprintf(stderr, "File is not a OMAGIC file\n");
00136         unlink(noffFileName);
00137         exit(1);
00138     }
00139     
00140 /* Read in the section headers. */
00141     numsections = fileh.f_nscns;
00142     printf("numsections %d \n",numsections);
00143     sections = (struct scnhdr *)malloc(numsections * sizeof(struct scnhdr));
00144     Read(fdIn, (char *) sections, numsections * sizeof(struct scnhdr));
00145 
00146    for (i = 0; i < numsections; i++) {
00147      sections[i].s_paddr =  WordToHost(sections[i].s_paddr);
00148      sections[i].s_size = WordToHost(sections[i].s_size);
00149      sections[i].s_scnptr = WordToHost(sections[i].s_scnptr);
00150    }
00151 
00152  /* initialize the NOFF header, in case not all the segments are defined
00153   * in the COFF file
00154   */
00155     noffH.noffMagic = NOFFMAGIC;
00156     noffH.code.size = 0;
00157     noffH.initData.size = 0;
00158     noffH.uninitData.size = 0;
00159 
00160  /* Copy the segments in */
00161     inNoffFile = sizeof(NoffHeader);
00162     lseek(fdOut, inNoffFile, 0);
00163     printf("Loading %d sections:\n", numsections);
00164     for (i = 0; i < numsections; i++) {
00165         printf("\t\"%s\", filepos 0x%x, mempos 0x%x, size 0x%x\n",
00166               sections[i].s_name, sections[i].s_scnptr,
00167               sections[i].s_paddr, sections[i].s_size);
00168         if (sections[i].s_size == 0) {
00169                 /* do nothing! */       
00170         } else if (!strcmp(sections[i].s_name, ".text")) {
00171             noffH.code.virtualAddr = sections[i].s_paddr;
00172             noffH.code.inFileAddr = inNoffFile;
00173             noffH.code.size = sections[i].s_size;
00174             lseek(fdIn, sections[i].s_scnptr, 0);
00175             buffer = malloc(sections[i].s_size);
00176             Read(fdIn, buffer, sections[i].s_size);
00177             Write(fdOut, buffer, sections[i].s_size);
00178             free(buffer);
00179             inNoffFile += sections[i].s_size;
00180         } else if (!strcmp(sections[i].s_name, ".data")
00181                         || !strcmp(sections[i].s_name, ".rdata")) {
00182             /* need to check if we have both .data and .rdata 
00183              *  -- make sure one or the other is empty! */ 
00184             if (noffH.initData.size != 0) {
00185                 fprintf(stderr, "Can't handle both data and rdata\n");
00186                 unlink(noffFileName);
00187                 exit(1);
00188             }
00189             noffH.initData.virtualAddr = sections[i].s_paddr;
00190             noffH.initData.inFileAddr = inNoffFile;
00191             noffH.initData.size = sections[i].s_size;
00192             lseek(fdIn, sections[i].s_scnptr, 0);
00193             buffer = malloc(sections[i].s_size);
00194             Read(fdIn, buffer, sections[i].s_size);
00195             Write(fdOut, buffer, sections[i].s_size);
00196             free(buffer);
00197             inNoffFile += sections[i].s_size;
00198         } else if (!strcmp(sections[i].s_name, ".bss") ||
00199                         !strcmp(sections[i].s_name, ".sbss")) {
00200             /* need to check if we have both .bss and .sbss -- make sure they 
00201              * are contiguous
00202              */
00203             if (noffH.uninitData.size != 0) {
00204                 if (sections[i].s_paddr == (noffH.uninitData.virtualAddr +
00205                                                 noffH.uninitData.size)) {
00206                     fprintf(stderr, "Can't handle both bss and sbss\n");
00207                     unlink(noffFileName);
00208                     exit(1);
00209                 }
00210                 noffH.uninitData.size += sections[i].s_size;
00211             } else {
00212                 noffH.uninitData.virtualAddr = sections[i].s_paddr;
00213                 noffH.uninitData.size = sections[i].s_size;
00214             }
00215             /* we don't need to copy the uninitialized data! */
00216         } else {
00217             fprintf(stderr, "Unknown segment type: %s\n", sections[i].s_name);
00218             unlink(noffFileName);
00219             exit(1);
00220         }
00221     }
00222     lseek(fdOut, 0, 0);
00223     Write(fdOut, (char *)&noffH, sizeof(NoffHeader));
00224     close(fdIn);
00225     close(fdOut);
00226     exit(0);
00227 }

Generated on Mon Feb 10 09:54:44 2003 for nachos by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002
The University of Southern California does not screen or control the content on this website and thus does not guarantee the accuracy, integrity, or quality of such content. All content on this website is provided by and is the sole responsibility of the person from which such content originated, and such content does not necessarily reflect the opinions of the University administration or the Board of Trustees