home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / binutils-2.7-src.tgz / tar.out / fsf / binutils / bfd / amigaos.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  79KB  |  2,831 lines

  1. /* BFD back-end for Commodore-Amiga AmigaOS binaries.
  2.    Copyright (C) 1990-1994 Free Software Foundation, Inc.
  3.    Contributed by Leonard Norrgard.  Partially based on the bout
  4.    and ieee BFD backends and Markus Wild's tool hunk2gcc.
  5.    Revised and updated by Stephan Thesing 
  6.  
  7. This file is part of BFD, the Binary File Descriptor library.
  8.  
  9. This program is free software; you can redistribute it and/or modify
  10. it under the terms of the GNU General Public License as published by
  11. the Free Software Foundation; either version 2 of the License, or
  12. (at your option) any later version.
  13.  
  14. This program is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. GNU General Public License for more details.
  18.  
  19. You should have received a copy of the GNU General Public License
  20. along with this program; if not, write to the Free Software
  21. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  22.  
  23. /*
  24. SECTION
  25.     amiga back end
  26.  
  27. This section describes the overall structure of the Amiga BFD back end.
  28. The linker stuff can be found in @xref{amigalink}.
  29. @menu
  30. @* implementation::
  31. @* amigalink::
  32. @end menu
  33.  
  34. INODE
  35. implementation, amigalink, amiga, amiga
  36.  
  37.  
  38. SECTION
  39.     implementation
  40.  
  41.  
  42. The need for a port of the bfd library for Amiga style object (hunk) files
  43. arose by the desire to port the GNU debugger gdb to the Amiga.
  44. Also, the linker ld should be updated to the current version (2.5.2).
  45. @@*
  46. This port bases on the work done by Leonard Norrgard, who started porting
  47. gdb. Raphael Luebbert, who supports the ixemul.library, has also worked on
  48. implementing the needed @code{ptrace()} system call and gas2.5.
  49.  
  50. @menu
  51. @* not supported::
  52. @* Does it work ?::
  53. @* TODO::
  54. @end menu
  55.  
  56. INODE
  57. not supported, Does it work ?,implementation,implementation
  58. SUBSECTION
  59.     not supported
  60.  
  61. Currently, the implementation does not support Amiga link library files, like
  62. e.g. amiga.lib. This may be added in a later version, if anyone starts work
  63. on it, or I find some time for it.
  64.  
  65. The handling of the symbols in hunk files is a little bit broken:
  66.       o The symbols in a load file are totally ignored at the moment, so gdb and gprof
  67.             do not work.
  68.       o The symbols of a object module (Hunk file, starting with HUNK_UNIT) are read in
  69.             correctly, but HUNK_SYMBOL hunks are also ignored.
  70.  
  71. The reason for this is the following:
  72. Amiga symbol hunks do not allow for much information. Only a name and a value are allowed.
  73. On the other hand, a.out format carries along much more information (see, e.g. the
  74. entry on set symbols in the ld manual). The old linker copied this information into
  75. a HUNK_DEBUG hunk. Now there is the choice:
  76.     o ignoring the debug hunk, read in only HUNK_SYMBOL definitions => extra info is lost.
  77.     o read in the debug hunk and use the information therein => How can clashs between the
  78.           information in the debug hunk and HUNK_SYMBOL or HUNK_EXT hunks be avoided ?
  79. I haven't decided yet, what to do about this.
  80.  
  81.  
  82. Although bfd allows to link together object modules of different flavours, 
  83. producing a.out style executables does not work on Amiga :-)
  84. It should, however, be possible to create a.out files with the -r option of ld
  85. (incremental link).
  86.  
  87. INODE 
  88. Does it work ?,TODO ,not supported , implementation
  89. SUBSECTION
  90.     Does it work ?
  91.  
  92. Currently, the following utilities work:
  93.     o objdump
  94.     o objcopy
  95.     o strip
  96.     o nm
  97.     o ar
  98.     o gas
  99.  
  100.     
  101. INODE
  102. TODO, , Does it work ?, implementation
  103. SUBSECTION
  104.     TODO
  105.  
  106.     o fix fixme:s
  107.  
  108. @*
  109. BFD:
  110.     o add flag to say if the format allows multiple sections with the
  111.           same name.  Fix bfd_get_section_by_name() and bfd_make_section()
  112.           accordingly.
  113.        
  114.     o dumpobj.c: the disassembler: use relocation record data to find symbolic
  115.            names of addresses, when available.  Needs new routine where one can
  116.           specify the source section of the symbol to be printed as well as some
  117.           rewrite of the disassemble functions.
  118.        
  119. */
  120.  
  121. #include "bfd.h"
  122. #include "bfdlink.h"
  123. #include "sysdep.h"
  124. #include "libbfd.h"
  125. #include "libamiga.h"
  126.  
  127. typedef struct aout_symbol {
  128.   asymbol symbol;
  129.   short desc;
  130.   char other;
  131.   unsigned char type;
  132. } aout_symbol_type;
  133.  
  134. #include "aout/aout64.h"
  135.  
  136. #define GL(x) bfd_get_32 (abfd, (bfd_byte *) (x))
  137. #define GW(x) bfd_get_16 (abfd, (bfd_byte *) (x))
  138.  
  139. #define DEBUG_AMIGA 10000
  140.  
  141. #if DEBUG_AMIGA
  142. #include <varargs.h>
  143. static void error_print(va_alist)
  144. va_dcl
  145. {
  146. va_list args;
  147. char *fmt;
  148.  
  149. va_start(args);
  150. fmt=va_arg(args,char *);
  151.  
  152. (void)vfprintf(stderr,fmt,args);
  153. va_end(args);
  154. }
  155.  
  156. #define DPRINT(L,x) if (L>=DEBUG_AMIGA) error_print x
  157. #else
  158. #define DPRINT(L,x) 
  159. #endif
  160.  
  161. static boolean amiga_digest_file ();
  162. static boolean amiga_mkobject ();
  163.  
  164. reloc_howto_type howto_hunk_reloc8 =
  165. {
  166.   HUNK_RELOC8, /* type */
  167.   0,           /* rightshift */
  168.   0,           /* size */
  169.   8,           /* bitsize */
  170.   true,        /* pc_relative */
  171.   0,           /* bitpos */
  172.   complain_overflow_bitfield,  /* complain_on_overflow */
  173.   0,           /* special_function */
  174.   "reloc8",    /* textual name */
  175.   false,       /* partial_inplace? */
  176.   0x000000ff,  /* src_mask */
  177.   0x000000ff,  /* dst_mask */
  178.   true         /* pcrel_offset */
  179. };
  180.  
  181. reloc_howto_type howto_hunk_reloc16 =
  182. {HUNK_RELOC16,0,1,16,true,0,complain_overflow_bitfield,0,"reloc16",false,0x0000ffff,0x0000ffff,true};
  183.  
  184. reloc_howto_type howto_hunk_reloc32 =
  185. {HUNK_RELOC32,0,2,32,true,0,complain_overflow_bitfield,0,"reloc32",false,0xffffffff,0xffffffff,true};
  186.  
  187. reloc_howto_type howto_hunk_drel8 =
  188. {HUNK_DREL8,0,0,8,false,0,complain_overflow_bitfield,0,"drel8",false,0x000000ff,0x000000ff,false};
  189.  
  190. reloc_howto_type howto_hunk_drel16 =
  191. {HUNK_DREL16,0,1,16,false,0,complain_overflow_bitfield,0,"drel16",false,0x0000ffff,0x0000ffff,false};
  192.  
  193. reloc_howto_type howto_hunk_drel32 =
  194. {HUNK_DREL32,0,2,32,false,0,complain_overflow_bitfield,0,"drel32",false,0xffffffff,0xffffffff,false};
  195.  
  196. reloc_howto_type *amiga_howto_array[2][3] =
  197. {
  198.   { &howto_hunk_reloc8, &howto_hunk_reloc16, &howto_hunk_reloc32 },
  199.   { &howto_hunk_drel8, &howto_hunk_drel16, &howto_hunk_drel32 }
  200. };
  201.  
  202. /* The following are gross hacks that need to be fixed.  The problem is
  203.    that the linker unconditionally references these values without
  204.    going through any of bfd's standard interface.  Thus they need to
  205.    be defined in a bfd module that is included in *all* configurations,
  206.    and are currently in bfd.c, otherwise linking the linker will fail
  207.    on non-Amiga target configurations. */
  208. /* This one is used by the linker and tells us, if a debug hunk should be
  209.    written out*/
  210. extern int write_debug_hunk;
  211. /* This is also used by the linker to set the attribute of sections */
  212. extern int amiga_attribute;
  213.  
  214. static const struct bfd_target *
  215. amiga_object_p (abfd)
  216.      bfd *abfd;
  217. {
  218.   char buf[8];
  219.   unsigned int x;
  220.   struct stat stat_buffer;
  221.  
  222.   /* An Amiga object file must be at least 8 bytes long.  */
  223.   if (bfd_read ((PTR) buf, 1, 8, abfd) != 8)
  224.     {
  225.       bfd_set_error(bfd_error_wrong_format);
  226.       return 0;
  227.     }
  228.  
  229.   /* Does it look like an Amiga object file?  */
  230.   x = GL(buf);
  231.   if ((x != HUNK_UNIT) && (x != HUNK_HEADER))
  232.     {
  233.       /* Not an Amiga file.  */
  234.       bfd_set_error(bfd_error_wrong_format);
  235.       return 0;
  236.     }
  237.  
  238.   /* So far it seems to be an Amiga file.  Now slurp it
  239.      in and examine it closer.  */
  240.   stat_buffer.st_size=0;
  241.   if ((-1 == fstat (fileno ((FILE *) abfd->iostream), &stat_buffer))||(stat_buffer.st_size%4!=0))
  242.     { /* Error during system call or file length is not multiple of longword size */
  243.       bfd_set_error((stat_buffer.st_size%4==0)?bfd_error_system_call:bfd_error_wrong_format);
  244.       return 0;
  245.     }
  246.  
  247.   /* Can't fail and return (but must be declared boolean to suit
  248.      other bfd requirements).  */
  249.   (void) amiga_mkobject (abfd);
  250.  
  251.   AMIGA_DATA(abfd)->IsLoadFile = (x == HUNK_HEADER);
  252.  
  253.   AMIGA_DATA(abfd)->first_byte = (unsigned long *) bfd_alloc (abfd, stat_buffer.st_size);
  254.   bfd_seek (abfd, 0, SEEK_SET);
  255.   
  256.   if (bfd_read (AMIGA_DATA(abfd)->first_byte, 1, stat_buffer.st_size, abfd)!=stat_buffer.st_size)
  257.     {
  258.       /* Error, reading file */
  259.      return (const struct bfd_target *)0;
  260.    }
  261.  
  262.   AMIGA_DATA(abfd)->file_pointer = AMIGA_DATA(abfd)->first_byte;
  263.   AMIGA_DATA(abfd)->file_end = (unsigned long *)((unsigned char *)AMIGA_DATA(abfd)->first_byte + stat_buffer.st_size);
  264.  
  265.   if (!amiga_digest_file (abfd))
  266.     {
  267.       /* Something went wrong.  */
  268.       return (const struct bfd_target *) 0;
  269.     }
  270.  
  271.   /* Set default architecture to m68k:68000.  */
  272.   /* So we can link on 68000 AMIGAs..... */
  273.   abfd->arch_info = bfd_scan_arch ("m68k:68000");
  274.  
  275.   return (abfd->xvec);
  276. }
  277.  
  278. /* Skip over the hunk length longword + the number of longwords given there.  */
  279. #define next_hunk(abfd) \
  280.   { AMIGA_DATA(abfd)->file_pointer += 1 + GL(AMIGA_DATA(abfd)->file_pointer); }
  281.  
  282. static asection *
  283. amiga_get_section_by_hunk_number (abfd, hunk_number)
  284.      bfd *abfd;
  285.       long hunk_number;
  286. {
  287.   /* A cache, so we don't have to search the entire list every time.  */
  288.   static asection *last_reference;
  289.   asection *p;
  290.  
  291.   switch(hunk_number)
  292.     {
  293.     case -1:
  294.       return bfd_abs_section_ptr;
  295.       break;
  296.     case -2:
  297.       return bfd_und_section_ptr;
  298.       break;
  299.     case -3: 
  300.       return bfd_com_section_ptr;
  301.       break;
  302.     default:
  303.       if (last_reference)
  304.     if (last_reference->target_index == hunk_number)
  305.       return last_reference;
  306.       for (p = abfd->sections; p != NULL; p = p->next)
  307.     if (p->target_index == hunk_number)
  308.       {
  309.         last_reference = p;
  310.         return p;
  311.       }
  312.       BFD_FAIL();
  313.       return (asection *) 0;
  314.     }
  315. return NULL;
  316. }
  317.  
  318. static boolean
  319. amiga_add_reloc (abfd, section, offset, symbol, howto, target_hunk)
  320.      bfd *abfd;
  321.      asection *section;
  322.      bfd_size_type offset;
  323.      amiga_symbol_type * symbol;
  324.      reloc_howto_type *howto;
  325.      long target_hunk;
  326. {
  327.   amiga_reloc_type *reloc;
  328.  
  329.   reloc = (amiga_reloc_type *) bfd_zalloc (abfd, sizeof (amiga_reloc_type));
  330.   reloc->next = 0;
  331.  
  332.   if (!reloc)
  333.     {
  334.       bfd_set_error(bfd_error_no_memory);
  335.       return(false);
  336.     }
  337.  
  338.  
  339.   abfd -> flags |= HAS_RELOC;
  340.   section -> flags |= SEC_RELOC;
  341.  
  342.   if (amiga_per_section(section)->reloc_tail)
  343.     amiga_per_section(section)->reloc_tail->next = reloc;
  344.   else
  345.     section->relocation = (struct reloc_cache_entry *) reloc;
  346.   amiga_per_section(section)->reloc_tail = reloc;
  347.   amiga_per_section(section)->reloc_tail->next = NULL;
  348.   reloc->relent.address = offset;
  349.   reloc->relent.addend = 0;
  350.   reloc->relent.howto = howto;
  351.  
  352.   if (symbol==NULL) /* relative to section */
  353.     reloc->symbol=(amiga_symbol_type *)(amiga_get_section_by_hunk_number(abfd,target_hunk)->symbol);
  354.   else
  355.     reloc->symbol = symbol;
  356.   reloc->relent.sym_ptr_ptr=(asymbol **)(&(reloc->symbol));
  357.   reloc->target_hunk = target_hunk;
  358.  
  359.   return true;
  360. }
  361.  
  362. /* BFD doesn't currently allow multiple sections with the same
  363.    name, so we try a little harder to get a unique name.  */
  364. asection *
  365. amiga_make_unique_section (abfd, name)
  366.      bfd *abfd;
  367.      CONST char *name;
  368. {
  369.   asection *section;
  370.  
  371.  
  372.   section = bfd_make_section (abfd, name);
  373.   if (!section)
  374.     {
  375.       int i = 1;
  376.       char *new_name;
  377.  
  378.       new_name = bfd_alloc (abfd, strlen(name) + 3);
  379.  
  380.       /* We try to come up with an original name (since BFD
  381.      currently requires all sections to have different names).  */
  382.       while (!section && (i<=99))
  383.     {
  384.       sprintf (new_name, "%s_%u", name, i++);
  385.       section = bfd_make_section (abfd, new_name);
  386.     }
  387.  
  388.       if (!section)
  389.     {
  390.       /* Complain about the given name.  */
  391.       bfd_set_error(bfd_error_bad_value);
  392.       return 0;
  393.     }
  394.     }
  395.  
  396.  
  397.   return section;
  398. }
  399.  
  400.  
  401.  
  402. #if DEBUG_AMIGA
  403. #define DPRINTHUNK(x)   fprintf (stderr,"Processing %s hunk (0x%x)...",\
  404.       (x) == HUNK_UNIT ? "HUNK_UNIT" :\
  405.       (x) == HUNK_NAME ? "HUNK_NAME" :\
  406.       (x) == HUNK_DEBUG ? "HUNK_DEBUG" :\
  407.       (x) == HUNK_OVERLAY ? "HUNK_OVERLAY" :\
  408.       (x) == HUNK_BREAK ? "HUNK_BREAK" :\
  409.       (x) == HUNK_HEADER ? "HUNK_HEADER" :\
  410.       (x) == HUNK_CODE ? "HUNK_CODE" :\
  411.       (x) == HUNK_DATA ? "HUNK_DATA" :\
  412.       (x) == HUNK_BSS ? "HUNK_BSS" :\
  413.       (x) == HUNK_RELOC8 ? "HUNK_RELOC8" :\
  414.       (x) == HUNK_RELOC16 ? "HUNK_RELOC16" :\
  415.       (x) == HUNK_RELOC32 ? "HUNK_RELOC32" :\
  416.       (x) == HUNK_DREL8 ? "HUNK_DREL8" :\
  417.       (x) == HUNK_DREL16 ? "HUNK_DREL16" :\
  418.       (x) == HUNK_DREL32 ? "HUNK_DREL32" :\
  419.       (x) == HUNK_SYMBOL ? "HUNK_SYMBOL" :\
  420.       (x) == HUNK_EXT ? "HUNK_EXT" :\
  421.       (x) == HUNK_END ? "HUNK_END" :\
  422.       (x) == HUNK_LIB ? "HUNK_LIB" :\
  423.       (x) == HUNK_INDEX ? "HUNK_INDEX" :\
  424.       "*unknown*",(x))
  425. #define DPRINTHUNKEND fprintf(stderr,"...done\n")
  426. #else
  427. #define DPRINTHUNK(x) 
  428. #define DPRINTHUNKEND 
  429. #endif
  430.  
  431. static boolean amiga_read_unit(bfd *abfd);
  432. static boolean amiga_read_load(bfd *abfd);
  433. static boolean amiga_handle_cdb_hunk(bfd *abfd, int ht,int hn,int ha,int hs);
  434. static boolean amiga_handle_rest(bfd *abfd,asection *cs,boolean isload);
  435.  
  436. static boolean
  437. amiga_digest_file (abfd)
  438.      bfd *abfd;
  439. {
  440.   amiga_data_type *amiga_data = AMIGA_DATA(abfd);
  441.   int hunk_type;
  442.  
  443.  
  444.   hunk_type = HUNK_VALUE(GL(amiga_data->file_pointer++));
  445.  
  446.  
  447.   switch (hunk_type)
  448.     {
  449.     case HUNK_UNIT:
  450.  
  451.       /* Read in the unit  */
  452.       if (!amiga_read_unit(abfd)) /* Error */
  453.     return(false);
  454.       break;
  455.       
  456.     case HUNK_HEADER:
  457.       /* This is a load file, well it should not be used with linking,
  458.      but it is possible to do so, so always allow it. */
  459.       
  460.       /* Read in the load file */
  461.       if (!amiga_read_load(abfd)) /* Error */
  462.     {
  463.       return(false);
  464.     }
  465.       break;
  466.     } /* of switch hunk_type */
  467.  
  468.  
  469.  
  470.   /* If there is any trailing garbage, i.e. we are not at EOF, then
  471.      complain and reject the file... */
  472.   if (amiga_data->file_pointer!=amiga_data->file_end) /* ooops */
  473.     {
  474.       bfd_set_error(bfd_error_wrong_format);
  475.       return(false);
  476.     }
  477.  
  478.   /* Success, all went well... */
  479.  return(true);
  480.  
  481. }/* of amiga_digest_file */
  482.  
  483.  
  484. /* If we read over the end of file, error */
  485. #define TOO_LARGE_P   if (amiga_data->file_pointer>=amiga_data->file_end)\
  486.     {DPRINT(10,("Overflow of file pointer\n"));bfd_set_error(bfd_error_wrong_format);return false;}
  487.  
  488.  
  489. /* Read in Unit file */
  490. /* file pointer is located after the HUNK_UNIT LW */
  491. static boolean amiga_read_unit(bfd *abfd)
  492. {
  493.  
  494.   amiga_data_type *amiga_data = AMIGA_DATA(abfd);
  495.   int hunk_type;
  496.   int hunk_number=0;
  497.   int hunk_attribute=0;
  498.  
  499.   /* The unit name, if given, has no meaning to us, 
  500.      since we are not in an archive. 
  501.      We could set the name of abfd to the name, but that 
  502.      may cause confusion... 
  503.      So just ignore the unit name 
  504.      ST 121194 */
  505.   amiga_data->file_pointer+=GL(amiga_data->file_pointer)+1;
  506.  
  507.   TOO_LARGE_P;
  508.  
  509.  
  510.   while (true)
  511.     {
  512.  
  513.       /* Now there may be CODE, DATA, BSS, SYMBOL, DEBUG, RELOC Hunks */
  514.       
  515.       hunk_type=HUNK_VALUE(GL(amiga_data->file_pointer)); /* Type of next hunk */
  516.       hunk_attribute=HUNK_ATTRIBUTE(GL(amiga_data->file_pointer++));
  517.       hunk_attribute=(hunk_attribute==HUNK_ATTR_CHIP)?
  518.     MEMF_CHIP:(hunk_attribute==HUNK_ATTR_FAST)?MEMF_FAST:0;
  519.       
  520.     
  521.       switch(hunk_type)
  522.     {
  523.     case HUNK_DEBUG:
  524.       /* We ignore debug hunks in UNITS, for now, because gnu's debug hunks
  525.          are only added by the linker to LOAD files.....
  526.          And anyhow, a.out format can keep much more information for units...
  527.          */
  528.       amiga_data->file_pointer+=1+GL(amiga_data->file_pointer);
  529.       TOO_LARGE_P;
  530.  
  531.       break;
  532.  
  533.     case HUNK_NAME:
  534.     case HUNK_CODE:
  535.     case HUNK_DATA:
  536.     case HUNK_BSS:
  537.       /* Handle this hunk, including relocs, etc.
  538.          The finishing HUNK_END is consumed by the routine
  539.          */
  540.       if (!amiga_handle_cdb_hunk(abfd,hunk_type,hunk_number++,hunk_attribute,-1))
  541.         return(false);
  542.  
  543.       break;
  544.  
  545.     default:
  546.       /* Something very nasty happened:
  547.          Illegal Hunk occured....
  548.          */
  549.       bfd_set_error(bfd_error_wrong_format);
  550.       return(false);
  551.       break;
  552.       
  553.     }/* Of switch hunk_type */
  554.  
  555.  
  556.       /* Last HUNK ?*/
  557.       if (amiga_data->file_pointer==amiga_data->file_end)
  558.     return true;
  559.  
  560.       TOO_LARGE_P; /* Sanity check */
  561.   
  562.       /* Next hunk */
  563.     }/* Of while */
  564.  
  565. }/* Of amiga_read_unit */
  566.  
  567.  
  568. #define MAX_HUNKS 200 /* Max # of hunks. we can read in.. */
  569.  
  570. /* Read a load file */
  571. static boolean amiga_read_load(bfd *abfd)
  572. {
  573.   amiga_data_type *amiga_data = AMIGA_DATA(abfd); 
  574.   int hunk_sizes[MAX_HUNKS]; /* If there are more hunks than this, we are in trouble...*/
  575.   int hunk_attributes[MAX_HUNKS];
  576.   int hunk_number=0;
  577.   int hunk_type;
  578.   int max_hunk_number=0;
  579.   int i,n;
  580.  
  581.   TOO_LARGE_P; /* Sanity */
  582.  
  583.   /* Read hunk lengths (and memory attributes...) */
  584.   /* Read in each hunk */
  585.  
  586.   /* If there are resident libs: abort (obsolete feature) */
  587.   if (GL(amiga_data->file_pointer++)!=0)
  588.     {
  589.       bfd_set_error(bfd_error_wrong_format);
  590.       return(false);
  591.     }
  592.  
  593.   TOO_LARGE_P;
  594.  
  595.   max_hunk_number=GL(amiga_data->file_pointer++);
  596.  
  597.   if (max_hunk_number > 3)
  598.     {
  599.       bfd_set_error (bfd_error_wrong_format);
  600.       return false;
  601.     }
  602.  
  603.   if (max_hunk_number>MAX_HUNKS) /* Ooops... too much hunks */
  604.     {
  605.       fprintf(stderr,"File %s has too many hunks (%d), aborting\n",abfd->filename,max_hunk_number);
  606.       bfd_set_error(bfd_error_wrong_format);
  607.       return(false);
  608.     }
  609.  
  610.   /* Sanity */
  611.   if ((max_hunk_number<1)||
  612.       (amiga_data->file_pointer+max_hunk_number+2>=amiga_data->file_end))
  613.     {
  614.       bfd_set_error(bfd_error_wrong_format);
  615.       return(false);
  616.     }
  617.  
  618.   /* Num of root hunk must be 0 */
  619.   if (GL(amiga_data->file_pointer++)!=0)
  620.     {
  621.       bfd_set_error(bfd_error_wrong_format);
  622.       return(false);
  623.     }
  624.  
  625.   /* Num of last hunk must be mhn-1 */
  626.   if (GL(amiga_data->file_pointer++)!=max_hunk_number-1)
  627.     {
  628.       bfd_set_error(bfd_error_wrong_format);
  629.       return(false);
  630.     }
  631.  
  632.   /* Now, read in sizes and memory attributes */
  633.  
  634.   for (i=0;i<max_hunk_number;i++)
  635.     {
  636.       n=HUNK_VALUE(GL(amiga_data->file_pointer));
  637.       hunk_sizes[i]=n<<2;
  638.       n=HUNK_ATTRIBUTE(GL(amiga_data->file_pointer++));
  639.       if (n==HUNK_ATTR_FOLLOWS) /* Attribute is in next long */
  640.     hunk_attributes[i]=GL(amiga_data->file_pointer++);
  641.       else
  642.     hunk_attributes[i]= (n==HUNK_ATTR_CHIP)?MEMF_CHIP:
  643.       (n==HUNK_ATTR_FAST)?MEMF_FAST:0;
  644.     }
  645.  
  646.   TOO_LARGE_P; /* Sanity */
  647.  
  648.   /* We can now read in all the hunks */
  649.  
  650.   for (hunk_number=0;hunk_number<max_hunk_number;hunk_number++)
  651.     {
  652.       hunk_type=HUNK_VALUE(GL(amiga_data->file_pointer++));
  653.  
  654.  
  655.       /* This may be HUNK_NAME, CODE, BSS, DEBUG, DATA */
  656.  
  657.       switch(hunk_type)
  658.     {
  659.     case HUNK_NAME:
  660.     case HUNK_CODE:
  661.     case HUNK_DATA:
  662.     case HUNK_BSS:
  663.     case HUNK_DEBUG:
  664.       if (
  665.       !amiga_handle_cdb_hunk(abfd,hunk_type,hunk_number,hunk_attributes[hunk_number],
  666.                 hunk_sizes[hunk_number]))
  667.         {
  668.           bfd_set_error(bfd_error_wrong_format);
  669.           return(false);
  670.         }
  671.       break;
  672.  
  673.     default:
  674.       /* illegal hunk */
  675.       bfd_set_error(bfd_error_wrong_format);
  676.       return(false);
  677.       break;
  678.     }/* Of switch */
  679.  
  680.  
  681.     }
  682.  
  683.   /* dgv -- if the end is not reached at this point, there could be a
  684.      HUNK_DEBUG here */
  685.  
  686.   if (amiga_data->file_pointer!=amiga_data->file_end) {
  687.     hunk_type = HUNK_VALUE (GL(amiga_data->file_pointer++));
  688.     if (hunk_type == HUNK_DEBUG) {
  689.       if (
  690.       !amiga_handle_cdb_hunk(abfd,hunk_type,0,0,0))
  691.         {
  692.           bfd_set_error(bfd_error_wrong_format);
  693.           return(false);
  694.         }
  695.     }
  696.   }
  697.  
  698.   if (amiga_data->file_pointer!=amiga_data->file_end)
  699.     {
  700.       bfd_set_error(bfd_error_wrong_format);
  701.       return(false);
  702.     }
  703.  
  704.   return(true);
  705.  
  706. }/* Of amiga_read_load */
  707.  
  708.  
  709. /* Handle NAME, CODE, DATA, BSS, DEBUG Hunks */
  710. static boolean 
  711. amiga_handle_cdb_hunk(bfd *abfd, 
  712.               int hunk_type, 
  713.               int hunk_number,
  714.               int hunk_attribute, /* MEMF_CHIP, etc. */
  715.               int hunk_size)
  716. /* If hunk_size==-1, then we are digesting a HUNK_UNIT */
  717. {
  718.   amiga_data_type *amiga_data = AMIGA_DATA(abfd);
  719.   char *current_name=NULL;
  720.   int len;
  721.   asection *current_section=NULL;
  722.   int load_file = (hunk_size!=-1);
  723.  
  724.   if (hunk_type==HUNK_NAME) /* get name */
  725.     {
  726.       len=HUNK_VALUE(GL(amiga_data->file_pointer))<<2; /* Length */
  727.       /* DIRTY: We move the name 4 bytes towards the beginning of the file,
  728.             overwriting the length,
  729.             and end it with a '\0' */
  730.       strncpy((char *)amiga_data->file_pointer,(char *)(amiga_data->file_pointer+1),len);
  731.       *(((char *)amiga_data->file_pointer)+len)='\0';
  732.       current_name=(char *)amiga_data->file_pointer;
  733.       amiga_data->file_pointer+=1+(len>>2); /* Advance */
  734.  
  735.       TOO_LARGE_P;
  736.  
  737.       hunk_type=HUNK_VALUE(GL(amiga_data->file_pointer++)); /* Next hunk */
  738.       if (hunk_size==-1) /* In a unit ==> Get attribute from file */
  739.     {
  740.       hunk_attribute=HUNK_ATTRIBUTE(GL(amiga_data->file_pointer-1));
  741.       hunk_attribute=(hunk_attribute==HUNK_ATTR_CHIP)?MEMF_CHIP:
  742.                  (hunk_attribute==HUNK_ATTR_FAST)?MEMF_FAST:0;
  743.     }
  744.     }
  745.   else /* Set curent name to something appropriate */
  746.     current_name=(hunk_type==HUNK_CODE)?".text":
  747.                  (hunk_type==HUNK_BSS)?".bss":".data";
  748.       
  749.  
  750.  
  751.   /* file_pointer is now at  hunk_type */
  752.  
  753.   switch (hunk_type)
  754.     {
  755.     case HUNK_CODE:
  756.       /* Handle code hunk */
  757.  
  758.       len=HUNK_VALUE(GL(amiga_data->file_pointer++))<<2; /* Length of section */
  759.       if (len>hunk_size) /* len may be shorter than hunk_size... */ 
  760.     if (hunk_size==-1)
  761.       hunk_size=len;
  762.     else
  763.       {
  764.         bfd_set_error(bfd_error_wrong_format);
  765.         return false;
  766.       }
  767.  
  768.       /* Make new section */
  769.       current_section=amiga_make_unique_section(abfd,current_name);
  770.       if (!current_section)
  771.     return false;
  772.  
  773.       current_section->filepos=(char *)(amiga_data->file_pointer)-(char *)amiga_data->first_byte;
  774.       current_section->_raw_size=hunk_size;
  775.       current_section->_cooked_size=hunk_size;
  776.       current_section->target_index=hunk_number;
  777.       bfd_set_section_flags(abfd,current_section, 
  778.                 SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS);
  779.  
  780.       amiga_per_section(current_section)->real_length=len; /* real size */
  781.       amiga_per_section(current_section)->attribute=hunk_attribute;
  782.  
  783.       amiga_data->file_pointer+=(len>>2); /* next hunk */
  784.  
  785.       if (!amiga_handle_rest(abfd,current_section,load_file))
  786.     return false;
  787.       
  788.       break;
  789.  
  790.     case HUNK_DATA:
  791.       /* Handle data hunk */
  792.  
  793.       len=HUNK_VALUE(GL(amiga_data->file_pointer++))<<2; /* Length of section */
  794.       if (len>hunk_size) /* len may be shorter than hunk_size... */ 
  795.     if (hunk_size==-1)
  796.       hunk_size=len;
  797.     else
  798.       {
  799.         bfd_set_error(bfd_error_wrong_format);
  800.         return false;
  801.       }
  802.  
  803.       current_section=amiga_make_unique_section(abfd,current_name);
  804.       if (!current_section)
  805.     return false;
  806.  
  807.       current_section->filepos=(char *)amiga_data->file_pointer-(char *)amiga_data->first_byte;
  808.       current_section->_raw_size=hunk_size;
  809.       current_section->_cooked_size=hunk_size;
  810.       current_section->target_index=hunk_number;
  811.       bfd_set_section_flags(abfd,current_section, 
  812.                 SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS);
  813.  
  814.       amiga_per_section(current_section)->real_length=len; /* real size */
  815.       amiga_per_section(current_section)->attribute=hunk_attribute;
  816.  
  817.       amiga_data->file_pointer+=(len>>2); /* next hunk */
  818.       if (!amiga_handle_rest(abfd,current_section,load_file))
  819.     return false;
  820.       break;
  821.  
  822.     case HUNK_BSS:
  823.       /* Handle bss hunk */
  824.       
  825.       len=HUNK_VALUE(GL(amiga_data->file_pointer++))<<2; /* Length of section */
  826.       if (len>hunk_size) /* len may be shorter than hunk_size... */ 
  827.     if (hunk_size==-1)
  828.       hunk_size=len;
  829.     else
  830.       {
  831.         bfd_set_error(bfd_error_wrong_format);
  832.         return false;
  833.       }
  834.  
  835.       current_section=amiga_make_unique_section(abfd,current_name);
  836.       if (!current_section)
  837.     return false;
  838.  
  839.       current_section->filepos=(file_ptr)-1;
  840.       current_section->_raw_size=hunk_size;
  841.       current_section->_cooked_size=hunk_size;
  842.       current_section->target_index=hunk_number;
  843.  
  844.       bfd_set_section_flags(abfd,current_section, SEC_ALLOC );
  845.  
  846.       amiga_per_section(current_section)->real_length=len; /* real size */
  847.       amiga_per_section(current_section)->attribute=hunk_attribute;
  848.  
  849.       if (!amiga_handle_rest(abfd,current_section,load_file))
  850.     return false;
  851.       break;
  852.  
  853.     case HUNK_DEBUG:
  854.       if (hunk_size==-1) /* We are digesting a unit ==> ignore debug hunks */
  855.     {
  856.       amiga_data->file_pointer+=1+GL(amiga_data->file_pointer);
  857.       return(true);
  858.     }
  859.       /* We are digesting a load file, so check for gnu debug hunk, else ignore it */
  860.       /* format of gnu debug hunk is:
  861.           HUNK_DEBUG
  862.               N
  863.             0413.L    Magic number
  864.       symtabsize
  865.       strtabsize
  866.       symtabdata  [length=symtabsize]
  867.       strtabdata  [length=strtabsize]
  868.           [pad bytes]
  869.       */
  870.  
  871.       if (GL(amiga_data->file_pointer+1)==0413) /* GNU DEBUG HUNK */
  872.     {
  873.       /*FIXME: we should add the symbols in the debug hunk to symtab... */
  874.       
  875.       amiga_data->symtab_size=GL(amiga_data->file_pointer+2);
  876.       amiga_data->stringtab_size=GL(amiga_data->file_pointer+3);
  877.       adata(abfd).sym_filepos=
  878.         (file_ptr)((char *)(amiga_data->file_pointer +4)-(char *)amiga_data->first_byte);
  879.       adata(abfd).str_filepos=adata(abfd).sym_filepos+amiga_data->symtab_size;
  880.       amiga_data->file_pointer+=1+GL(amiga_data->file_pointer);
  881.     }
  882.       else /* NOT GNU DEBUG HUNK... */
  883.     {
  884.       /* ignore it */
  885.       amiga_data->file_pointer+=1+GL(amiga_data->file_pointer);
  886.     }
  887.  
  888.       /* there has to be an HUNK_END here... */
  889.       if (GL(amiga_data->file_pointer++)!=HUNK_END)
  890.     {
  891.       bfd_set_error(bfd_error_wrong_format);
  892.       return(false);
  893.     }
  894.       break;
  895.  
  896.     default:
  897.       bfd_set_error(bfd_error_wrong_format);
  898.       return false;
  899.       break;
  900.     }/* of switch hunk_type */
  901.  
  902.  
  903.   return(true);
  904.  
  905. }/* Of amiga_handle_cdb_hunk */
  906.  
  907.  
  908. /* Handle rest of a hunk 
  909.    I.e.: Relocs, EXT, SYMBOLS... */
  910. static boolean amiga_handle_rest(bfd *abfd, asection *current_section, boolean isload)
  911. {
  912.   amiga_data_type *amiga_data = AMIGA_DATA(abfd);
  913.   int hunk_type;
  914.   int type;
  915.   int len;
  916.   int n;
  917.   unsigned long **p;
  918.   struct amiga_raw_symbol *sp=NULL;
  919.  
  920.  
  921.   while (1)/* loop */
  922.     {
  923.       hunk_type=GL(amiga_data->file_pointer++);
  924.  
  925.  
  926.       switch (hunk_type)
  927.     {
  928.     case HUNK_END: /* Reached end */
  929.       return(true); /* Done */
  930.       break;
  931.  
  932.     case HUNK_DEBUG: /* skip debug info -- dgv */
  933.       amiga_data->file_pointer += 1+GL (amiga_data->file_pointer);
  934.       break;
  935.  
  936.       /* Relocs.... */
  937.     case HUNK_RELOC8:
  938.     case HUNK_RELOC16:
  939.     case HUNK_RELOC32:
  940.     case HUNK_DREL8:
  941.     case HUNK_DREL16:
  942.     case HUNK_DREL32:
  943.       /* We leave them alone, but attach them to the section,
  944.          so we can read them in later.....*/
  945.       
  946.       /* But we already set the flags HAS_RELOC, SEC_RELOC */
  947.       /* We also maintain the reloc count */
  948.       /* This is simply done by adding all addresses of relocs to an array in the section */
  949.       p=amiga_per_section(current_section)->raw_relocs;
  950.       if (amiga_per_section(current_section)->max_raw_relocs<=
  951.           amiga_per_section(current_section)->num_raw_relocs) /* allocate more space */
  952.         {
  953.           if (p==NULL)
  954.         {
  955.           p=(unsigned long **)malloc(sizeof(unsigned long *)*10); /* initial */
  956.           amiga_per_section(current_section)->max_raw_relocs=10;
  957.           amiga_per_section(current_section)->num_raw_relocs=0;
  958.         }
  959.           else /* More space */
  960.         {
  961.           p=(unsigned long **)realloc((void *)p,
  962.                  sizeof(unsigned long *)*(amiga_per_section(current_section)->max_raw_relocs+30));
  963.           amiga_per_section(current_section)->max_raw_relocs+=30;
  964.         }
  965.  
  966.           if (p==NULL)
  967.         {
  968.           bfd_set_error(bfd_error_no_memory);
  969.           return(false);
  970.         }
  971.           amiga_per_section(current_section)->raw_relocs=p;
  972.         }
  973.       p[amiga_per_section(current_section)->num_raw_relocs++]=amiga_data->file_pointer-1;
  974.       
  975.       abfd->flags|=HAS_RELOC;
  976.       current_section->flags|=SEC_RELOC;
  977.  
  978.       /* Advance file_pointer */
  979.       while ((n=GL(amiga_data->file_pointer++)))
  980.         {
  981.           amiga_data->file_pointer+=1+n;
  982.           current_section->reloc_count+=n;
  983.           TOO_LARGE_P;    /* Sanity check */
  984.         }
  985.  
  986.       break;
  987.  
  988.       /* Symbol definition */
  989.     case HUNK_SYMBOL:
  990.       /* In a unit, we ignore these, since all symbol information comes with HUNK_EXT,
  991.          in a load file, these are added */
  992.       if (!isload)
  993.         {
  994.           int foo;
  995.           
  996.           while ((foo=GL(amiga_data->file_pointer))!=0)
  997.         amiga_data->file_pointer+=foo+2;
  998.           amiga_data->file_pointer++;
  999.           break;
  1000.         }
  1001.       /* We add these, by falling through... */
  1002.  
  1003.     case HUNK_EXT:
  1004.       /* We leave these alone, until they are requested by the user */
  1005.       sp=amiga_per_section(current_section)->last;
  1006.       
  1007.       if (sp==NULL) /* First one added */
  1008.         {
  1009.           amiga_per_section(current_section)->last=amiga_per_section(current_section)->first=
  1010.         (struct amiga_raw_symbol *)(amiga_data->file_pointer-1);
  1011.           *(amiga_data->file_pointer-1)=0;
  1012.         }
  1013.       else
  1014.         {
  1015.           sp->next=(struct amiga_raw_symbol *)(amiga_data->file_pointer-1);
  1016.           *(amiga_data->file_pointer-1)=0;
  1017.           amiga_per_section(current_section)->last=sp->next;
  1018.         }
  1019.       /* skip these */
  1020.  
  1021.       while ((n=GL(amiga_data->file_pointer)))
  1022.         {
  1023.           amiga_data->file_pointer++;
  1024.  
  1025.           type=(n>>24)&0xff;
  1026.           len=n&0xffffff;
  1027.           
  1028.           amiga_data->file_pointer+=len; /* skip name */
  1029.  
  1030.           switch(type)
  1031.         {
  1032.         case EXT_SYMB: /* Symbol hunks are relative to hunk start... */
  1033.         case EXT_DEF: /* def relative to hunk */
  1034.         case EXT_ABS: /* def absolute */
  1035.           abfd->flags|=HAS_SYMS; /* We have symbols */
  1036.           abfd->symcount++;
  1037.           amiga_data->file_pointer++;
  1038.           break;
  1039.  
  1040.         case EXT_REF8: /* 8 bit ref */
  1041.         case EXT_REF16: /* 16 bit ref */
  1042.         case EXT_REF32: /* 32 bit ref */
  1043.         case EXT_DEXT8: /* 8 bit base relative ref */
  1044.         case EXT_DEXT16: /* 16 bit " "*/
  1045.         case EXT_DEXT32: /* 32 bit " " */
  1046.           abfd->flags|=HAS_SYMS;
  1047.           n=GL(amiga_data->file_pointer);
  1048.           if (n)
  1049.             {
  1050.               abfd->flags|=HAS_RELOC;
  1051.               current_section->flags|=SEC_RELOC;
  1052.             }
  1053.           current_section->reloc_count+=n;
  1054.           amiga_data->file_pointer+=1+n;
  1055.           break;
  1056.           
  1057.         case EXT_COMMON: /* Common ref/def */
  1058.           abfd->flags|=HAS_SYMS;
  1059.           abfd->symcount++;
  1060.           n=GL(amiga_data->file_pointer+1);
  1061.           if (n)
  1062.             {
  1063.               abfd->flags|=HAS_RELOC;
  1064.               current_section->flags|=SEC_RELOC;
  1065.             }
  1066.               
  1067.           current_section->reloc_count+=n;
  1068.           amiga_data->file_pointer+=2+n;
  1069.           break;
  1070.           
  1071.         default: /* error */
  1072.           
  1073.           bfd_set_error(bfd_error_wrong_format);
  1074.           return false;
  1075.           break;
  1076.         }/* of switch type */
  1077.           
  1078.         }/* Of while */
  1079.       amiga_data->file_pointer++;
  1080.  
  1081.       break;
  1082.  
  1083.  
  1084.     default: /* error */
  1085.  
  1086.       bfd_set_error(bfd_error_wrong_format);
  1087.       return(false);
  1088.       break;
  1089.     }/* Of switch */
  1090.  
  1091.     }/* of while */
  1092.  
  1093.   return(true);
  1094.  
  1095. }/* of amiga_handle_rest*/
  1096.  
  1097.  
  1098.  
  1099. static boolean
  1100. amiga_mkobject (abfd)
  1101.      bfd *abfd;
  1102. {
  1103.   struct amiga_data_struct *rawptr;
  1104.  
  1105.   rawptr = (struct amiga_data_struct *) bfd_zalloc (abfd, sizeof (struct amiga_data_struct));
  1106.   abfd->tdata.amiga_data = rawptr;
  1107.  
  1108.   return true;
  1109. }
  1110.  
  1111.  
  1112. static long determine_datadata_relocs(bfd *, asection *);
  1113. static boolean amiga_write_section_contents(bfd *, asection *, asection *, long, long);
  1114. static boolean amiga_write_symbols(bfd *, asection *);
  1115.  
  1116. /* used with base relative linking */
  1117. extern int amiga_base_relative;
  1118.  
  1119. /* used with -resident linking */
  1120. extern int amiga_resident;
  1121.  
  1122. /* write at most 10 long words (possibly swapped out) to the output file */
  1123. static boolean
  1124. write_longs (unsigned long *in, long elt_size, long nb, bfd *abfd)
  1125. {
  1126.   unsigned long out [10];
  1127.   int i;
  1128.   
  1129.   if (nb > 10)
  1130.     {
  1131.       fprintf(stderr, "ERROR: writing more than 10 longs using write_longs()!\n");
  1132.       exit(2);
  1133.     }
  1134.   for (i=0; i<nb; i++)
  1135.     out[i] = GL (in++);
  1136.   return (bfd_write ((PTR)out, elt_size, nb, abfd) == elt_size*nb);
  1137. }
  1138.  
  1139. static long determine_datadata_relocs(bfd *abfd, asection *section)
  1140. {
  1141.   long relocs = 1, i;
  1142.   struct reloc_cache_entry *r;
  1143.   asection *insection;
  1144.   asymbol *sym_p;
  1145.   
  1146.   for (i=0;i<section->reloc_count;i++)
  1147.     {
  1148.       r=section->orelocation[i];
  1149.       if (r == NULL)
  1150.         continue;
  1151.       sym_p=*(r->sym_ptr_ptr); /* The symbol for this section */
  1152.       insection=sym_p->section;
  1153.  
  1154.       /* Is reloc relative to a special section ? */
  1155.       if ((insection==bfd_abs_section_ptr)||(insection==bfd_com_section_ptr)||
  1156.       (insection==bfd_und_section_ptr)||(insection==bfd_ind_section_ptr))
  1157.     continue; /* Nothing to do, since this translates to HUNK_EXT */
  1158.       if (insection->output_section == section)
  1159.         relocs++;
  1160.     }
  1161.   return relocs;
  1162. }
  1163.  
  1164. /* Write out the contents of a bfd */
  1165. static boolean
  1166. amiga_write_object_contents (abfd)
  1167.      bfd *abfd;
  1168. {
  1169.   struct amiga_data_struct *amiga_data=AMIGA_DATA(abfd);
  1170.   sec_ptr p;
  1171.   unsigned long n[5];
  1172.   long i;
  1173.   char b[3];
  1174.   long datadata_relocs, bss_size = 0;
  1175.   asection *data_sec;
  1176.  
  1177.   /* Distinguish UNITS, LOAD Files
  1178.     Write out hunks+relocs+HUNK_EXT+HUNK_DEBUG (GNU format)*/
  1179.   DPRINT(5,("Entering write_object_conts\n"));
  1180.  
  1181.   abfd->output_has_begun=true; /* Output has begun */
  1182.  
  1183.  
  1184.   /* Distinguish Load files and Unit files */
  1185.   if (amiga_data->IsLoadFile)
  1186.     {
  1187.       DPRINT(5,("Writing Load file\n"));
  1188.  
  1189.       /* Write out load file header */
  1190.       n[0]=HUNK_HEADER;
  1191.       n[1]=0;
  1192.       n[2]=abfd->section_count;
  1193.       /* If amiga_base_relative is set, we write out one hunk less */
  1194.       if (amiga_base_relative)
  1195.     {
  1196.       n[2]=abfd->section_count-1;
  1197.       BFD_ASSERT(abfd->section_count==3); /* Or we are in big trouble */
  1198.     }
  1199.  
  1200.       n[3]=0;
  1201.       n[4]=n[2]-1;
  1202.       if (!write_longs(n,sizeof(unsigned long),5,abfd))
  1203.     return false;
  1204.       /* Write out sizes and memory specifiers... */
  1205.       /* We have to traverse the section list again, bad but no other way... */
  1206.  
  1207.       if (amiga_base_relative)
  1208.         for (p=abfd->sections;p!=NULL;p=p->next)
  1209.       {
  1210.         if (amiga_resident && strcmp(p->name,".data")==0)
  1211.           {
  1212.             datadata_relocs = determine_datadata_relocs(abfd, p);
  1213.             data_sec = p;
  1214.           }
  1215.         else if (strcmp(p->name,".bss")==0)
  1216.           {
  1217.             /* Get size for header*/
  1218.             if (amiga_per_section(p)->real_length != 0)
  1219.               bss_size = (amiga_per_section(p)->real_length) >> 2;
  1220.             else
  1221.               bss_size = (p->_raw_size) >> 2;
  1222.           }
  1223.       }
  1224.       for (p=abfd->sections;p!=NULL;p=p->next)
  1225.     {
  1226.           long extra = 0;
  1227.  
  1228.       if (amiga_base_relative && (strcmp(p->name,".bss")==0)) /* skip */
  1229.         continue;
  1230.       if (amiga_resident && amiga_base_relative && (strcmp(p->name,".text")==0))
  1231.         extra = datadata_relocs;
  1232.  
  1233.       /* Get size for header*/
  1234.       if (amiga_per_section(p)->real_length!=0)
  1235.         n[0]=(amiga_per_section(p)->real_length)>>2;
  1236.       else
  1237.         n[0]=(p->_raw_size)>>2;
  1238.       n[0] += extra;
  1239.       i=amiga_per_section(p)->attribute;
  1240.       switch (i)
  1241.         {
  1242.         case MEMF_CHIP:
  1243.           n[0]|=0x40000000;
  1244.           i=1;
  1245.           break;
  1246.         case MEMF_FAST:
  1247.           n[0]|=0x80000000;
  1248.           i=1;
  1249.           break;
  1250.         case 0: /* nothing*/
  1251.           i=1;
  1252.           break;
  1253.         default: /* Special one */
  1254.           n[0]|=0xc0000000;
  1255.           n[1]=i;
  1256.           i=2;
  1257.           break;
  1258.         }/* Of switch */
  1259.  
  1260.       if (!write_longs (n,sizeof(unsigned long),i,abfd))
  1261.             return false;
  1262.     }/* Of for */
  1263.     }
  1264.   else
  1265.     {/* Unit , no base-relative linking here.... */
  1266.       /* Write out unit header */
  1267.       DPRINT(5,("Writing Unit\n"));
  1268.  
  1269.       n[0]=HUNK_UNIT;
  1270.       if (!write_longs (n,sizeof(unsigned long),1,abfd))
  1271.     return false;
  1272.  
  1273.       i=(strlen(abfd->filename)+3)>>2; /* longword size of name */
  1274.       if (!write_longs(&i,sizeof(unsigned long),1,abfd));
  1275.     return false;
  1276.       if (bfd_write((PTR)(abfd->filename),sizeof(char),strlen(abfd->filename),abfd)!=strlen(abfd->filename))
  1277.     return false;
  1278.       /* Pad to lw boundary */
  1279.       b[0]=b[1]=b[2]='\0';
  1280.       i=(i<<2)-strlen(abfd->filename);
  1281.       if (i)
  1282.     if (bfd_write((PTR)(b),sizeof(char),i,abfd)!=i)
  1283.       return false;
  1284.       /* That's all... for units :-)*/
  1285.     }
  1286.  
  1287.   /* Write out every section */
  1288.   for (p=abfd->sections;p!=NULL;p=p->next)
  1289.     {
  1290.       if (amiga_resident && amiga_base_relative && (strcmp(p->name,".text")==0))
  1291.         {
  1292.           if (!amiga_write_section_contents(abfd,p,data_sec,datadata_relocs,0)) /* Write out section data + relocs */
  1293.         return false;
  1294.         }
  1295.       else if (amiga_base_relative && (strcmp(p->name,".data")==0))
  1296.         {
  1297.           if (!amiga_write_section_contents(abfd,p,0,0,bss_size)) /* Write out section data + relocs */
  1298.         return false;
  1299.         }
  1300.       else
  1301.         {
  1302.           if (!amiga_write_section_contents(abfd,p,0,0,0)) /* Write out section data + relocs */
  1303.         return false;
  1304.         }
  1305.  
  1306.       if (!amiga_write_symbols(abfd,p)) /* Write out symbols, incl HUNK_END */
  1307.     return false;
  1308.  
  1309.     }/* of for sections */
  1310.  
  1311.   /* Write out debug hunk, if requested */
  1312.   if (amiga_data->IsLoadFile && write_debug_hunk)
  1313.     {
  1314.       extern boolean
  1315.     translate_to_native_sym_flags(bfd *, asymbol *, struct external_nlist *);
  1316.  
  1317.       /* We have to convert all the symbols in abfd to a.out style.... */
  1318.       struct external_nlist data;
  1319.       int str_size, offset = 4;
  1320.       int symbols = 0;
  1321.       asymbol *sym;
  1322.       asection *s;
  1323.  
  1324.       if (abfd->symcount)
  1325.     {
  1326.       /* Now, set the .text, .data and .bss fields in the tdata struct (because
  1327.          translate_to_native_sym_flags needs them... */
  1328.       for (i=0,s=abfd->sections;s!=NULL;s=s->next)
  1329.         if (strcmp(s->name,".text")==0)
  1330.           {
  1331.         i|=1;
  1332.         adata(abfd).textsec=s;
  1333.           }
  1334.         else if (strcmp(s->name,".data")==0)
  1335.           {
  1336.             i|=2;
  1337.             adata(abfd).datasec=s;
  1338.           }
  1339.         else if (strcmp(s->name,".bss")==0)
  1340.           {
  1341.             i|=4;
  1342.             adata(abfd).bsssec=s;
  1343.           }
  1344.  
  1345.       if (i!=7) /* One section missing... */
  1346.         {
  1347.           fprintf(stderr,"Missing section, hunk not written\n");
  1348.           return true;
  1349.         }
  1350.  
  1351.       str_size=4; /* the first 4 bytes will be replaced with the length */
  1352.  
  1353.       for (i = 0; i < abfd->symcount; i++) /* Translate every symbol */
  1354.         {
  1355.           sym = abfd->outsymbols[i];
  1356.           /* NULL entries have been written already.... */
  1357.           if (sym != NULL && sym->section)
  1358.             {
  1359.           str_size += strlen(sym->name) + 1;
  1360.           symbols++;
  1361.         }
  1362.         }
  1363.  
  1364.       /* Write out HUNK_DEBUG, size, 0413.... */
  1365.       n[0] = HUNK_DEBUG;
  1366.       n[1] = 3 + ((symbols * sizeof(struct internal_nlist) + str_size + 3) >> 2);
  1367.       n[2] = 0413L; /* Magic number */
  1368.       n[3] = symbols * sizeof(struct internal_nlist);
  1369.       n[4] = str_size;
  1370.       if (!write_longs ((PTR)(n),sizeof(unsigned long),5,abfd))
  1371.         return false;
  1372.  
  1373.       /* Write out symbols */
  1374.       for (i = 0; i < abfd->symcount; i++) /* Translate every symbol */
  1375.         {
  1376.           sym = abfd->outsymbols[i];
  1377.           /* NULL entries have been written already.... */
  1378.           if (sym != NULL && sym->section)
  1379.         {
  1380.                   if (bfd_asymbol_flavour(sym) == bfd_target_aout_flavour)
  1381.                 {
  1382.                       aout_symbol_type *t = ((aout_symbol_type *)(&(sym)->the_bfd));
  1383.                   bfd_h_put_16(abfd, t->desc, data.e_desc);
  1384.                   bfd_h_put_8(abfd, t->other, data.e_other);
  1385.                   bfd_h_put_8(abfd, t->type, data.e_type);
  1386.                 }
  1387.               else
  1388.                 {
  1389.                   bfd_h_put_16(abfd, 0, data.e_desc);
  1390.                   bfd_h_put_8(abfd, 0, data.e_other);
  1391.                   bfd_h_put_8(abfd, 0, data.e_type);
  1392.                 }
  1393.           if (!translate_to_native_sym_flags(abfd,sym,&data))
  1394.                 {
  1395.                   fprintf(stderr,"Cannot translate flags for %s, hunk not written\n",
  1396.                   sym->name);
  1397.                   /*return true;*/
  1398.                 }
  1399.           PUT_WORD(abfd, offset, &(data.e_strx[0])); /* Store index */
  1400.           offset += strlen(sym->name) + 1;
  1401.               if (bfd_write ((unsigned long *)&data,sizeof(long),3,abfd) != sizeof(long)*3)
  1402.                 return false;
  1403.         }
  1404.         }
  1405.  
  1406.       /* Write out strings */
  1407.       if (!write_longs ((unsigned long *)&str_size, sizeof(long),1,abfd))
  1408.         return false;
  1409.       
  1410.       for (i = 0; i < abfd->symcount; i++) /* Translate every symbol */
  1411.         {
  1412.           sym = abfd->outsymbols[i];
  1413.           /* NULL entries have been written already.... */
  1414.           if (sym != NULL && sym->section)
  1415.         {
  1416.           int len = strlen(sym->name) + 1;
  1417.  
  1418.               /* Write string tab */
  1419.               if (bfd_write((PTR)(sym->name),sizeof(char),len,abfd)!=len)
  1420.                 return false;
  1421.         }
  1422.         }
  1423.  
  1424.           i = ((str_size + 3) & (~3)) - str_size;
  1425.           str_size = 0;
  1426.       /* Write padding */
  1427.       if (i && bfd_write((PTR)(&str_size),sizeof(char),i,abfd)!=i)
  1428.         return false;
  1429.  
  1430.       /* dgv -- write a HUNK_END here to finish the loadfile, or amigaos
  1431.        will refuse to load it */
  1432.       n[0]=HUNK_END;
  1433.       if (!write_longs (n,sizeof(long),1,abfd))
  1434.         return false;
  1435.     }/* Of if abfd->symcount */
  1436.     }/* Of write out debug hunk */
  1437.  
  1438.   return true;
  1439. }
  1440.  
  1441. static int determine_size(int type)
  1442. {
  1443.   if (type >= 3)
  1444.     type -= 3;
  1445.   return 2 - type;
  1446. }
  1447.  
  1448. static int determine_type(struct reloc_cache_entry *r)
  1449. {
  1450.   switch (r->howto->type) /* FIXME: Is this sufficient to distinguish them ?*/
  1451.     {
  1452.       /* AMIGA specific */
  1453.       case HUNK_RELOC8:
  1454.       case HUNK_RELOC16:
  1455.       case HUNK_RELOC32:
  1456.       case HUNK_DREL8:
  1457.       case HUNK_DREL16:
  1458.       case HUNK_DREL32:
  1459.         if (r->howto->type >= HUNK_DREL32)
  1460.           return 3 + r->howto->type - HUNK_DREL32;
  1461.         return r->howto->type - HUNK_RELOC32;
  1462.  
  1463.       /* Now, these may occur, if a.out was used as input */
  1464.       case 0: /* 8 bit ref */
  1465.         return 2;
  1466.  
  1467.       case 1: /* 16 bit relative */
  1468.         return 1;
  1469.  
  1470.       case 2: /* 32 bit relative */
  1471.         return 0;
  1472.  
  1473.       case 9: /* 16 bit base rel */
  1474.         return 4;
  1475.  
  1476.       case 10: /* 32 bit baserel */
  1477.         return 3;
  1478.  
  1479.       /* FIXME: There are other (pc relative) displacements left */
  1480.       default: /* Error, can't represent this */
  1481.         bfd_set_error(bfd_error_nonrepresentable_section);
  1482.         return -1;
  1483.     }/* Of switch */
  1484. }
  1485.  
  1486. #define MAX_RELOC_OUT 3
  1487.  
  1488. /* Write out section contents, including relocs */
  1489. static boolean
  1490. amiga_write_section_contents(bfd *abfd, asection *section, asection *data_sec,
  1491.                  long datadata_relocs, long bss_size)
  1492. {
  1493.   unsigned long n[2];
  1494.   int i, j, type, size;
  1495.   unsigned int k;
  1496.   char b[3];
  1497.   struct reloc_cache_entry *r;
  1498.   asection *osection, *sec, *insection;
  1499.   asymbol *sym_p;
  1500.   int reloc_count = 0;
  1501.   unsigned long reloc_types[6]= { HUNK_RELOC32, HUNK_RELOC16, HUNK_RELOC8,
  1502.                   HUNK_DREL32,  HUNK_DREL16,  HUNK_DREL8 };
  1503.   int max_hunk = -1;
  1504.   char *c_p;
  1505.   unsigned char *values;
  1506.   /* 6 reloc types * 3 hunk types */
  1507.   int reloc_counts[6][3] = { 0, 0, 0, 0, 0, 0,
  1508.                    0, 0, 0, 0, 0, 0,
  1509.                    0, 0, 0, 0, 0, 0 };
  1510.  
  1511.   DPRINT(5, ("Entered Write-section-conts\n"));
  1512.  
  1513.   /* If we are base-relative linking and the section is .bss and abfd
  1514.      is a load file, then return */
  1515.   if (AMIGA_DATA(abfd)->IsLoadFile && amiga_base_relative &&
  1516.       (strcmp(section->name, ".bss") == 0))
  1517.     return true; /* Nothing to do */
  1518.  
  1519.   if (!AMIGA_DATA(abfd)->IsLoadFile)
  1520.   {
  1521.     /* WRITE out HUNK_NAME + section name */
  1522.     n[0] = HUNK_NAME;
  1523.     j = strlen(section->name);
  1524.     i = (j + 3) >> 2; /* LW len of name */
  1525.     n[1] = i;
  1526.     if (!write_longs ((PTR)(n), sizeof(unsigned long), 2, abfd))
  1527.       return false;
  1528.     if (bfd_write((PTR)(section->name), sizeof(char), j, abfd) != j)
  1529.       return false;
  1530.     b[0] = b[1] = b[2] = '\0';
  1531.     if ((i << 2) - j != 0) /* Pad */
  1532.       if (bfd_write((PTR)(b), sizeof(char), (i<<2) - j, abfd) != ((i<<2) - j))
  1533.         return false;
  1534.   }
  1535.   /* Depending on the type of the section, write out HUNK_{CODE|DATA|BSS} */
  1536.   if (section->flags & SEC_CODE) /* Code section */
  1537.     n[0] = HUNK_CODE;
  1538.   else if (section->flags & SEC_DATA) /* data section */
  1539.     n[0] = HUNK_DATA;
  1540.   else if (section->flags & SEC_ALLOC) /* BSS */
  1541.     n[0] = HUNK_BSS;
  1542.   else if (section->flags & SEC_DEBUGGING) /* debug section */
  1543.     n[0] = HUNK_DEBUG;
  1544.   else /* Error */
  1545.     {
  1546. #if 0
  1547.       bfd_set_error(bfd_error_nonrepresentable_section);
  1548.       return(false);
  1549. #else
  1550.       /* FIXME: Just dump everything we don't currently recognize into
  1551.      a DEBUG hunk. */
  1552.       n[0] = HUNK_DEBUG;
  1553. #endif
  1554.     }
  1555.  
  1556.   DPRINT(10,("Section type is %lx\n",n[0]));
  1557.  
  1558.   /* Get attribute for section */
  1559.   switch (amiga_per_section(section)->attribute)
  1560.     {
  1561.     case MEMF_CHIP:
  1562.       n[0] |= HUNKF_CHIP;
  1563.       break;
  1564.     case MEMF_FAST:
  1565.       n[0] |= HUNKF_FAST;
  1566.       break;
  1567.     case 0:
  1568.       break;
  1569.     default: /* error , can't represent this */
  1570.       bfd_set_error(bfd_error_nonrepresentable_section);
  1571.       return(false);
  1572.       break;
  1573.     }/* Of switch */
  1574.  
  1575.   DPRINT(10,("Section attribute is %lx\n",n[0]));
  1576.  
  1577.   /* Get real size in n[1], this may be shorter than the size in the header */
  1578.   n[1] = section->_cooked_size >> 2;
  1579.   if (n[1] == 0)
  1580.     n[1] = section->_raw_size >> 2;
  1581.   n[1] += datadata_relocs + bss_size;
  1582.   if (!write_longs ((PTR)(n), sizeof(unsigned long), 2, abfd))
  1583.       return false;
  1584.  
  1585.   DPRINT(5,("Wrote code and size=%lx\n",n[1]));
  1586.  
  1587.   /* If a BSS hunk, we're done, else write out section contents */
  1588.   if (HUNK_VALUE(n[0]) == HUNK_BSS)
  1589.     return true;
  1590.  
  1591.   DPRINT(5,("Non bss hunk...\n"));
  1592.  
  1593.   /* dgv -- if the section is empty, we're done as well */
  1594.   if (n[1] == 0)
  1595.     return true;
  1596.  
  1597.   /* Traverse through the relocs, sample them in reloc_data, adjust section
  1598.      data to get 0 addend
  1599.      Then compactify reloc_data 
  1600.      Set the entry in the section for the reloc to NULL */
  1601.  
  1602.   BFD_ASSERT((section->flags & SEC_IN_MEMORY) != 0);
  1603.  
  1604.   DPRINT(5,("Section has %d relocs\n", section->reloc_count));
  1605.  
  1606.   for (i = 0; i < section->reloc_count; i++)
  1607.     {
  1608.       r = section->orelocation[i];
  1609.       if (r == NULL)
  1610.         continue;
  1611.       sym_p = *(r->sym_ptr_ptr); /* The symbol for this section */
  1612.       insection = sym_p->section;
  1613.       DPRINT(5,("Sec for reloc is %lx(%s)\n",insection,insection->name));
  1614.       DPRINT(5,("Symbol for this reloc is %lx(%s)\n",sym_p, sym_p->name));
  1615.  
  1616.       /* Is reloc relative to a special section ? */
  1617.       if ((insection == bfd_abs_section_ptr) ||
  1618.       (insection == bfd_com_section_ptr) ||
  1619.       (insection == bfd_und_section_ptr) ||
  1620.       (insection == bfd_ind_section_ptr))
  1621.     continue; /* Nothing to do, since this translates to HUNK_EXT */
  1622.  
  1623.       r->addend += sym_p->value; /* Add offset of symbol from section start */
  1624.  
  1625.       /* Address of reloc has been unchanged since original reloc, or has been
  1626.      adjusted by get_relocated_section_contents */
  1627.       /* For relocs, the vma of the target section is in the data, the addend is
  1628.      -vma of that section =>No need to add vma*/
  1629.       /* Add in offset */
  1630.       r->addend += insection->output_offset;
  1631.       osection = insection->output_section; /* target section */
  1632.  
  1633.       /* Determine which hunk to write, and index of target */
  1634.       for (j = 0, sec = abfd->sections; sec != NULL; sec = sec->next, j++)
  1635.     {
  1636.       if (sec == osection)
  1637.         break;
  1638.     }
  1639.  
  1640.       BFD_ASSERT(sec != NULL);
  1641.  
  1642.       if (j > max_hunk) /* Maximum number used */
  1643.     max_hunk = j;
  1644.  
  1645.       BFD_ASSERT(max_hunk < 3);
  1646.  
  1647.       type = determine_type(r);
  1648.       if (type == -1)
  1649.     return false;
  1650.       size = determine_size(type);
  1651.       if (type < MAX_RELOC_OUT)
  1652.         reloc_counts[type][j]++;
  1653.  
  1654.       c_p = ((char *)(section->contents)) + r->address;
  1655.       DPRINT(5,("reloc address=%lx,addend=%lx\n",r->address,r->addend));
  1656.  
  1657.       /* There is no error checking with these.. */
  1658.       values = (unsigned char *)c_p;
  1659.       switch (size)
  1660.     {
  1661.     case 0: /* adjust byte */
  1662.       j = (int)(*c_p) + r->addend;
  1663.       *c_p = (signed char)j;
  1664.       break;
  1665.     case 1: /* Adjust word */
  1666.       k = values[1] | (values[0] << 8);
  1667.       j = (int)k + r->addend;
  1668.       values[0] = (j & 0xff00) >> 8;
  1669.       values[1] = j & 0xff;
  1670.       break;
  1671.     case 2: /* adjust long */
  1672.       k = values[3] | (values[2] << 8) | (values[1] << 16) | (values[0] << 24);
  1673.       j = (int)k + r->addend;
  1674.       values[3] = j & 0xff;
  1675.       values[2] = (j & 0xff00) >> 8;
  1676.       values[1] = (j & 0xff0000) >> 16;
  1677.       values[0] = ((unsigned int)j & 0xff000000) >> 24;
  1678.       break;
  1679.     } /* of switch */
  1680.  
  1681.       r->addend = 0;
  1682.       DPRINT(5,("Did adjusting\n"));
  1683.  
  1684.       if (type < MAX_RELOC_OUT)
  1685.         reloc_count++;
  1686.       else
  1687.         section->orelocation[i] = NULL;
  1688.     } /* of for i */
  1689.  
  1690.   DPRINT(5,("Did all relocs\n"));
  1691.  
  1692.   /* We applied all the relocs, as far as possible to obtain 0 addend fields */
  1693.   /* Write the section contents */
  1694.   if (bfd_write((PTR)(section->contents), sizeof(char), section->_raw_size,
  1695.         abfd) != section->_raw_size)
  1696.       return false;
  1697.  
  1698.   i = 0;
  1699.   /* write bss data in the data hunk if needed */
  1700.   while (bss_size--)
  1701.     if (!write_longs((PTR)&i, sizeof(long), 1, abfd))
  1702.       return false;
  1703.  
  1704.   if (datadata_relocs)
  1705.     {
  1706.       datadata_relocs--;
  1707.       if (!write_longs(&datadata_relocs, sizeof(long), 1, abfd))
  1708.         return false;
  1709.       for (i = 0; i < data_sec->reloc_count; i++)
  1710.         {
  1711.           r = data_sec->orelocation[i];
  1712.           if (r == NULL)
  1713.             continue;
  1714.           sym_p = *(r->sym_ptr_ptr); /* The symbol for this section */
  1715.           insection = sym_p->section;
  1716.  
  1717.           /* Is reloc relative to a special section ? */
  1718.           if ((insection == bfd_abs_section_ptr) ||
  1719.           (insection == bfd_com_section_ptr) ||
  1720.               (insection == bfd_und_section_ptr) ||
  1721.           (insection == bfd_ind_section_ptr))
  1722.             continue; /* Nothing to do, since this translates to HUNK_EXT */
  1723.  
  1724.       if (insection->output_section == data_sec)
  1725.         {
  1726.           int offset = r->address;
  1727.  
  1728.           if (determine_type(r) == 0)
  1729.         if (!write_longs((PTR)&offset, sizeof(long), 1, abfd))
  1730.           return false;
  1731.         }
  1732.     }
  1733.     }
  1734.   DPRINT(10,("Wrote contents, writing relocs now\n"));
  1735.  
  1736.   /* We gathered all the relocs, now compactify them */
  1737.   if (!reloc_count) /* No reloc found ==> We are done */
  1738.     return true;
  1739.  
  1740.   /* There are some relocs.... */
  1741.  
  1742.   /* Sample every reloc type */
  1743.   while (reloc_count) {
  1744.     for (i = 0; i < 3; i++)
  1745.       /* are there relocs of this type? */
  1746.       if (reloc_counts[i][0] || reloc_counts[i][1] || reloc_counts[i][2]) {
  1747.  
  1748.     if (!write_longs(&reloc_types[i], sizeof(long), 1, abfd))
  1749.       return false;
  1750.  
  1751.     for (j = 0; j <= max_hunk; j++) {
  1752.       while (reloc_counts[i][j] > 0) {
  1753.         int relocs = reloc_counts[i][j];
  1754.  
  1755.         if (relocs > 0xffff)
  1756.           relocs = 0xffff;
  1757.  
  1758.         reloc_counts[i][j] -= relocs;
  1759.         n[0] = relocs;
  1760.         n[1] = j;
  1761.         if (!write_longs(n, sizeof(long), 2, abfd))
  1762.           return false;
  1763.         reloc_count -= relocs;
  1764.  
  1765.         for (k = 0; k < section->reloc_count; k++) {
  1766.           int jj;
  1767.  
  1768.           r = section->orelocation[k];
  1769.           if (r == NULL)  /* already written */
  1770.         continue;
  1771.           sym_p = *(r->sym_ptr_ptr); /* The symbol for this section */
  1772.           insection = sym_p->section;
  1773.           /* Is reloc relative to a special section ? */
  1774.           if ((insection == bfd_abs_section_ptr) ||
  1775.           (insection == bfd_com_section_ptr) ||
  1776.           (insection == bfd_und_section_ptr) ||
  1777.           (insection == bfd_ind_section_ptr))
  1778.         continue; /* Nothing to do, since this translates to HUNK_EXT */
  1779.  
  1780.           osection = insection->output_section; /* target section */
  1781.  
  1782.           /* Determine which hunk to write, and index of target */
  1783.           for (jj = 0, sec = abfd->sections; sec != NULL; sec = sec->next, jj++) {
  1784.         if (sec == osection)
  1785.           break;
  1786.           }
  1787.           if (jj == j && i == determine_type(r)) {
  1788.         section->orelocation[k] = NULL;
  1789.         if (!write_longs((PTR)&r->address, sizeof(long), 1, abfd))
  1790.           return false;
  1791.         if (--relocs == 0)
  1792.           break;
  1793.           }
  1794.         }
  1795.       }
  1796.     }
  1797.       }
  1798.   }
  1799.  
  1800.   if (!write_longs((PTR)&reloc_count, sizeof(long), 1, abfd))
  1801.     return false;
  1802.  
  1803.   DPRINT(5,("Leaving write_section...\n"));
  1804.  
  1805.   return true;
  1806. }
  1807.  
  1808.  
  1809. /* Write out symbol information, including HUNK_EXT, DEFS, ABS */
  1810. /* In the case, we were linking base relative, the symbols of the .bss hunk have been converted already
  1811. to belong to the .data hunk */
  1812. static boolean amiga_write_symbols(bfd *abfd, asection *section)
  1813. {
  1814.  
  1815.   int i,j;
  1816.   struct reloc_cache_entry *r;
  1817.   asection *osection;
  1818.   asymbol *sym_p;
  1819.   char b[3]="\0\0\0";
  1820.   unsigned long n[3];
  1821.   int symbol_count;
  1822.   unsigned long symbol_header;
  1823.   unsigned long type, tmp;
  1824.   int len;
  1825.  
  1826.   /* If base rel linking and section is .bss ==> exit */
  1827.   if (amiga_base_relative && (strcmp(section->name,".bss")==0))
  1828.     return true;
  1829.  
  1830.   if (section->reloc_count==0 && abfd->symcount==0)
  1831.     {/* Write HUNK_END */
  1832.     alldone:
  1833.       DPRINT(5,("Leaving write_symbols\n"));
  1834.       n[0]=HUNK_END;
  1835.       return write_longs ((PTR)n,sizeof(unsigned long),1,abfd);
  1836.     }
  1837.  
  1838.   symbol_count=0;
  1839.   symbol_header=HUNK_EXT;
  1840.  
  1841.   /* If this is Loadfile, then do not write HUNK_EXT, but rather HUNK_SYMB*/
  1842.  
  1843.  /* Write out all the symbol definitions, then HUNK_END 
  1844.  
  1845.      Now, first traverse the relocs, all entries that are non NULL
  1846.      have to be taken into account */
  1847.   /* Determine the type of HUNK_EXT to issue and build a single HUNK_EXT subtype */
  1848.  
  1849.  
  1850.   /*FIXME: We write out many HUNK_EXT's entries for references to the same symbol.. */
  1851.   for (i=0;i<section->reloc_count;i++)
  1852.     {
  1853.       r=section->orelocation[i];
  1854.  
  1855.       if (r==NULL) /* Empty entry */
  1856.     continue;
  1857.  
  1858.       sym_p=*(r->sym_ptr_ptr); /* The symbol for this section */
  1859.  
  1860.       osection=sym_p->section; /* The section the symbol belongs to */
  1861.       /* this section MUST be a special section */
  1862.  
  1863.       DPRINT(5,("Symbol is %s, section is %lx(%s)\n",sym_p->name,osection,osection->name));
  1864.  
  1865.       if (osection!=bfd_com_section_ptr) /* Not common symbol */
  1866.     {
  1867.       DPRINT(5,("Non common ref\n"));
  1868.       /* Add a reference to this HUNK */
  1869.       if ((symbol_count++)==0) /* First write out the HUNK_EXT */
  1870.         {
  1871.           tmp=HUNK_EXT;
  1872.           if (!write_longs(&tmp,sizeof(long),1,abfd))
  1873.         return false;
  1874.         }
  1875.  
  1876.       /* Determine type of ref */
  1877.       switch(r->howto->type) /* FIXME: Is this sufficient to distinguish them ?*/
  1878.         {
  1879.           /* AMIGA specific */
  1880.         case 0:
  1881.         case HUNK_RELOC8:
  1882.           type=EXT_REF8;
  1883.           break;
  1884.  
  1885.         case 1:
  1886.         case HUNK_RELOC16:
  1887.           type=EXT_REF16;
  1888.           break;
  1889.  
  1890.         case 2:
  1891.         case HUNK_RELOC32:
  1892.           type=EXT_REF32;
  1893.           break;
  1894.         case HUNK_DREL8:
  1895.           type=EXT_DEXT8;
  1896.           break;
  1897.  
  1898.         case 9:
  1899.         case HUNK_DREL16:
  1900.           type=EXT_DEXT16;
  1901.           break;
  1902.  
  1903.         case 10:
  1904.         case HUNK_DREL32:
  1905.             type=EXT_DEXT32;
  1906.           break;
  1907.           
  1908.           /* FIXME: There are other (pc relative) displacements left */
  1909.         default: /* Error, can't represent this */
  1910.           bfd_set_error(bfd_error_nonrepresentable_section);
  1911.           return false;
  1912.           break;
  1913.         }/* Of switch */
  1914.       DPRINT(5,("Type is %x\n",type));
  1915.  
  1916.       type<<=24;
  1917.       type&=0xff000000;
  1918.  
  1919.       j=strlen(sym_p->name);
  1920.       len=(j+3)>>2; /* LW Len of name */
  1921.       
  1922.       type|=(len & 0xffffff);
  1923.       if (!write_longs (&type,sizeof(unsigned long),1,abfd))
  1924.         return false;
  1925.  
  1926.       if (bfd_write((PTR)(sym_p->name),sizeof(char),j,abfd)!=j)
  1927.         return false;
  1928.  
  1929.       if ((len<<2)-j!=0) /* Pad name */
  1930.         if (bfd_write((PTR)(b),sizeof(char),(len<<2)-j,abfd)!=((len<<2)-j))
  1931.           return false;
  1932.  
  1933.       n[0]=1; /* 1 ref at address... */
  1934.       n[1]=r->address;
  1935.  
  1936.       if (!write_longs (n,sizeof(unsigned long),2,abfd))
  1937.         return false;
  1938.       
  1939.       continue; /* Next relocation */
  1940.     }/* Of is ref to undefined or abs symbol */
  1941.  
  1942.       
  1943.       if (osection==bfd_com_section_ptr) /* ref to common symbol */
  1944.     {
  1945.       DPRINT(5,("Common ref\n"));
  1946.  
  1947.       /* If the reference is NOT 32 bit wide absolute , then issue warning */
  1948.       if ((r->howto->type!=2)&&(r->howto->type!=HUNK_RELOC32))
  1949.         fprintf(stderr,"Warning: Non 32 bit wide reference to common symbol %s\n",
  1950.             sym_p->name);
  1951.  
  1952.       if ((symbol_count++)==0) /* First write out the HUNK_EXT */
  1953.         {
  1954.           tmp=HUNK_EXT;
  1955.           if (!write_longs (&tmp,sizeof(long),1,abfd))
  1956.         return false;
  1957.         }
  1958.  
  1959.       type=(EXT_COMMON<<24)&0xff000000;
  1960.  
  1961.       j=strlen(sym_p->name);
  1962.  
  1963.       len=(j+3)>>2;
  1964.       type|=(len&0xffffff);
  1965.  
  1966.       if (!write_longs (&type,sizeof(unsigned long),1,abfd))
  1967.         return false;
  1968.       if (bfd_write((PTR)(sym_p->name),sizeof(char),j,abfd)!=j)
  1969.         return false;
  1970.       
  1971.       if ((len<<2)-j!=0) /* Pad name */
  1972.         if (bfd_write((PTR)(b),sizeof(char),(len<<2)-j,abfd)!=((len<<2)-j))
  1973.           return false;
  1974.       n[0]=sym_p->value; /* Size of common block */
  1975.       n[1]=1;
  1976.       n[2]=r->address;
  1977.  
  1978.       if (!write_longs ((PTR)(n),sizeof(unsigned long),3,abfd))
  1979.         return false;
  1980.       
  1981.       continue;
  1982.     }/* Of is common section */
  1983.  
  1984.       DPRINT(10,("Failing...\n"));
  1985.       BFD_FAIL();
  1986.     }/* Of traverse relocs */
  1987.       
  1988.       
  1989.   /* Now traverse the symbol table and write out all definitions, that are relative
  1990.      to this hunk */
  1991.   /* Absolute defs are always only written out with the first hunk */
  1992.   /* Don't write out COMMON symbols
  1993.                      local symbols
  1994.                      undefined symbols
  1995.              indirect symbols
  1996.              warning symbols
  1997.              debugging symbols
  1998.              warning symbols
  1999.              constructor symbols, since they are unrepresentable in HUNK format..*/
  2000.  
  2001.   DPRINT(10,("Traversing symbol table\n"));
  2002.   symbol_header=(AMIGA_DATA(abfd)->IsLoadFile)?HUNK_SYMBOL:HUNK_EXT;
  2003.   for (i=0;i<abfd->symcount;i++)
  2004.     {
  2005.       sym_p=abfd->outsymbols[i];
  2006.       osection=sym_p->section;
  2007.  
  2008.       DPRINT(5,("%d. symbol(%s), osec=%x(%s)\n",i,sym_p->name,osection,osection->name));
  2009.  
  2010.       if ((osection==bfd_und_section_ptr)||(osection==bfd_com_section_ptr)||
  2011.       (osection==bfd_ind_section_ptr))
  2012.     continue; /* Don't write these */
  2013.  
  2014.       /* Only write abs defs, if not writing A Loadfile */
  2015.       if ((osection==bfd_abs_section_ptr)&&(section->index==0)&&!AMIGA_DATA(abfd)->IsLoadFile) /* Write out abs defs */
  2016.     {
  2017.       DPRINT(5,("Abs symbol\n"));
  2018.       if ((symbol_count++)==0) /* First write out the HUNK_EXT */
  2019.         {
  2020.           if (!write_longs (&symbol_header,sizeof(long),1,abfd))
  2021.         return false;
  2022.         }
  2023.       type=(EXT_ABS<<24)&0xff000000;
  2024.  
  2025.       j=strlen(sym_p->name);
  2026.       
  2027.       len=(j+3)>>2;
  2028.       
  2029.       type|=(len & 0xffffff);
  2030.  
  2031.       if (!write_longs (&type,sizeof(unsigned long),1,abfd))
  2032.         return false;
  2033.       if (bfd_write((PTR)(sym_p->name),sizeof(char),j,abfd)!=j)
  2034.         return false;
  2035.       
  2036.       if ((len<<2)-j!=0) /* Pad name */
  2037.         if (bfd_write((PTR)(b),sizeof(char),(len<<2)-j,abfd)!=((len<<2)-j))
  2038.           return false;
  2039.       
  2040.       n[0]=sym_p->value;
  2041.       if (!write_longs (n,sizeof(unsigned long),1,abfd))
  2042.         return false;
  2043.       continue;
  2044.     }/* Of abs def */
  2045.       if (osection == NULL) /* Happens with constructor functions. FIXME */
  2046.         continue;
  2047.       if (osection==bfd_abs_section_ptr) /* Not first hunk. Already written */
  2048.     continue;
  2049.  
  2050.       /* If it is a warning symbol, or a constructor symbol or a debugging or a local symbol,
  2051.      don't write it */
  2052.       if (sym_p->flags & (BSF_WARNING|BSF_CONSTRUCTOR|BSF_DEBUGGING|BSF_LOCAL))
  2053.     continue;
  2054.  
  2055.       /* Now, if osection==section, write it out */
  2056.       if (osection->output_section==section)
  2057.     {
  2058.       DPRINT(5,("Writing it out\n"));
  2059.  
  2060.       if ((symbol_count++)==0) /* First write out the header */
  2061.         {
  2062.           if (!write_longs (&symbol_header,sizeof(long),1,abfd))
  2063.         return false;
  2064.         }
  2065.       type=((symbol_header==HUNK_EXT?EXT_DEF:0)<<24)&0xff000000;
  2066.  
  2067.       j=strlen(sym_p->name);
  2068.       
  2069.       /* workaround for an amigaos bug: symbol names longer than 124
  2070.          characters are not supported */
  2071.       if (j > 124)
  2072.         j = 124;
  2073.  
  2074.       len=(j+3)>>2;
  2075.  
  2076.       type|=(len & 0xffffff);
  2077.  
  2078.       if (!write_longs ((PTR)(&type),sizeof(unsigned long),1,abfd))
  2079.         return false;
  2080.       if (bfd_write((PTR)(sym_p->name),sizeof(char),j,abfd)!=j)
  2081.         return false;
  2082.       
  2083.       if ((len<<2)-j!=0) /* Pad name */
  2084.         if (bfd_write((PTR)(b),sizeof(char),(len<<2)-j,abfd)!=((len<<2)-j))
  2085.           return false;
  2086.  
  2087.       n[0]=sym_p->value+sym_p->section->output_offset;
  2088.       if (!write_longs (n,sizeof(unsigned long),1,abfd))
  2089.         return false;
  2090.     }/* Of this section */
  2091.     }/* Of for */
  2092.  
  2093.   DPRINT(10,("Did traversing\n"));
  2094.   if (symbol_count) /* terminate HUNK_EXT, HUNK_SYMBOL */
  2095.     {
  2096.       n[0]=0;
  2097.       if (!write_longs (n,sizeof(unsigned long),1,abfd))
  2098.     return false;
  2099.     }
  2100.   DPRINT(5,("Leaving\n"));
  2101.   goto alldone; /* Write HUNK_END, return */
  2102.  
  2103. }
  2104.  
  2105.  
  2106. static boolean
  2107. amiga_get_section_contents (abfd, section, location, offset, count)
  2108.      bfd *abfd;
  2109.      sec_ptr section;
  2110.      PTR location;
  2111.      file_ptr offset;
  2112.      bfd_size_type count;
  2113. {
  2114.   long disk_size = amiga_per_section (section)->real_length;
  2115.  
  2116.   if (offset+count > disk_size) {
  2117.     /* the section's size on disk may be smaller than in memory
  2118.        in this case, pad the contents */
  2119.     memmove ((void *) location,
  2120.          (void *) (((int) AMIGA_DATA(abfd)->first_byte)
  2121.                + (int) section->filepos
  2122.                + (int) offset),
  2123.          disk_size - offset);
  2124.     memset (location + disk_size - offset, 0, count-(disk_size-offset));
  2125.   }
  2126.   else {
  2127.     memmove ((void *) location,
  2128.          (void *) (((int) AMIGA_DATA(abfd)->first_byte)
  2129.                + (int) section->filepos
  2130.                + (int) offset),
  2131.          count);
  2132.   }
  2133.   return true;
  2134. }
  2135.  
  2136.  
  2137. boolean
  2138. amiga_new_section_hook (abfd, newsect)
  2139.      bfd *abfd;
  2140.      asection *newsect;
  2141. {
  2142.   newsect->used_by_bfd = (PTR) bfd_zalloc (abfd, sizeof (amiga_per_section_type));
  2143.   newsect->alignment_power = 2;
  2144.   amiga_per_section(newsect)->reloc_tail = NULL;
  2145.   return true;
  2146. }
  2147.  
  2148.  
  2149. /* This reads the symbol table, by following various pointers,
  2150.    set up by amiga_digest_file */
  2151. static boolean
  2152. amiga_slurp_symbol_table (abfd)
  2153.      bfd *abfd;
  2154. {
  2155.   /* slurp in symbols, associated with this bfd */
  2156.   amiga_data_type *amiga_data=AMIGA_DATA(abfd);
  2157.   asection *section;
  2158.   struct amiga_raw_symbol *sp;
  2159.   amiga_symbol_type *asp=NULL;
  2160.   unsigned long *lp, l;
  2161.   int len;
  2162.   int type;
  2163.  
  2164.   if (amiga_data->symbols)
  2165.     return true; /* already read */
  2166.  
  2167.   /* Symbols are associated with every section */
  2168.   for (section=abfd->sections;section!=NULL;section=section->next)
  2169.     {
  2170.       for (sp=amiga_per_section(section)->first;sp!=NULL;sp=sp->next)
  2171.     {
  2172.       lp=&(sp->data[0]);
  2173.       while ((l = GL(lp++)))
  2174.         {
  2175.           type = l>>24; /* type of entry */
  2176.           len = l & 0xffffff; /* namelength */
  2177.           
  2178.           switch(type)
  2179.         {
  2180.         case EXT_COMMON: /* Common reference/definition*/
  2181.         case EXT_ABS: /* Absolute */
  2182.         case EXT_DEF: /* Relative Definition */
  2183.         case EXT_SYMB: /* Same as EXT_DEF for load files */
  2184.           /* Add symbol to section.... */
  2185.           /* We don't have to increase symcount, this has already been done */
  2186.           
  2187.           asp=(amiga_symbol_type *)bfd_zalloc(abfd,sizeof(amiga_symbol_type));
  2188.           if (!asp) /* No mem */
  2189.             {
  2190.               bfd_set_error(bfd_error_no_memory);
  2191.               return(false);
  2192.             }
  2193.           
  2194.           /* Add symbol to list of all symbols */
  2195.           asp->next=NULL;
  2196.           if (!amiga_data->symbols) /* first one */
  2197.             {
  2198.               amiga_data->symbols=amiga_data->symbol_tail=asp;
  2199.             }
  2200.           else
  2201.             {
  2202.               amiga_data->symbol_tail->next=asp;
  2203.               amiga_data->symbol_tail=asp;
  2204.             }
  2205.  
  2206.           asp->symbol.section=((type==EXT_DEF)||(type==EXT_SYMB))?section:(type==EXT_COMMON)?
  2207.                bfd_com_section_ptr:bfd_abs_section_ptr;
  2208.           asp->symbol.flags=BSF_GLOBAL;
  2209.           asp->symbol.value= GL(lp+len);
  2210.           asp->symbol.the_bfd=abfd;
  2211.           asp->type=type;
  2212.           asp->hunk_number=((type==EXT_DEF)||(type==EXT_SYMB))?section->target_index:
  2213.              (type==EXT_ABS)?-1:-3;
  2214.           if ((asp->symbol.name=bfd_alloc(abfd,(len<<2)+1))==NULL)
  2215.             {
  2216.               bfd_set_error(bfd_error_no_memory);
  2217.               return(false);
  2218.             } 
  2219.           strncpy((char *)(asp->symbol.name),(char *)lp,len<<2);
  2220.           ((char*)(asp->symbol.name))[(len<<2)]='\0';
  2221.  
  2222.           /* Now store the symbol in the first name longword */
  2223.           *lp=(unsigned long)asp;
  2224.  
  2225.           lp+=len+1;
  2226.  
  2227.           if (type==EXT_COMMON) /* skip refs */
  2228.             lp+= GL(lp)+1;
  2229.  
  2230.           break;
  2231.  
  2232.         default: /* References to an undefined symbol */
  2233.           /* Problem is that this symbol may be defined in another hunk WITHIN this bfd */
  2234.           /* To avoid conflicts with bfd, we simply scan through the list of already defined symbols
  2235.              and add a symbol only, if we did not find it */
  2236.  
  2237.           for (asp=amiga_data->symbols;asp!=NULL;asp=asp->next)
  2238.             {
  2239.               if (strncmp((char *)lp,asp->symbol.name,len<<2)==0)
  2240.             break; /* Found symbol */
  2241.             }
  2242.  
  2243.           if (asp==NULL) /* Symbol not  defined */
  2244.             {
  2245.               asp=(amiga_symbol_type *)bfd_zalloc(abfd,sizeof(amiga_symbol_type));
  2246.               if (!asp) /* No mem */
  2247.             {
  2248.               bfd_set_error(bfd_error_no_memory);
  2249.               return(false);
  2250.             }
  2251.               
  2252.               /* Add symbol to list of all symbols */
  2253.               asp->next=NULL;
  2254.               if (!amiga_data->symbols) /* first one */
  2255.             {
  2256.               amiga_data->symbols=amiga_data->symbol_tail=asp;
  2257.             }
  2258.               else
  2259.             {
  2260.               amiga_data->symbol_tail->next=asp;
  2261.               amiga_data->symbol_tail=asp;
  2262.             }
  2263.               if ((asp->symbol.name=bfd_alloc(abfd,(len<<2)+1))==NULL)
  2264.             {
  2265.               bfd_set_error(bfd_error_no_memory);
  2266.               return(false);
  2267.             } 
  2268.               strncpy((char *)(asp->symbol.name),(const char *)lp,len<<2);
  2269.               ((char *)(asp->symbol.name))[(len<<2)]='\0';
  2270.  
  2271.               asp->symbol.section=bfd_und_section_ptr;
  2272.               asp->symbol.flags=0;
  2273.               asp->symbol.the_bfd=abfd;
  2274.               asp->hunk_number=-2;
  2275.               asp->type=type;
  2276.               abfd->symcount++;
  2277.  
  2278.             }
  2279.           
  2280.           /* Store symbol in 1st LW of name */
  2281.           *lp=(unsigned long)asp;
  2282.           lp+=len;
  2283.           lp+= 1+ GL(lp); /* skip refs */
  2284.           break;
  2285.         }/* Of switch type */
  2286.         }/* Of while *lp */
  2287.     }/* of for sp */
  2288.     }/* Of for section */
  2289.  
  2290.  
  2291.   return true;
  2292. }
  2293.  
  2294.  
  2295. /* Get size of symtab */
  2296. long
  2297. amiga_get_symtab_upper_bound (abfd)
  2298.      bfd *abfd;
  2299. {
  2300.   /* We read in the symbol table first */
  2301.   if (!amiga_slurp_symbol_table (abfd))
  2302.     return -1;
  2303.  
  2304.   return (abfd->symcount != 0) ?
  2305.     (abfd->symcount+1) * (sizeof (amiga_symbol_type *)) : 0;
  2306. }
  2307.  
  2308. long
  2309. amiga_get_symtab (abfd, location)
  2310.      bfd *abfd;
  2311.      asymbol **location;
  2312. {
  2313.   amiga_symbol_type *symp;
  2314.  
  2315.   if(!amiga_slurp_symbol_table(abfd))
  2316.     return -1;
  2317.  
  2318.   if (abfd->symcount)
  2319.     {
  2320.       int i = 0;
  2321.  
  2322.       for (symp = AMIGA_DATA(abfd)->symbols;
  2323.                  symp != (amiga_symbol_type *) NULL;
  2324.                  symp = symp->next)
  2325.     {
  2326.       location[i++] = &symp->symbol;
  2327.     }
  2328.     }
  2329.   return abfd->symcount;
  2330. }
  2331.  
  2332. asymbol *
  2333. amiga_make_empty_symbol (abfd)
  2334.      bfd *abfd;
  2335. {
  2336.   amiga_symbol_type *new =
  2337.     (amiga_symbol_type *) bfd_zalloc (abfd, sizeof (amiga_symbol_type));
  2338.   new->symbol.the_bfd = abfd;
  2339.   return &new->symbol;
  2340. }
  2341.  
  2342.  
  2343.  
  2344. void
  2345. amiga_get_symbol_info (ignore_abfd, symbol, ret)
  2346.       bfd *ignore_abfd;
  2347.       asymbol *symbol;
  2348.       symbol_info *ret;
  2349. {
  2350.   bfd_symbol_info (symbol, ret);
  2351.   if (symbol->name[0] == ' ')
  2352.     ret->name = "* empty table entry ";
  2353.   if (symbol->section==bfd_abs_section_ptr)
  2354.     ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
  2355. }
  2356.  
  2357.  
  2358.  
  2359. void
  2360. amiga_print_symbol (ignore_abfd, afile,  symbol, how)
  2361.       bfd *ignore_abfd;
  2362.       PTR afile;
  2363.       asymbol *symbol;
  2364.       bfd_print_symbol_type how;
  2365. {
  2366.   FILE *file = (FILE *)afile;
  2367.   
  2368.   switch (how) {
  2369.   case bfd_print_symbol_name:
  2370.     fprintf(file, "%s", symbol->name);
  2371.     break;
  2372.   case bfd_print_symbol_more:
  2373.     fprintf(stderr,"%4x %2x %2x",
  2374.         (unsigned int)((amiga_symbol(symbol)->hunk_number)&0xffff),0,amiga_symbol(symbol)->type);
  2375.     break;
  2376.   case bfd_print_symbol_all:
  2377.       {
  2378.     CONST char *section_name = symbol->section->name;
  2379.     if (symbol->name[0] == ' ')
  2380.       {
  2381.         fprintf(file, "* empty table entry ");
  2382.       }
  2383.     else
  2384.       {
  2385.         bfd_print_symbol_vandf ((PTR)file, symbol);
  2386.  
  2387.         fprintf(file," %-5s %04x %02x %s",
  2388.             section_name,
  2389.             (unsigned int)((amiga_symbol(symbol)->hunk_number)&0xffff),  /* ->desc */
  2390.             (unsigned) 0,                       /* ->other */
  2391.                                                 /* type */
  2392.             symbol->name);                      /* ->name */
  2393.     }
  2394.       }
  2395.     break;
  2396.   }
  2397. }
  2398.  
  2399.  long
  2400. amiga_get_reloc_upper_bound (abfd, asect)
  2401.      bfd *abfd;
  2402.      sec_ptr asect;
  2403. {
  2404.   if (bfd_get_format (abfd) != bfd_object)
  2405.     {
  2406.       bfd_set_error(bfd_error_invalid_operation);
  2407.       return 0;
  2408.     }
  2409.   return sizeof (arelent *) * (asect->reloc_count + 1);
  2410. }
  2411.  
  2412.  
  2413. /* slurp in relocs , amiga_digest_file left various pointers for us*/
  2414. static boolean 
  2415. amiga_slurp_relocs(bfd *abfd, sec_ptr section, asymbol **symbols)
  2416. {
  2417.   struct amiga_raw_symbol *sp;
  2418.   amiga_symbol_type *asp;
  2419.   long *lp;
  2420.   
  2421.   int i,n,br,j;
  2422.   int index;
  2423.   long hunk_number;
  2424.   int type;
  2425.  
  2426.   /* First browse through raw_relocs */
  2427.   for (i=0;i<amiga_per_section(section)->num_raw_relocs;i++)
  2428.     {
  2429.       lp=amiga_per_section(section)->raw_relocs[i];
  2430.  
  2431.       /* lp points to RELOC ID */
  2432.       /* first determine type of reloc */
  2433.       n = GL(lp);
  2434.       switch (n)
  2435.     {
  2436.     case HUNK_RELOC32: /* 32 bit ref */
  2437.     case HUNK_RELOC16: /* 16 bit ref */
  2438.     case HUNK_RELOC8: /* 8 bit ref */
  2439.     case HUNK_DREL32: /* 32 bit ref baserel */
  2440.     case HUNK_DREL16: /* 16 bit baserel */
  2441.     case HUNK_DREL8: /* 8 bit baserel */
  2442.       if (n < HUNK_DREL32)
  2443.         { /*0:8bit, 1: 16bit, 2:32bit */
  2444.           index=2-(n-HUNK_RELOC32);
  2445.           br=0; /* not base relative */
  2446.         }
  2447.       else
  2448.         {
  2449.           index=2-(n-HUNK_DREL32);
  2450.           br=1; /* base relative */
  2451.         }
  2452.  
  2453.       lp++;
  2454.       while ((n=GL(lp++))) /* read offsets and hunk number */
  2455.         {
  2456.           hunk_number=(long)GL(lp++);
  2457.           for (j=0;j<n;j++)
  2458.         { /* add relocs */
  2459.  
  2460.           if (!amiga_add_reloc(abfd,section,GL(lp+j),NULL,
  2461.                        amiga_howto_array[br][index],hunk_number))
  2462.             return false;
  2463.         }/* of for */
  2464.           lp+=n;
  2465.         }/* of while */
  2466.       break;
  2467.  
  2468.     default: /* error */
  2469.       bfd_set_error(bfd_error_wrong_format);
  2470.       return (false);
  2471.       break;
  2472.     }/* of switch */
  2473.  
  2474.     }/* of for i */
  2475.   
  2476.  
  2477.   /* Now step through the raw_symbols and add all relocs in them */
  2478.   for (sp=amiga_per_section(section)->first;sp!=NULL;sp=sp->next)
  2479.     {
  2480.       lp=&(sp->data[0]);
  2481.       /* points to id */
  2482.  
  2483.       while ((n=GL(lp++))) /* until end is reached */
  2484.     {
  2485.       type = (n>>24) & 0xff;
  2486.       n &= 0xffffff;
  2487.  
  2488.       /* lp points to symbol pointer (former 1st LW of name )*/
  2489.       asp=(amiga_symbol_type *) *lp;
  2490.  
  2491.       switch (type)
  2492.         {
  2493.         case EXT_SYMB:
  2494.         case EXT_DEF:
  2495.         case EXT_ABS: /* no relocs here, just advance the pointer */
  2496.           lp+=1+n;
  2497.           break;
  2498.  
  2499.         case EXT_COMMON: /* same as below, but advance lp by one to skip common size */
  2500.           lp++;
  2501.           /* Fall through */
  2502.         default: /* reference to something */
  2503.           /* skip name first */
  2504.           lp+=n;
  2505.  
  2506.           /* points to num of refs to hunk */
  2507.           n=GL(lp++);
  2508.  
  2509.           /* Add relocs to this section, relative to asp, offset is lp[i] */
  2510.           /* determine howto first */
  2511.           if (type==EXT_COMMON) /* 32 bit ref */
  2512.             {
  2513.               index=2;
  2514.               br=0;
  2515.             }
  2516.           else
  2517.             {
  2518.               if (type>EXT_REF32)
  2519.             type--; /* skip EXT_COMMON gap */
  2520.              
  2521.               type-=EXT_REF32;
  2522.               br=0;
  2523.  
  2524.               if (type>2) /* base relative */
  2525.                 {
  2526.               type-=3;
  2527.               br=1;
  2528.                 }
  2529.               index=2-type;
  2530.             }/* of else */
  2531.           
  2532.           for (i=0;i<n;i++) /* refs follow */
  2533.         {
  2534.           if (!amiga_add_reloc(abfd,section,GL(lp+i),asp,amiga_howto_array[br][index],-4))
  2535.             return false;
  2536.         }
  2537.           
  2538.           lp+=n;
  2539.           
  2540.           break;
  2541.         }/* of switch */
  2542.     }/* of while *lp */
  2543.     }/* Of for sp*/
  2544.  
  2545.   return true;
  2546.  
  2547. }/* Of slurp_relocs */
  2548.  
  2549.  
  2550. long
  2551. amiga_canonicalize_reloc (abfd, section, relptr, symbols)
  2552.      bfd *abfd;
  2553.      sec_ptr section;
  2554.      arelent **relptr;
  2555.      asymbol **symbols;
  2556. {
  2557.   amiga_reloc_type *src = NULL;
  2558.  
  2559.   if (!section->relocation && !amiga_slurp_relocs(abfd,section,symbols))
  2560.     return -1;
  2561.  
  2562.   src=(amiga_reloc_type *)section->relocation;
  2563.   while (src != (amiga_reloc_type *) 0)
  2564.     {
  2565.       *relptr++ = &src->relent;
  2566.       src = src->next;
  2567.     }
  2568.   *relptr = (arelent *) 0;
  2569.  
  2570.   return section->reloc_count;
  2571. }
  2572.  
  2573.  
  2574. /* Set section contents */
  2575. /* We do it the following way: 
  2576.    if this is a bss section ==> error
  2577.    otherwise, we try to allocate space for this section,
  2578.    if  this has not already been done
  2579.    Then we set the memory area to the contents */
  2580. static boolean
  2581. amiga_set_section_contents (abfd, section, location, offset, count)
  2582.      bfd *abfd;
  2583.      sec_ptr section;
  2584.      unsigned char *location;
  2585.      file_ptr offset;
  2586.       int count;
  2587. {
  2588.   unsigned char *contents;
  2589.  
  2590.   if ((section->flags&SEC_HAS_CONTENTS)==0) /* BSS */
  2591.     {
  2592.       bfd_set_error(bfd_error_invalid_operation);
  2593.       return false;
  2594.     }
  2595.   
  2596.   if ((section->flags&SEC_IN_MEMORY)==0) /* Not in memory, so alloc space */
  2597.     {
  2598.       contents=bfd_zalloc(abfd,section->_raw_size);
  2599.       if (!contents)
  2600.     {
  2601.       bfd_set_error(bfd_error_no_memory);
  2602.       return false;
  2603.     }
  2604.       
  2605.       DPRINT(5,("Allocated %lx bytes at %lx\n",section->_raw_size,contents));
  2606.  
  2607.       section->contents=contents;
  2608.       section->flags|=SEC_IN_MEMORY;
  2609.     }
  2610.   else /* In memory */
  2611.     contents=section->contents;
  2612.  
  2613.   /* Copy mem */
  2614.   memmove(contents+offset,location,count);
  2615.  
  2616.   return(true);
  2617.  
  2618. }/* Of section_set_contents */
  2619.  
  2620.  
  2621. /* FIXME: Is this everything ? */
  2622. static boolean
  2623. amiga_set_arch_mach (abfd, arch, machine)
  2624.      bfd *abfd;
  2625.      enum bfd_architecture arch;
  2626.      unsigned long machine;
  2627. {
  2628.   bfd_default_set_arch_mach(abfd, arch, machine);
  2629.  
  2630.   if (arch == bfd_arch_m68k)
  2631.     {
  2632.       switch (machine)
  2633.     {
  2634.     case 68000:
  2635.     case 68008:
  2636.     case 68010:
  2637.     case 68020:
  2638.     case 68030:
  2639.     case 68040:
  2640.     case 68070:
  2641.     case 0:
  2642.       return true;
  2643.     default:
  2644.       return false;
  2645.     }
  2646.     }
  2647.   else if (arch == bfd_arch_powerpc)
  2648.     {
  2649.       return true;
  2650.     }
  2651.   return false;
  2652. }
  2653.  
  2654. static int
  2655. DEFUN(amiga_sizeof_headers,(ignore_abfd, ignore),
  2656.       bfd *ignore_abfd AND
  2657.       boolean ignore)
  2658. {
  2659.   /* The amiga hunk format doesn't have headers.*/
  2660.   return 0;
  2661. }
  2662.  
  2663. /* Provided a BFD, a section and an offset into the section, calculate
  2664.    and return the name of the source file and the line nearest to the
  2665.    wanted location.  */
  2666. boolean
  2667. amiga_find_nearest_line(abfd, section, symbols, offset, filename_ptr,
  2668.             functionname_ptr, line_ptr)
  2669.      bfd *abfd;
  2670.      asection *section;
  2671.      asymbol **symbols;
  2672.      bfd_vma offset;
  2673.      char **filename_ptr;
  2674.      char **functionname_ptr;
  2675.      int *line_ptr;
  2676. {
  2677.   /* FIXME (see aoutx.h, for example) */
  2678.   return false;
  2679. }
  2680.  
  2681. static const struct reloc_howto_struct *
  2682. amiga_bfd_reloc_type_lookup (abfd, code)
  2683.        bfd *abfd;
  2684.        bfd_reloc_code_real_type code;
  2685. {
  2686.   switch (code)
  2687.     {
  2688.     case BFD_RELOC_8_PCREL:  return &howto_hunk_reloc8;
  2689.     case BFD_RELOC_16_PCREL: return &howto_hunk_reloc16;
  2690.     case BFD_RELOC_CTOR:    /* FIXME - assumes 32 bits */
  2691.     case BFD_RELOC_32_PCREL: return &howto_hunk_reloc32;
  2692.     case BFD_RELOC_8:        return &howto_hunk_drel8;
  2693.     case BFD_RELOC_16:       return &howto_hunk_drel16;
  2694.     case BFD_RELOC_32:       return &howto_hunk_drel32;
  2695.       /* FIXME: Add more cases here for base relative relocs*/
  2696.     default:                 return 0;
  2697.     }
  2698. }
  2699.  
  2700. static boolean
  2701. amiga_bfd_copy_private_bfd_data(bfd *ibfd, bfd *obfd)
  2702. {
  2703.   AMIGA_DATA(obfd)->IsLoadFile = AMIGA_DATA(ibfd)->IsLoadFile;
  2704.   return true;
  2705. }
  2706.  
  2707. /* We don't have core files.  */
  2708. #define    amiga_core_file_failing_command _bfd_dummy_core_file_failing_command
  2709. #define    amiga_core_file_failing_signal _bfd_dummy_core_file_failing_signal
  2710. #define    amiga_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
  2711.  
  2712. /* Entry points through BFD_JUMP_TABLE_ARCHIVE */
  2713. /* 101194: We do not use archive files, AMIGA Hunk load libs will be supported someday... ST */
  2714. #define    amiga_slurp_armap        bfd_slurp_armap
  2715. #define    amiga_slurp_extended_name_table    _bfd_slurp_extended_name_table
  2716. #define amiga_construct_extended_name_table _bfd_archive_bsd_construct_extended_name_table
  2717. #define    amiga_truncate_arname        bfd_bsd_truncate_arname
  2718. #define    amiga_write_armap        bsd_write_armap
  2719. #define    amiga_read_ar_hdr        _bfd_generic_read_ar_hdr
  2720. #define    amiga_openr_next_archived_file    bfd_generic_openr_next_archived_file
  2721.  
  2722. #define amiga_get_elt_at_index        _bfd_generic_get_elt_at_index
  2723. #define    amiga_generic_stat_arch_elt    bfd_generic_stat_arch_elt
  2724. #define amiga_update_armap_timestamp    _bfd_archive_bsd_update_armap_timestamp
  2725.  
  2726. /* Entry points through BFD_JUMP_TABLE_SYMBOLS */
  2727. #undef amiga_get_symtab_upper_bound    /* defined above */
  2728. #undef amiga_get_symtab            /* defined above */
  2729. #undef amiga_make_empty_symbol        /* defined above */
  2730. #undef amiga_print_symbol        /* defined above */
  2731. #undef amiga_get_symbol_info        /* defined above */
  2732. #define amiga_bfd_is_local_label    bfd_generic_is_local_label
  2733. #define amiga_get_lineno        (struct lineno_cache_entry *(*)())bfd_nullvoidptr
  2734. #undef amiga_find_nearest_line        /* defined above */
  2735. #define amiga_bfd_make_debug_symbol    (asymbol * (*)(bfd *, void *, unsigned long)) bfd_nullvoidptr
  2736. #define amiga_read_minisymbols        _bfd_generic_read_minisymbols
  2737. #define amiga_minisymbol_to_symbol    _bfd_generic_minisymbol_to_symbol
  2738.  
  2739. #define amiga_bfd_debug_info_start        bfd_void
  2740. #define amiga_bfd_debug_info_end        bfd_void
  2741. #define amiga_bfd_debug_info_accumulate    (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
  2742.  
  2743. /* NOTE: We use a special get_relocated_section_contents both in amiga AND in a.out files.
  2744.    In addition, we use an own final_link routine, which is nearly identical to _bfd_generic_final_link */
  2745. extern bfd_byte *get_relocated_section_contents(bfd*, struct bfd_link_info *,
  2746.                         struct bfd_link_order *, bfd_byte *,
  2747.                         boolean, asymbol **);
  2748. #define amiga_bfd_get_relocated_section_contents get_relocated_section_contents
  2749. #define amiga_bfd_relax_section                   bfd_generic_relax_section
  2750.  
  2751. #define amiga_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
  2752. #define amiga_bfd_link_add_symbols _bfd_generic_link_add_symbols
  2753. extern boolean amiga_final_link(bfd *, struct bfd_link_info *);
  2754. #define amiga_bfd_final_link amiga_final_link
  2755.  
  2756. /* Entry points through BFD_JUMP_TABLE_GENERIC */
  2757. #define amiga_close_and_cleanup         _bfd_generic_close_and_cleanup
  2758. #define amiga_bfd_free_cached_info    _bfd_generic_bfd_free_cached_info
  2759. /* amiga_new_section_hook defined above */
  2760. /* amiga_get_section_hook defined above */
  2761. #define amiga_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
  2762.  
  2763. /* Entry points through BFD_JUMP_TABLE_COPY */
  2764. #define amiga_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
  2765. #define amiga_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
  2766. #define amiga_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
  2767. #define amiga_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
  2768. #define amiga_bfd_print_private_flags _bfd_generic_bfd_print_private_flags
  2769. #define amiga_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
  2770.  
  2771. #define amiga_bfd_link_split_section  _bfd_generic_link_split_section
  2772.  
  2773. #if defined (amiga)
  2774. /* So that the JUMP_TABLE() macro below can work.  */
  2775. #undef amiga
  2776. #endif
  2777.  
  2778. const bfd_target amiga_vec =
  2779. {
  2780.   "amiga",        /* name */
  2781.   bfd_target_amiga_flavour,
  2782.   true,            /* data byte order is big */
  2783.   true,            /* header byte order is big */
  2784.   HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | WP_TEXT, /* object flags */
  2785.   SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC, /* section flags */
  2786.   '_',                /* symbol leading char */
  2787.   ' ',                /* ar_pad_char */
  2788.   15,                /* ar_max_namelen */    /* (15 for UNIX compatibility) */
  2789.   bfd_getb64, bfd_getb_signed_64, bfd_putb64, bfd_getb32, bfd_getb_signed_32,
  2790.   bfd_putb32, bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
  2791.   bfd_getb64, bfd_getb_signed_64, bfd_putb64, bfd_getb32, bfd_getb_signed_32,
  2792.   bfd_putb32, bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
  2793.   {
  2794.     /* bfd_check_format */
  2795.     _bfd_dummy_target,
  2796.     amiga_object_p,
  2797.     bfd_generic_archive_p,        /* AMIGA archives not supported yet */
  2798.     _bfd_dummy_target
  2799.   },
  2800.   {
  2801.     /* bfd_set_format */
  2802.     bfd_false,
  2803.     amiga_mkobject,
  2804.     _bfd_generic_mkarchive,        /* AMIGA archives not supported yet */
  2805.     bfd_false
  2806.   },
  2807.   {
  2808.     /* bfd_write_contents */
  2809.     bfd_false,
  2810.     amiga_write_object_contents,
  2811.     _bfd_write_archive_contents,    /* AMIGA archives not supported yet */
  2812.     bfd_false
  2813.   },
  2814.   BFD_JUMP_TABLE_GENERIC (amiga),
  2815.   BFD_JUMP_TABLE_COPY (amiga),
  2816.   BFD_JUMP_TABLE_CORE (_bfd_nocore),
  2817.   BFD_JUMP_TABLE_ARCHIVE (amiga),
  2818.   BFD_JUMP_TABLE_SYMBOLS (amiga),
  2819.   BFD_JUMP_TABLE_RELOCS (amiga),
  2820.   BFD_JUMP_TABLE_WRITE (amiga),
  2821.   BFD_JUMP_TABLE_LINK (amiga),
  2822.   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
  2823.   (PTR) 0
  2824. #if 0
  2825. /* fixme: no longer in use?  */
  2826.   /* How applications can find out about amiga relocation types (see
  2827.      documentation on reloc types).  */
  2828.   amiga_reloc_type_lookup
  2829. #endif
  2830. };
  2831.