OSDN Git Service

8249fd0de4ee28689408a793105c2ad30a3e0ce6
[pf3gnuchains/pf3gnuchains3x.git] / utils / amd-udi / mondfe / yank.c
1 static char _[] = "@(#)yank.c   5.20 93/07/30 16:39:05, Srini, AMD. ";
2 /******************************************************************************
3  * Copyright 1991 Advanced Micro Devices, Inc.
4  *
5  * This software is the property of Advanced Micro Devices, Inc  (AMD)  which
6  * specifically  grants the user the right to modify, use and distribute this
7  * software provided this notice is not removed or altered.  All other rights
8  * are reserved by AMD.
9  *
10  * AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS
11  * SOFTWARE.  IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL
12  * DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR
13  * USE OF THIS SOFTWARE.
14  *
15  * So that all may benefit from your experience, please report  any  problems
16  * or  suggestions about this software to the 29K Technical Support Center at
17  * 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131  in  the  UK,  or
18  * 0031-11-1129 in Japan, toll free.  The direct dial number is 512-462-4118.
19  *
20  * Advanced Micro Devices, Inc.
21  * 29K Support Products
22  * Mail Stop 573
23  * 5900 E. Ben White Blvd.
24  * Austin, TX 78741
25  * 800-292-9263
26  *****************************************************************************
27  *      Engineer: Srini Subramanian.
28  *****************************************************************************
29  **       This module is used to "yank" or load a COFF file
30  **       Into target memory.
31  *****************************************************************************
32  */
33
34
35 #include <stdio.h>
36 #include <memory.h>
37 #include <ctype.h>
38 #include "coff.h"
39 #include "memspcs.h"
40 #include "main.h"
41 #include "miniint.h"
42 #include "macros.h"
43 #include "error.h"
44
45 #ifdef  MSDOS
46 #include <string.h>
47 #include <stdlib.h>
48 #else
49 #include <string.h>
50 #endif
51
52 /* Definitions */
53
54 #define FILE_BUFFER_SIZE     1024
55
56 #ifdef MSDOS
57 #define FILE_OPEN_FLAG   "rb"
58 #else
59 #define FILE_OPEN_FLAG   "r"
60 #endif
61
62 #define FROM_BEGINNING  0
63
64 /* Function declarations */
65 INT32   Mini_load_coff PARAMS((char *fname,
66                                INT32 space, 
67                                INT32 sym,
68                                INT32 sects,
69                                int   msg));
70 INT32   Mini_init_info_ptr PARAMS((INIT_INFO *init));
71 INT32   Mini_send_init_info PARAMS((INIT_INFO *init));
72 INT32   Mini_load_file PARAMS((char *fname,
73                                INT32 mspace,
74                                int fargc,
75                                char *fargs,
76                                INT32 sym,
77                                INT32 sects,
78                                int msg));
79 void  convert32 PARAMS((BYTE *));
80 void  convert16 PARAMS((BYTE *));
81 int     SetSections PARAMS((char *));
82 void    print_ld_msg PARAMS((INT32, int, ADDR32, INT32));
83 void    print_ign_msg PARAMS((int, ADDR32, INT32));
84 void    print_end_msg PARAMS((INT32, int, ADDR32, INT32));
85
86 /* GLobal */
87
88 GLOBAL  INIT_INFO       init_info;
89
90 static  BYTE   buffer[FILE_BUFFER_SIZE];
91 extern  char    CoffFileName[];
92 static  INT32   Symbols=0;  /* No symbols support yet */
93 static  INT32   Sections=STYP_ABS | STYP_TEXT | STYP_DATA | STYP_LIT | STYP_BSS;
94 static  INT32   MSpace=I_MEM;
95 static  int     FileArgc;
96 static  char    ArgString[1024];
97 static  FILE    *coff_in;
98 static  int     InitializeProgram=1;
99
100
101 /*
102 ** This is the function called by the main program to load
103 ** a COFF file.  It also modifies the global data structure
104 ** init.  The data structure is then sent via an INIT message
105 ** to the target.  In addition, the "argv" parameter string
106 ** is sent to the target with WRITE messages.
107 **
108 */
109
110 INT32
111 yank_cmd(token, token_count)
112    char    *token[];
113    int      token_count;
114    {
115    int  i;
116    int  j;
117    int  SectionsGiven=0;
118    int  IPFlag=0;
119
120    for (j=1; j < token_count; j++) { /* parse command */
121       switch (token[j][0]) {
122          case   '-':
123                 if (token[j][1] == '\0')
124                    return (EMSYNTAX);
125                 if (strcmp(token[j],"-ms")==0) {/*mem stack opt */
126                   if (++j >= token_count)
127                      return (EMSYNTAX);
128                   if (sscanf(token[j],"%lx",&(init_info.mem_stack_size)) != 1) 
129                      return (EMSYNTAX);
130                 } else if (strcmp(token[j],"-rs")==0) {/*r stack*/
131                   if (++j >= token_count)
132                      return (EMSYNTAX);
133                   if (sscanf(token[j],"%lx",&(init_info.reg_stack_size)) != 1) 
134                      return (EMSYNTAX);
135                 } else if (strcmp(token[j],"-noi")==0) {/*no init */
136                   InitializeProgram = 0;
137                   IPFlag = 1;
138                 } else if (strcmp(token[j],"-i")==0) {/*init*/
139                   InitializeProgram = 1;
140                   IPFlag = 1;
141                 } else {
142                   if (SetSections(token[j]) == (int) -1) 
143                      return (EMSYNTAX);
144                   else
145                      SectionsGiven=1;
146                 }
147                 break;
148          default: /* filename etc. */
149                 if (!SectionsGiven) {
150                   Sections = STYP_ABS|STYP_TEXT|STYP_DATA|STYP_LIT|STYP_BSS; 
151                   SectionsGiven=0;
152                 }
153                 if (!IPFlag) {
154                   InitializeProgram = 1;
155                   IPFlag=0;
156                 }
157                 (void) strcpy (&CoffFileName[0], token[j]);
158                 FileArgc = token_count - j;
159                 (void) strcpy(ArgString, token[j]);
160                 for (i = 1; i < FileArgc; i++) {
161                    strcat(ArgString, " ");
162                    strcat(ArgString, token[j+i]);
163                 };
164                 j = token_count; /* break out of for loop */
165                 break;
166       };
167    }
168    if (strcmp(CoffFileName,"") == 0)  /* No COFF file given */
169      return (EMSYNTAX);
170
171    if (Mini_load_file(&CoffFileName[0], MSpace,
172                            FileArgc, ArgString,
173                            Symbols, Sections,
174                            QuietMode) != SUCCESS)  {
175        return(FAILURE);
176    } else
177      return(SUCCESS);
178 };
179
180
181 INT32
182 Mini_load_file(filename, mspace, fileargc, fileargs, sym, sects, quietmode)
183 char    *filename;
184 INT32   mspace;
185 int     fileargc;
186 char    *fileargs;
187 INT32   sym;
188 INT32   sects;
189 int     quietmode;
190 {
191
192    if (Mini_init_info_ptr(&init_info) != SUCCESS)
193      return(FAILURE);
194
195    if (Mini_load_coff(filename, mspace, sym, sects, quietmode) != SUCCESS)
196        return(FAILURE);
197
198    init_info.argstring = fileargs;   /* complete argv string */
199
200    if (InitializeProgram) {
201       if (Mini_send_init_info(&init_info) != SUCCESS)
202         return(FAILURE);
203    } else {
204      warning(EMNOINITP);
205    }
206
207    return(SUCCESS);
208 };
209
210 INT32
211 Mini_init_info_ptr(init_ptr)
212 INIT_INFO       *init_ptr;
213 {
214
215    /* Re-initialize INIT message */
216    init_ptr->text_start = 0xffffffff;
217    init_ptr->text_end = 0;
218    init_ptr->data_start = 0xffffffff;
219    init_ptr->data_end = 0;
220    init_ptr->entry_point = 0;
221    if (init_ptr->mem_stack_size == (UINT32) -1)
222        init_ptr->mem_stack_size = MEM_STACK_SIZE;
223    if (init_ptr->reg_stack_size == (UINT32) -1)
224        init_ptr->reg_stack_size = REG_STACK_SIZE;
225    init_ptr->argstring = (char *) 0;
226   return(SUCCESS);
227 };
228
229
230 INT32
231 Mini_send_init_info(info_ptr)
232 INIT_INFO       *info_ptr;
233 {
234    INT32        retval;
235
236    /* Align INIT values to word boundaries */
237    info_ptr->text_start = ALIGN32(info_ptr->text_start);
238    info_ptr->text_end = ALIGN32(info_ptr->text_end);
239    info_ptr->data_start = ALIGN32(info_ptr->data_start);
240    info_ptr->data_end = ALIGN32(info_ptr->data_end);
241    info_ptr->mem_stack_size = ALIGN32(info_ptr->mem_stack_size);
242    info_ptr->reg_stack_size = ALIGN32(info_ptr->reg_stack_size);
243
244    /* Send INIT message */
245
246    if ((retval = Mini_init (info_ptr->text_start,
247                             info_ptr->text_end,
248                             info_ptr->data_start,
249                             info_ptr->data_end,
250                             info_ptr->entry_point,
251                             info_ptr->mem_stack_size,
252                             info_ptr->reg_stack_size,
253                             info_ptr->argstring)) != SUCCESS) {
254        warning(EMINIT);
255        return(FAILURE);
256    }; 
257    return (SUCCESS);
258
259 }  /* Mini_send_init_info */
260
261
262
263 /*
264 ** This function is used to load a COFF file.  Depending on
265 ** the global variable "target_interface", data will be loaded
266 ** by either EB29K shared memory, PCEB shared memory, EB030
267 ** shared memory or serially.
268 **
269 ** In addition, the global data structure "init" is updated.
270 ** This data structure maintains the entry point and various
271 ** other target initialization parameters.
272 */
273
274 INT32
275 Mini_load_coff(filename, mspace, sym, Section, quietmode)
276    char *filename;
277    int   quietmode;
278    INT32        sym;
279    INT32        Section;
280    INT32        mspace;
281    {
282    unsigned short  COFF_sections;
283    INT32  flags;
284    INT32  memory_space;
285    INT32  address;
286    INT32  byte_count;
287    INT32  temp_byte_count;
288    INT32        bytes_ret;
289
290    struct  filehdr      COFF_header;
291    struct  aouthdr      COFF_aout_header;
292    struct  scnhdr      COFF_section_header;
293
294     if (!quietmode) {
295        fprintf(stderr, "loading %s\n", filename);
296        if (io_config.echo_mode == (INT32) TRUE)
297           fprintf(io_config.echo_file, "loading %s\n", filename);
298     }
299
300    /* Open the COFF input file (if we can) */
301    if ((coff_in = fopen(filename, FILE_OPEN_FLAG)) == NULL) {
302       warning (EMOPEN); return(FAILURE);
303    };
304
305    /* Read in COFF header information */
306    if (fread((char *)&COFF_header, sizeof(struct filehdr), 1, coff_in) != 1) {
307       fclose(coff_in); warning(EMHDR); return (FAILURE);
308    };
309
310
311    /* Is it an Am29000 COFF File? */
312    if ((COFF_header.f_magic != 0x17a) && (COFF_header.f_magic != 0x7a01) &&
313        (COFF_header.f_magic != 0x17b) && (COFF_header.f_magic != 0x7b01)) {
314       fclose(coff_in); warning (EMMAGIC); return (FAILURE);
315    }
316
317    /* Get number of COFF sections */
318    if ((COFF_header.f_magic != 0x17a) && (COFF_header.f_magic != 0x017b))
319       convert16((BYTE *) &COFF_header.f_nscns);
320    COFF_sections = (unsigned short) COFF_header.f_nscns;
321
322    /* Read in COFF a.out header information (if we can) */
323    if (COFF_header.f_opthdr > 0) {
324       if (fread((char *)&COFF_aout_header, sizeof(struct aouthdr), 
325                                                    1, coff_in) != 1) {
326          fclose(coff_in); warning (EMAOUT); return (FAILURE);
327       };
328       /* Set entry point in INIT message */
329       init_info.entry_point = COFF_aout_header.entry;
330       if ((COFF_header.f_magic != 0x17a) && (COFF_header.f_magic != 0x017b)) {
331          convert16((BYTE *) &COFF_header.f_opthdr);
332          convert32((BYTE *) &init_info.entry_point);
333       }
334    }
335
336
337    /*
338    ** Process COFF section headers
339    */
340
341    /* Process all sections */
342    while ((int) COFF_sections--) {
343
344       fseek (coff_in, (long) (FILHSZ+(int)COFF_header.f_opthdr+
345                               SCNHSZ*(COFF_header.f_nscns-COFF_sections-1)), 
346                               FROM_BEGINNING);
347
348       if (fread(&COFF_section_header, 1, SCNHSZ, coff_in) != SCNHSZ) {
349           fclose(coff_in); warning (EMSCNHDR); return (FAILURE);
350       }
351
352       if ((COFF_header.f_magic != 0x17a) && (COFF_header.f_magic != 0x017b)) {
353          convert32((BYTE *) &(COFF_section_header.s_paddr));
354          convert32((BYTE *) &(COFF_section_header.s_scnptr));
355          convert32((BYTE *) &(COFF_section_header.s_size));
356          convert32((BYTE *) &(COFF_section_header.s_flags));
357        }
358
359       address = COFF_section_header.s_paddr;
360       byte_count = COFF_section_header.s_size;
361       flags = COFF_section_header.s_flags;
362
363       /* Print downloading messages (if necessary) */
364       if ((flags == (INT32) STYP_TEXT) || (flags == (INT32) (STYP_TEXT | STYP_ABS))) {
365          memory_space = I_MEM;
366          init_info.text_start = MIN((ADDR32) address,
367                                     (ADDR32) init_info.text_start);
368          init_info.text_end = MAX((ADDR32) (address + byte_count), 
369                                   (ADDR32) init_info.text_end);
370       } else if ((flags == (INT32) STYP_DATA) || (flags == (INT32) (STYP_DATA | STYP_ABS)) ||
371           (flags == (INT32) STYP_LIT) || (flags == (INT32) (STYP_LIT | STYP_ABS)) ||
372           (flags == (INT32) STYP_BSS) || (flags == (INT32) (STYP_BSS | STYP_ABS))) {
373          memory_space = D_MEM;
374          init_info.data_start = MIN((ADDR32) address,
375                                     (ADDR32) init_info.data_start);
376          init_info.data_end = MAX((ADDR32) (address + byte_count),
377                                   (ADDR32)  init_info.data_end);
378       } else {
379          print_ign_msg(quietmode, address, byte_count);
380          flags = (INT32) 0;
381       }
382
383       if ((flags == (INT32) STYP_BSS) || (flags == (INT32) (STYP_BSS | STYP_ABS))) {
384       /* Clear BSS section */
385         if (flags & Section) {
386            print_ld_msg(flags,quietmode,address,byte_count);
387            if (Mini_fill ((INT32)  D_MEM,
388                            (ADDR32) address,
389                            (INT32)  (byte_count+3)/4,
390                            4 /* fill zeroes */,
391                            "\0\0\0") != SUCCESS)  {
392                    (void) fclose(coff_in); warning(EMFILL); return(FAILURE);
393             };
394            print_end_msg(flags,quietmode,address,byte_count);
395          }
396       } else if (flags & Section) { /* not a BSS or COmment */
397          if (flags == (INT32) (flags & Section)) {
398            fseek (coff_in, COFF_section_header.s_scnptr, FROM_BEGINNING);
399            while (byte_count > 0) {
400              temp_byte_count = MIN((INT32) byte_count, (INT32) sizeof(buffer));
401              if (fread((char *) buffer, (int) temp_byte_count, 1, coff_in) != 1) {
402                 fclose(coff_in); warning (EMSCN); return (FAILURE);
403              };
404              print_ld_msg(flags, quietmode,address, temp_byte_count);
405              /* Write to 29K memory*/
406              if (Mini_write_req ((INT32)  memory_space,
407                             (ADDR32) address,
408                             (INT32)  (temp_byte_count+3)/4,
409                             (INT16) 4, /* size */
410                             &bytes_ret,
411                             (BYTE *) buffer,
412                             (INT32) FALSE) != SUCCESS) {
413                     warning(EMWRITE); 
414                     return(FAILURE);
415              }
416              address = address + temp_byte_count;
417              byte_count = byte_count - temp_byte_count;
418            };
419            print_end_msg(flags, quietmode, COFF_section_header.s_paddr,
420                                          COFF_section_header.s_size);
421          };
422       }
423    }  /* end while */
424
425    (void) fclose(coff_in);
426    return (SUCCESS);
427
428    }   /* end Mini_loadcoff() */
429
430
431 int
432 SetSections(string)
433 char    *string;
434 {
435   int   i;
436
437   if (string[0] != '-')
438     return (-1);  /* not section options */
439
440   Sections = STYP_ABS;
441   for (i=1; string[i] != '\0'; i++) {
442      switch (string[i]) {
443        case     't':
444        case     'T':
445          Sections = Sections | STYP_TEXT;
446          break;
447        case     'd':
448        case     'D':
449          Sections = Sections | STYP_DATA;
450          break;
451        case     'b':
452        case     'B':
453          Sections = Sections | STYP_BSS;
454          break;
455        case     'l':
456        case     'L':
457          Sections = Sections | STYP_LIT;
458          break;
459        default:
460          return (EMSYNTAX);
461      }
462   }
463   return (0);
464 }
465
466 void
467 print_ld_msg(flags, mode, address, byte_count)
468 INT32   flags;
469 int     mode;
470 ADDR32  address;
471 INT32   byte_count;
472 {
473    if (!mode) {
474      if (flags & (INT32) STYP_BSS)
475        fprintf(stderr, "Clearing ");
476      else
477        fprintf(stderr, "Loading ");
478
479      if ((flags == (INT32) STYP_TEXT) || (flags == (INT32) (STYP_TEXT|STYP_ABS)))
480        fprintf(stderr, "TEXT ");
481      else if (flags & (INT32) STYP_DATA)
482        fprintf(stderr, "DATA ");
483      else if (flags & (INT32) STYP_LIT)
484        fprintf(stderr, "LIT ");
485      else if (flags & (INT32) STYP_BSS)
486        fprintf(stderr, "BSS ");
487      fprintf(stderr, "section from 0x%08lx to 0x%08lx\r", 
488                address, (ADDR32) (address+byte_count));
489    }
490 }
491
492 void
493 print_ign_msg(mode, address, byte_count)
494 int     mode;
495 ADDR32  address;
496 INT32   byte_count;
497 {
498   if (!mode) 
499     fprintf(stderr, "Ignoring COMMENT section (%ld bytes) ...\n", byte_count);
500 }
501
502 void
503 print_end_msg(flags, mode,address,size)
504 INT32   flags;
505 int     mode;
506 ADDR32  address;
507 INT32   size;
508 {
509    if (!mode) {
510      if (flags & (INT32) STYP_BSS)
511        fprintf(stderr, "Cleared  ");
512      else
513        fprintf(stderr, "Loaded  ");
514      if (io_config.echo_mode == (INT32) TRUE) {
515        if (flags & (INT32) STYP_BSS)
516          fprintf(io_config.echo_file, "Cleared  ");
517        else
518          fprintf(io_config.echo_file, "Loaded  ");
519      }
520
521      if ((flags == (INT32) STYP_TEXT) || 
522                      (flags == (INT32) (STYP_TEXT|STYP_ABS)))
523        fprintf(stderr, "TEXT ");
524      else if (flags & (INT32) STYP_DATA)
525        fprintf(stderr, "DATA ");
526      else if (flags & (INT32) STYP_LIT)
527        fprintf(stderr, "LIT ");
528      else if (flags & (INT32) STYP_BSS)
529        fprintf(stderr, "BSS ");
530
531      fprintf(stderr, "section from 0x%08lx to 0x%08lx\n", 
532                address, (ADDR32) (address+size));
533      if (io_config.echo_mode == (INT32) TRUE) {
534        if ((flags == (INT32) STYP_TEXT) || 
535                      (flags == (INT32) (STYP_TEXT|STYP_ABS)))
536          fprintf(io_config.echo_file, "TEXT ");
537        else if (flags & (INT32) STYP_DATA)
538          fprintf(io_config.echo_file, "DATA ");
539        else if (flags & (INT32) STYP_LIT)
540          fprintf(io_config.echo_file, "LIT ");
541        else if (flags & (INT32) STYP_BSS)
542          fprintf(io_config.echo_file, "BSS ");
543   
544        fprintf(io_config.echo_file, "section from 0x%08lx to 0x%08lx\n", 
545                  address, (ADDR32) (address+size));
546      }
547    }
548 }