00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
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
00077
00078 while(doubledollar<2 && fgets(buf, 80, file)) {
00079 int i;
00080 line++;
00081
00082
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
00091
00092 doubledollar++;
00093 } else {
00094
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
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
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
00145
00146 img->base =text;
00147
00148
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
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
00182
00183 while (fgets(buf, 80, file)) {
00184 int i,error;
00185 line++;
00186
00187
00188
00189 for(i=0; buf[i] && isspace(buf[i]); i++)
00190 ;
00191 if (!buf[i])
00192 continue;
00193
00194
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: 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
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
00230
00231 if(start != img->base + img->offset) {
00232 fprintf(stderr, "%s: main isn't entry point\n",filename);
00233 exit(1);
00234 }
00235 }