home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gdb-4.16-base.tgz / gdb-4.16-base.tar / fsf / gdb / utils / amd-udi / mondfe / yank.c < prev   
Encoding:
C/C++ Source or Header  |  1993-12-23  |  15.8 KB  |  549 lines

  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. }
  549.