/[gcl]/gcl/binutils/bfd/elf64-mmix.c
ViewVC logotype

Diff of /gcl/binutils/bfd/elf64-mmix.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.1.1 by camm, Fri Aug 9 05:35:55 2002 UTC revision 1.2 by camm, Fri Sep 9 23:32:13 2005 UTC
# Line 1  Line 1 
1  /* MMIX-specific support for 64-bit ELF.  /* MMIX-specific support for 64-bit ELF.
2     Copyright 2001, 2002 Free Software Foundation, Inc.     Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3     Contributed by Hans-Peter Nilsson <hp@bitrange.com>     Contributed by Hans-Peter Nilsson <hp@bitrange.com>
4    
5  This file is part of BFD, the Binary File Descriptor library.  This file is part of BFD, the Binary File Descriptor library.
# Line 21  Foundation, Inc., 59 Temple Place - Suit Line 21  Foundation, Inc., 59 Temple Place - Suit
21  /* No specific ABI or "processor-specific supplement" defined.  */  /* No specific ABI or "processor-specific supplement" defined.  */
22    
23  /* TODO:  /* TODO:
24     - Linker relaxation.  */     - "Traditional" linker relaxation (shrinking whole sections).
25       - Merge reloc stubs jumping to same location.
26       - GETA stub relaxation (call a stub for out of range new
27         R_MMIX_GETA_STUBBABLE).  */
28    
29  #include "bfd.h"  #include "bfd.h"
30  #include "sysdep.h"  #include "sysdep.h"
# Line 32  Foundation, Inc., 59 Temple Place - Suit Line 35  Foundation, Inc., 59 Temple Place - Suit
35    
36  #define MINUS_ONE       (((bfd_vma) 0) - 1)  #define MINUS_ONE       (((bfd_vma) 0) - 1)
37    
38    #define MAX_PUSHJ_STUB_SIZE (5 * 4)
39    
40  /* Put these everywhere in new code.  */  /* Put these everywhere in new code.  */
41  #define FATAL_DEBUG                                             \  #define FATAL_DEBUG                                             \
42   _bfd_abort (__FILE__, __LINE__,                                \   _bfd_abort (__FILE__, __LINE__,                                \
# Line 41  Foundation, Inc., 59 Temple Place - Suit Line 46  Foundation, Inc., 59 Temple Place - Suit
46   _bfd_abort (__FILE__, __LINE__,                \   _bfd_abort (__FILE__, __LINE__,                \
47               "bad case for " #x)               "bad case for " #x)
48    
49    struct _mmix_elf_section_data
50    {
51      struct bfd_elf_section_data elf;
52      union
53      {
54        struct bpo_reloc_section_info *reloc;
55        struct bpo_greg_section_info *greg;
56      } bpo;
57    
58      struct pushj_stub_info
59      {
60        /* Maximum number of stubs needed for this section.  */
61        bfd_size_type n_pushj_relocs;
62    
63        /* Size of stubs after a mmix_elf_relax_section round.  */
64        bfd_size_type stubs_size_sum;
65    
66        /* Per-reloc stubs_size_sum information.  The stubs_size_sum member is the sum
67           of these.  Allocated in mmix_elf_check_common_relocs.  */
68        bfd_size_type *stub_size;
69    
70        /* Offset of next stub during relocation.  Somewhat redundant with the
71           above: error coverage is easier and we don't have to reset the
72           stubs_size_sum for relocation.  */
73        bfd_size_type stub_offset;
74      } pjs;
75    };
76    
77    #define mmix_elf_section_data(sec) \
78      ((struct _mmix_elf_section_data *) elf_section_data (sec))
79    
80  /* For each section containing a base-plus-offset (BPO) reloc, we attach  /* For each section containing a base-plus-offset (BPO) reloc, we attach
81     this struct as elf_section_data (section)->tdata, which is otherwise     this struct as mmix_elf_section_data (section)->bpo, which is otherwise
82     NULL.  */     NULL.  */
83  struct bpo_reloc_section_info  struct bpo_reloc_section_info
84    {    {
# Line 78  struct bpo_reloc_request Line 114  struct bpo_reloc_request
114      size_t bpo_reloc_no;      size_t bpo_reloc_no;
115    
116      /* Set when the value is computed.  Better than coding "guard values"      /* Set when the value is computed.  Better than coding "guard values"
117         into the other members.  Is false only for BPO relocs in a GC:ed         into the other members.  Is FALSE only for BPO relocs in a GC:ed
118         section.  */         section.  */
119      boolean valid;      bfd_boolean valid;
120    };    };
121    
122  /* We attach this as elf_section_data (sec)->tdata in the linker-allocated  /* We attach this as mmix_elf_section_data (sec)->bpo in the linker-allocated
123     greg contents section (MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME),     greg contents section (MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME),
124     which is linked into the register contents section     which is linked into the register contents section
125     (MMIX_REG_CONTENTS_SECTION_NAME).  This section is created by the     (MMIX_REG_CONTENTS_SECTION_NAME).  This section is created by the
# Line 106  struct bpo_greg_section_info Line 142  struct bpo_greg_section_info
142      size_t n_remaining_bpo_relocs_this_relaxation_round;      size_t n_remaining_bpo_relocs_this_relaxation_round;
143    
144      /* The number of linker-allocated GREGs resulting from BPO relocs.      /* The number of linker-allocated GREGs resulting from BPO relocs.
145         This is an approximation after _bfd_mmix_allocated_gregs_init and         This is an approximation after _bfd_mmix_before_linker_allocation
146         supposedly accurate after mmix_elf_relax_section is called for all         and supposedly accurate after mmix_elf_relax_section is called for
147         incoming non-collected sections.  */         all incoming non-collected sections.  */
148      size_t n_allocated_bpo_gregs;      size_t n_allocated_bpo_gregs;
149    
150      /* Index into reloc_request[], sorted on increasing "value", secondary      /* Index into reloc_request[], sorted on increasing "value", secondary
# Line 120  struct bpo_greg_section_info Line 156  struct bpo_greg_section_info
156      struct bpo_reloc_request *reloc_request;      struct bpo_reloc_request *reloc_request;
157    };    };
158    
159  static boolean mmix_elf_link_output_symbol_hook  static bfd_boolean mmix_elf_link_output_symbol_hook
160    PARAMS ((bfd *, struct bfd_link_info *, const char *,    PARAMS ((struct bfd_link_info *, const char *, Elf_Internal_Sym *,
161             Elf_Internal_Sym *, asection *));             asection *, struct elf_link_hash_entry *));
162    
163  static bfd_reloc_status_type mmix_elf_reloc  static bfd_reloc_status_type mmix_elf_reloc
164    PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));    PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
# Line 131  static reloc_howto_type *bfd_elf64_bfd_r Line 167  static reloc_howto_type *bfd_elf64_bfd_r
167    PARAMS ((bfd *, bfd_reloc_code_real_type));    PARAMS ((bfd *, bfd_reloc_code_real_type));
168    
169  static void mmix_info_to_howto_rela  static void mmix_info_to_howto_rela
170    PARAMS ((bfd *, arelent *, Elf64_Internal_Rela *));    PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
171    
172  static int mmix_elf_sort_relocs PARAMS ((const PTR, const PTR));  static int mmix_elf_sort_relocs PARAMS ((const PTR, const PTR));
173    
174  static boolean mmix_elf_check_relocs  static bfd_boolean mmix_elf_new_section_hook
175      PARAMS ((bfd *, asection *));
176    
177    static bfd_boolean mmix_elf_check_relocs
178    PARAMS ((bfd *, struct bfd_link_info *, asection *,    PARAMS ((bfd *, struct bfd_link_info *, asection *,
179             const Elf_Internal_Rela *));             const Elf_Internal_Rela *));
180    
181  static boolean mmix_elf_check_common_relocs  static bfd_boolean mmix_elf_check_common_relocs
182    PARAMS ((bfd *, struct bfd_link_info *, asection *,    PARAMS ((bfd *, struct bfd_link_info *, asection *,
183             const Elf_Internal_Rela *));             const Elf_Internal_Rela *));
184    
185  static boolean mmix_elf_relocate_section  static bfd_boolean mmix_elf_relocate_section
186    PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,    PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
187             Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));             Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
188    
# Line 151  static asection * mmix_elf_gc_mark_hook Line 190  static asection * mmix_elf_gc_mark_hook
190    PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,    PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
191             struct elf_link_hash_entry *, Elf_Internal_Sym *));             struct elf_link_hash_entry *, Elf_Internal_Sym *));
192    
193  static boolean mmix_elf_gc_sweep_hook  static bfd_boolean mmix_elf_gc_sweep_hook
194    PARAMS ((bfd *, struct bfd_link_info *, asection *,    PARAMS ((bfd *, struct bfd_link_info *, asection *,
195             const Elf_Internal_Rela *));             const Elf_Internal_Rela *));
196    
# Line 162  static bfd_reloc_status_type mmix_final_ Line 201  static bfd_reloc_status_type mmix_final_
201  static bfd_reloc_status_type mmix_elf_perform_relocation  static bfd_reloc_status_type mmix_elf_perform_relocation
202    PARAMS ((asection *, reloc_howto_type *, PTR, bfd_vma, bfd_vma));    PARAMS ((asection *, reloc_howto_type *, PTR, bfd_vma, bfd_vma));
203    
204  static boolean mmix_elf_section_from_bfd_section  static bfd_boolean mmix_elf_section_from_bfd_section
205    PARAMS ((bfd *, asection *, int *));    PARAMS ((bfd *, asection *, int *));
206    
207  static boolean mmix_elf_add_symbol_hook  static bfd_boolean mmix_elf_add_symbol_hook
208    PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,    PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
209             const char **, flagword *, asection **, bfd_vma *));             const char **, flagword *, asection **, bfd_vma *));
210    
211  static boolean mmix_elf_is_local_label_name  static bfd_boolean mmix_elf_is_local_label_name
212    PARAMS ((bfd *, const char *));    PARAMS ((bfd *, const char *));
213    
214  static int bpo_reloc_request_sort_fn PARAMS ((const PTR, const PTR));  static int bpo_reloc_request_sort_fn PARAMS ((const PTR, const PTR));
215    
216  static boolean mmix_elf_relax_section  static bfd_boolean mmix_elf_relax_section
217    PARAMS ((bfd *abfd, asection *sec, struct bfd_link_info *link_info,    PARAMS ((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
218             boolean *again));             bfd_boolean *again));
219    
220  extern boolean mmix_elf_final_link PARAMS ((bfd *, struct bfd_link_info *));  extern bfd_boolean mmix_elf_final_link PARAMS ((bfd *, struct bfd_link_info *));
221    
222  extern void mmix_elf_symbol_processing PARAMS ((bfd *, asymbol *));  extern void mmix_elf_symbol_processing PARAMS ((bfd *, asymbol *));
223    
# Line 186  extern void mmix_elf_symbol_processing P Line 225  extern void mmix_elf_symbol_processing P
225  extern void mmix_dump_bpo_gregs  extern void mmix_dump_bpo_gregs
226    PARAMS ((struct bfd_link_info *, bfd_error_handler_type));    PARAMS ((struct bfd_link_info *, bfd_error_handler_type));
227    
228    static void
229    mmix_set_relaxable_size
230      PARAMS ((bfd *, asection *, void *));
231    
232    
233  /* Watch out: this currently needs to have elements with the same index as  /* Watch out: this currently needs to have elements with the same index as
234     their R_MMIX_ number.  */     their R_MMIX_ number.  */
235  static reloc_howto_type elf_mmix_howto_table[] =  static reloc_howto_type elf_mmix_howto_table[] =
# Line 195  static reloc_howto_type elf_mmix_howto_t Line 239  static reloc_howto_type elf_mmix_howto_t
239           0,                     /* rightshift */           0,                     /* rightshift */
240           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
241           32,                    /* bitsize */           32,                    /* bitsize */
242           false,                 /* pc_relative */           FALSE,                 /* pc_relative */
243           0,                     /* bitpos */           0,                     /* bitpos */
244           complain_overflow_bitfield, /* complain_on_overflow */           complain_overflow_bitfield, /* complain_on_overflow */
245           bfd_elf_generic_reloc, /* special_function */           bfd_elf_generic_reloc, /* special_function */
246           "R_MMIX_NONE",         /* name */           "R_MMIX_NONE",         /* name */
247           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
248           0,                     /* src_mask */           0,                     /* src_mask */
249           0,                     /* dst_mask */           0,                     /* dst_mask */
250           false),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
251    
252    /* An 8 bit absolute relocation.  */    /* An 8 bit absolute relocation.  */
253    HOWTO (R_MMIX_8,              /* type */    HOWTO (R_MMIX_8,              /* type */
254           0,                     /* rightshift */           0,                     /* rightshift */
255           0,                     /* size (0 = byte, 1 = short, 2 = long) */           0,                     /* size (0 = byte, 1 = short, 2 = long) */
256           8,                     /* bitsize */           8,                     /* bitsize */
257           false,                 /* pc_relative */           FALSE,                 /* pc_relative */
258           0,                     /* bitpos */           0,                     /* bitpos */
259           complain_overflow_bitfield, /* complain_on_overflow */           complain_overflow_bitfield, /* complain_on_overflow */
260           bfd_elf_generic_reloc, /* special_function */           bfd_elf_generic_reloc, /* special_function */
261           "R_MMIX_8",            /* name */           "R_MMIX_8",            /* name */
262           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
263           0,                     /* src_mask */           0,                     /* src_mask */
264           0xff,                  /* dst_mask */           0xff,                  /* dst_mask */
265           false),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
266    
267    /* An 16 bit absolute relocation.  */    /* An 16 bit absolute relocation.  */
268    HOWTO (R_MMIX_16,             /* type */    HOWTO (R_MMIX_16,             /* type */
269           0,                     /* rightshift */           0,                     /* rightshift */
270           1,                     /* size (0 = byte, 1 = short, 2 = long) */           1,                     /* size (0 = byte, 1 = short, 2 = long) */
271           16,                    /* bitsize */           16,                    /* bitsize */
272           false,                 /* pc_relative */           FALSE,                 /* pc_relative */
273           0,                     /* bitpos */           0,                     /* bitpos */
274           complain_overflow_bitfield, /* complain_on_overflow */           complain_overflow_bitfield, /* complain_on_overflow */
275           bfd_elf_generic_reloc, /* special_function */           bfd_elf_generic_reloc, /* special_function */
276           "R_MMIX_16",           /* name */           "R_MMIX_16",           /* name */
277           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
278           0,                     /* src_mask */           0,                     /* src_mask */
279           0xffff,                /* dst_mask */           0xffff,                /* dst_mask */
280           false),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
281    
282    /* An 24 bit absolute relocation.  */    /* An 24 bit absolute relocation.  */
283    HOWTO (R_MMIX_24,             /* type */    HOWTO (R_MMIX_24,             /* type */
284           0,                     /* rightshift */           0,                     /* rightshift */
285           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
286           24,                    /* bitsize */           24,                    /* bitsize */
287           false,                 /* pc_relative */           FALSE,                 /* pc_relative */
288           0,                     /* bitpos */           0,                     /* bitpos */
289           complain_overflow_bitfield, /* complain_on_overflow */           complain_overflow_bitfield, /* complain_on_overflow */
290           bfd_elf_generic_reloc, /* special_function */           bfd_elf_generic_reloc, /* special_function */
291           "R_MMIX_24",           /* name */           "R_MMIX_24",           /* name */
292           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
293           ~0xffffff,             /* src_mask */           ~0xffffff,             /* src_mask */
294           0xffffff,              /* dst_mask */           0xffffff,              /* dst_mask */
295           false),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
296    
297    /* A 32 bit absolute relocation.  */    /* A 32 bit absolute relocation.  */
298    HOWTO (R_MMIX_32,             /* type */    HOWTO (R_MMIX_32,             /* type */
299           0,                     /* rightshift */           0,                     /* rightshift */
300           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
301           32,                    /* bitsize */           32,                    /* bitsize */
302           false,                 /* pc_relative */           FALSE,                 /* pc_relative */
303           0,                     /* bitpos */           0,                     /* bitpos */
304           complain_overflow_bitfield, /* complain_on_overflow */           complain_overflow_bitfield, /* complain_on_overflow */
305           bfd_elf_generic_reloc, /* special_function */           bfd_elf_generic_reloc, /* special_function */
306           "R_MMIX_32",           /* name */           "R_MMIX_32",           /* name */
307           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
308           0,                     /* src_mask */           0,                     /* src_mask */
309           0xffffffff,            /* dst_mask */           0xffffffff,            /* dst_mask */
310           false),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
311    
312    /* 64 bit relocation.  */    /* 64 bit relocation.  */
313    HOWTO (R_MMIX_64,             /* type */    HOWTO (R_MMIX_64,             /* type */
314           0,                     /* rightshift */           0,                     /* rightshift */
315           4,                     /* size (0 = byte, 1 = short, 2 = long) */           4,                     /* size (0 = byte, 1 = short, 2 = long) */
316           64,                    /* bitsize */           64,                    /* bitsize */
317           false,                 /* pc_relative */           FALSE,                 /* pc_relative */
318           0,                     /* bitpos */           0,                     /* bitpos */
319           complain_overflow_bitfield, /* complain_on_overflow */           complain_overflow_bitfield, /* complain_on_overflow */
320           bfd_elf_generic_reloc, /* special_function */           bfd_elf_generic_reloc, /* special_function */
321           "R_MMIX_64",           /* name */           "R_MMIX_64",           /* name */
322           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
323           0,                     /* src_mask */           0,                     /* src_mask */
324           MINUS_ONE,             /* dst_mask */           MINUS_ONE,             /* dst_mask */
325           false),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
326    
327    /* An 8 bit PC-relative relocation.  */    /* An 8 bit PC-relative relocation.  */
328    HOWTO (R_MMIX_PC_8,           /* type */    HOWTO (R_MMIX_PC_8,           /* type */
329           0,                     /* rightshift */           0,                     /* rightshift */
330           0,                     /* size (0 = byte, 1 = short, 2 = long) */           0,                     /* size (0 = byte, 1 = short, 2 = long) */
331           8,                     /* bitsize */           8,                     /* bitsize */
332           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
333           0,                     /* bitpos */           0,                     /* bitpos */
334           complain_overflow_bitfield, /* complain_on_overflow */           complain_overflow_bitfield, /* complain_on_overflow */
335           bfd_elf_generic_reloc, /* special_function */           bfd_elf_generic_reloc, /* special_function */
336           "R_MMIX_PC_8",         /* name */           "R_MMIX_PC_8",         /* name */
337           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
338           0,                     /* src_mask */           0,                     /* src_mask */
339           0xff,                  /* dst_mask */           0xff,                  /* dst_mask */
340           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
341    
342    /* An 16 bit PC-relative relocation.  */    /* An 16 bit PC-relative relocation.  */
343    HOWTO (R_MMIX_PC_16,          /* type */    HOWTO (R_MMIX_PC_16,          /* type */
344           0,                     /* rightshift */           0,                     /* rightshift */
345           1,                     /* size (0 = byte, 1 = short, 2 = long) */           1,                     /* size (0 = byte, 1 = short, 2 = long) */
346           16,                    /* bitsize */           16,                    /* bitsize */
347           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
348           0,                     /* bitpos */           0,                     /* bitpos */
349           complain_overflow_bitfield, /* complain_on_overflow */           complain_overflow_bitfield, /* complain_on_overflow */
350           bfd_elf_generic_reloc, /* special_function */           bfd_elf_generic_reloc, /* special_function */
351           "R_MMIX_PC_16",        /* name */           "R_MMIX_PC_16",        /* name */
352           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
353           0,                     /* src_mask */           0,                     /* src_mask */
354           0xffff,                /* dst_mask */           0xffff,                /* dst_mask */
355           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
356    
357    /* An 24 bit PC-relative relocation.  */    /* An 24 bit PC-relative relocation.  */
358    HOWTO (R_MMIX_PC_24,          /* type */    HOWTO (R_MMIX_PC_24,          /* type */
359           0,                     /* rightshift */           0,                     /* rightshift */
360           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
361           24,                    /* bitsize */           24,                    /* bitsize */
362           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
363           0,                     /* bitpos */           0,                     /* bitpos */
364           complain_overflow_bitfield, /* complain_on_overflow */           complain_overflow_bitfield, /* complain_on_overflow */
365           bfd_elf_generic_reloc, /* special_function */           bfd_elf_generic_reloc, /* special_function */
366           "R_MMIX_PC_24",        /* name */           "R_MMIX_PC_24",        /* name */
367           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
368           ~0xffffff,             /* src_mask */           ~0xffffff,             /* src_mask */
369           0xffffff,              /* dst_mask */           0xffffff,              /* dst_mask */
370           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
371    
372    /* A 32 bit absolute PC-relative relocation.  */    /* A 32 bit absolute PC-relative relocation.  */
373    HOWTO (R_MMIX_PC_32,          /* type */    HOWTO (R_MMIX_PC_32,          /* type */
374           0,                     /* rightshift */           0,                     /* rightshift */
375           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
376           32,                    /* bitsize */           32,                    /* bitsize */
377           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
378           0,                     /* bitpos */           0,                     /* bitpos */
379           complain_overflow_bitfield, /* complain_on_overflow */           complain_overflow_bitfield, /* complain_on_overflow */
380           bfd_elf_generic_reloc, /* special_function */           bfd_elf_generic_reloc, /* special_function */
381           "R_MMIX_PC_32",        /* name */           "R_MMIX_PC_32",        /* name */
382           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
383           0,                     /* src_mask */           0,                     /* src_mask */
384           0xffffffff,            /* dst_mask */           0xffffffff,            /* dst_mask */
385           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
386    
387    /* 64 bit PC-relative relocation.  */    /* 64 bit PC-relative relocation.  */
388    HOWTO (R_MMIX_PC_64,          /* type */    HOWTO (R_MMIX_PC_64,          /* type */
389           0,                     /* rightshift */           0,                     /* rightshift */
390           4,                     /* size (0 = byte, 1 = short, 2 = long) */           4,                     /* size (0 = byte, 1 = short, 2 = long) */
391           64,                    /* bitsize */           64,                    /* bitsize */
392           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
393           0,                     /* bitpos */           0,                     /* bitpos */
394           complain_overflow_bitfield, /* complain_on_overflow */           complain_overflow_bitfield, /* complain_on_overflow */
395           bfd_elf_generic_reloc, /* special_function */           bfd_elf_generic_reloc, /* special_function */
396           "R_MMIX_PC_64",        /* name */           "R_MMIX_PC_64",        /* name */
397           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
398           0,                     /* src_mask */           0,                     /* src_mask */
399           MINUS_ONE,             /* dst_mask */           MINUS_ONE,             /* dst_mask */
400           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
401    
402    /* GNU extension to record C++ vtable hierarchy.  */    /* GNU extension to record C++ vtable hierarchy.  */
403    HOWTO (R_MMIX_GNU_VTINHERIT, /* type */    HOWTO (R_MMIX_GNU_VTINHERIT, /* type */
404           0,                     /* rightshift */           0,                     /* rightshift */
405           0,                     /* size (0 = byte, 1 = short, 2 = long) */           0,                     /* size (0 = byte, 1 = short, 2 = long) */
406           0,                     /* bitsize */           0,                     /* bitsize */
407           false,                 /* pc_relative */           FALSE,                 /* pc_relative */
408           0,                     /* bitpos */           0,                     /* bitpos */
409           complain_overflow_dont, /* complain_on_overflow */           complain_overflow_dont, /* complain_on_overflow */
410           NULL,                  /* special_function */           NULL,                  /* special_function */
411           "R_MMIX_GNU_VTINHERIT", /* name */           "R_MMIX_GNU_VTINHERIT", /* name */
412           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
413           0,                     /* src_mask */           0,                     /* src_mask */
414           0,                     /* dst_mask */           0,                     /* dst_mask */
415           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
416    
417    /* GNU extension to record C++ vtable member usage.  */    /* GNU extension to record C++ vtable member usage.  */
418    HOWTO (R_MMIX_GNU_VTENTRY,    /* type */    HOWTO (R_MMIX_GNU_VTENTRY,    /* type */
419           0,                     /* rightshift */           0,                     /* rightshift */
420           0,                     /* size (0 = byte, 1 = short, 2 = long) */           0,                     /* size (0 = byte, 1 = short, 2 = long) */
421           0,                     /* bitsize */           0,                     /* bitsize */
422           false,                 /* pc_relative */           FALSE,                 /* pc_relative */
423           0,                     /* bitpos */           0,                     /* bitpos */
424           complain_overflow_dont, /* complain_on_overflow */           complain_overflow_dont, /* complain_on_overflow */
425           _bfd_elf_rel_vtable_reloc_fn,  /* special_function */           _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
426           "R_MMIX_GNU_VTENTRY", /* name */           "R_MMIX_GNU_VTENTRY", /* name */
427           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
428           0,                     /* src_mask */           0,                     /* src_mask */
429           0,                     /* dst_mask */           0,                     /* dst_mask */
430           false),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
431    
432    /* The GETA relocation is supposed to get any address that could    /* The GETA relocation is supposed to get any address that could
433       possibly be reached by the GETA instruction.  It can silently expand       possibly be reached by the GETA instruction.  It can silently expand
# Line 393  static reloc_howto_type elf_mmix_howto_t Line 437  static reloc_howto_type elf_mmix_howto_t
437           2,                     /* rightshift */           2,                     /* rightshift */
438           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
439           19,                    /* bitsize */           19,                    /* bitsize */
440           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
441           0,                     /* bitpos */           0,                     /* bitpos */
442           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
443           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
444           "R_MMIX_GETA",         /* name */           "R_MMIX_GETA",         /* name */
445           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
446           ~0x0100ffff,           /* src_mask */           ~0x0100ffff,           /* src_mask */
447           0x0100ffff,            /* dst_mask */           0x0100ffff,            /* dst_mask */
448           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
449    
450    HOWTO (R_MMIX_GETA_1,         /* type */    HOWTO (R_MMIX_GETA_1,         /* type */
451           2,                     /* rightshift */           2,                     /* rightshift */
452           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
453           19,                    /* bitsize */           19,                    /* bitsize */
454           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
455           0,                     /* bitpos */           0,                     /* bitpos */
456           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
457           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
458           "R_MMIX_GETA_1",               /* name */           "R_MMIX_GETA_1",               /* name */
459           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
460           ~0x0100ffff,           /* src_mask */           ~0x0100ffff,           /* src_mask */
461           0x0100ffff,            /* dst_mask */           0x0100ffff,            /* dst_mask */
462           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
463    
464    HOWTO (R_MMIX_GETA_2,         /* type */    HOWTO (R_MMIX_GETA_2,         /* type */
465           2,                     /* rightshift */           2,                     /* rightshift */
466           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
467           19,                    /* bitsize */           19,                    /* bitsize */
468           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
469           0,                     /* bitpos */           0,                     /* bitpos */
470           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
471           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
472           "R_MMIX_GETA_2",               /* name */           "R_MMIX_GETA_2",               /* name */
473           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
474           ~0x0100ffff,           /* src_mask */           ~0x0100ffff,           /* src_mask */
475           0x0100ffff,            /* dst_mask */           0x0100ffff,            /* dst_mask */
476           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
477    
478    HOWTO (R_MMIX_GETA_3,         /* type */    HOWTO (R_MMIX_GETA_3,         /* type */
479           2,                     /* rightshift */           2,                     /* rightshift */
480           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
481           19,                    /* bitsize */           19,                    /* bitsize */
482           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
483           0,                     /* bitpos */           0,                     /* bitpos */
484           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
485           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
486           "R_MMIX_GETA_3",               /* name */           "R_MMIX_GETA_3",               /* name */
487           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
488           ~0x0100ffff,           /* src_mask */           ~0x0100ffff,           /* src_mask */
489           0x0100ffff,            /* dst_mask */           0x0100ffff,            /* dst_mask */
490           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
491    
492    /* The conditional branches are supposed to reach any (code) address.    /* The conditional branches are supposed to reach any (code) address.
493       It can silently expand to a 64-bit operand, but will emit an error if       It can silently expand to a 64-bit operand, but will emit an error if
# Line 453  static reloc_howto_type elf_mmix_howto_t Line 497  static reloc_howto_type elf_mmix_howto_t
497           2,                     /* rightshift */           2,                     /* rightshift */
498           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
499           19,                    /* bitsize */           19,                    /* bitsize */
500           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
501           0,                     /* bitpos */           0,                     /* bitpos */
502           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
503           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
504           "R_MMIX_CBRANCH",      /* name */           "R_MMIX_CBRANCH",      /* name */
505           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
506           ~0x0100ffff,           /* src_mask */           ~0x0100ffff,           /* src_mask */
507           0x0100ffff,            /* dst_mask */           0x0100ffff,            /* dst_mask */
508           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
509    
510    HOWTO (R_MMIX_CBRANCH_J,      /* type */    HOWTO (R_MMIX_CBRANCH_J,      /* type */
511           2,                     /* rightshift */           2,                     /* rightshift */
512           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
513           19,                    /* bitsize */           19,                    /* bitsize */
514           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
515           0,                     /* bitpos */           0,                     /* bitpos */
516           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
517           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
518           "R_MMIX_CBRANCH_J",    /* name */           "R_MMIX_CBRANCH_J",    /* name */
519           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
520           ~0x0100ffff,           /* src_mask */           ~0x0100ffff,           /* src_mask */
521           0x0100ffff,            /* dst_mask */           0x0100ffff,            /* dst_mask */
522           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
523    
524    HOWTO (R_MMIX_CBRANCH_1,      /* type */    HOWTO (R_MMIX_CBRANCH_1,      /* type */
525           2,                     /* rightshift */           2,                     /* rightshift */
526           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
527           19,                    /* bitsize */           19,                    /* bitsize */
528           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
529           0,                     /* bitpos */           0,                     /* bitpos */
530           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
531           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
532           "R_MMIX_CBRANCH_1",    /* name */           "R_MMIX_CBRANCH_1",    /* name */
533           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
534           ~0x0100ffff,           /* src_mask */           ~0x0100ffff,           /* src_mask */
535           0x0100ffff,            /* dst_mask */           0x0100ffff,            /* dst_mask */
536           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
537    
538    HOWTO (R_MMIX_CBRANCH_2,      /* type */    HOWTO (R_MMIX_CBRANCH_2,      /* type */
539           2,                     /* rightshift */           2,                     /* rightshift */
540           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
541           19,                    /* bitsize */           19,                    /* bitsize */
542           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
543           0,                     /* bitpos */           0,                     /* bitpos */
544           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
545           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
546           "R_MMIX_CBRANCH_2",    /* name */           "R_MMIX_CBRANCH_2",    /* name */
547           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
548           ~0x0100ffff,           /* src_mask */           ~0x0100ffff,           /* src_mask */
549           0x0100ffff,            /* dst_mask */           0x0100ffff,            /* dst_mask */
550           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
551    
552    HOWTO (R_MMIX_CBRANCH_3,      /* type */    HOWTO (R_MMIX_CBRANCH_3,      /* type */
553           2,                     /* rightshift */           2,                     /* rightshift */
554           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
555           19,                    /* bitsize */           19,                    /* bitsize */
556           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
557           0,                     /* bitpos */           0,                     /* bitpos */
558           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
559           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
560           "R_MMIX_CBRANCH_3",    /* name */           "R_MMIX_CBRANCH_3",    /* name */
561           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
562           ~0x0100ffff,           /* src_mask */           ~0x0100ffff,           /* src_mask */
563           0x0100ffff,            /* dst_mask */           0x0100ffff,            /* dst_mask */
564           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
565    
566    /* The PUSHJ instruction can reach any (code) address, as long as it's    /* The PUSHJ instruction can reach any (code) address, as long as it's
567       the beginning of a function (no usable restriction).  It can silently       the beginning of a function (no usable restriction).  It can silently
568       expand to a 64-bit operand, but will emit an error if any of the two       expand to a 64-bit operand, but will emit an error if any of the two
569       least significant bits are set.  The howto members reflect a simple       least significant bits are set.  It can also expand into a call to a
570         stub; see R_MMIX_PUSHJ_STUBBABLE.  The howto members reflect a simple
571       PUSHJ.  */       PUSHJ.  */
572    HOWTO (R_MMIX_PUSHJ,          /* type */    HOWTO (R_MMIX_PUSHJ,          /* type */
573           2,                     /* rightshift */           2,                     /* rightshift */
574           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
575           19,                    /* bitsize */           19,                    /* bitsize */
576           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
577           0,                     /* bitpos */           0,                     /* bitpos */
578           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
579           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
580           "R_MMIX_PUSHJ",        /* name */           "R_MMIX_PUSHJ",        /* name */
581           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
582           ~0x0100ffff,           /* src_mask */           ~0x0100ffff,           /* src_mask */
583           0x0100ffff,            /* dst_mask */           0x0100ffff,            /* dst_mask */
584           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
585    
586    HOWTO (R_MMIX_PUSHJ_1,        /* type */    HOWTO (R_MMIX_PUSHJ_1,        /* type */
587           2,                     /* rightshift */           2,                     /* rightshift */
588           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
589           19,                    /* bitsize */           19,                    /* bitsize */
590           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
591           0,                     /* bitpos */           0,                     /* bitpos */
592           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
593           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
594           "R_MMIX_PUSHJ_1",      /* name */           "R_MMIX_PUSHJ_1",      /* name */
595           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
596           ~0x0100ffff,           /* src_mask */           ~0x0100ffff,           /* src_mask */
597           0x0100ffff,            /* dst_mask */           0x0100ffff,            /* dst_mask */
598           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
599    
600    HOWTO (R_MMIX_PUSHJ_2,        /* type */    HOWTO (R_MMIX_PUSHJ_2,        /* type */
601           2,                     /* rightshift */           2,                     /* rightshift */
602           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
603           19,                    /* bitsize */           19,                    /* bitsize */
604           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
605           0,                     /* bitpos */           0,                     /* bitpos */
606           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
607           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
608           "R_MMIX_PUSHJ_2",      /* name */           "R_MMIX_PUSHJ_2",      /* name */
609           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
610           ~0x0100ffff,           /* src_mask */           ~0x0100ffff,           /* src_mask */
611           0x0100ffff,            /* dst_mask */           0x0100ffff,            /* dst_mask */
612           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
613    
614    HOWTO (R_MMIX_PUSHJ_3,        /* type */    HOWTO (R_MMIX_PUSHJ_3,        /* type */
615           2,                     /* rightshift */           2,                     /* rightshift */
616           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
617           19,                    /* bitsize */           19,                    /* bitsize */
618           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
619           0,                     /* bitpos */           0,                     /* bitpos */
620           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
621           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
622           "R_MMIX_PUSHJ_3",      /* name */           "R_MMIX_PUSHJ_3",      /* name */
623           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
624           ~0x0100ffff,           /* src_mask */           ~0x0100ffff,           /* src_mask */
625           0x0100ffff,            /* dst_mask */           0x0100ffff,            /* dst_mask */
626           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
627    
628    /* A JMP is supposed to reach any (code) address.  By itself, it can    /* A JMP is supposed to reach any (code) address.  By itself, it can
629       reach +-64M; the expansion can reach all 64 bits.  Note that the 64M       reach +-64M; the expansion can reach all 64 bits.  Note that the 64M
# Line 588  static reloc_howto_type elf_mmix_howto_t Line 633  static reloc_howto_type elf_mmix_howto_t
633           2,                     /* rightshift */           2,                     /* rightshift */
634           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
635           27,                    /* bitsize */           27,                    /* bitsize */
636           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
637           0,                     /* bitpos */           0,                     /* bitpos */
638           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
639           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
640           "R_MMIX_JMP",          /* name */           "R_MMIX_JMP",          /* name */
641           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
642           ~0x1ffffff,            /* src_mask */           ~0x1ffffff,            /* src_mask */
643           0x1ffffff,             /* dst_mask */           0x1ffffff,             /* dst_mask */
644           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
645    
646    HOWTO (R_MMIX_JMP_1,          /* type */    HOWTO (R_MMIX_JMP_1,          /* type */
647           2,                     /* rightshift */           2,                     /* rightshift */
648           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
649           27,                    /* bitsize */           27,                    /* bitsize */
650           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
651           0,                     /* bitpos */           0,                     /* bitpos */
652           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
653           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
654           "R_MMIX_JMP_1",        /* name */           "R_MMIX_JMP_1",        /* name */
655           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
656           ~0x1ffffff,            /* src_mask */           ~0x1ffffff,            /* src_mask */
657           0x1ffffff,             /* dst_mask */           0x1ffffff,             /* dst_mask */
658           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
659    
660    HOWTO (R_MMIX_JMP_2,          /* type */    HOWTO (R_MMIX_JMP_2,          /* type */
661           2,                     /* rightshift */           2,                     /* rightshift */
662           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
663           27,                    /* bitsize */           27,                    /* bitsize */
664           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
665           0,                     /* bitpos */           0,                     /* bitpos */
666           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
667           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
668           "R_MMIX_JMP_2",        /* name */           "R_MMIX_JMP_2",        /* name */
669           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
670           ~0x1ffffff,            /* src_mask */           ~0x1ffffff,            /* src_mask */
671           0x1ffffff,             /* dst_mask */           0x1ffffff,             /* dst_mask */
672           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
673    
674    HOWTO (R_MMIX_JMP_3,          /* type */    HOWTO (R_MMIX_JMP_3,          /* type */
675           2,                     /* rightshift */           2,                     /* rightshift */
676           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
677           27,                    /* bitsize */           27,                    /* bitsize */
678           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
679           0,                     /* bitpos */           0,                     /* bitpos */
680           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
681           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
682           "R_MMIX_JMP_3",        /* name */           "R_MMIX_JMP_3",        /* name */
683           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
684           ~0x1ffffff,            /* src_mask */           ~0x1ffffff,            /* src_mask */
685           0x1ffffff,             /* dst_mask */           0x1ffffff,             /* dst_mask */
686           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
687    
688    /* When we don't emit link-time-relaxable code from the assembler, or    /* When we don't emit link-time-relaxable code from the assembler, or
689       when relaxation has done all it can do, these relocs are used.  For       when relaxation has done all it can do, these relocs are used.  For
# Line 647  static reloc_howto_type elf_mmix_howto_t Line 692  static reloc_howto_type elf_mmix_howto_t
692           2,                     /* rightshift */           2,                     /* rightshift */
693           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
694           19,                    /* bitsize */           19,                    /* bitsize */
695           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
696           0,                     /* bitpos */           0,                     /* bitpos */
697           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
698           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
699           "R_MMIX_ADDR19",       /* name */           "R_MMIX_ADDR19",       /* name */
700           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
701           ~0x0100ffff,           /* src_mask */           ~0x0100ffff,           /* src_mask */
702           0x0100ffff,            /* dst_mask */           0x0100ffff,            /* dst_mask */
703           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
704    
705    /* For JMP.  */    /* For JMP.  */
706    HOWTO (R_MMIX_ADDR27,         /* type */    HOWTO (R_MMIX_ADDR27,         /* type */
707           2,                     /* rightshift */           2,                     /* rightshift */
708           2,                     /* size (0 = byte, 1 = short, 2 = long) */           2,                     /* size (0 = byte, 1 = short, 2 = long) */
709           27,                    /* bitsize */           27,                    /* bitsize */
710           true,                  /* pc_relative */           TRUE,                  /* pc_relative */
711           0,                     /* bitpos */           0,                     /* bitpos */
712           complain_overflow_signed, /* complain_on_overflow */           complain_overflow_signed, /* complain_on_overflow */
713           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
714           "R_MMIX_ADDR27",       /* name */           "R_MMIX_ADDR27",       /* name */
715           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
716           ~0x1ffffff,            /* src_mask */           ~0x1ffffff,            /* src_mask */
717           0x1ffffff,             /* dst_mask */           0x1ffffff,             /* dst_mask */
718           true),                 /* pcrel_offset */           TRUE),                 /* pcrel_offset */
719    
720    /* A general register or the value 0..255.  If a value, then the    /* A general register or the value 0..255.  If a value, then the
721       instruction (offset -3) needs adjusting.  */       instruction (offset -3) needs adjusting.  */
# Line 678  static reloc_howto_type elf_mmix_howto_t Line 723  static reloc_howto_type elf_mmix_howto_t
723           0,                     /* rightshift */           0,                     /* rightshift */
724           1,                     /* size (0 = byte, 1 = short, 2 = long) */           1,                     /* size (0 = byte, 1 = short, 2 = long) */
725           8,                     /* bitsize */           8,                     /* bitsize */
726           false,                 /* pc_relative */           FALSE,                 /* pc_relative */
727           0,                     /* bitpos */           0,                     /* bitpos */
728           complain_overflow_bitfield, /* complain_on_overflow */           complain_overflow_bitfield, /* complain_on_overflow */
729           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
730           "R_MMIX_REG_OR_BYTE",  /* name */           "R_MMIX_REG_OR_BYTE",  /* name */
731           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
732           0,                     /* src_mask */           0,                     /* src_mask */
733           0xff,                  /* dst_mask */           0xff,                  /* dst_mask */
734           false),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
735    
736    /* A general register.  */    /* A general register.  */
737    HOWTO (R_MMIX_REG,            /* type */    HOWTO (R_MMIX_REG,            /* type */
738           0,                     /* rightshift */           0,                     /* rightshift */
739           1,                     /* size (0 = byte, 1 = short, 2 = long) */           1,                     /* size (0 = byte, 1 = short, 2 = long) */
740           8,                     /* bitsize */           8,                     /* bitsize */
741           false,                 /* pc_relative */           FALSE,                 /* pc_relative */
742           0,                     /* bitpos */           0,                     /* bitpos */
743           complain_overflow_bitfield, /* complain_on_overflow */           complain_overflow_bitfield, /* complain_on_overflow */
744           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
745           "R_MMIX_REG",          /* name */           "R_MMIX_REG",          /* name */
746           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
747           0,                     /* src_mask */           0,                     /* src_mask */
748           0xff,                  /* dst_mask */           0xff,                  /* dst_mask */
749           false),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
750    
751    /* A register plus an index, corresponding to the relocation expression.    /* A register plus an index, corresponding to the relocation expression.
752       The sizes must correspond to the valid range of the expression, while       The sizes must correspond to the valid range of the expression, while
# Line 710  static reloc_howto_type elf_mmix_howto_t Line 755  static reloc_howto_type elf_mmix_howto_t
755           0,                     /* rightshift */           0,                     /* rightshift */
756           4,                     /* size (0 = byte, 1 = short, 2 = long) */           4,                     /* size (0 = byte, 1 = short, 2 = long) */
757           64,                    /* bitsize */           64,                    /* bitsize */
758           false,                 /* pc_relative */           FALSE,                 /* pc_relative */
759           0,                     /* bitpos */           0,                     /* bitpos */
760           complain_overflow_bitfield, /* complain_on_overflow */           complain_overflow_bitfield, /* complain_on_overflow */
761           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
762           "R_MMIX_BASE_PLUS_OFFSET", /* name */           "R_MMIX_BASE_PLUS_OFFSET", /* name */
763           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
764           0,                     /* src_mask */           0,                     /* src_mask */
765           0xffff,                /* dst_mask */           0xffff,                /* dst_mask */
766           false),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
767    
768    /* A "magic" relocation for a LOCAL expression, asserting that the    /* A "magic" relocation for a LOCAL expression, asserting that the
769       expression is less than the number of global registers.  No actual       expression is less than the number of global registers.  No actual
# Line 729  static reloc_howto_type elf_mmix_howto_t Line 774  static reloc_howto_type elf_mmix_howto_t
774           0,                     /* rightshift */           0,                     /* rightshift */
775           0,                     /* size (0 = byte, 1 = short, 2 = long) */           0,                     /* size (0 = byte, 1 = short, 2 = long) */
776           0,                     /* bitsize */           0,                     /* bitsize */
777           false,                 /* pc_relative */           FALSE,                 /* pc_relative */
778           0,                     /* bitpos */           0,                     /* bitpos */
779           complain_overflow_dont, /* complain_on_overflow */           complain_overflow_dont, /* complain_on_overflow */
780           mmix_elf_reloc,        /* special_function */           mmix_elf_reloc,        /* special_function */
781           "R_MMIX_LOCAL",        /* name */           "R_MMIX_LOCAL",        /* name */
782           false,                 /* partial_inplace */           FALSE,                 /* partial_inplace */
783           0,                     /* src_mask */           0,                     /* src_mask */
784           0,                     /* dst_mask */           0,                     /* dst_mask */
785           false),                /* pcrel_offset */           FALSE),                /* pcrel_offset */
786    
787      HOWTO (R_MMIX_PUSHJ_STUBBABLE, /* type */
788             2,                     /* rightshift */
789             2,                     /* size (0 = byte, 1 = short, 2 = long) */
790             19,                    /* bitsize */
791             TRUE,                  /* pc_relative */
792             0,                     /* bitpos */
793             complain_overflow_signed, /* complain_on_overflow */
794             mmix_elf_reloc,        /* special_function */
795             "R_MMIX_PUSHJ_STUBBABLE", /* name */
796             FALSE,                 /* partial_inplace */
797             ~0x0100ffff,           /* src_mask */
798             0x0100ffff,            /* dst_mask */
799             TRUE)                  /* pcrel_offset */
800   };   };
801    
802    
# Line 774  static const struct mmix_reloc_map mmix_ Line 833  static const struct mmix_reloc_map mmix_
833      {BFD_RELOC_MMIX_REG_OR_BYTE, R_MMIX_REG_OR_BYTE},      {BFD_RELOC_MMIX_REG_OR_BYTE, R_MMIX_REG_OR_BYTE},
834      {BFD_RELOC_MMIX_REG, R_MMIX_REG},      {BFD_RELOC_MMIX_REG, R_MMIX_REG},
835      {BFD_RELOC_MMIX_BASE_PLUS_OFFSET, R_MMIX_BASE_PLUS_OFFSET},      {BFD_RELOC_MMIX_BASE_PLUS_OFFSET, R_MMIX_BASE_PLUS_OFFSET},
836      {BFD_RELOC_MMIX_LOCAL, R_MMIX_LOCAL}      {BFD_RELOC_MMIX_LOCAL, R_MMIX_LOCAL},
837        {BFD_RELOC_MMIX_PUSHJ_STUBBABLE, R_MMIX_PUSHJ_STUBBABLE}
838    };    };
839    
840  static reloc_howto_type *  static reloc_howto_type *
# Line 795  bfd_elf64_bfd_reloc_type_lookup (abfd, c Line 855  bfd_elf64_bfd_reloc_type_lookup (abfd, c
855    return NULL;    return NULL;
856  }  }
857    
858    static bfd_boolean
859    mmix_elf_new_section_hook (abfd, sec)
860         bfd *abfd;
861         asection *sec;
862    {
863      struct _mmix_elf_section_data *sdata;
864      bfd_size_type amt = sizeof (*sdata);
865    
866      sdata = (struct _mmix_elf_section_data *) bfd_zalloc (abfd, amt);
867      if (sdata == NULL)
868        return FALSE;
869      sec->used_by_bfd = (PTR) sdata;
870    
871      return _bfd_elf_new_section_hook (abfd, sec);
872    }
873    
874    
875  /* This function performs the actual bitfiddling and sanity check for a  /* This function performs the actual bitfiddling and sanity check for a
876     final relocation.  Each relocation gets its *worst*-case expansion     final relocation.  Each relocation gets its *worst*-case expansion
# Line 848  mmix_elf_perform_relocation (isec, howto Line 924  mmix_elf_perform_relocation (isec, howto
924       asection *isec;       asection *isec;
925       reloc_howto_type *howto;       reloc_howto_type *howto;
926       PTR datap;       PTR datap;
927       bfd_vma addr ATTRIBUTE_UNUSED;       bfd_vma addr;
928       bfd_vma value;       bfd_vma value;
929  {  {
930    bfd *abfd = isec->owner;    bfd *abfd = isec->owner;
# Line 899  mmix_elf_perform_relocation (isec, howto Line 975  mmix_elf_perform_relocation (isec, howto
975        }        }
976        break;        break;
977    
978        case R_MMIX_PUSHJ_STUBBABLE:
979          /* If the address fits, we're fine.  */
980          if ((value & 3) == 0
981              /* Note rightshift 0; see R_MMIX_JMP case below.  */
982              && (r = bfd_check_overflow (complain_overflow_signed,
983                                          howto->bitsize,
984                                          0,
985                                          bfd_arch_bits_per_address (abfd),
986                                          value)) == bfd_reloc_ok)
987            goto pcrel_mmix_reloc_fits;
988          else
989            {
990              bfd_size_type size = isec->rawsize ? isec->rawsize : isec->size;
991    
992              /* We have the bytes at the PUSHJ insn and need to get the
993                 position for the stub.  There's supposed to be room allocated
994                 for the stub.  */
995              bfd_byte *stubcontents
996                = ((bfd_byte *) datap
997                   - (addr - (isec->output_section->vma + isec->output_offset))
998                   + size
999                   + mmix_elf_section_data (isec)->pjs.stub_offset);
1000              bfd_vma stubaddr;
1001    
1002              /* The address doesn't fit, so redirect the PUSHJ to the
1003                 location of the stub.  */
1004              r = mmix_elf_perform_relocation (isec,
1005                                               &elf_mmix_howto_table
1006                                               [R_MMIX_ADDR19],
1007                                               datap,
1008                                               addr,
1009                                               isec->output_section->vma
1010                                               + isec->output_offset
1011                                               + size
1012                                               + (mmix_elf_section_data (isec)
1013                                                  ->pjs.stub_offset)
1014                                               - addr);
1015              if (r != bfd_reloc_ok)
1016                return r;
1017    
1018              stubaddr
1019                = (isec->output_section->vma
1020                   + isec->output_offset
1021                   + size
1022                   + mmix_elf_section_data (isec)->pjs.stub_offset);
1023    
1024              /* We generate a simple JMP if that suffices, else the whole 5
1025                 insn stub.  */
1026              if (bfd_check_overflow (complain_overflow_signed,
1027                                      elf_mmix_howto_table[R_MMIX_ADDR27].bitsize,
1028                                      0,
1029                                      bfd_arch_bits_per_address (abfd),
1030                                      addr + value - stubaddr) == bfd_reloc_ok)
1031                {
1032                  bfd_put_32 (abfd, JMP_INSN_BYTE << 24, stubcontents);
1033                  r = mmix_elf_perform_relocation (isec,
1034                                                   &elf_mmix_howto_table
1035                                                   [R_MMIX_ADDR27],
1036                                                   stubcontents,
1037                                                   stubaddr,
1038                                                   value + addr - stubaddr);
1039                  mmix_elf_section_data (isec)->pjs.stub_offset += 4;
1040    
1041                  if (size + mmix_elf_section_data (isec)->pjs.stub_offset
1042                      > isec->size)
1043                    abort ();
1044    
1045                  return r;
1046                }
1047              else
1048                {
1049                  /* Put a "GO $255,0" after the common sequence.  */
1050                  bfd_put_32 (abfd,
1051                              ((GO_INSN_BYTE | IMM_OFFSET_BIT) << 24)
1052                              | 0xff00, (bfd_byte *) stubcontents + 16);
1053    
1054                  /* Prepare for the general code to set the first part of the
1055                     linker stub, and */
1056                  value += addr;
1057                  datap = stubcontents;
1058                  mmix_elf_section_data (isec)->pjs.stub_offset
1059                    += MAX_PUSHJ_STUB_SIZE;
1060                }
1061            }
1062          break;
1063    
1064      case R_MMIX_PUSHJ:      case R_MMIX_PUSHJ:
1065        {        {
1066          int inreg = bfd_get_8 (abfd, (bfd_byte *) datap + 1);          int inreg = bfd_get_8 (abfd, (bfd_byte *) datap + 1);
# Line 946  mmix_elf_perform_relocation (isec, howto Line 1108  mmix_elf_perform_relocation (isec, howto
1108        /* FALLTHROUGH.  */        /* FALLTHROUGH.  */
1109      case R_MMIX_ADDR19:      case R_MMIX_ADDR19:
1110      case R_MMIX_ADDR27:      case R_MMIX_ADDR27:
1111        pcrel_mmix_reloc_fits:
1112        /* These must be in range, or else we emit an error.  */        /* These must be in range, or else we emit an error.  */
1113        if ((value & 3) == 0        if ((value & 3) == 0
1114            /* Note rightshift 0; see above.  */            /* Note rightshift 0; see above.  */
# Line 961  mmix_elf_perform_relocation (isec, howto Line 1124  mmix_elf_perform_relocation (isec, howto
1124    
1125            if ((bfd_signed_vma) value < 0)            if ((bfd_signed_vma) value < 0)
1126              {              {
1127                highbit = (1 << 24);                highbit = 1 << 24;
1128                value += (1 << (howto->bitsize - 1));                value += (1 << (howto->bitsize - 1));
1129              }              }
1130            else            else
# Line 983  mmix_elf_perform_relocation (isec, howto Line 1146  mmix_elf_perform_relocation (isec, howto
1146      case R_MMIX_BASE_PLUS_OFFSET:      case R_MMIX_BASE_PLUS_OFFSET:
1147        {        {
1148          struct bpo_reloc_section_info *bpodata          struct bpo_reloc_section_info *bpodata
1149            = (struct bpo_reloc_section_info *)            = mmix_elf_section_data (isec)->bpo.reloc;
           elf_section_data (isec)->tdata;  
1150          asection *bpo_greg_section          asection *bpo_greg_section
1151            = bpodata->bpo_greg_section;            = bpodata->bpo_greg_section;
1152          struct bpo_greg_section_info *gregdata          struct bpo_greg_section_info *gregdata
1153            = (struct bpo_greg_section_info *)            = mmix_elf_section_data (bpo_greg_section)->bpo.greg;
           elf_section_data (bpo_greg_section)->tdata;  
1154          size_t bpo_index          size_t bpo_index
1155            = gregdata->bpo_reloc_indexes[bpodata->bpo_index++];            = gregdata->bpo_reloc_indexes[bpodata->bpo_index++];
1156    
# Line 1063  static void Line 1224  static void
1224  mmix_info_to_howto_rela (abfd, cache_ptr, dst)  mmix_info_to_howto_rela (abfd, cache_ptr, dst)
1225       bfd *abfd ATTRIBUTE_UNUSED;       bfd *abfd ATTRIBUTE_UNUSED;
1226       arelent *cache_ptr;       arelent *cache_ptr;
1227       Elf64_Internal_Rela *dst;       Elf_Internal_Rela *dst;
1228  {  {
1229    unsigned int r_type;    unsigned int r_type;
1230    
# Line 1108  mmix_elf_reloc (abfd, reloc_entry, symbo Line 1269  mmix_elf_reloc (abfd, reloc_entry, symbo
1269      return bfd_reloc_undefined;      return bfd_reloc_undefined;
1270    
1271    /* Is the address of the relocation really within the section?  */    /* Is the address of the relocation really within the section?  */
1272    if (reloc_entry->address > input_section->_cooked_size)    if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
1273      return bfd_reloc_outofrange;      return bfd_reloc_outofrange;
1274    
1275    /* Work out which section the relocation is targetted at and the    /* Work out which section the relocation is targeted at and the
1276       initial relocation command value.  */       initial relocation command value.  */
1277    
1278    /* Get symbol value.  (Common symbols are special.)  */    /* Get symbol value.  (Common symbols are special.)  */
# Line 1157  mmix_elf_reloc (abfd, reloc_entry, symbo Line 1318  mmix_elf_reloc (abfd, reloc_entry, symbo
1318  /* Relocate an MMIX ELF section.  Modified from elf32-fr30.c; look to it  /* Relocate an MMIX ELF section.  Modified from elf32-fr30.c; look to it
1319     for guidance if you're thinking of copying this.  */     for guidance if you're thinking of copying this.  */
1320    
1321  static boolean  static bfd_boolean
1322  mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section,  mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section,
1323                             contents, relocs, local_syms, local_sections)                             contents, relocs, local_syms, local_sections)
1324       bfd *output_bfd ATTRIBUTE_UNUSED;       bfd *output_bfd ATTRIBUTE_UNUSED;
# Line 1173  mmix_elf_relocate_section (output_bfd, i Line 1334  mmix_elf_relocate_section (output_bfd, i
1334    struct elf_link_hash_entry **sym_hashes;    struct elf_link_hash_entry **sym_hashes;
1335    Elf_Internal_Rela *rel;    Elf_Internal_Rela *rel;
1336    Elf_Internal_Rela *relend;    Elf_Internal_Rela *relend;
1337      bfd_size_type size;
1338      size_t pjsno = 0;
1339    
1340      size = input_section->rawsize ? input_section->rawsize : input_section->size;
1341    symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;    symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1342    sym_hashes = elf_sym_hashes (input_bfd);    sym_hashes = elf_sym_hashes (input_bfd);
1343    relend = relocs + input_section->reloc_count;    relend = relocs + input_section->reloc_count;
1344    
1345      /* Zero the stub area before we start.  */
1346      if (input_section->rawsize != 0
1347          && input_section->size > input_section->rawsize)
1348        memset (contents + input_section->rawsize, 0,
1349                input_section->size - input_section->rawsize);
1350    
1351    for (rel = relocs; rel < relend; rel ++)    for (rel = relocs; rel < relend; rel ++)
1352      {      {
1353        reloc_howto_type *howto;        reloc_howto_type *howto;
# Line 1189  mmix_elf_relocate_section (output_bfd, i Line 1359  mmix_elf_relocate_section (output_bfd, i
1359        bfd_reloc_status_type r;        bfd_reloc_status_type r;
1360        const char *name = NULL;        const char *name = NULL;
1361        int r_type;        int r_type;
1362        boolean undefined_signalled = false;        bfd_boolean undefined_signalled = FALSE;
1363    
1364        r_type = ELF64_R_TYPE (rel->r_info);        r_type = ELF64_R_TYPE (rel->r_info);
1365    
# Line 1199  mmix_elf_relocate_section (output_bfd, i Line 1369  mmix_elf_relocate_section (output_bfd, i
1369    
1370        r_symndx = ELF64_R_SYM (rel->r_info);        r_symndx = ELF64_R_SYM (rel->r_info);
1371    
1372        if (info->relocateable)        if (info->relocatable)
1373          {          {
1374            /* This is a relocateable link.  We don't have to change            /* This is a relocatable link.  For most relocs we don't have to
1375               anything, unless the reloc is against a section symbol,               change anything, unless the reloc is against a section
1376               in which case we have to adjust according to where the               symbol, in which case we have to adjust according to where
1377               section symbol winds up in the output section.  */               the section symbol winds up in the output section.  */
1378            if (r_symndx < symtab_hdr->sh_info)            if (r_symndx < symtab_hdr->sh_info)
1379              {              {
1380                sym = local_syms + r_symndx;                sym = local_syms + r_symndx;
# Line 1216  mmix_elf_relocate_section (output_bfd, i Line 1386  mmix_elf_relocate_section (output_bfd, i
1386                  }                  }
1387              }              }
1388    
1389              /* For PUSHJ stub relocs however, we may need to change the
1390                 reloc and the section contents, if the reloc doesn't reach
1391                 beyond the end of the output section and previous stubs.
1392                 Then we change the section contents to be a PUSHJ to the end
1393                 of the input section plus stubs (we can do that without using
1394                 a reloc), and then we change the reloc to be a R_MMIX_PUSHJ
1395                 at the stub location.  */
1396              if (r_type == R_MMIX_PUSHJ_STUBBABLE)
1397                {
1398                  /* We've already checked whether we need a stub; use that
1399                     knowledge.  */
1400                  if (mmix_elf_section_data (input_section)->pjs.stub_size[pjsno]
1401                      != 0)
1402                    {
1403                      Elf_Internal_Rela relcpy;
1404    
1405                      if (mmix_elf_section_data (input_section)
1406                          ->pjs.stub_size[pjsno] != MAX_PUSHJ_STUB_SIZE)
1407                        abort ();
1408    
1409                      /* There's already a PUSHJ insn there, so just fill in
1410                         the offset bits to the stub.  */
1411                      if (mmix_final_link_relocate (elf_mmix_howto_table
1412                                                    + R_MMIX_ADDR19,
1413                                                    input_section,
1414                                                    contents,
1415                                                    rel->r_offset,
1416                                                    0,
1417                                                    input_section
1418                                                    ->output_section->vma
1419                                                    + input_section->output_offset
1420                                                    + size
1421                                                    + mmix_elf_section_data (input_section)
1422                                                    ->pjs.stub_offset,
1423                                                    NULL, NULL) != bfd_reloc_ok)
1424                        return FALSE;
1425    
1426                      /* Put a JMP insn at the stub; it goes with the
1427                         R_MMIX_JMP reloc.  */
1428                      bfd_put_32 (output_bfd, JMP_INSN_BYTE << 24,
1429                                  contents
1430                                  + size
1431                                  + mmix_elf_section_data (input_section)
1432                                  ->pjs.stub_offset);
1433    
1434                      /* Change the reloc to be at the stub, and to a full
1435                         R_MMIX_JMP reloc.  */
1436                      rel->r_info = ELF64_R_INFO (r_symndx, R_MMIX_JMP);
1437                      rel->r_offset
1438                        = (size
1439                           + mmix_elf_section_data (input_section)
1440                           ->pjs.stub_offset);
1441    
1442                      mmix_elf_section_data (input_section)->pjs.stub_offset
1443                        += MAX_PUSHJ_STUB_SIZE;
1444    
1445                      /* Shift this reloc to the end of the relocs to maintain
1446                         the r_offset sorted reloc order.  */
1447                      relcpy = *rel;
1448                      memmove (rel, rel + 1, (char *) relend - (char *) rel);
1449                      relend[-1] = relcpy;
1450    
1451                      /* Back up one reloc, or else we'd skip the next reloc
1452                       in turn.  */
1453                      rel--;
1454                    }
1455    
1456                  pjsno++;
1457                }
1458            continue;            continue;
1459          }          }
1460    
# Line 1229  mmix_elf_relocate_section (output_bfd, i Line 1468  mmix_elf_relocate_section (output_bfd, i
1468          {          {
1469            sym = local_syms + r_symndx;            sym = local_syms + r_symndx;
1470            sec = local_sections [r_symndx];            sec = local_sections [r_symndx];
1471            relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);            relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1472    
1473            name = bfd_elf_string_from_elf_section            name = bfd_elf_string_from_elf_section (input_bfd,
1474              (input_bfd, symtab_hdr->sh_link, sym->st_name);                                                    symtab_hdr->sh_link,
1475            name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;                                                    sym->st_name);
1476              if (name == NULL)
1477                name = bfd_section_name (input_bfd, sec);
1478          }          }
1479        else        else
1480          {          {
1481            h = sym_hashes [r_symndx - symtab_hdr->sh_info];            bfd_boolean unresolved_reloc;
   
           while (h->root.type == bfd_link_hash_indirect  
                  || h->root.type == bfd_link_hash_warning)  
             h = (struct elf_link_hash_entry *) h->root.u.i.link;  
1482    
1483              RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1484                                       r_symndx, symtab_hdr, sym_hashes,
1485                                       h, sec, relocation,
1486                                       unresolved_reloc, undefined_signalled);
1487            name = h->root.root.string;            name = h->root.root.string;
   
           if (h->root.type == bfd_link_hash_defined  
               || h->root.type == bfd_link_hash_defweak)  
             {  
               sec = h->root.u.def.section;  
               relocation = (h->root.u.def.value  
                             + sec->output_section->vma  
                             + sec->output_offset);  
             }  
           else if (h->root.type == bfd_link_hash_undefweak)  
             relocation = 0;  
           else if (info->shared  
                    && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)  
             relocation = 0;  
           else  
             {  
               /* The test on undefined_signalled is redundant at the  
                  moment, but kept for symmetry.  */  
               if (! undefined_signalled  
                   && ! ((*info->callbacks->undefined_symbol)  
                         (info, h->root.root.string, input_bfd,  
                          input_section, rel->r_offset, true)))  
                 return false;  
               undefined_signalled = true;  
               relocation = 0;  
             }  
1488          }          }
1489    
1490        r = mmix_final_link_relocate (howto, input_section,        r = mmix_final_link_relocate (howto, input_section,
# Line 1278  mmix_elf_relocate_section (output_bfd, i Line 1493  mmix_elf_relocate_section (output_bfd, i
1493    
1494        if (r != bfd_reloc_ok)        if (r != bfd_reloc_ok)
1495          {          {
1496            boolean check_ok = true;            bfd_boolean check_ok = TRUE;
1497            const char * msg = (const char *) NULL;            const char * msg = (const char *) NULL;
1498    
1499            switch (r)            switch (r)
1500              {              {
1501              case bfd_reloc_overflow:              case bfd_reloc_overflow:
1502                check_ok = info->callbacks->reloc_overflow                check_ok = info->callbacks->reloc_overflow
1503                  (info, name, howto->name, (bfd_vma) 0,                  (info, (h ? &h->root : NULL), name, howto->name,
1504                   input_bfd, input_section, rel->r_offset);                   (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
1505                break;                break;
1506    
1507              case bfd_reloc_undefined:              case bfd_reloc_undefined:
# Line 1294  mmix_elf_relocate_section (output_bfd, i Line 1509  mmix_elf_relocate_section (output_bfd, i
1509                if (! undefined_signalled)                if (! undefined_signalled)
1510                  check_ok = info->callbacks->undefined_symbol                  check_ok = info->callbacks->undefined_symbol
1511                    (info, name, input_bfd, input_section, rel->r_offset,                    (info, name, input_bfd, input_section, rel->r_offset,
1512                     true);                     TRUE);
1513                undefined_signalled = true;                undefined_signalled = TRUE;
1514                break;                break;
1515    
1516              case bfd_reloc_outofrange:              case bfd_reloc_outofrange:
# Line 1320  mmix_elf_relocate_section (output_bfd, i Line 1535  mmix_elf_relocate_section (output_bfd, i
1535                (info, msg, name, input_bfd, input_section, rel->r_offset);                (info, msg, name, input_bfd, input_section, rel->r_offset);
1536    
1537            if (! check_ok)            if (! check_ok)
1538              return false;              return FALSE;
1539          }          }
1540      }      }
1541    
1542    return true;    return TRUE;
1543  }  }
1544    
1545  /* Perform a single relocation.  By default we use the standard BFD  /* Perform a single relocation.  By default we use the standard BFD
# Line 1353  mmix_final_link_relocate (howto, input_s Line 1568  mmix_final_link_relocate (howto, input_s
1568    switch (howto->type)    switch (howto->type)
1569      {      {
1570        /* All these are PC-relative.  */        /* All these are PC-relative.  */
1571        case R_MMIX_PUSHJ_STUBBABLE:
1572      case R_MMIX_PUSHJ:      case R_MMIX_PUSHJ:
1573      case R_MMIX_CBRANCH:      case R_MMIX_CBRANCH:
1574      case R_MMIX_ADDR19:      case R_MMIX_ADDR19:
# Line 1565  mmix_elf_gc_mark_hook (sec, info, rel, h Line 1781  mmix_elf_gc_mark_hook (sec, info, rel, h
1781     GC (or section merge) and the point when all input sections must be     GC (or section merge) and the point when all input sections must be
1782     present.  Better to waste some memory and (perhaps) a little time.  */     present.  Better to waste some memory and (perhaps) a little time.  */
1783    
1784  static boolean  static bfd_boolean
1785  mmix_elf_gc_sweep_hook (abfd, info, sec, relocs)  mmix_elf_gc_sweep_hook (abfd, info, sec, relocs)
1786       bfd *abfd ATTRIBUTE_UNUSED;       bfd *abfd ATTRIBUTE_UNUSED;
1787       struct bfd_link_info *info ATTRIBUTE_UNUSED;       struct bfd_link_info *info ATTRIBUTE_UNUSED;
# Line 1573  mmix_elf_gc_sweep_hook (abfd, info, sec, Line 1789  mmix_elf_gc_sweep_hook (abfd, info, sec,
1789       const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;       const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
1790  {  {
1791    struct bpo_reloc_section_info *bpodata    struct bpo_reloc_section_info *bpodata
1792      = (struct bpo_reloc_section_info *)      = mmix_elf_section_data (sec)->bpo.reloc;
     elf_section_data (sec)->tdata;  
1793    asection *allocated_gregs_section;    asection *allocated_gregs_section;
1794    
1795    /* If no bpodata here, we have nothing to do.  */    /* If no bpodata here, we have nothing to do.  */
1796    if (bpodata == NULL)    if (bpodata == NULL)
1797      return true;      return TRUE;
1798    
1799    allocated_gregs_section = bpodata->bpo_greg_section;    allocated_gregs_section = bpodata->bpo_greg_section;
1800    
1801    ((struct bpo_greg_section_info *)    mmix_elf_section_data (allocated_gregs_section)->bpo.greg->n_bpo_relocs
    elf_section_data (allocated_gregs_section)->tdata)  
     ->n_bpo_relocs  
1802      -= bpodata->n_bpo_relocs_this_section;      -= bpodata->n_bpo_relocs_this_section;
1803    
1804    return true;    return TRUE;
1805  }  }
1806    
1807  /* Sort register relocs to come before expanding relocs.  */  /* Sort register relocs to come before expanding relocs.  */
# Line 1628  mmix_elf_sort_relocs (p1, p2) Line 1841  mmix_elf_sort_relocs (p1, p2)
1841    
1842  /* Subset of mmix_elf_check_relocs, common to ELF and mmo linking.  */  /* Subset of mmix_elf_check_relocs, common to ELF and mmo linking.  */
1843    
1844  static boolean  static bfd_boolean
1845  mmix_elf_check_common_relocs  (abfd, info, sec, relocs)  mmix_elf_check_common_relocs  (abfd, info, sec, relocs)
1846       bfd *abfd;       bfd *abfd;
1847       struct bfd_link_info *info;       struct bfd_link_info *info;
# Line 1642  mmix_elf_check_common_relocs  (abfd, inf Line 1855  mmix_elf_check_common_relocs  (abfd, inf
1855    const Elf_Internal_Rela *rel;    const Elf_Internal_Rela *rel;
1856    const Elf_Internal_Rela *rel_end;    const Elf_Internal_Rela *rel_end;
1857    
   if (info->relocateable)  
     return true;  
   
1858    /* We currently have to abuse this COFF-specific member, since there's    /* We currently have to abuse this COFF-specific member, since there's
1859       no target-machine-dedicated member.  There's no alternative outside       no target-machine-dedicated member.  There's no alternative outside
1860       the bfd_link_info struct; we can't specialize a hash-table since       the bfd_link_info struct; we can't specialize a hash-table since
# Line 1662  mmix_elf_check_common_relocs  (abfd, inf Line 1872  mmix_elf_check_common_relocs  (abfd, inf
1872               the ELF dynobj for this, since the ELF bits assume lots of               the ELF dynobj for this, since the ELF bits assume lots of
1873               DSO-related stuff if that member is non-NULL.  */               DSO-related stuff if that member is non-NULL.  */
1874          case R_MMIX_BASE_PLUS_OFFSET:          case R_MMIX_BASE_PLUS_OFFSET:
1875              /* We don't do anything with this reloc for a relocatable link.  */
1876              if (info->relocatable)
1877                break;
1878    
1879            if (bpo_greg_owner == NULL)            if (bpo_greg_owner == NULL)
1880              {              {
1881                bpo_greg_owner = abfd;                bpo_greg_owner = abfd;
# Line 1692  mmix_elf_check_common_relocs  (abfd, inf Line 1906  mmix_elf_check_common_relocs  (abfd, inf
1906                    || !bfd_set_section_alignment (bpo_greg_owner,                    || !bfd_set_section_alignment (bpo_greg_owner,
1907                                                   allocated_gregs_section,                                                   allocated_gregs_section,
1908                                                   3))                                                   3))
1909                  return false;                  return FALSE;
1910    
1911                gregdata = (struct bpo_greg_section_info *)                gregdata = (struct bpo_greg_section_info *)
1912                  bfd_zalloc (bpo_greg_owner, sizeof (struct bpo_greg_section_info));                  bfd_zalloc (bpo_greg_owner, sizeof (struct bpo_greg_section_info));
1913                if (gregdata == NULL)                if (gregdata == NULL)
1914                  return false;                  return FALSE;
1915                elf_section_data (allocated_gregs_section)->tdata = gregdata;                mmix_elf_section_data (allocated_gregs_section)->bpo.greg
1916                    = gregdata;
1917              }              }
1918            else if (gregdata == NULL)            else if (gregdata == NULL)
1919              gregdata = elf_section_data (allocated_gregs_section)->tdata;              gregdata
1920                  = mmix_elf_section_data (allocated_gregs_section)->bpo.greg;
1921    
1922            /* Get ourselves some auxiliary info for the BPO-relocs.  */            /* Get ourselves some auxiliary info for the BPO-relocs.  */
1923            if (bpodata == NULL)            if (bpodata == NULL)
# Line 1713  mmix_elf_check_common_relocs  (abfd, inf Line 1929  mmix_elf_check_common_relocs  (abfd, inf
1929                             sizeof (struct bpo_reloc_section_info)                             sizeof (struct bpo_reloc_section_info)
1930                             * (sec->reloc_count + 1));                             * (sec->reloc_count + 1));
1931                if (bpodata == NULL)                if (bpodata == NULL)
1932                  return false;                  return FALSE;
1933                elf_section_data (sec)->tdata = bpodata;                mmix_elf_section_data (sec)->bpo.reloc = bpodata;
1934                bpodata->first_base_plus_offset_reloc                bpodata->first_base_plus_offset_reloc
1935                  = bpodata->bpo_index                  = bpodata->bpo_index
1936                  = gregdata->n_max_bpo_relocs;                  = gregdata->n_max_bpo_relocs;
# Line 1727  mmix_elf_check_common_relocs  (abfd, inf Line 1943  mmix_elf_check_common_relocs  (abfd, inf
1943            gregdata->n_max_bpo_relocs++;            gregdata->n_max_bpo_relocs++;
1944    
1945            /* We don't get another chance to set this before GC; we've not            /* We don't get another chance to set this before GC; we've not
1946               set up set up any hook that runs before GC.  */               set up any hook that runs before GC.  */
1947            gregdata->n_bpo_relocs            gregdata->n_bpo_relocs
1948              = gregdata->n_max_bpo_relocs;              = gregdata->n_max_bpo_relocs;
1949            break;            break;
1950    
1951            case R_MMIX_PUSHJ_STUBBABLE:
1952              mmix_elf_section_data (sec)->pjs.n_pushj_relocs++;
1953              break;
1954          }          }
1955      }      }
1956    
1957    return true;    /* Allocate per-reloc stub storage and initialize it to the max stub
1958         size.  */
1959      if (mmix_elf_section_data (sec)->pjs.n_pushj_relocs != 0)
1960        {
1961          size_t i;
1962    
1963          mmix_elf_section_data (sec)->pjs.stub_size
1964            = bfd_alloc (abfd, mmix_elf_section_data (sec)->pjs.n_pushj_relocs
1965                         * sizeof (mmix_elf_section_data (sec)
1966                                   ->pjs.stub_size[0]));
1967          if (mmix_elf_section_data (sec)->pjs.stub_size == NULL)
1968            return FALSE;
1969    
1970          for (i = 0; i < mmix_elf_section_data (sec)->pjs.n_pushj_relocs; i++)
1971            mmix_elf_section_data (sec)->pjs.stub_size[i] = MAX_PUSHJ_STUB_SIZE;
1972        }
1973    
1974      return TRUE;
1975  }  }
1976    
1977  /* Look through the relocs for a section during the first phase.  */  /* Look through the relocs for a section during the first phase.  */
1978    
1979  static boolean  static bfd_boolean
1980  mmix_elf_check_relocs (abfd, info, sec, relocs)  mmix_elf_check_relocs (abfd, info, sec, relocs)
1981       bfd *abfd;       bfd *abfd;
1982       struct bfd_link_info *info;       struct bfd_link_info *info;
# Line 1751  mmix_elf_check_relocs (abfd, info, sec, Line 1988  mmix_elf_check_relocs (abfd, info, sec,
1988    const Elf_Internal_Rela *rel;    const Elf_Internal_Rela *rel;
1989    const Elf_Internal_Rela *rel_end;    const Elf_Internal_Rela *rel_end;
1990    
   if (info->relocateable)  
     return true;  
   
1991    symtab_hdr = &elf_tdata (abfd)->symtab_hdr;    symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1992    sym_hashes = elf_sym_hashes (abfd);    sym_hashes = elf_sym_hashes (abfd);
1993    sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf64_External_Sym);    sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf64_External_Sym);
# Line 1767  mmix_elf_check_relocs (abfd, info, sec, Line 2001  mmix_elf_check_relocs (abfd, info, sec,
2001    
2002    /* Do the common part.  */    /* Do the common part.  */
2003    if (!mmix_elf_check_common_relocs (abfd, info, sec, relocs))    if (!mmix_elf_check_common_relocs (abfd, info, sec, relocs))
2004      return false;      return FALSE;
2005    
2006      if (info->relocatable)
2007        return TRUE;
2008    
2009    rel_end = relocs + sec->reloc_count;    rel_end = relocs + sec->reloc_count;
2010    for (rel = relocs; rel < rel_end; rel++)    for (rel = relocs; rel < rel_end; rel++)
# Line 1786  mmix_elf_check_relocs (abfd, info, sec, Line 2023  mmix_elf_check_relocs (abfd, info, sec,
2023          /* This relocation describes the C++ object vtable hierarchy.          /* This relocation describes the C++ object vtable hierarchy.
2024             Reconstruct it for later use during GC.  */             Reconstruct it for later use during GC.  */
2025          case R_MMIX_GNU_VTINHERIT:          case R_MMIX_GNU_VTINHERIT:
2026            if (!_bfd_elf64_gc_record_vtinherit (abfd, sec, h, rel->r_offset))            if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2027              return false;              return FALSE;
2028            break;            break;
2029    
2030          /* This relocation describes which C++ vtable entries are actually          /* This relocation describes which C++ vtable entries are actually
2031             used.  Record for later use during GC.  */             used.  Record for later use during GC.  */
2032          case R_MMIX_GNU_VTENTRY:          case R_MMIX_GNU_VTENTRY:
2033            if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend))            if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2034              return false;              return FALSE;
2035            break;            break;
2036          }          }
2037      }      }
2038    
2039    return true;    return TRUE;
2040  }  }
2041    
2042  /* Wrapper for mmix_elf_check_common_relocs, called when linking to mmo.  /* Wrapper for mmix_elf_check_common_relocs, called when linking to mmo.
2043     Copied from elf_link_add_object_symbols.  */     Copied from elf_link_add_object_symbols.  */
2044    
2045  boolean  bfd_boolean
2046  _bfd_mmix_check_all_relocs (abfd, info)  _bfd_mmix_check_all_relocs (abfd, info)
2047       bfd *abfd;       bfd *abfd;
2048       struct bfd_link_info *info;       struct bfd_link_info *info;
# Line 1815  _bfd_mmix_check_all_relocs (abfd, info) Line 2052  _bfd_mmix_check_all_relocs (abfd, info)
2052    for (o = abfd->sections; o != NULL; o = o->next)    for (o = abfd->sections; o != NULL; o = o->next)
2053      {      {
2054        Elf_Internal_Rela *internal_relocs;        Elf_Internal_Rela *internal_relocs;
2055        boolean ok;        bfd_boolean ok;
2056    
2057        if ((o->flags & SEC_RELOC) == 0        if ((o->flags & SEC_RELOC) == 0
2058            || o->reloc_count == 0            || o->reloc_count == 0
# Line 1825  _bfd_mmix_check_all_relocs (abfd, info) Line 2062  _bfd_mmix_check_all_relocs (abfd, info)
2062          continue;          continue;
2063    
2064        internal_relocs        internal_relocs
2065          = _bfd_elf64_link_read_relocs (abfd, o, (PTR) NULL,          = _bfd_elf_link_read_relocs (abfd, o, (PTR) NULL,
2066                                         (Elf_Internal_Rela *) NULL,                                       (Elf_Internal_Rela *) NULL,
2067                                         info->keep_memory);                                       info->keep_memory);
2068        if (internal_relocs == NULL)        if (internal_relocs == NULL)
2069          return false;          return FALSE;
2070    
2071        ok = mmix_elf_check_common_relocs (abfd, info, o, internal_relocs);        ok = mmix_elf_check_common_relocs (abfd, info, o, internal_relocs);
2072    
# Line 1837  _bfd_mmix_check_all_relocs (abfd, info) Line 2074  _bfd_mmix_check_all_relocs (abfd, info)
2074          free (internal_relocs);          free (internal_relocs);
2075    
2076        if (! ok)        if (! ok)
2077          return false;          return FALSE;
2078      }      }
2079    
2080    return true;    return TRUE;
2081  }  }
2082    
2083  /* Change symbols relative to the reg contents section to instead be to  /* Change symbols relative to the reg contents section to instead be to
2084     the register section, and scale them down to correspond to the register     the register section, and scale them down to correspond to the register
2085     number.  */     number.  */
2086    
2087  static boolean  static bfd_boolean
2088  mmix_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)  mmix_elf_link_output_symbol_hook (info, name, sym, input_sec, h)
      bfd *abfd ATTRIBUTE_UNUSED;  
2089       struct bfd_link_info *info ATTRIBUTE_UNUSED;       struct bfd_link_info *info ATTRIBUTE_UNUSED;
2090       const char *name ATTRIBUTE_UNUSED;       const char *name ATTRIBUTE_UNUSED;
2091       Elf_Internal_Sym *sym;       Elf_Internal_Sym *sym;
2092       asection *input_sec;       asection *input_sec;
2093         struct elf_link_hash_entry *h ATTRIBUTE_UNUSED;
2094  {  {
2095    if (input_sec != NULL    if (input_sec != NULL
2096        && input_sec->name != NULL        && input_sec->name != NULL
# Line 1864  mmix_elf_link_output_symbol_hook (abfd, Line 2101  mmix_elf_link_output_symbol_hook (abfd,
2101        sym->st_shndx = SHN_REGISTER;        sym->st_shndx = SHN_REGISTER;
2102      }      }
2103    
2104    return true;    return TRUE;
2105  }  }
2106    
2107  /* We fake a register section that holds values that are register numbers.  /* We fake a register section that holds values that are register numbers.
# Line 1875  static asection mmix_elf_reg_section; Line 2112  static asection mmix_elf_reg_section;
2112  static asymbol mmix_elf_reg_section_symbol;  static asymbol mmix_elf_reg_section_symbol;
2113  static asymbol *mmix_elf_reg_section_symbol_ptr;  static asymbol *mmix_elf_reg_section_symbol_ptr;
2114    
2115  /* Handle the special MIPS section numbers that a symbol may use.  /* Handle the special section numbers that a symbol may use.  */
    This is used for both the 32-bit and the 64-bit ABI.  */  
2116    
2117  void  void
2118  mmix_elf_symbol_processing (abfd, asym)  mmix_elf_symbol_processing (abfd, asym)
# Line 1913  mmix_elf_symbol_processing (abfd, asym) Line 2149  mmix_elf_symbol_processing (abfd, asym)
2149  /* Given a BFD section, try to locate the corresponding ELF section  /* Given a BFD section, try to locate the corresponding ELF section
2150     index.  */     index.  */
2151    
2152  static boolean  static bfd_boolean
2153  mmix_elf_section_from_bfd_section (abfd, sec, retval)  mmix_elf_section_from_bfd_section (abfd, sec, retval)
2154       bfd *                 abfd ATTRIBUTE_UNUSED;       bfd *                 abfd ATTRIBUTE_UNUSED;
2155       asection *            sec;       asection *            sec;
# Line 1922  mmix_elf_section_from_bfd_section (abfd, Line 2158  mmix_elf_section_from_bfd_section (abfd,
2158    if (strcmp (bfd_get_section_name (abfd, sec), MMIX_REG_SECTION_NAME) == 0)    if (strcmp (bfd_get_section_name (abfd, sec), MMIX_REG_SECTION_NAME) == 0)
2159      *retval = SHN_REGISTER;      *retval = SHN_REGISTER;
2160    else    else
2161      return false;      return FALSE;
2162    
2163    return true;    return TRUE;
2164  }  }
2165    
2166  /* Hook called by the linker routine which adds symbols from an object  /* Hook called by the linker routine which adds symbols from an object
# Line 1934  mmix_elf_section_from_bfd_section (abfd, Line 2170  mmix_elf_section_from_bfd_section (abfd,
2170     symbols, since otherwise having two with the same value would cause     symbols, since otherwise having two with the same value would cause
2171     them to be "merged", but with the contents serialized.  */     them to be "merged", but with the contents serialized.  */
2172    
2173  boolean  bfd_boolean
2174  mmix_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)  mmix_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
2175       bfd *abfd;       bfd *abfd;
2176       struct bfd_link_info *info ATTRIBUTE_UNUSED;       struct bfd_link_info *info ATTRIBUTE_UNUSED;
2177       const Elf_Internal_Sym *sym;       Elf_Internal_Sym *sym;
2178       const char **namep ATTRIBUTE_UNUSED;       const char **namep ATTRIBUTE_UNUSED;
2179       flagword *flagsp ATTRIBUTE_UNUSED;       flagword *flagsp ATTRIBUTE_UNUSED;
2180       asection **secp;       asection **secp;
# Line 1953  mmix_elf_add_symbol_hook (abfd, info, sy Line 2189  mmix_elf_add_symbol_hook (abfd, info, sy
2189        /* See if we have another one.  */        /* See if we have another one.  */
2190        struct bfd_link_hash_entry *h = bfd_link_hash_lookup (info->hash,        struct bfd_link_hash_entry *h = bfd_link_hash_lookup (info->hash,
2191                                                              *namep,                                                              *namep,
2192                                                              false,                                                              FALSE,
2193                                                              false,                                                              FALSE,
2194                                                              false);                                                              FALSE);
2195    
2196        if (h != NULL && h->type != bfd_link_hash_undefined)        if (h != NULL && h->type != bfd_link_hash_undefined)
2197          {          {
# Line 1966  mmix_elf_add_symbol_hook (abfd, info, sy Line 2202  mmix_elf_add_symbol_hook (abfd, info, sy
2202              bfd_get_filename (abfd), *namep,              bfd_get_filename (abfd), *namep,
2203              *namep + strlen (MMIX_LOC_SECTION_START_SYMBOL_PREFIX)));              *namep + strlen (MMIX_LOC_SECTION_START_SYMBOL_PREFIX)));
2204             bfd_set_error (bfd_error_bad_value);             bfd_set_error (bfd_error_bad_value);
2205             return false;             return FALSE;
2206          }          }
2207      }      }
2208    
2209    return true;    return TRUE;
2210  }  }
2211    
2212  /* We consider symbols matching "L.*:[0-9]+" to be local symbols.  */  /* We consider symbols matching "L.*:[0-9]+" to be local symbols.  */
2213    
2214  boolean  bfd_boolean
2215  mmix_elf_is_local_label_name (abfd, name)  mmix_elf_is_local_label_name (abfd, name)
2216       bfd *abfd;       bfd *abfd;
2217       const char *name;       const char *name;
# Line 1985  mmix_elf_is_local_label_name (abfd, name Line 2221  mmix_elf_is_local_label_name (abfd, name
2221    
2222    /* Also include the default local-label definition.  */    /* Also include the default local-label definition.  */
2223    if (_bfd_elf_is_local_label_name (abfd, name))    if (_bfd_elf_is_local_label_name (abfd, name))
2224      return true;      return TRUE;
2225    
2226    if (*name != 'L')    if (*name != 'L')
2227      return false;      return FALSE;
2228    
2229    /* If there's no ":", or more than one, it's not a local symbol.  */    /* If there's no ":", or more than one, it's not a local symbol.  */
2230    colpos = strchr (name, ':');    colpos = strchr (name, ':');
2231    if (colpos == NULL || strchr (colpos + 1, ':') != NULL)    if (colpos == NULL || strchr (colpos + 1, ':') != NULL)
2232      return false;      return FALSE;
2233    
2234    /* Check that there are remaining characters and that they are digits.  */    /* Check that there are remaining characters and that they are digits.  */
2235    if (colpos[1] == 0)    if (colpos[1] == 0)
2236      return false;      return FALSE;
2237    
2238    digits = strspn (colpos + 1, "0123456789");    digits = strspn (colpos + 1, "0123456789");
2239    return digits != 0 && colpos[1 + digits] == 0;    return digits != 0 && colpos[1 + digits] == 0;
# Line 2005  mmix_elf_is_local_label_name (abfd, name Line 2241  mmix_elf_is_local_label_name (abfd, name
2241    
2242  /* We get rid of the register section here.  */  /* We get rid of the register section here.  */
2243    
2244  boolean  bfd_boolean
2245  mmix_elf_final_link (abfd, info)  mmix_elf_final_link (abfd, info)
2246       bfd *abfd;       bfd *abfd;
2247       struct bfd_link_info *info;       struct bfd_link_info *info;
# Line 2032  mmix_elf_final_link (abfd, info) Line 2268  mmix_elf_final_link (abfd, info)
2268        --abfd->section_count;        --abfd->section_count;
2269      }      }
2270    
2271    if (! bfd_elf64_bfd_final_link (abfd, info))    if (! bfd_elf_final_link (abfd, info))
2272      return false;      return FALSE;
2273    
2274    /* Since this section is marked SEC_LINKER_CREATED, it isn't output by    /* Since this section is marked SEC_LINKER_CREATED, it isn't output by
2275       the regular linker machinery.  We do it here, like other targets with       the regular linker machinery.  We do it here, like other targets with
# Line 2047  mmix_elf_final_link (abfd, info) Line 2283  mmix_elf_final_link (abfd, info)
2283                                       greg_section->output_section,                                       greg_section->output_section,
2284                                       greg_section->contents,                                       greg_section->contents,
2285                                       (file_ptr) greg_section->output_offset,                                       (file_ptr) greg_section->output_offset,
2286                                       greg_section->_cooked_size))                                       greg_section->size))
2287          return false;          return FALSE;
2288      }      }
2289    return true;    return TRUE;
2290    }
2291    
2292    /* We need to include the maximum size of PUSHJ-stubs in the initial
2293       section size.  This is expected to shrink during linker relaxation.  */
2294    
2295    static void
2296    mmix_set_relaxable_size (abfd, sec, ptr)
2297         bfd *abfd ATTRIBUTE_UNUSED;
2298         asection *sec;
2299         void *ptr;
2300    {
2301      struct bfd_link_info *info = ptr;
2302    
2303      /* Make sure we only do this for section where we know we want this,
2304         otherwise we might end up resetting the size of COMMONs.  */
2305      if (mmix_elf_section_data (sec)->pjs.n_pushj_relocs == 0)
2306        return;
2307    
2308      sec->rawsize = sec->size;
2309      sec->size += (mmix_elf_section_data (sec)->pjs.n_pushj_relocs
2310                    * MAX_PUSHJ_STUB_SIZE);
2311    
2312      /* For use in relocatable link, we start with a max stubs size.  See
2313         mmix_elf_relax_section.  */
2314      if (info->relocatable && sec->output_section)
2315        mmix_elf_section_data (sec->output_section)->pjs.stubs_size_sum
2316          += (mmix_elf_section_data (sec)->pjs.n_pushj_relocs
2317              * MAX_PUSHJ_STUB_SIZE);
2318  }  }
2319    
2320  /* Initialize stuff for the linker-generated GREGs to match  /* Initialize stuff for the linker-generated GREGs to match
2321     R_MMIX_BASE_PLUS_OFFSET relocs seen by the linker.  */     R_MMIX_BASE_PLUS_OFFSET relocs seen by the linker.  */
2322    
2323  boolean  bfd_boolean
2324  _bfd_mmix_prepare_linker_allocated_gregs (abfd, info)  _bfd_mmix_before_linker_allocation (abfd, info)
2325       bfd *abfd ATTRIBUTE_UNUSED;       bfd *abfd ATTRIBUTE_UNUSED;
2326       struct bfd_link_info *info;       struct bfd_link_info *info;
2327  {  {
# Line 2068  _bfd_mmix_prepare_linker_allocated_gregs Line 2332  _bfd_mmix_prepare_linker_allocated_gregs
2332    bfd_vma gregs_size;    bfd_vma gregs_size;
2333    size_t i;    size_t i;
2334    size_t *bpo_reloc_indexes;    size_t *bpo_reloc_indexes;
2335      bfd *ibfd;
2336    
2337      /* Set the initial size of sections.  */
2338      for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
2339        bfd_map_over_sections (ibfd, mmix_set_relaxable_size, info);
2340    
2341    /* The bpo_greg_owner bfd is supposed to have been set by    /* The bpo_greg_owner bfd is supposed to have been set by
2342       mmix_elf_check_relocs when the first R_MMIX_BASE_PLUS_OFFSET is seen.       mmix_elf_check_relocs when the first R_MMIX_BASE_PLUS_OFFSET is seen.
2343       If there is no such object, there was no R_MMIX_BASE_PLUS_OFFSET.  */       If there is no such object, there was no R_MMIX_BASE_PLUS_OFFSET.  */
2344    bpo_greg_owner = (bfd *) info->base_file;    bpo_greg_owner = (bfd *) info->base_file;
2345    if (bpo_greg_owner == NULL)    if (bpo_greg_owner == NULL)
2346      return true;      return TRUE;
2347    
2348    bpo_gregs_section    bpo_gregs_section
2349      = bfd_get_section_by_name (bpo_greg_owner,      = bfd_get_section_by_name (bpo_greg_owner,
2350                                 MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);                                 MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
2351    
2352    if (bpo_gregs_section == NULL)    if (bpo_gregs_section == NULL)
2353      return true;      return TRUE;
2354    
2355    /* We use the target-data handle in the ELF section data.  */    /* We use the target-data handle in the ELF section data.  */
2356    gregdata = (struct bpo_greg_section_info *)    gregdata = mmix_elf_section_data (bpo_gregs_section)->bpo.greg;
     elf_section_data (bpo_gregs_section)->tdata;  
2357    if (gregdata == NULL)    if (gregdata == NULL)
2358      return false;      return FALSE;
2359    
2360    n_gregs = gregdata->n_bpo_relocs;    n_gregs = gregdata->n_bpo_relocs;
2361    gregdata->n_allocated_bpo_gregs = n_gregs;    gregdata->n_allocated_bpo_gregs = n_gregs;
# Line 2100  _bfd_mmix_prepare_linker_allocated_gregs Line 2368  _bfd_mmix_prepare_linker_allocated_gregs
2368    gregs_size = n_gregs * 8;    gregs_size = n_gregs * 8;
2369    
2370    if (!bfd_set_section_size (bpo_greg_owner, bpo_gregs_section, gregs_size))    if (!bfd_set_section_size (bpo_greg_owner, bpo_gregs_section, gregs_size))
2371      return false;      return FALSE;
2372    
2373    /* Allocate and set up the GREG arrays.  They're filled in at relaxation    /* Allocate and set up the GREG arrays.  They're filled in at relaxation
2374       time.  Note that we must use the max number ever noted for the array,       time.  Note that we must use the max number ever noted for the array,
# Line 2116  _bfd_mmix_prepare_linker_allocated_gregs Line 2384  _bfd_mmix_prepare_linker_allocated_gregs
2384                   gregdata->n_max_bpo_relocs                   gregdata->n_max_bpo_relocs
2385                   * sizeof (size_t));                   * sizeof (size_t));
2386    if (bpo_reloc_indexes == NULL)    if (bpo_reloc_indexes == NULL)
2387      return false;      return FALSE;
2388    
2389    /* The default order is an identity mapping.  */    /* The default order is an identity mapping.  */
2390    for (i = 0; i < gregdata->n_max_bpo_relocs; i++)    for (i = 0; i < gregdata->n_max_bpo_relocs; i++)
# Line 2125  _bfd_mmix_prepare_linker_allocated_gregs Line 2393  _bfd_mmix_prepare_linker_allocated_gregs
2393        gregdata->reloc_request[i].bpo_reloc_no = i;        gregdata->reloc_request[i].bpo_reloc_no = i;
2394      }      }
2395    
2396    return true;    return TRUE;
2397  }  }
2398    
2399  /* Fill in contents in the linker allocated gregs.  Everything is  /* Fill in contents in the linker allocated gregs.  Everything is
2400     calculated at this point; we just move the contents into place here.  */     calculated at this point; we just move the contents into place here.  */
2401    
2402  boolean  bfd_boolean
2403  _bfd_mmix_finalize_linker_allocated_gregs (abfd, link_info)  _bfd_mmix_after_linker_allocation (abfd, link_info)
2404       bfd *abfd ATTRIBUTE_UNUSED;       bfd *abfd ATTRIBUTE_UNUSED;
2405       struct bfd_link_info *link_info;       struct bfd_link_info *link_info;
2406  {  {
# Line 2149  _bfd_mmix_finalize_linker_allocated_greg Line 2417  _bfd_mmix_finalize_linker_allocated_greg
2417       object, there was no R_MMIX_BASE_PLUS_OFFSET.  */       object, there was no R_MMIX_BASE_PLUS_OFFSET.  */
2418    bpo_greg_owner = (bfd *) link_info->base_file;    bpo_greg_owner = (bfd *) link_info->base_file;
2419    if (bpo_greg_owner == NULL)    if (bpo_greg_owner == NULL)
2420      return true;      return TRUE;
2421    
2422    bpo_gregs_section    bpo_gregs_section
2423      = bfd_get_section_by_name (bpo_greg_owner,      = bfd_get_section_by_name (bpo_greg_owner,
# Line 2159  _bfd_mmix_finalize_linker_allocated_greg Line 2427  _bfd_mmix_finalize_linker_allocated_greg
2427       without any R_MMIX_BASE_PLUS_OFFSET seen, there will be no such       without any R_MMIX_BASE_PLUS_OFFSET seen, there will be no such
2428       section.  */       section.  */
2429    if (bpo_gregs_section == NULL)    if (bpo_gregs_section == NULL)
2430      return true;      return TRUE;
2431    
2432    /* We use the target-data handle in the ELF section data.  */    /* We use the target-data handle in the ELF section data.  */
2433    
2434    gregdata = (struct bpo_greg_section_info *)    gregdata = mmix_elf_section_data (bpo_gregs_section)->bpo.greg;
     elf_section_data (bpo_gregs_section)->tdata;  
2435    if (gregdata == NULL)    if (gregdata == NULL)
2436      return false;      return FALSE;
2437    
2438    n_gregs = gregdata->n_allocated_bpo_gregs;    n_gregs = gregdata->n_allocated_bpo_gregs;
2439    
2440    bpo_gregs_section->contents    bpo_gregs_section->contents
2441      = contents = bfd_alloc (bpo_greg_owner, bpo_gregs_section->_cooked_size);      = contents = bfd_alloc (bpo_greg_owner, bpo_gregs_section->size);
2442    if (contents == NULL)    if (contents == NULL)
2443      return false;      return FALSE;
2444    
2445    /* Sanity check: If these numbers mismatch, some relocation has not been    /* Sanity check: If these numbers mismatch, some relocation has not been
2446       accounted for and the rest of gregdata is probably inconsistent.       accounted for and the rest of gregdata is probably inconsistent.
# Line 2187  _bfd_mmix_finalize_linker_allocated_greg Line 2454  _bfd_mmix_finalize_linker_allocated_greg
2454    Please report this bug."),    Please report this bug."),
2455           gregdata->n_remaining_bpo_relocs_this_relaxation_round,           gregdata->n_remaining_bpo_relocs_this_relaxation_round,
2456           gregdata->n_bpo_relocs);           gregdata->n_bpo_relocs);
2457        return false;        return FALSE;
2458      }      }
2459    
2460    for (lastreg = 255, i = 0, j = 0; j < n_gregs; i++)    for (lastreg = 255, i = 0, j = 0; j < n_gregs; i++)
# Line 2199  _bfd_mmix_finalize_linker_allocated_greg Line 2466  _bfd_mmix_finalize_linker_allocated_greg
2466          j++;          j++;
2467        }        }
2468    
2469    return true;    return TRUE;
2470  }  }
2471    
2472  /* Sort valid relocs to come before non-valid relocs, then on increasing  /* Sort valid relocs to come before non-valid relocs, then on increasing
# Line 2257  mmix_dump_bpo_gregs (link_info, pf) Line 2524  mmix_dump_bpo_gregs (link_info, pf)
2524    if (bpo_gregs_section == NULL)    if (bpo_gregs_section == NULL)
2525      return;      return;
2526    
2527    gregdata = (struct bpo_greg_section_info *)    gregdata = mmix_elf_section_data (bpo_gregs_section)->bpo.greg;
     elf_section_data (bpo_gregs_section)->tdata;  
2528    if (gregdata == NULL)    if (gregdata == NULL)
2529      return;      return;
2530    
# Line 2278  mmix_dump_bpo_gregs (link_info, pf) Line 2544  mmix_dump_bpo_gregs (link_info, pf)
2544      for (i = 0; i < gregdata->n_max_bpo_relocs; i++)      for (i = 0; i < gregdata->n_max_bpo_relocs; i++)
2545        (*pf) ("%4u (%4u)/%4u#%u: 0x%08lx%08lx  r: %3u o: %3u\n",        (*pf) ("%4u (%4u)/%4u#%u: 0x%08lx%08lx  r: %3u o: %3u\n",
2546               i,               i,
2547               gregdata->bpo_reloc_indexes != NULL               (gregdata->bpo_reloc_indexes != NULL
2548               ? gregdata->bpo_reloc_indexes[i] : -1,                ? gregdata->bpo_reloc_indexes[i] : (size_t) -1),
2549               gregdata->reloc_request[i].bpo_reloc_no,               gregdata->reloc_request[i].bpo_reloc_no,
2550               gregdata->reloc_request[i].valid,               gregdata->reloc_request[i].valid,
2551    
# Line 2295  mmix_dump_bpo_gregs (link_info, pf) Line 2561  mmix_dump_bpo_gregs (link_info, pf)
2561     from the first allocated register number) and offsets for use in real     from the first allocated register number) and offsets for use in real
2562     relocation.     relocation.
2563    
2564       PUSHJ stub accounting is also done here.
2565    
2566     Symbol- and reloc-reading infrastructure copied from elf-m10200.c.  */     Symbol- and reloc-reading infrastructure copied from elf-m10200.c.  */
2567    
2568  static boolean  static bfd_boolean
2569  mmix_elf_relax_section (abfd, sec, link_info, again)  mmix_elf_relax_section (abfd, sec, link_info, again)
2570       bfd *abfd;       bfd *abfd;
2571       asection *sec;       asection *sec;
2572       struct bfd_link_info *link_info;       struct bfd_link_info *link_info;
2573       boolean *again;       bfd_boolean *again;
2574  {  {
2575    Elf_Internal_Shdr *symtab_hdr;    Elf_Internal_Shdr *symtab_hdr;
2576    Elf_Internal_Rela *internal_relocs;    Elf_Internal_Rela *internal_relocs;
# Line 2310  mmix_elf_relax_section (abfd, sec, link_ Line 2578  mmix_elf_relax_section (abfd, sec, link_
2578    asection *bpo_gregs_section = NULL;    asection *bpo_gregs_section = NULL;
2579    struct bpo_greg_section_info *gregdata;    struct bpo_greg_section_info *gregdata;
2580    struct bpo_reloc_section_info *bpodata    struct bpo_reloc_section_info *bpodata
2581      = (struct bpo_reloc_section_info *)      = mmix_elf_section_data (sec)->bpo.reloc;
2582      elf_section_data (sec)->tdata;    /* The initialization is to quiet compiler warnings.  The value is to
2583    size_t bpono;       spot a missing actual initialization.  */
2584      size_t bpono = (size_t) -1;
2585      size_t pjsno = 0;
2586    bfd *bpo_greg_owner;    bfd *bpo_greg_owner;
2587    Elf_Internal_Sym *isymbuf = NULL;    Elf_Internal_Sym *isymbuf = NULL;
2588      bfd_size_type size = sec->rawsize ? sec->rawsize : sec->size;
2589    
2590      mmix_elf_section_data (sec)->pjs.stubs_size_sum = 0;
2591    
2592    /* Assume nothing changes.  */    /* Assume nothing changes.  */
2593    *again = false;    *again = FALSE;
2594    
2595    /* If this is the first time we have been called for this section,    /* We don't have to do anything if this section does not have relocs, or
2596       initialize the cooked size.  */       if this is not a code section.  */
2597    if (sec->_cooked_size == 0)    if ((sec->flags & SEC_RELOC) == 0
     sec->_cooked_size = sec->_raw_size;  
   
   /* We don't have to do anything for a relocateable link, if  
      this section does not have relocs, or if this is not a  
      code section.  */  
   if (link_info->relocateable  
       || (sec->flags & SEC_RELOC) == 0  
2598        || sec->reloc_count == 0        || sec->reloc_count == 0
2599        || (sec->flags & SEC_CODE) == 0        || (sec->flags & SEC_CODE) == 0
2600        || (sec->flags & SEC_LINKER_CREATED) != 0        || (sec->flags & SEC_LINKER_CREATED) != 0
2601        /* If no R_MMIX_BASE_PLUS_OFFSET relocs, then nothing to do.  */        /* If no R_MMIX_BASE_PLUS_OFFSET relocs and no PUSHJ-stub relocs,
2602        || bpodata == NULL)           then nothing to do.  */
2603      return true;        || (bpodata == NULL
2604              && mmix_elf_section_data (sec)->pjs.n_pushj_relocs == 0))
2605        return TRUE;
2606    
2607    symtab_hdr = &elf_tdata (abfd)->symtab_hdr;    symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2608    
2609    bpo_greg_owner = (bfd *) link_info->base_file;    bpo_greg_owner = (bfd *) link_info->base_file;
   bpo_gregs_section = bpodata->bpo_greg_section;  
   gregdata = (struct bpo_greg_section_info *)  
     elf_section_data (bpo_gregs_section)->tdata;  
2610    
2611    bpono = bpodata->first_base_plus_offset_reloc;    if (bpodata != NULL)
2612        {
2613          bpo_gregs_section = bpodata->bpo_greg_section;
2614          gregdata = mmix_elf_section_data (bpo_gregs_section)->bpo.greg;
2615          bpono = bpodata->first_base_plus_offset_reloc;
2616        }
2617      else
2618        gregdata = NULL;
2619    
2620    /* Get a copy of the native relocations.  */    /* Get a copy of the native relocations.  */
2621    internal_relocs    internal_relocs
2622      = _bfd_elf64_link_read_relocs (abfd, sec, (PTR) NULL,      = _bfd_elf_link_read_relocs (abfd, sec, (PTR) NULL,
2623                                     (Elf_Internal_Rela *) NULL,                                   (Elf_Internal_Rela *) NULL,
2624                                     link_info->keep_memory);                                   link_info->keep_memory);
2625    if (internal_relocs == NULL)    if (internal_relocs == NULL)
2626      goto error_return;      goto error_return;
2627    
# Line 2358  mmix_elf_relax_section (abfd, sec, link_ Line 2630  mmix_elf_relax_section (abfd, sec, link_
2630    for (irel = internal_relocs; irel < irelend; irel++)    for (irel = internal_relocs; irel < irelend; irel++)
2631      {      {
2632        bfd_vma symval;        bfd_vma symval;
2633          struct elf_link_hash_entry *h = NULL;
2634    
2635        if (ELF64_R_TYPE (irel->r_info) != (int) R_MMIX_BASE_PLUS_OFFSET)        /* We only process two relocs.  */
2636          if (ELF64_R_TYPE (irel->r_info) != (int) R_MMIX_BASE_PLUS_OFFSET
2637              && ELF64_R_TYPE (irel->r_info) != (int) R_MMIX_PUSHJ_STUBBABLE)
2638          continue;          continue;
2639    
2640          /* We process relocs in a distinctly different way when this is a
2641             relocatable link (for one, we don't look at symbols), so we avoid
2642             mixing its code with that for the "normal" relaxation.  */
2643          if (link_info->relocatable)
2644            {
2645              /* The only transformation in a relocatable link is to generate
2646                 a full stub at the location of the stub calculated for the
2647                 input section, if the relocated stub location, the end of the
2648                 output section plus earlier stubs, cannot be reached.  Thus
2649                 relocatable linking can only lead to worse code, but it still
2650                 works.  */
2651              if (ELF64_R_TYPE (irel->r_info) == R_MMIX_PUSHJ_STUBBABLE)
2652                {
2653                  /* If we can reach the end of the output-section and beyond
2654                     any current stubs, then we don't need a stub for this
2655                     reloc.  The relaxed order of output stub allocation may
2656                     not exactly match the straightforward order, so we always
2657                     assume presence of output stubs, which will allow
2658                     relaxation only on relocations indifferent to the
2659                     presence of output stub allocations for other relocations
2660                     and thus the order of output stub allocation.  */
2661                  if (bfd_check_overflow (complain_overflow_signed,
2662                                          19,
2663                                          0,
2664                                          bfd_arch_bits_per_address (abfd),
2665                                          /* Output-stub location.  */
2666                                          sec->output_section->rawsize
2667                                          + (mmix_elf_section_data (sec
2668                                                                   ->output_section)
2669                                             ->pjs.stubs_size_sum)
2670                                          /* Location of this PUSHJ reloc.  */
2671                                          - (sec->output_offset + irel->r_offset)
2672                                          /* Don't count *this* stub twice.  */
2673                                          - (mmix_elf_section_data (sec)
2674                                             ->pjs.stub_size[pjsno]
2675                                             + MAX_PUSHJ_STUB_SIZE))
2676                      == bfd_reloc_ok)
2677                    mmix_elf_section_data (sec)->pjs.stub_size[pjsno] = 0;
2678    
2679                  mmix_elf_section_data (sec)->pjs.stubs_size_sum
2680                    += mmix_elf_section_data (sec)->pjs.stub_size[pjsno];
2681    
2682                  pjsno++;
2683                }
2684    
2685              continue;
2686            }
2687    
2688        /* Get the value of the symbol referred to by the reloc.  */        /* Get the value of the symbol referred to by the reloc.  */
2689        if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)        if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2690          {          {
# Line 2397  mmix_elf_relax_section (abfd, sec, link_ Line 2720  mmix_elf_relax_section (abfd, sec, link_
2720        else        else
2721          {          {
2722            unsigned long indx;            unsigned long indx;
           struct elf_link_hash_entry *h;  
2723    
2724            /* An external symbol.  */            /* An external symbol.  */
2725            indx = ELF64_R_SYM (irel->r_info) - symtab_hdr->sh_info;            indx = ELF64_R_SYM (irel->r_info) - symtab_hdr->sh_info;
# Line 2406  mmix_elf_relax_section (abfd, sec, link_ Line 2728  mmix_elf_relax_section (abfd, sec, link_
2728            if (h->root.type != bfd_link_hash_defined            if (h->root.type != bfd_link_hash_defined
2729                && h->root.type != bfd_link_hash_defweak)                && h->root.type != bfd_link_hash_defweak)
2730              {              {
2731                /* This appears to be a reference to an undefined symbol.                /* This appears to be a reference to an undefined symbol.  Just
2732                   Just ignore it--it will be caught by the regular reloc                   ignore it--it will be caught by the regular reloc processing.
2733                   processing.  We need to keep BPO reloc accounting                   We need to keep BPO reloc accounting consistent, though
2734                   consistent, though.  */                   else we'll abort instead of emitting an error message.  */
2735                gregdata->n_remaining_bpo_relocs_this_relaxation_round--;                if (ELF64_R_TYPE (irel->r_info) == R_MMIX_BASE_PLUS_OFFSET
2736                bpono++;                    && gregdata != NULL)
2737                    {
2738                      gregdata->n_remaining_bpo_relocs_this_relaxation_round--;
2739                      bpono++;
2740                    }
2741                continue;                continue;
2742              }              }
2743    
# Line 2420  mmix_elf_relax_section (abfd, sec, link_ Line 2746  mmix_elf_relax_section (abfd, sec, link_
2746                      + h->root.u.def.section->output_offset);                      + h->root.u.def.section->output_offset);
2747          }          }
2748    
2749          if (ELF64_R_TYPE (irel->r_info) == (int) R_MMIX_PUSHJ_STUBBABLE)
2750            {
2751              bfd_vma value = symval + irel->r_addend;
2752              bfd_vma dot
2753                = (sec->output_section->vma
2754                   + sec->output_offset
2755                   + irel->r_offset);
2756              bfd_vma stubaddr
2757                = (sec->output_section->vma
2758                   + sec->output_offset
2759                   + size
2760                   + mmix_elf_section_data (sec)->pjs.stubs_size_sum);
2761    
2762              if ((value & 3) == 0
2763                  && bfd_check_overflow (complain_overflow_signed,
2764                                         19,
2765                                         0,
2766                                         bfd_arch_bits_per_address (abfd),
2767                                         value - dot
2768                                         - (value > dot
2769                                            ? mmix_elf_section_data (sec)
2770                                            ->pjs.stub_size[pjsno]
2771                                            : 0))
2772                  == bfd_reloc_ok)
2773                /* If the reloc fits, no stub is needed.  */
2774                mmix_elf_section_data (sec)->pjs.stub_size[pjsno] = 0;
2775              else
2776                /* Maybe we can get away with just a JMP insn?  */
2777                if ((value & 3) == 0
2778                    && bfd_check_overflow (complain_overflow_signed,
2779                                           27,
2780                                           0,
2781                                           bfd_arch_bits_per_address (abfd),
2782                                           value - stubaddr
2783                                           - (value > dot
2784                                              ? mmix_elf_section_data (sec)
2785                                              ->pjs.stub_size[pjsno] - 4
2786                                              : 0))
2787                    == bfd_reloc_ok)
2788                  /* Yep, account for a stub consisting of a single JMP insn.  */
2789                  mmix_elf_section_data (sec)->pjs.stub_size[pjsno] = 4;
2790              else
2791                /* Nope, go for the full insn stub.  It doesn't seem useful to
2792                   emit the intermediate sizes; those will only be useful for
2793                   a >64M program assuming contiguous code.  */
2794                mmix_elf_section_data (sec)->pjs.stub_size[pjsno]
2795                  = MAX_PUSHJ_STUB_SIZE;
2796    
2797              mmix_elf_section_data (sec)->pjs.stubs_size_sum
2798                += mmix_elf_section_data (sec)->pjs.stub_size[pjsno];
2799              pjsno++;
2800              continue;
2801            }
2802    
2803          /* We're looking at a R_MMIX_BASE_PLUS_OFFSET reloc.  */
2804    
2805        gregdata->reloc_request[gregdata->bpo_reloc_indexes[bpono]].value        gregdata->reloc_request[gregdata->bpo_reloc_indexes[bpono]].value
2806          = symval + irel->r_addend;          = symval + irel->r_addend;
2807        gregdata->reloc_request[gregdata->bpo_reloc_indexes[bpono++]].valid = true;        gregdata->reloc_request[gregdata->bpo_reloc_indexes[bpono++]].valid = TRUE;
2808        gregdata->n_remaining_bpo_relocs_this_relaxation_round--;        gregdata->n_remaining_bpo_relocs_this_relaxation_round--;
2809      }      }
2810    
# Line 2430  mmix_elf_relax_section (abfd, sec, link_ Line 2812  mmix_elf_relax_section (abfd, sec, link_
2812       calculate how many registers we need to cover them.  Set the size of       calculate how many registers we need to cover them.  Set the size of
2813       the linker gregs, and if the number of registers changed, indicate       the linker gregs, and if the number of registers changed, indicate
2814       that we need to relax some more because we have more work to do.  */       that we need to relax some more because we have more work to do.  */
2815    if (gregdata->n_remaining_bpo_relocs_this_relaxation_round == 0)    if (gregdata != NULL
2816          && gregdata->n_remaining_bpo_relocs_this_relaxation_round == 0)
2817      {      {
2818        size_t i;        size_t i;
2819        bfd_vma prev_base;        bfd_vma prev_base;
# Line 2455  mmix_elf_relax_section (abfd, sec, link_ Line 2838  mmix_elf_relax_section (abfd, sec, link_
2838            {            {
2839              gregdata->bpo_reloc_indexes[gregdata->reloc_request[i].bpo_reloc_no]              gregdata->bpo_reloc_indexes[gregdata->reloc_request[i].bpo_reloc_no]
2840                = i;                = i;
2841              *again = true;              *again = TRUE;
2842            }            }
2843    
2844        /* Allocate register numbers (indexing from 0).  Stop at the first        /* Allocate register numbers (indexing from 0).  Stop at the first
# Line 2481  mmix_elf_relax_section (abfd, sec, link_ Line 2864  mmix_elf_relax_section (abfd, sec, link_
2864        if (gregdata->n_allocated_bpo_gregs != regindex + 1)        if (gregdata->n_allocated_bpo_gregs != regindex + 1)
2865          {          {
2866            gregdata->n_allocated_bpo_gregs = regindex + 1;            gregdata->n_allocated_bpo_gregs = regindex + 1;
2867            *again = true;            *again = TRUE;
2868          }          }
2869    
2870        bpo_gregs_section->_cooked_size = (regindex + 1) * 8;        bpo_gregs_section->size = (regindex + 1) * 8;
2871      }      }
2872    
2873    if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)    if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
# Line 2502  mmix_elf_relax_section (abfd, sec, link_ Line 2885  mmix_elf_relax_section (abfd, sec, link_
2885        && elf_section_data (sec)->relocs != internal_relocs)        && elf_section_data (sec)->relocs != internal_relocs)
2886      free (internal_relocs);      free (internal_relocs);
2887    
2888    return true;    if (sec->size < size + mmix_elf_section_data (sec)->pjs.stubs_size_sum)
2889        abort ();
2890    
2891      if (sec->size > size + mmix_elf_section_data (sec)->pjs.stubs_size_sum)
2892        {
2893          sec->size = size + mmix_elf_section_data (sec)->pjs.stubs_size_sum;
2894          *again = TRUE;
2895        }
2896    
2897      return TRUE;
2898    
2899   error_return:   error_return:
2900    if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)    if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
# Line 2510  mmix_elf_relax_section (abfd, sec, link_ Line 2902  mmix_elf_relax_section (abfd, sec, link_
2902    if (internal_relocs != NULL    if (internal_relocs != NULL
2903        && elf_section_data (sec)->relocs != internal_relocs)        && elf_section_data (sec)->relocs != internal_relocs)
2904      free (internal_relocs);      free (internal_relocs);
2905    return false;    return FALSE;
2906  }  }
2907    
2908  #define ELF_ARCH                bfd_arch_mmix  #define ELF_ARCH                bfd_arch_mmix
# Line 2557  mmix_elf_relax_section (abfd, sec, link_ Line 2949  mmix_elf_relax_section (abfd, sec, link_
2949  #define elf_backend_section_from_bfd_section \  #define elf_backend_section_from_bfd_section \
2950          mmix_elf_section_from_bfd_section          mmix_elf_section_from_bfd_section
2951    
2952    #define bfd_elf64_new_section_hook      mmix_elf_new_section_hook
2953  #define bfd_elf64_bfd_final_link        mmix_elf_final_link  #define bfd_elf64_bfd_final_link        mmix_elf_final_link
2954  #define bfd_elf64_bfd_relax_section     mmix_elf_relax_section  #define bfd_elf64_bfd_relax_section     mmix_elf_relax_section
2955    

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26