home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / gnu / src / amiga / gdb-4.12-src.lha / gdb-4.12 / bfd / amiga.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-17  |  29.7 KB  |  1,020 lines

  1. /* BFD back-end for Commodore-Amiga AmigaDOS 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.  
  6. This file is part of BFD, the Binary File Descriptor library.
  7.  
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12.  
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with this program; if not, write to the Free Software
  20. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  21.  
  22. /* TODO:
  23.  
  24.    - writing of object files
  25.  
  26.    - .chipdata, .chipbss
  27.  
  28.    - fix fixme:s
  29.  
  30.    BFD:
  31.    - add flag to say if the format allows multiple sections with the
  32.      same name.  Fix bfd_get_section_by_name() and bfd_make_section()
  33.      accordingly.
  34.  
  35.    - dumpobj.c: the disassembler: use relocation record data to find symbolic
  36.      names of addresses, when available.  Needs new routine where one can
  37.      specify the source section of the symbol to be printed as well as some
  38.      rewrite of the disassemble functions.
  39.  
  40.    */
  41.  
  42. #include "bfd.h"
  43. #include "sysdep.h"
  44. #include "libbfd.h"
  45. #include "libamiga.h"
  46.  
  47. #define GL(x) bfd_get_32 (abfd, (bfd_byte *) (x))
  48.  
  49. #define DEBUG_AMIGA 0
  50.  
  51. static boolean amiga_digest_file ();
  52. static boolean amiga_mkobject ();
  53.  
  54. reloc_howto_type howto_hunk_reloc8 =
  55. {
  56.   HUNK_RELOC8, /* type */
  57.   0,           /* rightshift */
  58.   0,           /* size */
  59.   0,           /* bitsize */
  60.   true,        /* pc_relative */
  61.   0,           /* bitpos */
  62.   complain_overflow_bitfield,  /* complain_on_overflow */
  63.   0,           /* special_function */
  64.   "reloc8",    /* textual name */
  65.   false,       /* partial_inplace? */
  66.   0x000000ff,  /* src_mask */
  67.   0x000000ff,  /* dst_mask */
  68.   true         /* pcrel_offset */
  69. };
  70.  
  71. reloc_howto_type howto_hunk_reloc16 =
  72. {HUNK_RELOC16,0,0,0,true,0,complain_overflow_bitfield,0,"reloc16",false,0x0000ffff,0x0000ffff,true};
  73.  
  74. reloc_howto_type howto_hunk_reloc32 =
  75. {HUNK_RELOC32,0,0,0,true,0,complain_overflow_bitfield,0,"reloc32",false,0xffffffff,0xffffffff,true};
  76.  
  77. reloc_howto_type howto_hunk_drel8 =
  78. {HUNK_DREL8,0,0,0,false,0,complain_overflow_bitfield,0,"drel8",false,0x000000ff,0x000000ff,true};
  79.  
  80. reloc_howto_type howto_hunk_drel16 =
  81. {HUNK_DREL16,0,0,0,false,0,complain_overflow_bitfield,0,"drel16",false,0x0000ffff,0x0000ffff,true};
  82.  
  83. reloc_howto_type howto_hunk_drel32 =
  84. {HUNK_DREL32,0,0,0,false,0,complain_overflow_bitfield,0,"drel32",false,0xffffffff,0xffffffff,true};
  85.  
  86. reloc_howto_type *amiga_howto_array[2][3] =
  87. {
  88.   { &howto_hunk_reloc8, &howto_hunk_reloc16, &howto_hunk_reloc32 },
  89.   { &howto_hunk_drel8, &howto_hunk_drel16, &howto_hunk_drel32 }
  90. };
  91.  
  92. static bfd_target *
  93. amiga_object_p (abfd)
  94.      bfd *abfd;
  95. {
  96.   char buf[8];
  97.   unsigned int x;
  98.   struct stat stat_buffer;
  99.  
  100.   /* An Amiga object file must be at least 8 bytes long.  */
  101.   if (bfd_read ((PTR) buf, 1, 8, abfd) != 8)
  102.     {
  103.       bfd_error = wrong_format;
  104.       return 0;
  105.     }
  106.  
  107.   /* Does it look like an Amiga object file?  */
  108.   x = GL(buf);
  109.   if ((x != HUNK_UNIT) && (x != HUNK_HEADER))
  110.     {
  111.       /* Not an Amiga file.  */
  112.       bfd_error = wrong_format;
  113.       return 0;
  114.     }
  115.  
  116.   /* So far it seems to be an Amiga file.  Now slurp it
  117.      in and examine it closer.  */
  118.   if (-1 == fstat (fileno ((FILE *) abfd->iostream), &stat_buffer))
  119.     {
  120.       bfd_error = system_call_error;
  121.       return 0;
  122.     }
  123.  
  124.   /* Can't fail and return (but must be declared boolean to suit
  125.      other bfd requirements).  */
  126.   (void) amiga_mkobject (abfd);
  127.  
  128.   AMIGA_DATA(abfd)->symbol_tail_ptr = &AMIGA_DATA(abfd)->external_symbols;
  129.   
  130.   AMIGA_DATA(abfd)->first_byte = (unsigned long *) bfd_alloc (abfd, stat_buffer.st_size);
  131.   bfd_seek (abfd, 0, SEEK_SET);
  132.   bfd_read (AMIGA_DATA(abfd)->first_byte, 1, stat_buffer.st_size, abfd);
  133.   AMIGA_DATA(abfd)->file_pointer = AMIGA_DATA(abfd)->first_byte;
  134.   AMIGA_DATA(abfd)->file_end = (unsigned long *)((unsigned char *)AMIGA_DATA(abfd)->first_byte + stat_buffer.st_size);
  135.  
  136.   if (!amiga_digest_file (abfd))
  137.     {
  138.       /* Something went wrong.  */
  139.       return (struct bfd_target *) 0;
  140.     }
  141.  
  142.   /* Set default architecture to m68k:68020.  */
  143.   abfd->arch_info = bfd_scan_arch ("m68k:68020");
  144.  
  145.   return abfd->xvec;
  146. }
  147.  
  148. /* Skip over the hunk length longword + the number of longwords given there.  */
  149. #define next_hunk(abfd) \
  150.   { AMIGA_DATA(abfd)->file_pointer += 1 + GL(AMIGA_DATA(abfd)->file_pointer); }
  151.  
  152. static asection *
  153. amiga_get_section_by_hunk_number (abfd, hunk_number)
  154.      bfd *abfd;
  155.      unsigned int hunk_number;
  156. {
  157.   /* A cache, so we don't have to search the entire list every time.  */
  158.   static asection *last_reference;
  159.   asection *p;
  160.  
  161.   if (last_reference)
  162.     if (last_reference->target_index == hunk_number)
  163.       return last_reference;
  164.   for (p = abfd->sections; p != NULL; p = p->next)
  165.     if (p->target_index == hunk_number)
  166.       {
  167.     last_reference = p;
  168.     return p;
  169.       }
  170.   BFD_FAIL();
  171.   return (asection *) 0;
  172. }
  173.  
  174. /* Remember about a symbol found at the current file position.
  175.    Return number of longwords to advance the file_pointer with.  */
  176. static unsigned long
  177. amiga_add_symbol (abfd, hunk_number)
  178.      bfd *abfd;
  179.      unsigned int hunk_number;
  180. {
  181.   int length;
  182.  
  183.   amiga_symbol_type *symbol = bfd_alloc (abfd, sizeof (amiga_symbol_type));
  184.  
  185.   if (symbol)
  186.     {
  187.       amiga_data_type *amiga_data = AMIGA_DATA(abfd);
  188.       unsigned long *file_pointer = amiga_data->file_pointer;
  189.       unsigned char type = GL(file_pointer) >> 24;
  190.  
  191.       ++abfd->symcount;
  192.       *amiga_data->symbol_tail_ptr = symbol;
  193.       amiga_data->symbol_tail_ptr = &symbol->next;
  194.  
  195.       symbol->symbol.the_bfd = abfd;
  196.  
  197.       /* The symbol name is not necessarily nul-terminated in the file.
  198.      So, we move it to start on the length word and put a NUL at the
  199.      end of it all.  This way, we avoid allocating separate memory for
  200.      the symbol name, while assuring that the name is nul-terminated.  */
  201.  
  202.       length = (GL(file_pointer) & 0xffffff) << 2;
  203.       strncpy ((char *) file_pointer, (char *) (file_pointer + 1), length);
  204.       *(((char *)file_pointer) + length) = '\0';
  205.  
  206.       symbol->symbol.name = (char *)file_pointer;
  207.       symbol->symbol.udata = (PTR) NULL;
  208.       symbol->symbol.flags = ((type == EXT_DEF) || (type == EXT_ABS))
  209.                  ? BSF_GLOBAL : BSF_NO_FLAGS;
  210.       symbol->symbol.value = ((type == EXT_DEF) || (type == EXT_ABS))
  211.                  ? (symvalue) GL(file_pointer + 1 + (length>>2)) : 0;
  212.       symbol->symbol.section = amiga_get_section_by_hunk_number (abfd, hunk_number);
  213.       symbol->hunk_number = hunk_number;
  214.       symbol->type = type;
  215.       symbol->next = 0;
  216.     }
  217.   return length >> 2;
  218. }
  219.  
  220. static void
  221. amiga_add_reloc (abfd, section, offset, symbol_number, howto, target_hunk)
  222.      bfd *abfd;
  223.      asection *section;
  224.      bfd_size_type offset;
  225.      int symbol_number;
  226.      reloc_howto_type *howto;
  227.      unsigned int target_hunk;
  228. {
  229.   amiga_reloc_type *reloc;
  230.  
  231.   reloc = (amiga_reloc_type *) bfd_alloc (abfd, sizeof (amiga_reloc_type));
  232.   reloc->next = 0;
  233.  
  234.   abfd -> flags |= HAS_RELOC;
  235.   section -> flags |= SEC_RELOC;
  236.   ++section->reloc_count;
  237.   if (amiga_per_section(section)->reloc_tail_ptr)
  238.     amiga_per_section(section)->reloc_tail_ptr->next = reloc;
  239.   else
  240.     section->relocation = (struct reloc_cache_entry *) reloc;
  241.   amiga_per_section(section)->reloc_tail_ptr = reloc;
  242.   amiga_per_section(section)->reloc_tail_ptr->next = (amiga_reloc_type *) 0;
  243.   reloc->relent.address = offset;
  244.   reloc->relent.addend = 0;
  245.   reloc->relent.howto = howto;
  246.   reloc->symbol_number = symbol_number;
  247.   reloc->target_hunk = target_hunk;
  248. }
  249.  
  250. /* BFD doesn't currently allow multiple sections with the same
  251.    name, so we try a little harder to get a unique name.  */
  252. asection *
  253. amiga_make_unique_section (abfd, name)
  254.      bfd *abfd;
  255.      CONST char *name;
  256. {
  257.   asection *section;
  258.  
  259.   section = bfd_make_section (abfd, name);
  260.   if (!section)
  261.     {
  262.       int i = 1;
  263.       char *new_name;
  264.  
  265.       new_name = bfd_alloc (abfd, strlen(name) + 3);
  266.  
  267.       /* We try to come up with an original name (since BFD
  268.      currently requires all sections to have different names).  */
  269.       while (!section && (i<=99))
  270.     {
  271.       sprintf (new_name, "%s_%u", name, i);
  272.       section = bfd_make_section (abfd, new_name);
  273.     }
  274.  
  275.       if (!section)
  276.     {
  277.       /* Complain about the given name.  */
  278.       bfd_error = bad_value;
  279.       return 0;
  280.     }
  281.     }
  282.   return section;
  283. }
  284.  
  285. static boolean
  286. amiga_digest_file (abfd)
  287.      bfd *abfd;
  288. {
  289.   int is_chip;
  290.   int units = 0;
  291.   int hunk_number;
  292.   char *current_name = 0;
  293.   asection *current_section;
  294.   amiga_data_type *amiga_data = AMIGA_DATA(abfd);
  295.   int hunk_type;
  296.  
  297.   /* Hunk numbers starts with 0, but we pre-increment the hunk_number when
  298.      we assign a new one, so this really makes the first hunk number 0.  */
  299.   hunk_number = -1;
  300.  
  301.   while (units < 2)
  302.     {
  303.       hunk_type = HUNK_VALUE(GL(amiga_data->file_pointer++));
  304. #if DEBUG_AMIGA
  305.       printf ("Processing %s hunk...",
  306.           hunk_type == HUNK_UNIT ? "HUNK_UNIT" :
  307.           hunk_type == HUNK_NAME ? "HUNK_NAME" :
  308.           hunk_type == HUNK_DEBUG ? "HUNK_DEBUG" :
  309.           hunk_type == HUNK_OVERLAY ? "HUNK_OVERLAY" :
  310.           hunk_type == HUNK_BREAK ? "HUNK_BREAK" :
  311.           hunk_type == HUNK_HEADER ? "HUNK_HEADER" :
  312.           hunk_type == HUNK_CODE ? "HUNK_CODE" :
  313.           hunk_type == HUNK_DATA ? "HUNK_DATA" :
  314.           hunk_type == HUNK_BSS ? "HUNK_BSS" :
  315.           hunk_type == HUNK_RELOC8 ? "HUNK_RELOC8" :
  316.           hunk_type == HUNK_RELOC16 ? "HUNK_RELOC16" :
  317.           hunk_type == HUNK_RELOC32 ? "HUNK_RELOC32" :
  318.           hunk_type == HUNK_DREL8 ? "HUNK_DREL8" :
  319.           hunk_type == HUNK_DREL16 ? "HUNK_DREL16" :
  320.           hunk_type == HUNK_DREL32 ? "HUNK_DREL32" :
  321.           hunk_type == HUNK_SYMBOL ? "HUNK_SYMBOL" :
  322.           hunk_type == HUNK_EXT ? "HUNK_EXT" :
  323.           hunk_type == HUNK_END ? "HUNK_END" :
  324.           hunk_type == HUNK_LIB ? "HUNK_LIB" :
  325.           hunk_type == HUNK_INDEX ? "HUNK_INDEX" :
  326.           "*unknown*");
  327. #endif
  328.       switch (hunk_type)
  329.     {
  330.     case HUNK_UNIT:
  331.       current_name =
  332.         (GL(amiga_data->file_pointer) == 0)
  333.           ? "" : (char *)(amiga_data->file_pointer + 1);
  334.  
  335.       /* Allow only one program unit per bfd.  */
  336.       if (units++)
  337.         break;
  338.  
  339.       /* We always initialize hunk_number to -1, as desribed above.  */
  340.       hunk_number = -1;
  341.  
  342.       next_hunk (abfd);
  343.       break;
  344.  
  345.     case HUNK_NAME:
  346.       {
  347.         int length = GL(amiga_data->file_pointer) << 2;
  348.  
  349.         /* Change the name to a nul-terminated string.  */
  350.         strncpy ((char *)amiga_data->file_pointer, (char *)(amiga_data->file_pointer + 1), length);
  351.         *(((char *) amiga_data->file_pointer) + length) = '\0';
  352.         current_name = (char *) amiga_data->file_pointer;
  353.  
  354.         /* Can't use next_hunk() here, as we wrote over the hunk length
  355.            that next_hunk() looks at.  */
  356.         amiga_data->file_pointer += 1 + (length>>2);
  357.       }
  358.       break;
  359.  
  360.     case HUNK_DEBUG:
  361.       /* The format for the HUNK_DEBUG, as produced by Amiga GNU C:
  362.  
  363.          longwords:
  364.  
  365.             |---------------|
  366.             |  HUNK_DEBUG   |  0x3f1, Amigados imposed
  367.         |---------------|
  368.         |      N        |  Size of this hunk in longwords
  369.         |---------------|
  370.         | AMIGA_ZMAGIC  |  0413, same as BSD unix ZMAGIC
  371.         |---------------|
  372.         |  symtabsize   |  size of the symbol table in bytes
  373.         |---------------|
  374.         | stringtabsize |  size of the string table in bytes
  375.         |---------------|
  376.         | symtab data   |  symbol table in a.out format,
  377.         :               :  size is symtabsize.
  378.         :          .....:
  379.         |..........|    |  
  380.         |   stringtab   |  string table in a.out format,
  381.         :     data      :  size is stringtabsize.
  382.         :               :  (can start on byte boundary,
  383.         |---------------|   and can be padded at the end).
  384.  
  385.       /* Same as BSD unix ZMAGIC, but I don't want to include
  386.          any BSD files here.  */
  387.  
  388. #define    AMIGA_ZMAGIC 0413 
  389.  
  390.       /* Identifier for the GNU C format for HUNK_DEBUG on the Amiga.  */
  391.       if (GL(amiga_data->file_pointer + 1) == AMIGA_ZMAGIC)
  392.         {
  393.           amiga_data->symtab_size = GL(amiga_data->file_pointer + 2);
  394.           amiga_data->stringtab_size = GL(amiga_data->file_pointer + 3);
  395.           adata(abfd).sym_filepos =
  396.         (file_ptr) ((char *)(amiga_data->file_pointer + 4) - (char *)amiga_data->first_byte);
  397.           adata(abfd).str_filepos = adata(abfd).sym_filepos
  398.         + amiga_data->symtab_size;
  399.         }
  400.       else
  401.         fprintf (stderr, "unknown debug hunk type\n");
  402.       next_hunk (abfd);
  403.       break;
  404.  
  405.     case HUNK_OVERLAY:
  406.       /* Poor man's virtual memory.  Not yet supported.  */
  407.       /* fixme */
  408.       fprintf (stderr, "Warning: HUNK_OVERLAY encountered, ignoring.\n");
  409.       next_hunk (abfd);
  410.       break;
  411.  
  412.     case HUNK_BREAK:
  413.       /* HUNK_BREAK indicates the end of an overlay node.  This
  414.          hunk consists of a single longword, HUNK_BREAK.  As we
  415.          do not yet support overlays, we ignore thins hunk for now.  */
  416.       /* fixme */
  417.       fprintf(stderr, "Warning: HUNK_BREAK encountered, ignoring.\n");
  418.       next_hunk (abfd);
  419.       break;
  420.  
  421.     case HUNK_HEADER:
  422.       /* This is the header of a load file.
  423.          
  424.          Skip resident library names (never used, it's
  425.          an obsolete feature of the file format).  fixme: verify that!  */
  426.       while (GL(amiga_data->file_pointer))
  427.         next_hunk (abfd);
  428.  
  429.       /* Skip null-word, table_size, F & L, and size-table.  */
  430.       amiga_data->file_pointer += 4 + GL(amiga_data->file_pointer + 1) - GL(amiga_data->file_pointer + 2);
  431.       break;
  432.  
  433.     case HUNK_CODE:
  434.       is_chip = HUNK_ATTRIBUTE (GL(amiga_data->file_pointer - 1)) == HUNK_ATTR_CHIP;
  435.       if (is_chip)
  436.         fprintf (stderr, "Warning: CHIP code hunks are not supported, ignoring CHIP attribute\n");
  437.  
  438.       current_section = amiga_make_unique_section (abfd, (current_name && current_name[0]) ? current_name : ".text");
  439.       if (current_section == 0)
  440.         {
  441.           /* Fatal error.  */
  442.           return false;
  443.         }
  444.       current_section->filepos = (char *) (amiga_data->file_pointer + 1) - (char *)amiga_data->first_byte;
  445.       current_section->_raw_size = GL(amiga_data->file_pointer) << 2;
  446.       current_section->target_index = ++hunk_number;
  447.       bfd_set_section_flags (abfd, current_section, SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS);
  448.  
  449.       next_hunk (abfd);
  450.       break;
  451.  
  452.     case HUNK_DATA:
  453.       current_section = amiga_make_unique_section (abfd, (current_name && current_name[0]) ? current_name : ".data");
  454.       if (current_section == 0)
  455.         {
  456.           /* Fatal error.  */
  457.           return false;
  458.         }
  459.       current_section->filepos = (char *) (amiga_data->file_pointer + 1) - (char *)amiga_data->first_byte;
  460.       current_section->_raw_size = GL(amiga_data->file_pointer) << 2;
  461.       current_section->target_index = ++hunk_number;
  462.       bfd_set_section_flags (abfd, current_section, SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS);
  463.       next_hunk (abfd);
  464.       break;
  465.  
  466.     case HUNK_BSS:
  467.       current_section = amiga_make_unique_section (abfd, (current_name && current_name[0]) ? current_name : ".bss");
  468.       if (current_section == 0)
  469.         {
  470.           /* Fatal error.  */
  471.           return false;
  472.         }
  473.       current_section->filepos = (file_ptr) -1;
  474.       current_section->_raw_size = GL(amiga_data->file_pointer) << 2;
  475.       current_section->target_index = ++hunk_number;
  476.       bfd_set_section_flags (abfd, current_section, SEC_ALLOC);
  477.       ++ amiga_data->file_pointer;
  478.       break;
  479.  
  480.     case HUNK_RELOC8:
  481.     case HUNK_RELOC16:
  482.     case HUNK_RELOC32:
  483.     case HUNK_DREL8:
  484.     case HUNK_DREL16:
  485.     case HUNK_DREL32:
  486.       {
  487.         int size, base_relative;
  488.         reloc_howto_type *howto;
  489.       
  490.         base_relative = GL(&amiga_data->file_pointer[-1]) >= HUNK_DREL32;
  491.         size = (base_relative ? HUNK_DREL8 : HUNK_RELOC8) - GL(&amiga_data->file_pointer[-1]);
  492.         howto = amiga_howto_array[base_relative][size];
  493.  
  494.         while (GL(amiga_data->file_pointer))
  495.           {
  496.         long to_reloc = GL(amiga_data->file_pointer + 1);
  497.         long n        = GL(amiga_data->file_pointer);
  498.         long i = 1;
  499.         
  500.         while (i++ < n)
  501.           amiga_add_reloc (abfd, current_section,
  502.                    GL(amiga_data->file_pointer + i + 1),
  503.                    -1, howto, to_reloc);
  504.         amiga_data->file_pointer += GL(amiga_data->file_pointer) + 2;
  505.           }
  506.         ++amiga_data->file_pointer;
  507.       }
  508.       break;
  509.  
  510.     case HUNK_SYMBOL:
  511.       /* "You use this block to attach a symbol table to a hunk so that
  512.          you can use a symbolic debugger on the code.  The linker passes
  513.          symbol table blocks through attached to the hunk and, if the hunks
  514.          are coagulated, coagulates the symbol tables.  The loader does not
  515.          load symbol table blocks into memory; when this is required,
  516.          the debugger is expected to read the load file."
  517.                                            -- The AmigaDOS Manual, 3rd ed.
  518.  
  519.          GNU C on the Amiga passes all needed debug information in the
  520.          debug hunk (HUNK_DEBUG).  Thus we do not depend on HUNK_SYMBOL
  521.          for the GNU debugger GDB to get symbol information and can safely
  522.          ignore this hunk.
  523.            If, however, someone would like to add full support for
  524.          HUNK_SYMBOL to be able to use some debugger that doesn't
  525.          understand the GNU C debug hunk, please go ahead.
  526.            As of this writing, the BarFly debugger written by
  527.          Ralph "laire" Schmidt is starting to understand the GNU C debug
  528.          hunk.  As the GNU version of the debug hunk is publically
  529.          documented, unlike for example the format used by SAS Insitute
  530.          on the Amiga, I hope other debugger writers will follow his
  531.          example.                          -- vinsci@nic.funet.fi   */
  532.  
  533.       /* The formats of the HUNK_SYMBOL and HUNK_EXT hunks are exactly
  534.          the same, except the type byte of anything in the HUNK_SYMBOL
  535.          is always zero.  Thus we ignore the symbol hunk by ignoring
  536.          all EXT_SYMB's below and can thus reuse the code.  */
  537.  
  538.       /* Fall through */
  539.  
  540.     case HUNK_EXT:
  541.  
  542.       while (GL(amiga_data->file_pointer))
  543.         {
  544.           int num, size, base_relative;
  545.           unsigned char type;
  546.           reloc_howto_type *howto;
  547.  
  548.           /* Make sure we don't set this flag for HUNK_SYMBOL hunks.  */
  549.           if (hunk_type == HUNK_EXT)
  550.             abfd -> flags |= HAS_SYMS;
  551.           
  552.           switch (type = (GL(amiga_data->file_pointer) >> 24))
  553.         {
  554.         case EXT_SYMB:  /* This is a symbol from HUNK_SYMBOL, which we
  555.                    ignore.  See long description above.  */
  556.           num = GL(amiga_data->file_pointer) & 0xffffff;
  557.           amiga_data->file_pointer += 2 + num;
  558.           break;
  559.  
  560.         case EXT_DEF:   /* Relocatable definition.  */
  561.         case EXT_ABS:   /* Absolute definition.  */
  562.         /* case EXT_RES: obsolete; Resident library definition.  */
  563.  
  564.           num = amiga_add_symbol (abfd, hunk_number);
  565.           amiga_data->file_pointer += 2 + num;
  566.           break;
  567.           
  568.         case EXT_COMMON:  /* 32 bit reference to COMMON block.  */
  569.           {
  570.             int i = 0;
  571.  
  572.             num = amiga_add_symbol (abfd, hunk_number);
  573.             amiga_data->file_pointer += 2 + num;
  574.           
  575.             num = GL(amiga_data->file_pointer);
  576.             while (i++ < num)
  577.               amiga_add_reloc
  578.             (abfd, current_section, GL(amiga_data->file_pointer + i),
  579.              amiga_data->a.n_symbols, &howto_hunk_drel32, -1);
  580.             next_hunk (abfd);
  581.           }
  582.           break;
  583.           
  584.         case EXT_REF8:     /*  8 bit reference to symbol.  */
  585.         case EXT_REF16:    /* 16 bit reference to symbol.  */
  586.         case EXT_REF32:    /* 32 bit reference to symbol.  */
  587.         case EXT_DEXT8:    /*  8 bit data relative reference.  */
  588.         case EXT_DEXT16:   /* 16 bit data relative reference.  */
  589.         case EXT_DEXT32:   /* 32 bit data relative reference.  */
  590.           size = GL(amiga_data->file_pointer) >> 24;
  591.           base_relative = size >= EXT_DEXT32;
  592.           switch (size)
  593.             {
  594.             case EXT_REF32:
  595.             case EXT_DEXT32:
  596.               size = 2;
  597.               break;
  598.             case EXT_REF16:
  599.             case EXT_DEXT16:
  600.               size = 1;
  601.               break;
  602.             default:
  603.               size = 0;
  604.             }
  605.           howto = amiga_howto_array[base_relative][size];
  606.           
  607.           num = amiga_add_symbol (abfd, hunk_number);
  608.           
  609.           amiga_data->file_pointer += 1 + num;
  610.           {
  611.             int i = 0;
  612.             
  613.             num = GL(amiga_data->file_pointer);
  614.             while (i++ < num)
  615.               amiga_add_reloc (abfd, current_section,
  616.                        GL(amiga_data->file_pointer + i),
  617.                        amiga_data->a.n_symbols, howto, -1);
  618.           }
  619.           next_hunk (abfd);
  620.           break;
  621.           
  622.         default:
  623.           fprintf (stderr, "Unknown symbol type %d, don't know how to handle.\n", type);
  624.           /* Fatal error.  */
  625.           return false;
  626.         }
  627.         }
  628.       ++ amiga_data->file_pointer;
  629.       break;
  630.  
  631.     case HUNK_END:
  632.       break;
  633.  
  634.     case HUNK_LIB:
  635.     case HUNK_INDEX:
  636.       fprintf (stderr, "Can not handle HUNK_LIB and HUNK_INDEX hunks.\nConvert the library to ALINK (join) format.\n");
  637.       break;
  638.  
  639.     default:
  640.       fprintf (stderr, "Unknown hunk type $%x, unit offset = $%x.\n",
  641.            GL(amiga_data->file_pointer -1),
  642.            ((amiga_data->file_pointer - 1) - amiga_data->first_byte) * 4);
  643.       /* Fatal error.  */
  644.       return false;
  645.     }
  646.  
  647. #if DEBUG_AMIGA
  648.       printf ("...hunk processed.\n");
  649. #endif
  650.       if (amiga_data->file_pointer >= amiga_data->file_end)
  651.     break;
  652.     }
  653.  
  654.   /* OK.  */
  655.   return true;
  656. }
  657.  
  658. static boolean
  659. amiga_mkobject (abfd)
  660.      bfd *abfd;
  661. {
  662.   struct amiga_data_struct *rawptr;
  663.  
  664.   rawptr = (struct amiga_data_struct *) bfd_zalloc (abfd, sizeof (struct amiga_data_struct));
  665.   abfd->tdata.amiga_data = rawptr;
  666.  
  667.   return true;
  668. }
  669.  
  670. static boolean
  671. amiga_write_object_contents (abfd)
  672.      bfd *abfd;
  673. {
  674.   /* fixme */
  675.   return true;
  676. }
  677.  
  678. static boolean
  679. amiga_get_section_contents (abfd, section, location, offset, count)
  680.      bfd *abfd;
  681.      sec_ptr section;
  682.      PTR location;
  683.      file_ptr offset;
  684.      bfd_size_type count;
  685. {
  686.   memmove ((void *) location,
  687.        (void *) (((int) AMIGA_DATA(abfd)->first_byte)
  688.              + (int) section->filepos
  689.              + (int) offset),
  690.        count);
  691.   return true;
  692. }
  693.  
  694. boolean
  695. amiga_new_section_hook (abfd, newsect)
  696.      bfd *abfd;
  697.      asection *newsect;
  698. {
  699.   newsect->used_by_bfd = (PTR) bfd_alloc (abfd, sizeof (amiga_per_section_type));
  700.   newsect->alignment_power = 2;
  701.   amiga_per_section(newsect)->reloc_tail_ptr = (amiga_reloc_type *) 0;
  702.   return true;
  703. }
  704.  
  705. void
  706. amiga_slurp_symbol_table (abfd)
  707.      bfd *abfd;
  708. {
  709.   /* fixme:  currently we always load the symbols at check_format time,
  710.      so we don't do it here.  When the amiga backend someday doesn't
  711.      keep more info than needed in memory, this will have to be fixed.  */
  712. }
  713.  
  714. unsigned int
  715. amiga_get_symtab_upper_bound (abfd)
  716.      bfd *abfd;
  717. {
  718.   amiga_slurp_symbol_table (abfd);
  719.   return (abfd->symcount != 0) ?
  720.     (abfd->symcount+1) * (sizeof (amiga_symbol_type *)) : 0;
  721. }
  722.  
  723. unsigned int
  724. amiga_get_symtab (abfd, location)
  725.      bfd *abfd;
  726.      asymbol **location;
  727. {
  728.   amiga_symbol_type *symp;
  729.  
  730.   if (abfd->symcount)
  731.     {
  732.       int i = 0;
  733.  
  734.       amiga_slurp_symbol_table (abfd);
  735.  
  736.       for (symp = AMIGA_DATA(abfd)->external_symbols;
  737.                  symp != (amiga_symbol_type *) NULL;
  738.                  symp = symp->next)
  739.     {
  740.       location[i++] = &symp->symbol;
  741.     }
  742.       for (symp = AMIGA_DATA(abfd)->external_references;
  743.                  symp != (amiga_symbol_type *) NULL;
  744.                  symp = symp->next)
  745.     {
  746.       location[i++] = &symp->symbol;
  747.     }
  748.     }
  749.   return abfd->symcount;
  750. }
  751.  
  752. asymbol *
  753. amiga_make_empty_symbol (abfd)
  754.      bfd *abfd;
  755. {
  756.   amiga_symbol_type *new =
  757.     (amiga_symbol_type *) bfd_zalloc (abfd, sizeof (amiga_symbol_type));
  758.   new->symbol.the_bfd = abfd;
  759.   return &new->symbol;
  760. }
  761.  
  762. void 
  763. amiga_get_symbol_info (ignore_abfd, symbol, ret)
  764.       bfd *ignore_abfd;
  765.       asymbol *symbol;
  766.       symbol_info *ret;
  767. {
  768.   bfd_symbol_info (symbol, ret);
  769.   if (symbol->name[0] == ' ')
  770.     ret->name = "* empty table entry ";
  771.   if (!symbol->section)
  772.     ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A';
  773. }
  774.  
  775. void 
  776. amiga_print_symbol (ignore_abfd, afile,  symbol, how)
  777.       bfd *ignore_abfd;
  778.       PTR afile;
  779.       asymbol *symbol;
  780.       bfd_print_symbol_type how;
  781. {
  782.   FILE *file = (FILE *)afile;
  783.  
  784.   switch (how) {
  785.   case bfd_print_symbol_name:
  786.     fprintf(file, "%s", symbol->name);
  787.     break;
  788.   case bfd_print_symbol_more:
  789.     /* fixme: adapt for amiga */
  790.     BFD_FAIL();
  791.     break;
  792.   case bfd_print_symbol_all:
  793.       {
  794.     CONST char *section_name = (symbol->section == (asection *)NULL)
  795.       ? (CONST char *)"*abs" : symbol->section->name;
  796.     if (symbol->name[0] == ' ')
  797.       {
  798.         fprintf(file, "* empty table entry ");
  799.       }
  800.     else
  801.       {
  802.         bfd_print_symbol_vandf ((PTR)file, symbol);
  803.  
  804.         fprintf(file," %-5s %04x %02x %s",
  805.             section_name,
  806.             amiga_symbol(symbol)->hunk_number,  /* ->desc */
  807.             (unsigned) 0,                       /* ->other */
  808.                                                 /* type */
  809.             symbol->name);                      /* ->name */
  810.     }
  811.       }
  812.     break;
  813.   }
  814. }
  815.  
  816. static unsigned int
  817. amiga_get_reloc_upper_bound (abfd, asect)
  818.      bfd *abfd;
  819.      sec_ptr asect;
  820. {
  821.   if (bfd_get_format (abfd) != bfd_object)
  822.     {
  823.       bfd_error = invalid_operation;
  824.       return 0;
  825.     }
  826.   return sizeof (arelent *) * (asect->reloc_count + 1);
  827. }
  828.  
  829. unsigned int
  830. amiga_canonicalize_reloc (abfd, section, relptr, symbols)
  831.      bfd *abfd;
  832.      sec_ptr section;
  833.      arelent **relptr;
  834.      asymbol **symbols;
  835. {
  836.   amiga_reloc_type *src = (amiga_reloc_type *) section->relocation;
  837.   int i = 0;
  838.  
  839.   while (src != (amiga_reloc_type *) 0)
  840.     {
  841.       if (src->symbol_number == -1)
  842.         src->relent.sym_ptr_ptr =
  843.       &(amiga_get_section_by_hunk_number(abfd,src->target_hunk))->symbol;
  844.       else
  845.     src->relent.sym_ptr_ptr = symbols + i++;
  846.       *relptr++ = &src->relent;
  847.       src = src->next;
  848.     }
  849.   *relptr = (arelent *) 0;
  850.  
  851.   return section->reloc_count;
  852. }
  853.  
  854. static boolean
  855. amiga_set_section_contents (abfd, section, location, offset, count)
  856.      bfd *abfd;
  857.      sec_ptr section;
  858.      unsigned char *location;
  859.      file_ptr offset;
  860.       int count;
  861. {
  862.   /* fixme */
  863.   return true;
  864. }
  865.  
  866. static boolean
  867. amiga_set_arch_mach (abfd, arch, machine)
  868.      bfd *abfd;
  869.      enum bfd_architecture arch;
  870.      unsigned long machine;
  871. {
  872.   bfd_default_set_arch_mach(abfd, arch, machine);
  873.  
  874.   if (arch == bfd_arch_m68k)
  875.     {
  876.       switch (machine)
  877.     {
  878.     case 68000:
  879.     case 68008:
  880.     case 68010:
  881.     case 68020:
  882.     case 68030:
  883.     case 68040:
  884.     case 68070:
  885.     case 0:
  886.       return true;
  887.     default:
  888.       return false;
  889.     }
  890.     }
  891.   return false;
  892. }
  893.  
  894. static int 
  895. DEFUN(amiga_sizeof_headers,(ignore_abfd, ignore),
  896.       bfd *ignore_abfd AND
  897.       boolean ignore)
  898. {
  899.   /* The amiga hunk format doesn't have headers.  */
  900.   return 0;
  901. }
  902.  
  903. /* Provided a BFD, a section and an offset into the section, calculate
  904.    and return the name of the source file and the line nearest to the
  905.    wanted location.  */
  906. boolean
  907. amiga_find_nearest_line(abfd, section, symbols, offset, filename_ptr,
  908.             functionname_ptr, line_ptr)
  909.      bfd *abfd;
  910.      asection *section;
  911.      asymbol **symbols;
  912.      bfd_vma offset;
  913.      char **filename_ptr;
  914.      char **functionname_ptr;
  915.      int *line_ptr;
  916. {
  917.   /* fixme (see aoutx.h, for example) */
  918.   return false;
  919. }
  920.  
  921. static const struct reloc_howto_struct *
  922. amiga_bfd_reloc_type_lookup (abfd, code)
  923.        bfd *abfd;
  924.        bfd_reloc_code_real_type code;
  925. {
  926.   switch (code)
  927.     {
  928.     case BFD_RELOC_8_PCREL:  return &howto_hunk_reloc8;
  929.     case BFD_RELOC_16_PCREL: return &howto_hunk_reloc16;
  930.     case BFD_RELOC_32_PCREL: return &howto_hunk_reloc32;
  931.     case BFD_RELOC_8:        return &howto_hunk_drel8;
  932.     case BFD_RELOC_16:       return &howto_hunk_drel16;
  933.     case BFD_RELOC_32:       return &howto_hunk_drel32;
  934.     default:                 return 0;
  935.     }
  936. }
  937.  
  938.  
  939. /* We don't have core files.  */
  940. #define    amiga_core_file_failing_command _bfd_dummy_core_file_failing_command
  941. #define    amiga_core_file_failing_signal _bfd_dummy_core_file_failing_signal
  942. #define    amiga_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
  943.  
  944. /* We use BSD-Unix generic archive files (fixme: test that this actually works).  */
  945. #define    amiga_openr_next_archived_file    bfd_generic_openr_next_archived_file
  946. #define    amiga_generic_stat_arch_elt    bfd_generic_stat_arch_elt
  947. #define    amiga_slurp_armap        bfd_slurp_bsd_armap
  948. #define    amiga_slurp_extended_name_table    bfd_true
  949. #define    amiga_write_armap        bsd_write_armap
  950. #define    amiga_truncate_arname        bfd_bsd_truncate_arname
  951.  
  952. #define amiga_bfd_debug_info_start        bfd_void
  953. #define amiga_bfd_debug_info_end        bfd_void
  954. #define amiga_bfd_debug_info_accumulate    (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
  955.  
  956. /* fixme: (when everything else has been done) a tailor-made
  957.    amiga_get_relocated_section_contents would probably be faster
  958.    than the generic routine.  */
  959. #define amiga_bfd_get_relocated_section_contents  bfd_generic_get_relocated_section_contents
  960. #define amiga_bfd_relax_section                   bfd_generic_relax_section
  961. #define amiga_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
  962. #define amiga_close_and_cleanup         bfd_generic_close_and_cleanup
  963. #define amiga_bfd_make_debug_symbol \
  964.   ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
  965. #define amiga_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
  966. #define amiga_bfd_link_add_symbols _bfd_generic_link_add_symbols
  967. #define amiga_bfd_final_link _bfd_generic_final_link
  968.  
  969. #if defined (amiga)
  970. /* So that the JUMP_TABLE() macro below can work.  */
  971. #undef amiga
  972. #endif
  973.  
  974. bfd_target amiga_vec =
  975. {
  976.   "amiga",        /* name */
  977.   bfd_target_amiga_flavour,
  978.   true,            /* data byte order is little */
  979.   true,            /* header byte order is little */
  980.   HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT, /* object flags */
  981.   SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC, /* section flags */
  982.   '_',                /* symbol leading char */
  983.   ' ',                /* ar_pad_char */
  984.   31,                /* ar_max_namelen */
  985.   2,                /* minimum align */
  986.   bfd_getb64, bfd_getb_signed_64, bfd_putb64, bfd_getb32, bfd_getb_signed_32,
  987.   bfd_putb32, bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
  988.   bfd_getb64, bfd_getb_signed_64, bfd_putb64, bfd_getb32, bfd_getb_signed_32,
  989.   bfd_putb32, bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
  990.   {
  991.     /* bfd_check_format */
  992.     _bfd_dummy_target,
  993.     amiga_object_p, 
  994.     bfd_generic_archive_p,
  995.     _bfd_dummy_target
  996.   },
  997.   {
  998.     /* bfd_set_format */
  999.     bfd_false,
  1000.     amiga_mkobject,
  1001.     _bfd_generic_mkarchive,
  1002.     bfd_false
  1003.   },
  1004.   {
  1005.     /* bfd_write_contents */
  1006.     bfd_false,
  1007.     amiga_write_object_contents,
  1008.     _bfd_write_archive_contents,
  1009.     bfd_false
  1010.   },
  1011.   JUMP_TABLE(amiga),
  1012.   (PTR) 0
  1013. #if 0
  1014. /* fixme: no longer in use?  */
  1015.   /* How applications can find out about amiga relocation types (see
  1016.      documentation on reloc types).  */
  1017.   amiga_reloc_type_lookup
  1018. #endif
  1019. };
  1020.