home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / gnu / djgpp / diffs / binutils.2 / bfd / coff-go3.c < prev    next >
Encoding:
Text File  |  1993-11-28  |  14.0 KB  |  345 lines

  1. *** orig/binutils.2/bfd/coff-go3.c    Sun Jun 20 10:24:54 1993
  2. --- src/binutils.2/bfd/coff-go3.c    Sun Jun 20 15:15:52 1993
  3. ***************
  4. *** 0 ****
  5. --- 1,339 ----
  6. + /* BFD back-end for GO32 COFF files.
  7. +    Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
  8. +    Written by Cygnus Support.
  9. +    Edited by DJ Delorie
  10. + This file is part of BFD, the Binary File Descriptor library.
  11. + This program is free software; you can redistribute it and/or modify
  12. + it under the terms of the GNU General Public License as published by
  13. + the Free Software Foundation; either version 2 of the License, or
  14. + (at your option) any later version.
  15. + This program is distributed in the hope that it will be useful,
  16. + but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. + GNU General Public License for more details.
  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. + #include "bfd.h"
  23. + #include "sysdep.h"
  24. + #include "libbfd.h"
  25. + #include "obstack.h"
  26. + #include "coff/i386.h"
  27. + #include "coff/internal.h"
  28. + #include "libcoff.h"
  29. + static bfd_reloc_status_type coff_go32_reloc PARAMS ((bfd *abfd,
  30. +                               arelent *reloc_entry,
  31. +                               asymbol *symbol,
  32. +                               PTR data,
  33. +                               asection *input_section,
  34. +                               bfd *output_bfd));
  35. + /* For some reason when using i386 COFF the value stored in the .text
  36. +    section for a reference to a common symbol is the value itself plus
  37. +    any desired offset.  Ian Taylor, Cygnus Support.  */
  38. + /* If we are producing relocateable output, we need to do some
  39. +    adjustments to the object file that are not done by the
  40. +    bfd_perform_relocation function.  This function is called by every
  41. +    reloc type to make any required adjustments.  */
  42. + static bfd_reloc_status_type
  43. + coff_go32_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd)
  44. +      bfd *abfd;
  45. +      arelent *reloc_entry;
  46. +      asymbol *symbol;
  47. +      PTR data;
  48. +      asection *input_section;
  49. +      bfd *output_bfd;
  50. + {
  51. +   symvalue diff;
  52. +   if (output_bfd == (bfd *) NULL)
  53. +     return bfd_reloc_continue;
  54. +   if (bfd_is_com_section (symbol->section))
  55. +     {
  56. +       /* We are relocating a common symbol.  The current value in the
  57. +      object file is ORIG + OFFSET, where ORIG is the value of the
  58. +      common symbol as seen by the object file when it was compiled
  59. +      (this may be zero if the symbol was undefined) and OFFSET is
  60. +      the offset into the common symbol (normally zero, but may be
  61. +      non-zero when referring to a field in a common structure).
  62. +      ORIG is the negative of reloc_entry->addend, which is set by
  63. +      the CALC_ADDEND macro below.  We want to replace the value in
  64. +      the object file with NEW + OFFSET, where NEW is the value of
  65. +      the common symbol which we are going to put in the final
  66. +      object file.  NEW is symbol->value.  */
  67. +       diff = symbol->value + reloc_entry->addend;
  68. +     }
  69. +   else
  70. +     {
  71. +       /* For some reason bfd_perform_relocation always effectively
  72. +      ignores the addend for a COFF target when producing
  73. +      relocateable output.  This seems to be always wrong for 386
  74. +      COFF, so we handle the addend here instead.  */
  75. +       diff = reloc_entry->addend;
  76. +     }
  77. + #define DOIT(x) \
  78. +   x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
  79. +   if (diff != 0)
  80. +     {
  81. +       reloc_howto_type *howto = reloc_entry->howto;
  82. +       char *addr = (char *) data + reloc_entry->address;
  83. +       switch (howto->size)
  84. +     {
  85. +     case 0:
  86. +       {
  87. +         char x = bfd_get_8 (abfd, addr);
  88. +         DOIT (x);
  89. +         bfd_put_8 (abfd, x, addr);
  90. +       }
  91. +       break;
  92. +     case 1:
  93. +       {
  94. +         short x = bfd_get_16 (abfd, addr);
  95. +         DOIT (x);
  96. +         bfd_put_16 (abfd, x, addr);
  97. +       }
  98. +       break;
  99. +     case 2:
  100. +       {
  101. +         long x = bfd_get_32 (abfd, addr);
  102. +         DOIT (x);
  103. +         bfd_put_32 (abfd, x, addr);
  104. +       }
  105. +       break;
  106. +     default:
  107. +       abort ();
  108. +     }
  109. +     }
  110. +   /* Now let bfd_perform_relocation finish everything up.  */
  111. +   return bfd_reloc_continue;
  112. + }
  113. + static reloc_howto_type howto_table[] = 
  114. + {
  115. +   {0},
  116. +   {1},
  117. +   {2},
  118. +   {3},
  119. +   {4},
  120. +   {5},
  121. +   HOWTO (R_DIR32,               /* type */                                 
  122. +      0,                    /* rightshift */                           
  123. +      2,                    /* size (0 = byte, 1 = short, 2 = long) */ 
  124. +      32,                    /* bitsize (obsolete) */                   
  125. +      false,                    /* pc_relative */                          
  126. +      0,                    /* bitpos */                               
  127. +      true,                    /* absolute (obsolete) */                  
  128. +      true,                    /* complain_on_overflow */                 
  129. +      coff_go32_reloc,       /* special_function */                     
  130. +      "dir32",               /* name */                                 
  131. +      true,                    /* partial_inplace */                      
  132. +      0xffffffff,            /* src_mask */                             
  133. +      0xffffffff,            /* dst_mask */                             
  134. +      false),                /* pcrel_offset */
  135. +   {7},
  136. +   {010},
  137. +   {011},
  138. +   {012},
  139. +   {013},
  140. +   {014},
  141. +   {015},
  142. +   {016},
  143. +   HOWTO (R_RELBYTE,        /* type */                                 
  144. +      0,            /* rightshift */                           
  145. +      0,            /* size (0 = byte, 1 = short, 2 = long) */ 
  146. +      8,            /* bitsize (obsolete) */                   
  147. +      false,            /* pc_relative */                          
  148. +      0,            /* bitpos */                               
  149. +      true,            /* absolute (obsolete) */                  
  150. +      true,            /* complain_on_overflow */                 
  151. +      coff_go32_reloc,    /* special_function */                     
  152. +      "8",            /* name */                                 
  153. +      true,            /* partial_inplace */                      
  154. +      0x000000ff,        /* src_mask */                             
  155. +      0x000000ff,        /* dst_mask */                             
  156. +      false),        /* pcrel_offset */
  157. +   HOWTO (R_RELWORD,        /* type */                                 
  158. +      0,            /* rightshift */                           
  159. +      1,            /* size (0 = byte, 1 = short, 2 = long) */ 
  160. +      16,            /* bitsize (obsolete) */                   
  161. +      false,            /* pc_relative */                          
  162. +      0,            /* bitpos */                               
  163. +      true,            /* absolute (obsolete) */                  
  164. +      true,            /* complain_on_overflow */                 
  165. +      coff_go32_reloc,    /* special_function */                     
  166. +      "16",            /* name */                                 
  167. +      true,            /* partial_inplace */                      
  168. +      0x0000ffff,        /* src_mask */                             
  169. +      0x0000ffff,        /* dst_mask */                             
  170. +      false),        /* pcrel_offset */
  171. +   HOWTO (R_RELLONG,        /* type */                                 
  172. +      0,            /* rightshift */                           
  173. +      2,            /* size (0 = byte, 1 = short, 2 = long) */ 
  174. +      32,            /* bitsize (obsolete) */                   
  175. +      false,            /* pc_relative */                          
  176. +      0,            /* bitpos */                               
  177. +      true,            /* absolute (obsolete) */                  
  178. +      true,            /* complain_on_overflow */                 
  179. +      coff_go32_reloc,    /* special_function */                     
  180. +      "32",            /* name */                                 
  181. +      true,            /* partial_inplace */                      
  182. +      0xffffffff,        /* src_mask */                             
  183. +      0xffffffff,        /* dst_mask */                             
  184. +      false),        /* pcrel_offset */
  185. +   HOWTO (R_PCRBYTE,        /* type */                                 
  186. +      0,            /* rightshift */                           
  187. +      0,            /* size (0 = byte, 1 = short, 2 = long) */ 
  188. +      8,            /* bitsize (obsolete) */                   
  189. +      true,            /* pc_relative */                          
  190. +      0,            /* bitpos */                               
  191. +      false,            /* absolute (obsolete) */                  
  192. +      true,            /* complain_on_overflow */                 
  193. +      coff_go32_reloc,    /* special_function */                     
  194. +      "DISP8",        /* name */                                 
  195. +      true,            /* partial_inplace */                      
  196. +      0x000000ff,        /* src_mask */                             
  197. +      0x000000ff,        /* dst_mask */                             
  198. +      false),        /* pcrel_offset */
  199. +   HOWTO (R_PCRWORD,        /* type */                                 
  200. +      0,            /* rightshift */                           
  201. +      1,            /* size (0 = byte, 1 = short, 2 = long) */ 
  202. +      16,            /* bitsize (obsolete) */                   
  203. +      true,            /* pc_relative */                          
  204. +      0,            /* bitpos */                               
  205. +      false,            /* absolute (obsolete) */                  
  206. +      true,            /* complain_on_overflow */                 
  207. +      coff_go32_reloc,    /* special_function */                     
  208. +      "DISP16",        /* name */                                 
  209. +      true,            /* partial_inplace */                      
  210. +      0x0000ffff,        /* src_mask */                             
  211. +      0x0000ffff,        /* dst_mask */                             
  212. +      false),        /* pcrel_offset */
  213. +   HOWTO (R_PCRLONG,        /* type */                                 
  214. +      0,            /* rightshift */                           
  215. +      2,            /* size (0 = byte, 1 = short, 2 = long) */ 
  216. +      32,            /* bitsize (obsolete) */                   
  217. +      true,            /* pc_relative */                          
  218. +      0,            /* bitpos */                               
  219. +      false,            /* absolute (obsolete) */                  
  220. +      true,            /* complain_on_overflow */                 
  221. +      coff_go32_reloc,    /* special_function */                     
  222. +      "DISP32",        /* name */                                 
  223. +      true,            /* partial_inplace */                      
  224. +      0xffffffff,        /* src_mask */                             
  225. +      0xffffffff,        /* dst_mask */                             
  226. +      false)            /* pcrel_offset */
  227. + };
  228. + /* Turn a howto into a reloc  nunmber */
  229. + #define SELECT_RELOC(x,howto) { x = howto->type; }
  230. + #define BADMAG(x) I386BADMAG(x)
  231. + #define I386 1            /* Customize coffcode.h */
  232. + #define RTYPE2HOWTO(cache_ptr, dst) \
  233. +         cache_ptr->howto = howto_table + (dst)->r_type;
  234. + /* On SCO Unix 3.2.2 the native assembler generates two .data
  235. +    sections.  We handle that by renaming the second one to .data2.  It
  236. +    does no harm to do this for any 386 COFF target.  */
  237. + #define TWO_DATA_SECS
  238. + /* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
  239. +    library.  On some other COFF targets STYP_BSS is normally
  240. +    STYP_NOLOAD.  */
  241. + #define BSS_NOLOAD_IS_SHARED_LIBRARY
  242. + /* Compute the addend of a reloc.  If the reloc is to a common symbol,
  243. +    the object file contains the value of the common symbol.  By the
  244. +    time this is called, the linker may be using a different symbol
  245. +    from a different object file with a different value.  Therefore, we
  246. +    hack wildly to locate the original symbol from this file so that we
  247. +    can make the correct adjustment.  This macro sets coffsym to the
  248. +    symbol from the original file, and uses it to set the addend value
  249. +    correctly.  If this is not a common symbol, the usual addend
  250. +    calculation is done, except that an additional tweak is needed for
  251. +    PC relative relocs.
  252. +    FIXME: This macro refers to symbols and asect; these are from the
  253. +    calling function, not the macro arguments.  */
  254. + #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)        \
  255. +   {                                \
  256. +     coff_symbol_type *coffsym = (coff_symbol_type *) NULL;    \
  257. +     if (ptr && bfd_asymbol_bfd (ptr) != abfd)            \
  258. +       coffsym = (obj_symbols (abfd)                \
  259. +              + (cache_ptr->sym_ptr_ptr - symbols));        \
  260. +     else if (ptr)                        \
  261. +       coffsym = coff_symbol_from (abfd, ptr);            \
  262. +     if (coffsym != (coff_symbol_type *) NULL            \
  263. +     && coffsym->native->u.syment.n_scnum == 0)        \
  264. +       cache_ptr->addend = - coffsym->native->u.syment.n_value;    \
  265. +     else if (ptr && bfd_asymbol_bfd (ptr) == abfd        \
  266. +          && ptr->section != (asection *) NULL)        \
  267. +       cache_ptr->addend = - (ptr->section->vma + ptr->value);    \
  268. +     else                            \
  269. +       cache_ptr->addend = 0;                    \
  270. +     if (ptr && howto_table[reloc.r_type].pc_relative)        \
  271. +       cache_ptr->addend += asect->vma;                \
  272. +   }
  273. + #include "coffcode.h"
  274. + bfd_target *go32coff_object_p(a)
  275. + bfd *a ;
  276. + { return coff_object_p(a); }
  277. + bfd_target *go32coff_archive_p(a)
  278. + bfd *a ;
  279. + { return 0; }
  280. + bfd_target go32coff_vec =
  281. + {
  282. +   "coff-go32",            /* name */
  283. +   bfd_target_coff_flavour,
  284. +   false,            /* data byte order is little */
  285. +   false,            /* header byte order is little */
  286. +   (HAS_RELOC | EXEC_P |        /* object flags */
  287. +    HAS_LINENO | HAS_DEBUG |
  288. +    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
  289. +   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
  290. +   '_',                /* leading underscore */
  291. +   '/',                /* ar_pad_char */
  292. +   15,                /* ar_max_namelen */
  293. +   2,                /* minimum alignment power */
  294. +   _do_getl64, _do_getl_signed_64, _do_putl64,
  295. +      _do_getl32, _do_getl_signed_32, _do_putl32,
  296. +      _do_getl16, _do_getl_signed_16, _do_putl16, /* data */
  297. +   _do_getl64, _do_getl_signed_64, _do_putl64,
  298. +      _do_getl32, _do_getl_signed_32, _do_putl32,
  299. +      _do_getl16, _do_getl_signed_16, _do_putl16, /* hdrs */
  300. + /* Note that we allow an object file to be treated as a core file as well. */
  301. +     {_bfd_dummy_target, go32coff_object_p, /* bfd_check_format */
  302. +        go32coff_archive_p, go32coff_object_p},
  303. +     {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
  304. +        bfd_false},
  305. +     {bfd_false, coff_write_object_contents, /* bfd_write_contents */
  306. +        _bfd_write_archive_contents, bfd_false},
  307. +   JUMP_TABLE(coff),
  308. +   COFF_SWAP_TABLE,
  309. + };
  310.