home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / programm / programi / gcc_9112.lzh / hunk2gcc / hunk2gcc.c next >
Encoding:
C/C++ Source or Header  |  1991-10-09  |  21.3 KB  |  749 lines

  1. ;/* how to compile this thingy:
  2. gcc2 -s -O2 -mc68000 -DNDEBUG hunk2gcc.c -o hunk2gcc
  3. quit
  4. */
  5.  
  6. /*
  7.  * Convert amiga object files in the hunk format into a.out-object files.
  8.  * ALINK style (ie. concatenated) libraries are supported as well, in that
  9.  * case a collection of object files is generated, you'll have to run
  10.  * `ar rs libfoo.a obj.*' on them to make an a.out-style library out of 
  11.  * them.
  12.  *
  13.  * Currently untested are:
  14.  *  o  base-relative relocs and references
  15.  *     I'll first have to teach gnu-ld how to deal with them ;-)
  16.  *  o  conversion of load files...
  17.  *  o  common symbols, amiga objects normally don't use them, sigh
  18.  *
  19.  * Currently not implemented are:
  20.  *  o  BLINK style indexed libraries (HUNK_LIB and HUNK_INDEX). If you're
  21.  *     generating such libraries yourself, you can as well generate oldstyle
  22.  *     libraries, and the libraries from Commodore-Amiga are in ALINK format
  23.  *     (amiga.lib and friends).
  24.  *     This index-format is so weird and complicated that I didn't bother
  25.  *     long to decide not to support it. If someone volunteers (you got
  26.  *     the source;-)) please send me enhancements!
  27.  *
  28.  * V1.0  91-10-08  M.Wild  first hack
  29.  *
  30.  * This is free software. This means that I don't care what you do with it
  31.  * as long as you don't claim you wrote it. If you enhance it, please
  32.  * send me your diffs! 
  33.  * Oh, of course, you use this stuff entirely at your own risk, I'm not 
  34.  * responsible for any damage this program might cause to you, your computer,
  35.  * your data, your cat, your whateveryoucanthinkof, no warranty whatsoever is
  36.  * granted.
  37.  *
  38.  * I can be reached on internet as: wild@nessie.cs.id.ethz.ch (Markus Wild)
  39.  *
  40.  */
  41.  
  42. #include <sys/types.h>
  43. #include <sys/stat.h>
  44. #include <sys/file.h>
  45. /* sun3-a.out file */
  46. #include <a.out.h>
  47. #include <stdio.h>
  48. #include <stdlib.h>
  49.  
  50. /* This is really <dos/doshunks.h>, which is a 2.0 header file.
  51.  * You can get those 2.0 headers from CATS.
  52.  * Sorry, I'm not allowed to include them here. You may as well take the
  53.  * AmigaDOS Manual 2nd ed. (you'll miss the a4-rel hunks) or 3rd ed. and write
  54.  * the header yourself, it's not that long and difficult
  55.  */
  56. #include "doshunks.h"
  57.  
  58.  
  59. #ifndef NDEBUG
  60. #define DP(a) printf a
  61. #else
  62. #define DP(a)
  63. #endif
  64.  
  65.  
  66. extern int errno;
  67.  
  68. /* my favorite typedefs ;-)) */
  69. typedef unsigned char uchar;
  70. typedef unsigned long ulong;
  71.  
  72. ulong *file_buf = 0;
  73.  
  74. struct reloc {
  75.   /* at which offset to relocate */
  76.   int offset;
  77.   /* based on which hunk base */
  78.   int from_hunk, to_hunk;
  79.   int size;
  80.   int pcrel;
  81.   int baserel;
  82.   /* if != -1, the "to_hunk" field is not used */
  83.   int sym_num;
  84. };
  85.  
  86. /* NOTE: this symbol definition is compatible with struct nlist, and it will
  87.  * be converted into a struct nlist in 'emit_aout_obj' */
  88. struct symbol {
  89.   int   name;        /* string as offset into string table */
  90.   uchar type;
  91.   uchar pad1;        /* really n_other */
  92.   short hunk_num;    /* really n_desc  */
  93.   ulong value;
  94. };
  95.  
  96. struct table {
  97.   void *base;
  98.   int el_size;
  99.   int i;
  100.   int max_el;
  101. };
  102.  
  103. void
  104. emit_aout_file (int fd, void *text, void *data, struct exec *hdr,
  105.         struct table *ch_tab, struct table *dh_tab, struct table *bh_tab,
  106.         struct table *reloc_tab,  struct table *symbol_tab, int max_hunk);
  107.  
  108. #define TAB_START_SIZE 1024
  109.  
  110. /* advance the hunk-pointer to the next hunk. Assumes the hunk-pointer is
  111.  * pointing at the length-field currently
  112.  */
  113. static void inline 
  114. next_hunk(ulong **hp)
  115. {
  116.   /* skip over the length field and the there given length */
  117.   *hp += 1 + **hp;
  118. }
  119.  
  120. /****************************************************************************/
  121.  
  122. /* these two function maintain the string table. You may only free the last
  123.  * string allocated. (This could be done with an obstack as well, but I really
  124.  * don't need the whole functionality of an obstack, so I kept it simple ;-))
  125.  * Only use the offset, since the table itself may be reallocated.
  126.  */
  127. char *str_table = 0;
  128. int strtab_size, strtab_index;
  129.  
  130. static int inline
  131. stralloc (int len)
  132. {
  133.   int res;
  134.  
  135.   /* always include the zero terminator */
  136.   len++;
  137.  
  138.   if (! str_table)
  139.     {
  140.       strtab_size = TAB_START_SIZE;
  141.       /* start the table at index 4, leaving space to later fill in the 
  142.        * size of the table */
  143.       strtab_index = 4;
  144.       str_table = malloc (strtab_size);
  145.     }
  146.  
  147.   while (strtab_index + len > strtab_size)
  148.     {
  149.       strtab_size <<= 1;
  150.       str_table = realloc (str_table, strtab_size);
  151.     }
  152.   
  153.   res = strtab_index;
  154.   strtab_index += len;
  155.   return res;
  156. }
  157.  
  158. static void inline
  159. strfree (int str)
  160. {
  161.   strtab_index = str;
  162. }
  163.  
  164. /****************************************************************************/
  165.  
  166. static void inline
  167. add_table (struct table *tab, void *el)
  168. {
  169.   if (tab->i == tab->max_el)
  170.     {
  171.       if (! tab->base)
  172.         {
  173.           tab->max_el = TAB_START_SIZE;
  174.           tab->base = malloc (tab->max_el * tab->el_size);
  175.         }
  176.       else
  177.     {
  178.       tab->max_el <<= 1;
  179.       tab->base = realloc (tab->base, tab->max_el * tab->el_size);
  180.     }
  181.       if (! tab->base)
  182.         {
  183.       fprintf (stderr, "Out of memory adding to table.\n");
  184.       /* exit does close all outstanding files ;-) */
  185.       exit (20);
  186.     }
  187.     }
  188.   bcopy (el, (uchar *)tab->base + (tab->i++ * tab->el_size), tab->el_size);
  189. }
  190.  
  191. static void inline
  192. add_reloc (struct table *tab, int from, int to, int offset,
  193.            int size, int pcrel, int baserel, int sym_num)
  194. {
  195.   struct reloc r;
  196.  
  197. DP(("reloc: from=%d, to=%d, off=%d, size=%d, pc=%d, ba=%d, syn=%d\n",
  198.     from, to, offset, size, pcrel, baserel, sym_num));
  199.  
  200.   r.from_hunk = from;
  201.   r.to_hunk   = to;
  202.   r.offset    = offset;
  203.   r.size      = size;
  204.   r.pcrel     = pcrel;
  205.   r.baserel   = baserel;
  206.   r.sym_num   = sym_num;
  207.   add_table (tab, &r);
  208. }
  209.  
  210. static void inline
  211. add_symbol (struct table *tab, int num, ulong type, int value, char *name)
  212. {
  213.   struct symbol s;
  214.   
  215.   s.hunk_num = num;
  216.   s.type     = type >> 24;
  217.   s.value    = value;
  218.   s.name     = stralloc ((type & 0xffffff)<<2);
  219.   bcopy (name, str_table+s.name, (type & 0xffffff)<<2);
  220.   (str_table+s.name)[(type & 0xffffff)<<2] = 0;
  221.   
  222.   /* some (really stupid..) compilers mention symbols twice, once as 
  223.    * a definition, and once as an EXT_SYMB. So we really have to search 
  224.    * the symbol_table before adding an EXT_SYMB and check if a symbol of this name
  225.    * isn't already defined for this value. If this hack should slow down
  226.    * the conversion dramatically, I'll have to resort to hashing, I don't
  227.    * like that idea... */
  228.   if (s.type == EXT_SYMB)
  229.     {
  230.       int i;
  231.       
  232.       for (i = 0; i < tab->i; i++)
  233.     /* we have CSE in the compiler, right? ;-)) */
  234.     if (((struct symbol *)tab->base)[i].value    == s.value    &&
  235.         ((struct symbol *)tab->base)[i].hunk_num == s.hunk_num &&
  236.         ! strcmp (str_table+((struct symbol *)tab->base)[i].name,
  237.               str_table+s.name))
  238.       {
  239.         strfree (s.name);
  240.         return;
  241.       }
  242.     }
  243.   
  244.   add_table (tab, &s);
  245. }
  246.  
  247. /****************************************************************************/
  248.  
  249. void
  250. digest_objfile (ulong **file_pptr, ulong *max_fp)
  251. {
  252.   /* this makes it less clumsy.. */
  253.   ulong *file_ptr = *file_pptr;
  254.   static int obj_file_num = 0;
  255.   int units = 0;
  256.   /* to be filled in by the hunk_unit name parameter */
  257.   int fd = -1;
  258.   
  259.   /* buffer-pointers, where text, data & bss sections are stored.
  260.    * Currently only one hunk with size!=0 of type text/data/bss each is
  261.    * supported */
  262.   uchar *text, *data;
  263.   struct exec hdr;
  264.   
  265.   /* hunk numbers, needed to associate reloc blocks with segments */ 
  266.   int hunk_num;
  267.   static struct table code_hunks = { 0, 4, 0, 0 };
  268.   static struct table data_hunks = { 0, 4, 0, 0 };
  269.   static struct table  bss_hunks = { 0, 4, 0, 0 };
  270.  
  271.   /* static so that no initialization code is required */
  272.   static struct table reloc_tab  = { 0, sizeof (struct reloc), 0, 0 };
  273.   static struct table symbol_tab = { 0, sizeof (struct symbol), 0, 0 };
  274.  
  275.   /* (re) init tables */
  276.   strtab_index = 4;
  277.   code_hunks.i =
  278.     data_hunks.i =
  279.       bss_hunks.i =
  280.         reloc_tab.i =
  281.           symbol_tab.i = 0;
  282.   
  283.   
  284.   while (units < 2)
  285.     {
  286.       switch (*file_ptr++)
  287.         {
  288.         case HUNK_UNIT:
  289. DP(("HUNK_UNIT: units = %d\n", units));
  290.           if (units++) break;
  291. #if 0
  292.       if (! file_ptr[0])
  293. #endif
  294.         {
  295.           /* need [], not *, so that gcc allocates a fresh copy for
  296.            * mkstemp() to modify! */
  297.           char tmp_nam[] = "obj.YYYY.XXXXXX";
  298.           /* this trick makes mkstemp() lots faster ;-) */
  299.           sprintf (tmp_nam, "obj.%04d.XXXXXX", obj_file_num++);
  300.           if ((fd = mkstemp (tmp_nam)) < 0)
  301.               fprintf (stderr, "Can't create object file: %s. Ignoring it.\n",
  302.                        tmp_nam, strerror (errno));
  303.         }
  304. #if 0
  305. /* this idea was too good.. there are so many stupid (and duplicate!) names
  306.  * of program units, that this generated ridiculous results... */
  307.  
  308.       else
  309.         {
  310.           char *file_name;
  311.           file_name = alloca (file_ptr[0] + 1);
  312.           strncpy (file_name, (char *)&file_ptr[1], file_ptr[0]);
  313.           if ((fd = open (file_name, O_RDWR|O_CREAT|O_EXCL, 0666)) < 0)
  314.               fprintf (stderr, "Can't create %s: %s. Ignoring it.\n",
  315.                        file_name, strerror (errno));
  316.         }
  317. #endif
  318.  
  319.       /* init data for new object file */
  320.       text = data = 0;
  321.       bzero (&hdr, sizeof (hdr));
  322.       /* if someone want's to use'em on a sun, why shouldn't we make
  323.        * the files sun-conformant? */
  324.       hdr.a_toolversion = TV_SUN2_SUN3;
  325.       hdr.a_machtype = M_68010;    /* not restricted to 68020 only */
  326.       hdr.a_magic = OMAGIC;        /* relocatable format */
  327.       hunk_num = 0;
  328.       next_hunk (& file_ptr);
  329.       break;
  330.  
  331.         case HUNK_NAME:
  332.         case HUNK_DEBUG:
  333. DP(("HUNK_NAME/DEBUG\n"));
  334.       /* this hunk is silently ignored ;-) */
  335.       next_hunk (& file_ptr);
  336.       break;
  337.     
  338.         case HUNK_OVERLAY:
  339.           fprintf (stderr, "warning: overlay hunk ignored!\n");
  340.           next_hunk (& file_ptr);
  341.           break;
  342.         
  343.         case HUNK_BREAK:
  344.           fprintf (stderr, "warning: break hunk ignored!\n");
  345.       break;
  346.     
  347.         case HUNK_HEADER:
  348.           fprintf (stderr, "warning: load file header encountered.\n");
  349.           fprintf (stderr, "         are you sure this is an object file?\n");
  350.           /* nevertheless, we go on. perhaps some day I need this feature to
  351.            * be able to convert a loadfile into an object file?! */
  352.          
  353.           /* skip (never used) resident library names */
  354.           while (file_ptr[0]) next_hunk (& file_ptr);
  355.           /* skip null-word, table_size, F & L, and size-table */
  356.           file_ptr += 4 + (file_ptr[1] - file_ptr[2] + 1);
  357.           break;
  358.         
  359.         case HUNK_CODE:
  360. DP(("HUNK_CODE, size = $%x\n", file_ptr[0] << 2));
  361.       if (file_ptr[0])
  362.         {
  363.           /* only accept one code hunk with size != 0 */
  364.           if (hdr.a_text)
  365.             fprintf (stderr, "only one code hunk with size!=0 supported.\n");
  366.           else
  367.             {
  368.                 text = (uchar *)&file_ptr[1];
  369.                 hdr.a_text = file_ptr[0] << 2;
  370.             }
  371.         }
  372.       next_hunk (& file_ptr);
  373.       add_table (& code_hunks, &hunk_num);
  374.       hunk_num++;
  375.       break;
  376.  
  377.         case HUNK_DATA:
  378. DP(("HUNK_DATA, size = $%x\n", file_ptr[0] << 2));
  379.       if (file_ptr[0])
  380.         {
  381.           /* only accept one data hunk with size != 0 */
  382.           if (hdr.a_data)
  383.             fprintf (stderr, "only one data hunk with size!=0 supported.\n");
  384.           else
  385.             {
  386.                 data = (uchar *)&file_ptr[1];
  387.                 hdr.a_data = file_ptr[0] << 2;
  388.             }
  389.         }
  390.       next_hunk (& file_ptr);
  391.       add_table (& data_hunks, & hunk_num);
  392.       hunk_num++;
  393.       break;
  394.  
  395.         case HUNK_BSS:
  396. DP(("HUNK_BSS, size = $%x\n", file_ptr[0] << 2));
  397.       if (file_ptr[0])
  398.         {
  399.           /* only accept one bss hunk with size != 0 */
  400.           if (hdr.a_bss)
  401.             fprintf (stderr, "only one bss hunk with size!=0 supported.\n");
  402.           else
  403.             hdr.a_bss = file_ptr[0] << 2;
  404.         }
  405.       file_ptr++;
  406.       add_table (& bss_hunks, & hunk_num);
  407.       hunk_num++;
  408.       break;
  409.  
  410.         case HUNK_RELOC8:
  411.         case HUNK_RELOC16:
  412.         case HUNK_RELOC32:
  413.         /* do they work like this? don't know... */
  414.         case HUNK_DREL8:
  415.         case HUNK_DREL16:
  416.         case HUNK_DREL32:
  417.       {
  418.         int size, brel;
  419.  
  420.         brel = file_ptr[-1] >= HUNK_DREL32;
  421.         size = (brel ? HUNK_DREL8 : HUNK_RELOC8) - file_ptr[-1];
  422. DP(("HUNK_RELOC/DREL ($%x), brel = %d, size = %d\n", file_ptr[-1], brel, size));
  423.                 
  424.         while (file_ptr[0])
  425.           {
  426.             long to_reloc = file_ptr[1];
  427.             long n        = file_ptr[0];
  428.  
  429.             while (n--)
  430.               /* amiga relocs are automatically pcrel, when size < 2
  431.            * according to the AmigaDOS-Manual 2nd ed. */
  432.               add_reloc (&reloc_tab, hunk_num-1, to_reloc, file_ptr[n+2],
  433.                          size, size != 2, brel, -1);
  434.         
  435.             file_ptr += file_ptr[0] + 2;
  436.           }
  437.       }
  438.           file_ptr++;
  439.           break;
  440.         
  441.         case HUNK_SYMBOL:
  442.         case HUNK_EXT:
  443. DP(("HUNK_SYMBOL/EXT\n"));
  444.       while (file_ptr[0])
  445.         {
  446.           int n, size, brel;
  447.  
  448. DP(("  EXT_: %d, %-*.*s\n", file_ptr[0] >> 24, 
  449.     4*(file_ptr[0] & 0xffffff), 4*(file_ptr[0] & 0xffffff), &file_ptr[1]));
  450.  
  451.           switch (file_ptr[0] >> 24)
  452.             {
  453.               case EXT_SYMB:
  454.               case EXT_DEF:
  455.               case EXT_ABS:
  456.               case EXT_RES:
  457.                 add_symbol (&symbol_tab, hunk_num-1, file_ptr[0], 
  458.                     file_ptr[1+(file_ptr[0] & 0xffffff)],
  459.                     (char *)&file_ptr[1]);
  460.             file_ptr += 2+(file_ptr[0] & 0xffffff);
  461.             break;
  462.           
  463.           case EXT_COMMON:
  464.             /* first define the common symbol, then add the relocs */
  465.             add_symbol (&symbol_tab, hunk_num-1, file_ptr[0], 
  466.                      file_ptr[1+(file_ptr[0] & 0xffffff)],
  467.                     (char *)&file_ptr[1]);
  468.             file_ptr += 2+(file_ptr[0] & 0xffffff);
  469.  
  470.             /* now the references, translated into relocs */
  471.             for (n = file_ptr[0]; n--; )
  472.               add_reloc (&reloc_tab, hunk_num - 1, -1, file_ptr[n],
  473.                      2, 0, 0, symbol_tab.i - 1);
  474.             next_hunk (&file_ptr);
  475.             break;
  476.           
  477.           case EXT_REF8:
  478.           case EXT_REF16:
  479.           case EXT_REF32:
  480.           case EXT_DEXT8:
  481.           case EXT_DEXT16:
  482.           case EXT_DEXT32:
  483.             size = file_ptr[0] >> 24;
  484.             brel = size >= EXT_DEXT32;
  485.             size = (size == EXT_REF32 || size == EXT_DEXT32) ? 2 :
  486.                  ((size == EXT_REF16 || size == EXT_DEXT16) ? 1 : 0);
  487.             /* first define the symbol (as undefined ;-)), 
  488.              * then add the relocs */
  489.             add_symbol (&symbol_tab, hunk_num-1, file_ptr[0], 
  490.                     0, (char *)&file_ptr[1]);
  491.             file_ptr += 1+(file_ptr[0] & 0xffffff);
  492.  
  493.             /* now the references, translated into relocs */
  494.             for (n = file_ptr[0]; n; n--)
  495.               add_reloc (&reloc_tab, hunk_num - 1, -1, file_ptr[n],
  496.                      size, size < 2, brel, symbol_tab.i - 1);
  497.             next_hunk (&file_ptr);
  498.             break;
  499.  
  500.           default:
  501.             fprintf (stderr, 
  502.                  "Unknown symbol type %d, don't know how to handle!\n",
  503.                  file_ptr[0] >> 24);
  504.             /* can't continue, don't know how much to advance the file_ptr
  505.              * to reach the next valid hunk/block */
  506.             exit(20);
  507.             }
  508.         }
  509.       file_ptr++;
  510.       break;
  511.  
  512.         case HUNK_END:
  513. DP(("HUNK_END\n"));
  514.       break;
  515.  
  516.     default:
  517.       fprintf (stderr, "Unknown hunk type $%x, unit offset = $%x.\n",
  518.              file_ptr[-1], ((file_ptr-1)-*file_pptr) * 2);
  519.       /* can't continue, don't know how much to advance the file_ptr
  520.        * to reach the next valid hunk/block */
  521.       exit(20);
  522.     }
  523.       
  524.       if (file_ptr >= max_fp) break;
  525.     }
  526.  
  527.   *file_pptr = file_ptr >= max_fp ? max_fp : file_ptr-1;
  528.  
  529.   if (fd != -1)
  530.     emit_aout_file (fd, text, data, & hdr, 
  531.                 & code_hunks, & data_hunks, & bss_hunks,
  532.                 & reloc_tab, & symbol_tab, hunk_num);
  533. }
  534.  
  535.  
  536. void
  537. emit_aout_file (int fd, void *text, void *data, struct exec *hdr,
  538.         struct table *ch_tab, struct table *dh_tab, struct table *bh_tab,
  539.         struct table *reloc_tab,  struct table *symbol_tab, int max_hunk)
  540. {
  541.   int *code_hunks = ch_tab->base;
  542.   int *data_hunks = dh_tab->base;
  543.   int *bss_hunks  = bh_tab->base;
  544.   char htype[max_hunk];  
  545.   int i;
  546.   struct reloc *r;
  547.   struct symbol *s;
  548.   static struct table text_relocs = { 0, sizeof (struct reloc_info_68k), 0, 0 };
  549.   static struct table data_relocs = { 0, sizeof (struct reloc_info_68k), 0, 0 };
  550.  
  551.   text_relocs.i =
  552.     data_relocs.i = 0;
  553.  
  554.   /* convert hunk-numbers into N_TEXT,N_DATA,N_BSS types */
  555.   for (i = 0; i < ch_tab->i; i++) htype[code_hunks[i]] = N_TEXT;
  556.   for (i = 0; i < dh_tab->i; i++) htype[data_hunks[i]] = N_DATA;
  557.   for (i = 0; i < bh_tab->i; i++) htype[bss_hunks[i]]  = N_BSS;
  558.  
  559.   /* first conversion run. Change all hunk-numbers into N_TEXT, N_DATA and
  560.    * N_BSS rsp.
  561.    * (If you wanted to support multi-hunk files (ie. files with more than
  562.    * one code/data/bss hunk with size > 0) you'd want to do the necessary
  563.    * conversions here.)
  564.    */
  565.   for (i = 0, r = (struct reloc *)reloc_tab->base; i < reloc_tab->i; i++, r++)
  566.     {
  567.       r->from_hunk = htype[r->from_hunk];
  568.       if (r->to_hunk > -1)
  569.         r->to_hunk = htype[r->to_hunk];
  570.     }
  571.   for (i = 0, s = (struct symbol *)symbol_tab->base; i < symbol_tab->i; i++, s++)
  572.     s->hunk_num = htype[s->hunk_num];
  573.     
  574.   /* now convert the symbols into nlist's */
  575.   for (i = 0, s = (struct symbol *)symbol_tab->base; i < symbol_tab->i; i++, s++)
  576.     {
  577.       int nl_type = 0;
  578.  
  579.       switch (s->type)
  580.     {
  581.     case EXT_DEF:
  582.       /* externally visible symbol */
  583.       nl_type = N_EXT;
  584.       /* fall into */
  585.     
  586.     case EXT_SYMB:
  587.       nl_type |= s->hunk_num;
  588.       /* adjust DATA and BSS values to the one-seg model */
  589.       if (s->hunk_num == N_DATA)
  590.         s->value += hdr->a_text;
  591.       if (s->hunk_num == N_BSS)
  592.         s->value += hdr->a_text + hdr->a_data;
  593.       break;
  594.       
  595.     case EXT_ABS:
  596.       nl_type = N_ABS | N_EXT;
  597.       break;
  598.       
  599.     case EXT_COMMON:
  600.       /* ok for common as well, because the value field is only setup
  601.        * for common-symbols */
  602.  
  603.     case EXT_REF32:
  604.     case EXT_REF16:
  605.     case EXT_REF8:
  606.     case EXT_DEXT32:
  607.     case EXT_DEXT16:
  608.     case EXT_DEXT8:
  609.       nl_type = N_UNDF | N_EXT;
  610.       break;
  611.  
  612.     default:
  613.       fprintf (stderr, "What kind of symbol is THAT? (%d)\n", s->type);
  614.       break;
  615.     }
  616.  
  617.       s->type = nl_type;
  618.       s->pad1 = s->hunk_num = 0;  /* clear nl_other & nl_desc fields */
  619.     }
  620.     
  621.   /* now convert the reloc table. Adjust (like above) data/bss values to the
  622.    * one-segment model for local relocations */
  623.   for (i =  0, r = (struct reloc *)reloc_tab->base; i < reloc_tab->i; i++, r++)
  624.     {
  625.       struct reloc_info_68k rel;
  626.       uchar *core_addr;
  627.       
  628.       rel.r_address = r->offset;
  629.       core_addr = (r->from_hunk == N_TEXT) ? text : data;
  630.  
  631.       if (r->to_hunk == N_DATA)
  632.     if (r->size == 2)
  633.           *(ulong *)(core_addr + rel.r_address) += hdr->a_text;
  634.         else
  635.           fprintf (stderr, "%s reloc into N_DATA, what should I do?\n",
  636.            r->size == 1 ? "Short" : "Byte");
  637.       else if (r->to_hunk == N_BSS)
  638.     if (r->size == 2)
  639.           *(ulong *)(core_addr + rel.r_address) += hdr->a_text + hdr->a_data;
  640.         else
  641.           fprintf (stderr, "%s reloc into N_BSS, what should I do?\n",
  642.            r->size == 1 ? "Short" : "Byte");
  643.  
  644.       /* hmm... amigadog-hunks seem to do this in a strange way...
  645.        * Those relocs *are* treated as pcrel relocs by the linker (blink), 
  646.        * but they're not setup as such... geez, this hunk format.. */
  647.       if (r->pcrel)
  648.         switch (r->size)
  649.       {
  650.       case 2:
  651.         *(long *)(core_addr + rel.r_address)  -= rel.r_address;
  652.         break;
  653.  
  654.       case 1:
  655.         *(short *)(core_addr + rel.r_address) -= rel.r_address;
  656.         break;
  657.         
  658.       case 0:
  659.         *(char *)(core_addr + rel.r_address)  -= rel.r_address;
  660.         break;
  661.       }
  662.  
  663.       rel.r_symbolnum = r->sym_num > -1 ? r->sym_num : r->to_hunk;
  664.       rel.r_pcrel     = r->pcrel;
  665.       rel.r_length    = r->size;
  666.       rel.r_extern    = r->sym_num > -1;
  667.       rel.r_baserel   = r->baserel;
  668.       rel.r_jmptable = rel.r_relative = 0;
  669.  
  670. DP(("r68: %s reloc\n", (r->from_hunk == N_TEXT) ? "text" : "data"));
  671.       add_table ((r->from_hunk == N_TEXT) ? & text_relocs : & data_relocs,
  672.             &rel);
  673.     }
  674.  
  675. DP(("r68: #tr = %d, #dr = %d\n", text_relocs.i, data_relocs.i));
  676.  
  677.   /* oky, fill out the rest of the header and dump everything */
  678.   hdr->a_syms = symbol_tab->i * sizeof (struct nlist);
  679.   hdr->a_trsize = text_relocs.i * sizeof (struct reloc_info_68k);
  680.   hdr->a_drsize = data_relocs.i * sizeof (struct reloc_info_68k);
  681.   *(ulong *)str_table = strtab_index;
  682.   write (fd, (char *)hdr, sizeof (*hdr));
  683.   if (hdr->a_text) write (fd, text, hdr->a_text);
  684.   if (hdr->a_data) write (fd, data, hdr->a_data);
  685.   if (hdr->a_trsize) write (fd, text_relocs.base, hdr->a_trsize);
  686.   if (hdr->a_drsize) write (fd, data_relocs.base, hdr->a_drsize);
  687.   if (hdr->a_syms) write (fd, symbol_tab->base, hdr->a_syms);
  688.   write (fd, str_table, strtab_index);
  689.   close (fd);
  690. }
  691.  
  692.  
  693.  
  694. int
  695. main (int argc, char *argv[])
  696. {
  697.   struct stat stb;
  698.   int ret_val = 0;
  699.   ulong *obj_pointer;
  700.   
  701.   FILE *fp;
  702.  
  703.   /* loop over all arguments. Can be either
  704.    *  o  object files
  705.    *  o  libraries (ALINK style for now)
  706.    */
  707.   while (*++argv)
  708.     {
  709.       if (stat (*argv, &stb) == -1)
  710.         {
  711.           fprintf (stderr, "%s: %s\n", *argv, strerror (errno));
  712.           continue;
  713.         }
  714.       
  715.       file_buf = file_buf ? realloc (file_buf, stb.st_size) 
  716.               : malloc (stb.st_size);
  717.       if (! file_buf)
  718.         {
  719.           fprintf (stderr, "%s: can't allocate %d byte of memory.\n", 
  720.            *argv, stb.st_size);
  721.       ret_val = 20;
  722.       break;
  723.     }
  724.     
  725.       if (!(fp = fopen (*argv, "r")))
  726.         {
  727.           fprintf (stderr, "Can't open %s: %s.\n", *argv, strerror (errno));
  728.       continue;
  729.         }
  730.       
  731.       /* read the file in at once */
  732.       if (fread (file_buf, stb.st_size, 1, fp) != 1)
  733.         {
  734.       fprintf (stderr, "Can't read %s: %s.\n", *argv, strerror (errno));
  735.       fclose (fp);
  736.       continue;
  737.     }
  738.     
  739.       /* oky, now digest the file (possibly more than one object file) */
  740.       for (obj_pointer = file_buf;
  741.        obj_pointer < (ulong *)((uchar *)file_buf + stb.st_size); )
  742.     digest_objfile (&obj_pointer, (ulong *)((uchar *)file_buf + stb.st_size));
  743.  
  744.       fclose (fp);
  745.     }
  746.  
  747.   return ret_val;
  748. }
  749.