Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

srecload.c

Go to the documentation of this file.
00001 
00006 /*
00007  *  The contents of this file are subject to the Mozilla Public License
00008  *  Version 1.0 (the "License"); you may not use this file except in
00009  *  compliance with the License. You may obtain a copy of the License at
00010  *  http://www.mozilla.org/MPL/
00011  *
00012  *  Software distributed under the License is distributed on an "AS IS"
00013  *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
00014  *  License for the specific language governing rights and limitations
00015  *  under the License.
00016  *
00017  *  The Original Code is legOS code, released October 2, 1999.
00018  *
00019  *  The Initial Developer of the Original Code is Markus L. Noga.
00020  *  Portions created by Markus L. Noga are Copyright (C) 1999
00021  *  Markus L. Noga. All Rights Reserved.
00022  *
00023  *  Contributor(s): Markus L. Noga
00024  */
00025 
00026 /*
00027  *  Copyright (C) 1998, 1999, Kekoa Proudfoot.  All Rights Reserved.
00028  *
00029  *  License to copy, use, and modify this software is granted provided that
00030  *  this notice is retained in any copies of any part of this software.
00031  *
00032  *  The author makes no guarantee that this software will compile or
00033  *  function correctly.  Also, if you use this software, you do so at your
00034  *  own risk.
00035  *
00036  *  Kekoa Proudfoot
00037  *  kekoa@graphics.stanford.edu
00038  *  10/3/98
00039  */
00040  
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #include <string.h>
00044 #include <ctype.h>
00045 
00046 #include "srec.h"
00047 #include "srecload.h"
00048 
00049 #define IMG_LOWEST    0x0000
00050 #define IMG_HIGHEST   0xffff
00051 #define IMG_MAXSIZE   0x10000
00052 
00053 
00055 
00060 static int symbols_load(image_t *img,FILE *file) {
00061   char buf[256];
00062   int doubledollar=0;
00063   unsigned short text=0,
00064                  text_end=0,
00065                  data=0,
00066                  data_end=0,
00067                  bss=0,
00068                  bss_end=0,
00069                  ctors=0,
00070                  ctors_end=0,
00071                  dtors=0,
00072                  dtors_end=0,
00073                  _main=0;
00074   int line=0;
00075     
00076   // read in symbols
00077   //
00078   while(doubledollar<2 && fgets(buf, 80, file)) {
00079     int i;
00080     line++;
00081 
00082     // skip empty lines
00083     //
00084     for(i=0; buf[i] && isspace(buf[i]); i++)
00085       ;
00086     if (!buf[i])
00087         continue;
00088     
00089     if(buf[i]=='$' && buf[i+1]=='$') {
00090       // delimiter?
00091       //
00092       doubledollar++;
00093     } else {
00094       // symbol / address pair
00095       //
00096       char *symbol;
00097       unsigned short address;
00098       
00099       if(doubledollar<1) {
00100         fprintf(stderr,"malformed symbolsrec file at line %d\n",line);
00101         exit(-1);
00102       }
00103       
00104       // read symbol
00105       //
00106       symbol=buf+i;
00107       while(buf[i] && buf[i]!=' ')
00108         i++;
00109       if(buf[i]!=' ' || buf[i+1]!='$') {
00110         fprintf(stderr,"malformed symbolsrec file at line %d\n",line);
00111         exit(-1);
00112       }
00113       buf[i]=0;
00114       
00115       address=(unsigned short) strtoul(buf+i+2,NULL,16);
00116   
00117       // retain relevant offsets
00118       //
00119       if(!strcmp(symbol,"___text"))
00120         text=address; 
00121       else if(!strcmp(symbol,"___text_end"))
00122         text_end=address; 
00123       else if(!strcmp(symbol,"___data"))
00124         data=address; 
00125       else if(!strcmp(symbol,"___data_end"))
00126         data_end=address; 
00127       else if(!strcmp(symbol,"___bss"))
00128         bss=address; 
00129       else if(!strcmp(symbol,"___bss_end"))
00130         bss_end=address; 
00131       else if(!strcmp(symbol,"___ctors"))
00132         ctors=address; 
00133       else if(!strcmp(symbol,"___ctors_end"))
00134         ctors_end=address; 
00135       else if(!strcmp(symbol,"___dtors"))
00136         dtors=address; 
00137       else if(!strcmp(symbol,"___dtors_end"))
00138         dtors_end=address; 
00139       else if(!strcmp(symbol,"_main"))
00140         _main=address; 
00141     }   
00142   }
00143 
00144   // save general file information
00145   //
00146   img->base     =text;  
00147   //  added ctor/dtor sections for C++.  They reside between text and data
00148   //   so they've been added to text for simplicity.  -stephen 14Jan01
00149   img->text_size=(text_end - text) + (ctors_end - ctors) + (dtors_end - dtors);
00150   img->data_size=data_end - data;
00151   img->bss_size = bss_end - bss;
00152   img->offset   =_main-text;
00153   
00154   return line;
00155 }
00156 
00157 
00158 void image_load(image_t *img,const char *filename)
00159 {
00160   FILE *file;
00161   char buf[256];
00162   srec_t srec;
00163   int line;
00164   unsigned short size,start=0;
00165 
00166   if ((file = fopen(filename, "r")) == NULL) {
00167     fprintf(stderr, "%s: failed to open\n", filename);
00168     exit(1);
00169   }
00170 
00171   // read symbols from file
00172   //
00173   line=symbols_load(img,file);
00174   size=img->text_size+img->data_size;
00175   
00176   if((img->text=calloc(size,1))== NULL) {
00177     fprintf(stderr, "out of memory\n");
00178     exit(1);
00179   }
00180         
00181   // Build an image of the srecord data 
00182   //
00183   while (fgets(buf, 80, file)) {
00184     int i,error;
00185     line++;
00186 
00187     // skip empty lines
00188     //
00189     for(i=0; buf[i] && isspace(buf[i]); i++)
00190       ;
00191     if (!buf[i])
00192         continue;
00193 
00194     // decode line
00195     //
00196     if ((error = srec_decode(&srec, buf)) < 0) {
00197         char *errstr = NULL;
00198         switch (error) {
00199           case S_NULL:         errstr = "null string error"; break;
00200           case S_INVALID_HDR:  errstr = "invalid header";    break;
00201           case S_INVALID_CHAR: errstr = "invalid character"; break;
00202           case S_INVALID_TYPE: errstr = "invalid type";      break;
00203           case S_TOO_SHORT:    errstr = "line to short";     break;
00204           case S_TOO_LONG:     errstr = "line too line";     break;
00205           case S_INVALID_CKSUM:       /* ignored */          break;
00206           default:             errstr = "unknown error";     break;
00207         }
00208         if (errstr) {
00209           fprintf(stderr, "%s: %s on line %d\n", filename, errstr, line);
00210           exit(1);
00211         }
00212     }
00213     
00214     // handle lines
00215     //
00216     if (srec.type == 1) {
00217       if (srec.addr < img->base || srec.addr + srec.count > img->base + size) {
00218         fprintf(stderr, "%s: address [0x%4.4lX, 0x%4.4lX] out of bounds [0x%4.4X-0x%4.4X] on line %d\n",filename, srec.addr, (srec.addr + srec.count), img->base, (img->base + size), line);
00219         exit(1);
00220       }
00221 
00222       memcpy(img->text + srec.addr - img->base, srec.data, srec.count);
00223     }
00224     else if (srec.type == 9) {
00225       start = srec.addr;
00226     }
00227   }
00228 
00229   // trivial verification
00230   //
00231   if(start != img->base + img->offset) {
00232     fprintf(stderr, "%s: main isn't entry point\n",filename);
00233     exit(1);
00234   }
00235 }

Generated on Fri Feb 25 08:02:40 2005 for brickos by  doxygen 1.3.9.1