Subversion Repositories Kolibri OS

Rev

Rev 6429 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  *  COFF file handling for TCC
  3.  *
  4.  *  Copyright (c) 2003, 2004 TK
  5.  *  Copyright (c) 2004 Fabrice Bellard
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20.  */
  21.  
  22. #include "tcc.h"
  23.  
  24. #define MAXNSCNS 255            /* MAXIMUM NUMBER OF SECTIONS         */
  25. #define MAX_STR_TABLE 1000000
  26. AOUTHDR o_filehdr;              /* OPTIONAL (A.OUT) FILE HEADER       */
  27.  
  28. SCNHDR section_header[MAXNSCNS];
  29.  
  30. #define MAX_FUNCS 1000
  31. #define MAX_FUNC_NAME_LENGTH 128
  32.  
  33. int nFuncs;
  34. char Func[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
  35. char AssociatedFile[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
  36. int LineNoFilePtr[MAX_FUNCS];
  37. int EndAddress[MAX_FUNCS];
  38. int LastLineNo[MAX_FUNCS];
  39. int FuncEntries[MAX_FUNCS];
  40.  
  41. int OutputTheSection(Section * sect);
  42. short int GetCoffFlags(const char *s);
  43. void SortSymbolTable(void);
  44. Section *FindSection(TCCState * s1, const char *sname);
  45.  
  46. int C67_main_entry_point;
  47.  
  48. int FindCoffSymbolIndex(const char *func_name);
  49. int nb_syms;
  50.  
  51. typedef struct {
  52.     long tag;
  53.     long size;
  54.     long fileptr;
  55.     long nextsym;
  56.     short int dummy;
  57. } AUXFUNC;
  58.  
  59. typedef struct {
  60.     long regmask;
  61.     unsigned short lineno;
  62.     unsigned short nentries;
  63.     int localframe;
  64.     int nextentry;
  65.     short int dummy;
  66. } AUXBF;
  67.  
  68. typedef struct {
  69.     long dummy;
  70.     unsigned short lineno;
  71.     unsigned short dummy1;
  72.     int dummy2;
  73.     int dummy3;
  74.     unsigned short dummy4;
  75. } AUXEF;
  76.  
  77. ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
  78. {
  79.     Section *tcc_sect;
  80.     SCNHDR *coff_sec;
  81.     int file_pointer;
  82.     char *Coff_str_table, *pCoff_str_table;
  83.     int CoffTextSectionNo, coff_nb_syms;
  84.     FILHDR file_hdr;            /* FILE HEADER STRUCTURE              */
  85.     Section *stext, *sdata, *sbss;
  86.     int i, NSectionsToOutput = 0;
  87.  
  88.     Coff_str_table = pCoff_str_table = NULL;
  89.  
  90.     stext = FindSection(s1, ".text");
  91.     sdata = FindSection(s1, ".data");
  92.     sbss = FindSection(s1, ".bss");
  93.  
  94.     nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
  95.     coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1");
  96.  
  97.     file_hdr.f_magic = COFF_C67_MAGIC;  /* magic number */
  98.     file_hdr.f_timdat = 0;      /* time & date stamp */
  99.     file_hdr.f_opthdr = sizeof(AOUTHDR);        /* sizeof(optional hdr) */
  100.     file_hdr.f_flags = 0x1143;  /* flags (copied from what code composer does) */
  101.     file_hdr.f_TargetID = 0x99; /* for C6x = 0x0099 */
  102.  
  103.     o_filehdr.magic = 0x0108;   /* see magic.h                          */
  104.     o_filehdr.vstamp = 0x0190;  /* version stamp                        */
  105.     o_filehdr.tsize = stext->data_offset;       /* text size in bytes, padded to FW bdry */
  106.     o_filehdr.dsize = sdata->data_offset;       /* initialized data "  "                */
  107.     o_filehdr.bsize = sbss->data_offset;        /* uninitialized data "   "             */
  108.     o_filehdr.entrypt = C67_main_entry_point;   /* entry pt.                          */
  109.     o_filehdr.text_start = stext->sh_addr;      /* base of text used for this file      */
  110.     o_filehdr.data_start = sdata->sh_addr;      /* base of data used for this file      */
  111.  
  112.  
  113.     // create all the section headers
  114.  
  115.     file_pointer = FILHSZ + sizeof(AOUTHDR);
  116.  
  117.     CoffTextSectionNo = -1;
  118.  
  119.     for (i = 1; i < s1->nb_sections; i++) {
  120.         coff_sec = &section_header[i];
  121.         tcc_sect = s1->sections[i];
  122.  
  123.         if (OutputTheSection(tcc_sect)) {
  124.             NSectionsToOutput++;
  125.  
  126.             if (CoffTextSectionNo == -1 && tcc_sect == stext)
  127.                 CoffTextSectionNo = NSectionsToOutput;  // rem which coff sect number the .text sect is
  128.  
  129.             strcpy(coff_sec->s_name, tcc_sect->name);   /* section name */
  130.  
  131.             coff_sec->s_paddr = tcc_sect->sh_addr;      /* physical address */
  132.             coff_sec->s_vaddr = tcc_sect->sh_addr;      /* virtual address */
  133.             coff_sec->s_size = tcc_sect->data_offset;   /* section size */
  134.             coff_sec->s_scnptr = 0;     /* file ptr to raw data for section */
  135.             coff_sec->s_relptr = 0;     /* file ptr to relocation */
  136.             coff_sec->s_lnnoptr = 0;    /* file ptr to line numbers */
  137.             coff_sec->s_nreloc = 0;     /* number of relocation entries */
  138.             coff_sec->s_flags = GetCoffFlags(coff_sec->s_name); /* flags */
  139.             coff_sec->s_reserved = 0;   /* reserved byte */
  140.             coff_sec->s_page = 0;       /* memory page id */
  141.  
  142.             file_pointer += sizeof(SCNHDR);
  143.         }
  144.     }
  145.  
  146.     file_hdr.f_nscns = NSectionsToOutput;       /* number of sections */
  147.  
  148.     // now loop through and determine file pointer locations
  149.     // for the raw data
  150.  
  151.  
  152.     for (i = 1; i < s1->nb_sections; i++) {
  153.         coff_sec = &section_header[i];
  154.         tcc_sect = s1->sections[i];
  155.  
  156.         if (OutputTheSection(tcc_sect)) {
  157.             // put raw data
  158.             coff_sec->s_scnptr = file_pointer;  /* file ptr to raw data for section */
  159.             file_pointer += coff_sec->s_size;
  160.         }
  161.     }
  162.  
  163.     // now loop through and determine file pointer locations
  164.     // for the relocation data
  165.  
  166.     for (i = 1; i < s1->nb_sections; i++) {
  167.         coff_sec = &section_header[i];
  168.         tcc_sect = s1->sections[i];
  169.  
  170.         if (OutputTheSection(tcc_sect)) {
  171.             // put relocations data
  172.             if (coff_sec->s_nreloc > 0) {
  173.                 coff_sec->s_relptr = file_pointer;      /* file ptr to relocation */
  174.                 file_pointer += coff_sec->s_nreloc * sizeof(struct reloc);
  175.             }
  176.         }
  177.     }
  178.  
  179.     // now loop through and determine file pointer locations
  180.     // for the line number data
  181.  
  182.     for (i = 1; i < s1->nb_sections; i++) {
  183.         coff_sec = &section_header[i];
  184.         tcc_sect = s1->sections[i];
  185.  
  186.         coff_sec->s_nlnno = 0;
  187.         coff_sec->s_lnnoptr = 0;
  188.  
  189.         if (s1->do_debug && tcc_sect == stext) {
  190.             // count how many line nos data
  191.  
  192.             // also find association between source file name and function
  193.             // so we can sort the symbol table
  194.  
  195.  
  196.             Stab_Sym *sym, *sym_end;
  197.             char func_name[MAX_FUNC_NAME_LENGTH],
  198.                 last_func_name[MAX_FUNC_NAME_LENGTH];
  199.             unsigned long func_addr, last_pc, pc;
  200.             const char *incl_files[INCLUDE_STACK_SIZE];
  201.             int incl_index, len, last_line_num;
  202.             const char *str, *p;
  203.  
  204.             coff_sec->s_lnnoptr = file_pointer; /* file ptr to linno */
  205.  
  206.  
  207.             func_name[0] = '\0';
  208.             func_addr = 0;
  209.             incl_index = 0;
  210.             last_func_name[0] = '\0';
  211.             last_pc = 0xffffffff;
  212.             last_line_num = 1;
  213.             sym = (Stab_Sym *) stab_section->data + 1;
  214.             sym_end =
  215.                 (Stab_Sym *) (stab_section->data +
  216.                               stab_section->data_offset);
  217.  
  218.             nFuncs = 0;
  219.             while (sym < sym_end) {
  220.                 switch (sym->n_type) {
  221.                     /* function start or end */
  222.                 case N_FUN:
  223.                     if (sym->n_strx == 0) {
  224.                         // end of function
  225.  
  226.                         coff_sec->s_nlnno++;
  227.                         file_pointer += LINESZ;
  228.  
  229.                         pc = sym->n_value + func_addr;
  230.                         func_name[0] = '\0';
  231.                         func_addr = 0;
  232.                         EndAddress[nFuncs] = pc;
  233.                         FuncEntries[nFuncs] =
  234.                             (file_pointer -
  235.                              LineNoFilePtr[nFuncs]) / LINESZ - 1;
  236.                         LastLineNo[nFuncs++] = last_line_num + 1;
  237.                     } else {
  238.                         // beginning of function
  239.  
  240.                         LineNoFilePtr[nFuncs] = file_pointer;
  241.                         coff_sec->s_nlnno++;
  242.                         file_pointer += LINESZ;
  243.  
  244.                         str =
  245.                             (const char *) stabstr_section->data +
  246.                             sym->n_strx;
  247.  
  248.                         p = strchr(str, ':');
  249.                         if (!p) {
  250.                             pstrcpy(func_name, sizeof(func_name), str);
  251.                             pstrcpy(Func[nFuncs], sizeof(func_name), str);
  252.                         } else {
  253.                             len = p - str;
  254.                             if (len > sizeof(func_name) - 1)
  255.                                 len = sizeof(func_name) - 1;
  256.                             memcpy(func_name, str, len);
  257.                             memcpy(Func[nFuncs], str, len);
  258.                             func_name[len] = '\0';
  259.                         }
  260.  
  261.                         // save the file that it came in so we can sort later
  262.                         pstrcpy(AssociatedFile[nFuncs], sizeof(func_name),
  263.                                 incl_files[incl_index - 1]);
  264.  
  265.                         func_addr = sym->n_value;
  266.                     }
  267.                     break;
  268.  
  269.                     /* line number info */
  270.                 case N_SLINE:
  271.                     pc = sym->n_value + func_addr;
  272.  
  273.                     last_pc = pc;
  274.                     last_line_num = sym->n_desc;
  275.  
  276.                     /* XXX: slow! */
  277.                     strcpy(last_func_name, func_name);
  278.  
  279.                     coff_sec->s_nlnno++;
  280.                     file_pointer += LINESZ;
  281.                     break;
  282.                     /* include files */
  283.                 case N_BINCL:
  284.                     str =
  285.                         (const char *) stabstr_section->data + sym->n_strx;
  286.                   add_incl:
  287.                     if (incl_index < INCLUDE_STACK_SIZE) {
  288.                         incl_files[incl_index++] = str;
  289.                     }
  290.                     break;
  291.                 case N_EINCL:
  292.                     if (incl_index > 1)
  293.                         incl_index--;
  294.                     break;
  295.                 case N_SO:
  296.                     if (sym->n_strx == 0) {
  297.                         incl_index = 0; /* end of translation unit */
  298.                     } else {
  299.                         str =
  300.                             (const char *) stabstr_section->data +
  301.                             sym->n_strx;
  302.                         /* do not add path */
  303.                         len = strlen(str);
  304.                         if (len > 0 && str[len - 1] != '/')
  305.                             goto add_incl;
  306.                     }
  307.                     break;
  308.                 }
  309.                 sym++;
  310.             }
  311.         }
  312.  
  313.     }
  314.  
  315.     file_hdr.f_symptr = file_pointer;   /* file pointer to symtab */
  316.  
  317.     if (s1->do_debug)
  318.         file_hdr.f_nsyms = coff_nb_syms;        /* number of symtab entries */
  319.     else
  320.         file_hdr.f_nsyms = 0;
  321.  
  322.     file_pointer += file_hdr.f_nsyms * SYMNMLEN;
  323.  
  324.     // OK now we are all set to write the file
  325.  
  326.  
  327.     fwrite(&file_hdr, FILHSZ, 1, f);
  328.     fwrite(&o_filehdr, sizeof(o_filehdr), 1, f);
  329.  
  330.     // write section headers
  331.     for (i = 1; i < s1->nb_sections; i++) {
  332.         coff_sec = &section_header[i];
  333.         tcc_sect = s1->sections[i];
  334.  
  335.         if (OutputTheSection(tcc_sect)) {
  336.             fwrite(coff_sec, sizeof(SCNHDR), 1, f);
  337.         }
  338.     }
  339.  
  340.     // write raw data
  341.     for (i = 1; i < s1->nb_sections; i++) {
  342.         coff_sec = &section_header[i];
  343.         tcc_sect = s1->sections[i];
  344.  
  345.         if (OutputTheSection(tcc_sect)) {
  346.             fwrite(tcc_sect->data, tcc_sect->data_offset, 1, f);
  347.         }
  348.     }
  349.  
  350.     // write relocation data
  351.     for (i = 1; i < s1->nb_sections; i++) {
  352.         coff_sec = &section_header[i];
  353.         tcc_sect = s1->sections[i];
  354.  
  355.         if (OutputTheSection(tcc_sect)) {
  356.             // put relocations data
  357.             if (coff_sec->s_nreloc > 0) {
  358.                 fwrite(tcc_sect->reloc,
  359.                        coff_sec->s_nreloc * sizeof(struct reloc), 1, f);
  360.             }
  361.         }
  362.     }
  363.  
  364.  
  365.     // group the symbols in order of filename, func1, func2, etc
  366.     // finally global symbols
  367.  
  368.     if (s1->do_debug)
  369.         SortSymbolTable();
  370.  
  371.     // write line no data
  372.  
  373.     for (i = 1; i < s1->nb_sections; i++) {
  374.         coff_sec = &section_header[i];
  375.         tcc_sect = s1->sections[i];
  376.  
  377.         if (s1->do_debug && tcc_sect == stext) {
  378.             // count how many line nos data
  379.  
  380.  
  381.             Stab_Sym *sym, *sym_end;
  382.             char func_name[128], last_func_name[128];
  383.             unsigned long func_addr, last_pc, pc;
  384.             const char *incl_files[INCLUDE_STACK_SIZE];
  385.             int incl_index, len, last_line_num;
  386.             const char *str, *p;
  387.  
  388.             LINENO CoffLineNo;
  389.  
  390.             func_name[0] = '\0';
  391.             func_addr = 0;
  392.             incl_index = 0;
  393.             last_func_name[0] = '\0';
  394.             last_pc = 0;
  395.             last_line_num = 1;
  396.             sym = (Stab_Sym *) stab_section->data + 1;
  397.             sym_end =
  398.                 (Stab_Sym *) (stab_section->data +
  399.                               stab_section->data_offset);
  400.  
  401.             while (sym < sym_end) {
  402.                 switch (sym->n_type) {
  403.                     /* function start or end */
  404.                 case N_FUN:
  405.                     if (sym->n_strx == 0) {
  406.                         // end of function
  407.  
  408.                         CoffLineNo.l_addr.l_paddr = last_pc;
  409.                         CoffLineNo.l_lnno = last_line_num + 1;
  410.                         fwrite(&CoffLineNo, 6, 1, f);
  411.  
  412.                         pc = sym->n_value + func_addr;
  413.                         func_name[0] = '\0';
  414.                         func_addr = 0;
  415.                     } else {
  416.                         // beginning of function
  417.  
  418.                         str =
  419.                             (const char *) stabstr_section->data +
  420.                             sym->n_strx;
  421.  
  422.  
  423.                         p = strchr(str, ':');
  424.                         if (!p) {
  425.                             pstrcpy(func_name, sizeof(func_name), str);
  426.                         } else {
  427.                             len = p - str;
  428.                             if (len > sizeof(func_name) - 1)
  429.                                 len = sizeof(func_name) - 1;
  430.                             memcpy(func_name, str, len);
  431.                             func_name[len] = '\0';
  432.                         }
  433.                         func_addr = sym->n_value;
  434.                         last_pc = func_addr;
  435.                         last_line_num = -1;
  436.  
  437.                         // output a function begin
  438.  
  439.                         CoffLineNo.l_addr.l_symndx =
  440.                             FindCoffSymbolIndex(func_name);
  441.                         CoffLineNo.l_lnno = 0;
  442.  
  443.                         fwrite(&CoffLineNo, 6, 1, f);
  444.                     }
  445.                     break;
  446.  
  447.                     /* line number info */
  448.                 case N_SLINE:
  449.                     pc = sym->n_value + func_addr;
  450.  
  451.  
  452.                     /* XXX: slow! */
  453.                     strcpy(last_func_name, func_name);
  454.  
  455.                     // output a line reference
  456.  
  457.                     CoffLineNo.l_addr.l_paddr = last_pc;
  458.  
  459.                     if (last_line_num == -1) {
  460.                         CoffLineNo.l_lnno = sym->n_desc;
  461.                     } else {
  462.                         CoffLineNo.l_lnno = last_line_num + 1;
  463.                     }
  464.  
  465.                     fwrite(&CoffLineNo, 6, 1, f);
  466.  
  467.                     last_pc = pc;
  468.                     last_line_num = sym->n_desc;
  469.  
  470.                     break;
  471.  
  472.                     /* include files */
  473.                 case N_BINCL:
  474.                     str =
  475.                         (const char *) stabstr_section->data + sym->n_strx;
  476.                   add_incl2:
  477.                     if (incl_index < INCLUDE_STACK_SIZE) {
  478.                         incl_files[incl_index++] = str;
  479.                     }
  480.                     break;
  481.                 case N_EINCL:
  482.                     if (incl_index > 1)
  483.                         incl_index--;
  484.                     break;
  485.                 case N_SO:
  486.                     if (sym->n_strx == 0) {
  487.                         incl_index = 0; /* end of translation unit */
  488.                     } else {
  489.                         str =
  490.                             (const char *) stabstr_section->data +
  491.                             sym->n_strx;
  492.                         /* do not add path */
  493.                         len = strlen(str);
  494.                         if (len > 0 && str[len - 1] != '/')
  495.                             goto add_incl2;
  496.                     }
  497.                     break;
  498.                 }
  499.                 sym++;
  500.             }
  501.         }
  502.     }
  503.  
  504.     // write symbol table
  505.     if (s1->do_debug) {
  506.         int k;
  507.         struct syment csym;
  508.         AUXFUNC auxfunc;
  509.         AUXBF auxbf;
  510.         AUXEF auxef;
  511.         int i;
  512.         Elf32_Sym *p;
  513.         const char *name;
  514.         int nstr;
  515.         int n = 0;
  516.  
  517.         Coff_str_table = (char *) tcc_malloc(MAX_STR_TABLE);
  518.         pCoff_str_table = Coff_str_table;
  519.         nstr = 0;
  520.  
  521.         p = (Elf32_Sym *) symtab_section->data;
  522.  
  523.  
  524.         for (i = 0; i < nb_syms; i++) {
  525.  
  526.             name = symtab_section->link->data + p->st_name;
  527.  
  528.             for (k = 0; k < 8; k++)
  529.                 csym._n._n_name[k] = 0;
  530.  
  531.             if (strlen(name) <= 8) {
  532.                 strcpy(csym._n._n_name, name);
  533.             } else {
  534.                 if (pCoff_str_table - Coff_str_table + strlen(name) >
  535.                     MAX_STR_TABLE - 1)
  536.                     tcc_error("String table too large");
  537.  
  538.                 csym._n._n_n._n_zeroes = 0;
  539.                 csym._n._n_n._n_offset =
  540.                     pCoff_str_table - Coff_str_table + 4;
  541.  
  542.                 strcpy(pCoff_str_table, name);
  543.                 pCoff_str_table += strlen(name) + 1;    // skip over null
  544.                 nstr++;
  545.             }
  546.  
  547.             if (p->st_info == 4) {
  548.                 // put a filename symbol
  549.                 csym.n_value = 33;      // ?????
  550.                 csym.n_scnum = N_DEBUG;
  551.                 csym.n_type = 0;
  552.                 csym.n_sclass = C_FILE;
  553.                 csym.n_numaux = 0;
  554.                 fwrite(&csym, 18, 1, f);
  555.                 n++;
  556.  
  557.             } else if (p->st_info == 0x12) {
  558.                 // find the function data
  559.  
  560.                 for (k = 0; k < nFuncs; k++) {
  561.                     if (strcmp(name, Func[k]) == 0)
  562.                         break;
  563.                 }
  564.  
  565.                 if (k >= nFuncs) {
  566.                     tcc_error("debug info can't find function: %s", name);
  567.                 }
  568.                 // put a Function Name
  569.  
  570.                 csym.n_value = p->st_value;     // physical address
  571.                 csym.n_scnum = CoffTextSectionNo;
  572.                 csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0);
  573.                 csym.n_sclass = C_EXT;
  574.                 csym.n_numaux = 1;
  575.                 fwrite(&csym, 18, 1, f);
  576.  
  577.                 // now put aux info
  578.  
  579.                 auxfunc.tag = 0;
  580.                 auxfunc.size = EndAddress[k] - p->st_value;
  581.                 auxfunc.fileptr = LineNoFilePtr[k];
  582.                 auxfunc.nextsym = n + 6;        // tktk
  583.                 auxfunc.dummy = 0;
  584.                 fwrite(&auxfunc, 18, 1, f);
  585.  
  586.                 // put a .bf
  587.  
  588.                 strcpy(csym._n._n_name, ".bf");
  589.                 csym.n_value = p->st_value;     // physical address
  590.                 csym.n_scnum = CoffTextSectionNo;
  591.                 csym.n_type = 0;
  592.                 csym.n_sclass = C_FCN;
  593.                 csym.n_numaux = 1;
  594.                 fwrite(&csym, 18, 1, f);
  595.  
  596.                 // now put aux info
  597.  
  598.                 auxbf.regmask = 0;
  599.                 auxbf.lineno = 0;
  600.                 auxbf.nentries = FuncEntries[k];
  601.                 auxbf.localframe = 0;
  602.                 auxbf.nextentry = n + 6;
  603.                 auxbf.dummy = 0;
  604.                 fwrite(&auxbf, 18, 1, f);
  605.  
  606.                 // put a .ef
  607.  
  608.                 strcpy(csym._n._n_name, ".ef");
  609.                 csym.n_value = EndAddress[k];   // physical address  
  610.                 csym.n_scnum = CoffTextSectionNo;
  611.                 csym.n_type = 0;
  612.                 csym.n_sclass = C_FCN;
  613.                 csym.n_numaux = 1;
  614.                 fwrite(&csym, 18, 1, f);
  615.  
  616.                 // now put aux info
  617.  
  618.                 auxef.dummy = 0;
  619.                 auxef.lineno = LastLineNo[k];
  620.                 auxef.dummy1 = 0;
  621.                 auxef.dummy2 = 0;
  622.                 auxef.dummy3 = 0;
  623.                 auxef.dummy4 = 0;
  624.                 fwrite(&auxef, 18, 1, f);
  625.  
  626.                 n += 6;
  627.  
  628.             } else {
  629.                 // try an put some type info
  630.  
  631.                 if ((p->st_other & VT_BTYPE) == VT_DOUBLE) {
  632.                     csym.n_type = T_DOUBLE;     // int
  633.                     csym.n_sclass = C_EXT;
  634.                 } else if ((p->st_other & VT_BTYPE) == VT_FLOAT) {
  635.                     csym.n_type = T_FLOAT;
  636.                     csym.n_sclass = C_EXT;
  637.                 } else if ((p->st_other & VT_BTYPE) == VT_INT) {
  638.                     csym.n_type = T_INT;        // int
  639.                     csym.n_sclass = C_EXT;
  640.                 } else if ((p->st_other & VT_BTYPE) == VT_SHORT) {
  641.                     csym.n_type = T_SHORT;
  642.                     csym.n_sclass = C_EXT;
  643.                 } else if ((p->st_other & VT_BTYPE) == VT_BYTE) {
  644.                     csym.n_type = T_CHAR;
  645.                     csym.n_sclass = C_EXT;
  646.                 } else {
  647.                     csym.n_type = T_INT;        // just mark as a label
  648.                     csym.n_sclass = C_LABEL;
  649.                 }
  650.  
  651.  
  652.                 csym.n_value = p->st_value;
  653.                 csym.n_scnum = 2;
  654.                 csym.n_numaux = 1;
  655.                 fwrite(&csym, 18, 1, f);
  656.  
  657.                 auxfunc.tag = 0;
  658.                 auxfunc.size = 0x20;
  659.                 auxfunc.fileptr = 0;
  660.                 auxfunc.nextsym = 0;
  661.                 auxfunc.dummy = 0;
  662.                 fwrite(&auxfunc, 18, 1, f);
  663.                 n++;
  664.                 n++;
  665.  
  666.             }
  667.  
  668.             p++;
  669.         }
  670.     }
  671.  
  672.     if (s1->do_debug) {
  673.         // write string table
  674.  
  675.         // first write the size
  676.         i = pCoff_str_table - Coff_str_table;
  677.         fwrite(&i, 4, 1, f);
  678.  
  679.         // then write the strings
  680.         fwrite(Coff_str_table, i, 1, f);
  681.  
  682.         tcc_free(Coff_str_table);
  683.     }
  684.  
  685.     return 0;
  686. }
  687.  
  688.  
  689.  
  690. // group the symbols in order of filename, func1, func2, etc
  691. // finally global symbols
  692.  
  693. void SortSymbolTable(void)
  694. {
  695.     int i, j, k, n = 0;
  696.     Elf32_Sym *p, *p2, *NewTable;
  697.     char *name, *name2;
  698.  
  699.     NewTable = (Elf32_Sym *) tcc_malloc(nb_syms * sizeof(Elf32_Sym));
  700.  
  701.     p = (Elf32_Sym *) symtab_section->data;
  702.  
  703.  
  704.     // find a file symbol, copy it over
  705.     // then scan the whole symbol list and copy any function
  706.     // symbols that match the file association
  707.  
  708.     for (i = 0; i < nb_syms; i++) {
  709.         if (p->st_info == 4) {
  710.             name = (char *) symtab_section->link->data + p->st_name;
  711.  
  712.             // this is a file symbol, copy it over
  713.  
  714.             NewTable[n++] = *p;
  715.  
  716.             p2 = (Elf32_Sym *) symtab_section->data;
  717.  
  718.             for (j = 0; j < nb_syms; j++) {
  719.                 if (p2->st_info == 0x12) {
  720.                     // this is a func symbol
  721.  
  722.                     name2 =
  723.                         (char *) symtab_section->link->data + p2->st_name;
  724.  
  725.                     // find the function data index
  726.  
  727.                     for (k = 0; k < nFuncs; k++) {
  728.                         if (strcmp(name2, Func[k]) == 0)
  729.                             break;
  730.                     }
  731.  
  732.                     if (k >= nFuncs) {
  733.                         tcc_error("debug (sort) info can't find function: %s", name2);
  734.                     }
  735.  
  736.                     if (strcmp(AssociatedFile[k], name) == 0) {
  737.                         // yes they match copy it over
  738.  
  739.                         NewTable[n++] = *p2;
  740.                     }
  741.                 }
  742.                 p2++;
  743.             }
  744.         }
  745.         p++;
  746.     }
  747.  
  748.     // now all the filename and func symbols should have been copied over
  749.     // copy all the rest over (all except file and funcs)
  750.  
  751.     p = (Elf32_Sym *) symtab_section->data;
  752.     for (i = 0; i < nb_syms; i++) {
  753.         if (p->st_info != 4 && p->st_info != 0x12) {
  754.             NewTable[n++] = *p;
  755.         }
  756.         p++;
  757.     }
  758.  
  759.     if (n != nb_syms)
  760.         tcc_error("Internal Compiler error, debug info");
  761.  
  762.     // copy it all back
  763.  
  764.     p = (Elf32_Sym *) symtab_section->data;
  765.     for (i = 0; i < nb_syms; i++) {
  766.         *p++ = NewTable[i];
  767.     }
  768.  
  769.     tcc_free(NewTable);
  770. }
  771.  
  772.  
  773. int FindCoffSymbolIndex(const char *func_name)
  774. {
  775.     int i, n = 0;
  776.     Elf32_Sym *p;
  777.     char *name;
  778.  
  779.     p = (Elf32_Sym *) symtab_section->data;
  780.  
  781.     for (i = 0; i < nb_syms; i++) {
  782.  
  783.         name = (char *) symtab_section->link->data + p->st_name;
  784.  
  785.         if (p->st_info == 4) {
  786.             // put a filename symbol
  787.             n++;
  788.         } else if (p->st_info == 0x12) {
  789.  
  790.             if (strcmp(func_name, name) == 0)
  791.                 return n;
  792.  
  793.             n += 6;
  794.  
  795.             // put a Function Name
  796.  
  797.             // now put aux info
  798.  
  799.             // put a .bf
  800.  
  801.             // now put aux info
  802.  
  803.             // put a .ef
  804.  
  805.             // now put aux info
  806.  
  807.         } else {
  808.             n += 2;
  809.         }
  810.  
  811.         p++;
  812.     }
  813.  
  814.     return n;                   // total number of symbols
  815. }
  816.  
  817. int OutputTheSection(Section * sect)
  818. {
  819.     const char *s = sect->name;
  820.  
  821.     if (!strcmp(s, ".text"))
  822.         return 1;
  823.     else if (!strcmp(s, ".data"))
  824.         return 1;
  825.     else
  826.         return 0;
  827. }
  828.  
  829. short int GetCoffFlags(const char *s)
  830. {
  831.     if (!strcmp(s, ".text"))
  832.         return STYP_TEXT | STYP_DATA | STYP_ALIGN | 0x400;
  833.     else if (!strcmp(s, ".data"))
  834.         return STYP_DATA;
  835.     else if (!strcmp(s, ".bss"))
  836.         return STYP_BSS;
  837.     else if (!strcmp(s, ".stack"))
  838.         return STYP_BSS | STYP_ALIGN | 0x200;
  839.     else if (!strcmp(s, ".cinit"))
  840.         return STYP_COPY | STYP_DATA | STYP_ALIGN | 0x200;
  841.     else
  842.         return 0;
  843. }
  844.  
  845. Section *FindSection(TCCState * s1, const char *sname)
  846. {
  847.     Section *s;
  848.     int i;
  849.  
  850.     for (i = 1; i < s1->nb_sections; i++) {
  851.         s = s1->sections[i];
  852.  
  853.         if (!strcmp(sname, s->name))
  854.             return s;
  855.     }
  856.  
  857.     tcc_error("could not find section %s", sname);
  858.     return 0;
  859. }
  860.  
  861. ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
  862. {
  863. // tktk TokenSym *ts;
  864.  
  865.     FILE *f;
  866.     unsigned int str_size;
  867.     char *Coff_str_table, *name;
  868.     int i, k;
  869.     struct syment csym;
  870.     char name2[9];
  871.     FILHDR file_hdr;            /* FILE HEADER STRUCTURE              */
  872.  
  873.     f = fdopen(fd, "rb");
  874.     if (!f) {
  875.         tcc_error("Unable to open .out file for input");
  876.     }
  877.  
  878.     if (fread(&file_hdr, FILHSZ, 1, f) != 1)
  879.         tcc_error("error 1 reading .out file for input");
  880.  
  881.     if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1)
  882.         tcc_error("error 2 reading .out file for input");
  883.  
  884.     // first read the string table
  885.  
  886.     if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET))
  887.         tcc_error("error 3 reading .out file for input");
  888.  
  889.     if (fread(&str_size, sizeof(int), 1, f) != 1)
  890.         tcc_error("error 4 reading .out file for input");
  891.  
  892.  
  893.     Coff_str_table = (char *) tcc_malloc(str_size);
  894.  
  895.     if (fread(Coff_str_table, str_size - 4, 1, f) != 1)
  896.         tcc_error("error 5 reading .out file for input");
  897.  
  898.     // read/process all the symbols
  899.  
  900.     // seek back to symbols
  901.  
  902.     if (fseek(f, file_hdr.f_symptr, SEEK_SET))
  903.         tcc_error("error 6 reading .out file for input");
  904.  
  905.     for (i = 0; i < file_hdr.f_nsyms; i++) {
  906.         if (fread(&csym, SYMESZ, 1, f) != 1)
  907.             tcc_error("error 7 reading .out file for input");
  908.  
  909.         if (csym._n._n_n._n_zeroes == 0) {
  910.             name = Coff_str_table + csym._n._n_n._n_offset - 4;
  911.         } else {
  912.             name = csym._n._n_name;
  913.  
  914.             if (name[7] != 0) {
  915.                 for (k = 0; k < 8; k++)
  916.                     name2[k] = name[k];
  917.  
  918.                 name2[8] = 0;
  919.  
  920.                 name = name2;
  921.             }
  922.         }
  923. //              if (strcmp("_DAC_Buffer",name)==0)  // tktk
  924. //                      name[0]=0;
  925.  
  926.         if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) || ((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) || (csym.n_type == 0x4 && csym.n_sclass == 0x2) || (csym.n_type == 0x8 && csym.n_sclass == 0x2) || // structures
  927.             (csym.n_type == 0x18 && csym.n_sclass == 0x2) ||    // pointer to structure
  928.             (csym.n_type == 0x7 && csym.n_sclass == 0x2) ||     // doubles
  929.             (csym.n_type == 0x6 && csym.n_sclass == 0x2))       // floats
  930.         {
  931.             // strip off any leading underscore (except for other main routine)
  932.  
  933.             if (name[0] == '_' && strcmp(name, "_main") != 0)
  934.                 name++;
  935.  
  936.             tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value);
  937.         }
  938.         // skip any aux records
  939.  
  940.         if (csym.n_numaux == 1) {
  941.             if (fread(&csym, SYMESZ, 1, f) != 1)
  942.                 tcc_error("error reading .out file for input");
  943.             i++;
  944.         }
  945.     }
  946.  
  947.     return 0;
  948. }
  949.