Develop and Download Open Source Software

Browse Subversion Repository

Diff of /trunk/bfd/elf32-m68k.c

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

revision 20 by monabuilder, Sun Dec 28 03:31:28 2008 UTC revision 21 by monamour, Mon Jul 27 20:34:36 2009 UTC
# Line 1  Line 1 
1  /* Motorola 68k series support for 32-bit ELF  /* Motorola 68k series support for 32-bit ELF
2     Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,     Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3     2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.     2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4    
5     This file is part of BFD, the Binary File Descriptor library.     This file is part of BFD, the Binary File Descriptor library.
6    
# Line 114  static reloc_howto_type howto_table[] = Line 114  static reloc_howto_type howto_table[] =
114           0,                     /* src_mask */           0,                     /* src_mask */
115           0,                     /* dst_mask */           0,                     /* dst_mask */
116           FALSE),           FALSE),
117    
118      /* TLS general dynamic variable reference.  */
119      HOWTO (R_68K_TLS_GD32,        /* type */
120             0,                     /* rightshift */
121             2,                     /* size (0 = byte, 1 = short, 2 = long) */
122             32,                    /* bitsize */
123             FALSE,                 /* pc_relative */
124             0,                     /* bitpos */
125             complain_overflow_bitfield, /* complain_on_overflow */
126             bfd_elf_generic_reloc, /* special_function */
127             "R_68K_TLS_GD32",      /* name */
128             FALSE,                 /* partial_inplace */
129             0,                     /* src_mask */
130             0xffffffff,            /* dst_mask */
131             FALSE),                /* pcrel_offset */
132    
133      HOWTO (R_68K_TLS_GD16,        /* type */
134             0,                     /* rightshift */
135             1,                     /* size (0 = byte, 1 = short, 2 = long) */
136             16,                    /* bitsize */
137             FALSE,                 /* pc_relative */
138             0,                     /* bitpos */
139             complain_overflow_signed, /* complain_on_overflow */
140             bfd_elf_generic_reloc, /* special_function */
141             "R_68K_TLS_GD16",      /* name */
142             FALSE,                 /* partial_inplace */
143             0,                     /* src_mask */
144             0x0000ffff,            /* dst_mask */
145             FALSE),                /* pcrel_offset */
146    
147      HOWTO (R_68K_TLS_GD8,         /* type */
148             0,                     /* rightshift */
149             0,                     /* size (0 = byte, 1 = short, 2 = long) */
150             8,                     /* bitsize */
151             FALSE,                 /* pc_relative */
152             0,                     /* bitpos */
153             complain_overflow_signed, /* complain_on_overflow */
154             bfd_elf_generic_reloc, /* special_function */
155             "R_68K_TLS_GD8",       /* name */
156             FALSE,                 /* partial_inplace */
157             0,                     /* src_mask */
158             0x000000ff,            /* dst_mask */
159             FALSE),                /* pcrel_offset */
160    
161      /* TLS local dynamic variable reference.  */
162      HOWTO (R_68K_TLS_LDM32,       /* type */
163             0,                     /* rightshift */
164             2,                     /* size (0 = byte, 1 = short, 2 = long) */
165             32,                    /* bitsize */
166             FALSE,                 /* pc_relative */
167             0,                     /* bitpos */
168             complain_overflow_bitfield, /* complain_on_overflow */
169             bfd_elf_generic_reloc, /* special_function */
170             "R_68K_TLS_LDM32",     /* name */
171             FALSE,                 /* partial_inplace */
172             0,                     /* src_mask */
173             0xffffffff,            /* dst_mask */
174             FALSE),                /* pcrel_offset */
175    
176      HOWTO (R_68K_TLS_LDM16,       /* type */
177             0,                     /* rightshift */
178             1,                     /* size (0 = byte, 1 = short, 2 = long) */
179             16,                    /* bitsize */
180             FALSE,                 /* pc_relative */
181             0,                     /* bitpos */
182             complain_overflow_signed, /* complain_on_overflow */
183             bfd_elf_generic_reloc, /* special_function */
184             "R_68K_TLS_LDM16",     /* name */
185             FALSE,                 /* partial_inplace */
186             0,                     /* src_mask */
187             0x0000ffff,            /* dst_mask */
188             FALSE),                /* pcrel_offset */
189    
190      HOWTO (R_68K_TLS_LDM8,                /* type */
191             0,                     /* rightshift */
192             0,                     /* size (0 = byte, 1 = short, 2 = long) */
193             8,                     /* bitsize */
194             FALSE,                 /* pc_relative */
195             0,                     /* bitpos */
196             complain_overflow_signed, /* complain_on_overflow */
197             bfd_elf_generic_reloc, /* special_function */
198             "R_68K_TLS_LDM8",      /* name */
199             FALSE,                 /* partial_inplace */
200             0,                     /* src_mask */
201             0x000000ff,            /* dst_mask */
202             FALSE),                /* pcrel_offset */
203    
204      HOWTO (R_68K_TLS_LDO32,       /* type */
205             0,                     /* rightshift */
206             2,                     /* size (0 = byte, 1 = short, 2 = long) */
207             32,                    /* bitsize */
208             FALSE,                 /* pc_relative */
209             0,                     /* bitpos */
210             complain_overflow_bitfield, /* complain_on_overflow */
211             bfd_elf_generic_reloc, /* special_function */
212             "R_68K_TLS_LDO32",     /* name */
213             FALSE,                 /* partial_inplace */
214             0,                     /* src_mask */
215             0xffffffff,            /* dst_mask */
216             FALSE),                /* pcrel_offset */
217    
218      HOWTO (R_68K_TLS_LDO16,       /* type */
219             0,                     /* rightshift */
220             1,                     /* size (0 = byte, 1 = short, 2 = long) */
221             16,                    /* bitsize */
222             FALSE,                 /* pc_relative */
223             0,                     /* bitpos */
224             complain_overflow_signed, /* complain_on_overflow */
225             bfd_elf_generic_reloc, /* special_function */
226             "R_68K_TLS_LDO16",     /* name */
227             FALSE,                 /* partial_inplace */
228             0,                     /* src_mask */
229             0x0000ffff,            /* dst_mask */
230             FALSE),                /* pcrel_offset */
231    
232      HOWTO (R_68K_TLS_LDO8,                /* type */
233             0,                     /* rightshift */
234             0,                     /* size (0 = byte, 1 = short, 2 = long) */
235             8,                     /* bitsize */
236             FALSE,                 /* pc_relative */
237             0,                     /* bitpos */
238             complain_overflow_signed, /* complain_on_overflow */
239             bfd_elf_generic_reloc, /* special_function */
240             "R_68K_TLS_LDO8",      /* name */
241             FALSE,                 /* partial_inplace */
242             0,                     /* src_mask */
243             0x000000ff,            /* dst_mask */
244             FALSE),                /* pcrel_offset */
245    
246      /* TLS initial execution variable reference.  */
247      HOWTO (R_68K_TLS_IE32,        /* type */
248             0,                     /* rightshift */
249             2,                     /* size (0 = byte, 1 = short, 2 = long) */
250             32,                    /* bitsize */
251             FALSE,                 /* pc_relative */
252             0,                     /* bitpos */
253             complain_overflow_bitfield, /* complain_on_overflow */
254             bfd_elf_generic_reloc, /* special_function */
255             "R_68K_TLS_IE32",      /* name */
256             FALSE,                 /* partial_inplace */
257             0,                     /* src_mask */
258             0xffffffff,            /* dst_mask */
259             FALSE),                /* pcrel_offset */
260    
261      HOWTO (R_68K_TLS_IE16,        /* type */
262             0,                     /* rightshift */
263             1,                     /* size (0 = byte, 1 = short, 2 = long) */
264             16,                    /* bitsize */
265             FALSE,                 /* pc_relative */
266             0,                     /* bitpos */
267             complain_overflow_signed, /* complain_on_overflow */
268             bfd_elf_generic_reloc, /* special_function */
269             "R_68K_TLS_IE16",      /* name */
270             FALSE,                 /* partial_inplace */
271             0,                     /* src_mask */
272             0x0000ffff,            /* dst_mask */
273             FALSE),                /* pcrel_offset */
274    
275      HOWTO (R_68K_TLS_IE8,         /* type */
276             0,                     /* rightshift */
277             0,                     /* size (0 = byte, 1 = short, 2 = long) */
278             8,                     /* bitsize */
279             FALSE,                 /* pc_relative */
280             0,                     /* bitpos */
281             complain_overflow_signed, /* complain_on_overflow */
282             bfd_elf_generic_reloc, /* special_function */
283             "R_68K_TLS_IE8",       /* name */
284             FALSE,                 /* partial_inplace */
285             0,                     /* src_mask */
286             0x000000ff,            /* dst_mask */
287             FALSE),                /* pcrel_offset */
288    
289      /* TLS local execution variable reference.  */
290      HOWTO (R_68K_TLS_LE32,        /* type */
291             0,                     /* rightshift */
292             2,                     /* size (0 = byte, 1 = short, 2 = long) */
293             32,                    /* bitsize */
294             FALSE,                 /* pc_relative */
295             0,                     /* bitpos */
296             complain_overflow_bitfield, /* complain_on_overflow */
297             bfd_elf_generic_reloc, /* special_function */
298             "R_68K_TLS_LE32",      /* name */
299             FALSE,                 /* partial_inplace */
300             0,                     /* src_mask */
301             0xffffffff,            /* dst_mask */
302             FALSE),                /* pcrel_offset */
303    
304      HOWTO (R_68K_TLS_LE16,        /* type */
305             0,                     /* rightshift */
306             1,                     /* size (0 = byte, 1 = short, 2 = long) */
307             16,                    /* bitsize */
308             FALSE,                 /* pc_relative */
309             0,                     /* bitpos */
310             complain_overflow_signed, /* complain_on_overflow */
311             bfd_elf_generic_reloc, /* special_function */
312             "R_68K_TLS_LE16",      /* name */
313             FALSE,                 /* partial_inplace */
314             0,                     /* src_mask */
315             0x0000ffff,            /* dst_mask */
316             FALSE),                /* pcrel_offset */
317    
318      HOWTO (R_68K_TLS_LE8,         /* type */
319             0,                     /* rightshift */
320             0,                     /* size (0 = byte, 1 = short, 2 = long) */
321             8,                     /* bitsize */
322             FALSE,                 /* pc_relative */
323             0,                     /* bitpos */
324             complain_overflow_signed, /* complain_on_overflow */
325             bfd_elf_generic_reloc, /* special_function */
326             "R_68K_TLS_LE8",       /* name */
327             FALSE,                 /* partial_inplace */
328             0,                     /* src_mask */
329             0x000000ff,            /* dst_mask */
330             FALSE),                /* pcrel_offset */
331    
332      /* TLS GD/LD dynamic relocations.  */
333      HOWTO (R_68K_TLS_DTPMOD32,    /* type */
334             0,                     /* rightshift */
335             2,                     /* size (0 = byte, 1 = short, 2 = long) */
336             32,                    /* bitsize */
337             FALSE,                 /* pc_relative */
338             0,                     /* bitpos */
339             complain_overflow_dont, /* complain_on_overflow */
340             bfd_elf_generic_reloc, /* special_function */
341             "R_68K_TLS_DTPMOD32",  /* name */
342             FALSE,                 /* partial_inplace */
343             0,                     /* src_mask */
344             0xffffffff,            /* dst_mask */
345             FALSE),                /* pcrel_offset */
346    
347      HOWTO (R_68K_TLS_DTPREL32,    /* type */
348             0,                     /* rightshift */
349             2,                     /* size (0 = byte, 1 = short, 2 = long) */
350             32,                    /* bitsize */
351             FALSE,                 /* pc_relative */
352             0,                     /* bitpos */
353             complain_overflow_dont, /* complain_on_overflow */
354             bfd_elf_generic_reloc, /* special_function */
355             "R_68K_TLS_DTPREL32",  /* name */
356             FALSE,                 /* partial_inplace */
357             0,                     /* src_mask */
358             0xffffffff,            /* dst_mask */
359             FALSE),                /* pcrel_offset */
360    
361      HOWTO (R_68K_TLS_TPREL32,     /* type */
362             0,                     /* rightshift */
363             2,                     /* size (0 = byte, 1 = short, 2 = long) */
364             32,                    /* bitsize */
365             FALSE,                 /* pc_relative */
366             0,                     /* bitpos */
367             complain_overflow_dont, /* complain_on_overflow */
368             bfd_elf_generic_reloc, /* special_function */
369             "R_68K_TLS_TPREL32",   /* name */
370             FALSE,                 /* partial_inplace */
371             0,                     /* src_mask */
372             0xffffffff,            /* dst_mask */
373             FALSE),                /* pcrel_offset */
374  };  };
375    
376  static void  static void
# Line 132  static const struct Line 389  static const struct
389  {  {
390    bfd_reloc_code_real_type bfd_val;    bfd_reloc_code_real_type bfd_val;
391    int elf_val;    int elf_val;
392  } reloc_map[] = {  }
393      reloc_map[] =
394    {
395    { BFD_RELOC_NONE, R_68K_NONE },    { BFD_RELOC_NONE, R_68K_NONE },
396    { BFD_RELOC_32, R_68K_32 },    { BFD_RELOC_32, R_68K_32 },
397    { BFD_RELOC_16, R_68K_16 },    { BFD_RELOC_16, R_68K_16 },
# Line 159  static const struct Line 418  static const struct
418    { BFD_RELOC_CTOR, R_68K_32 },    { BFD_RELOC_CTOR, R_68K_32 },
419    { BFD_RELOC_VTABLE_INHERIT, R_68K_GNU_VTINHERIT },    { BFD_RELOC_VTABLE_INHERIT, R_68K_GNU_VTINHERIT },
420    { BFD_RELOC_VTABLE_ENTRY, R_68K_GNU_VTENTRY },    { BFD_RELOC_VTABLE_ENTRY, R_68K_GNU_VTENTRY },
421      { BFD_RELOC_68K_TLS_GD32, R_68K_TLS_GD32 },
422      { BFD_RELOC_68K_TLS_GD16, R_68K_TLS_GD16 },
423      { BFD_RELOC_68K_TLS_GD8, R_68K_TLS_GD8 },
424      { BFD_RELOC_68K_TLS_LDM32, R_68K_TLS_LDM32 },
425      { BFD_RELOC_68K_TLS_LDM16, R_68K_TLS_LDM16 },
426      { BFD_RELOC_68K_TLS_LDM8, R_68K_TLS_LDM8 },
427      { BFD_RELOC_68K_TLS_LDO32, R_68K_TLS_LDO32 },
428      { BFD_RELOC_68K_TLS_LDO16, R_68K_TLS_LDO16 },
429      { BFD_RELOC_68K_TLS_LDO8, R_68K_TLS_LDO8 },
430      { BFD_RELOC_68K_TLS_IE32, R_68K_TLS_IE32 },
431      { BFD_RELOC_68K_TLS_IE16, R_68K_TLS_IE16 },
432      { BFD_RELOC_68K_TLS_IE8, R_68K_TLS_IE8 },
433      { BFD_RELOC_68K_TLS_LE32, R_68K_TLS_LE32 },
434      { BFD_RELOC_68K_TLS_LE16, R_68K_TLS_LE16 },
435      { BFD_RELOC_68K_TLS_LE8, R_68K_TLS_LE8 },
436  };  };
437    
438  static reloc_howto_type *  static reloc_howto_type *
# Line 419  struct elf_m68k_got_entry_key Line 693  struct elf_m68k_got_entry_key
693    
694    /* Symbol index.  Either local symbol index or h->got_entry_key.  */    /* Symbol index.  Either local symbol index or h->got_entry_key.  */
695    unsigned long symndx;    unsigned long symndx;
696    
697      /* Type is one of R_68K_GOT{8, 16, 32}O, R_68K_TLS_GD{8, 16, 32},
698         R_68K_TLS_LDM{8, 16, 32} or R_68K_TLS_IE{8, 16, 32}.
699    
700         From perspective of hashtable key, only elf_m68k_got_reloc_type (type)
701         matters.  That is, we distinguish between, say, R_68K_GOT16O
702         and R_68K_GOT32O when allocating offsets, but they are considered to be
703         the same when searching got->entries.  */
704      enum elf_m68k_reloc_type type;
705  };  };
706    
707    /* Size of the GOT offset suitable for relocation.  */
708    enum elf_m68k_got_offset_size { R_8, R_16, R_32, R_LAST };
709    
710  /* Entry of the GOT.  */  /* Entry of the GOT.  */
711  struct elf_m68k_got_entry  struct elf_m68k_got_entry
712  {  {
# Line 435  struct elf_m68k_got_entry Line 721  struct elf_m68k_got_entry
721        /* Number of times this entry is referenced.  It is used to        /* Number of times this entry is referenced.  It is used to
722           filter out unnecessary GOT slots in elf_m68k_gc_sweep_hook.  */           filter out unnecessary GOT slots in elf_m68k_gc_sweep_hook.  */
723        bfd_vma refcount;        bfd_vma refcount;
   
       /* Type is one of R_68K_GOT8O, R_68K_GOT16O or R_68K_GOT32O.  */  
       int type;  
724      } s1;      } s1;
725    
726      struct      struct
# Line 456  struct elf_m68k_got_entry Line 739  struct elf_m68k_got_entry
739    } u;    } u;
740  };  };
741    
742    /* Return representative type for relocation R_TYPE.
743       This is used to avoid enumerating many relocations in comparisons,
744       switches etc.  */
745    
746    static enum elf_m68k_reloc_type
747    elf_m68k_reloc_got_type (enum elf_m68k_reloc_type r_type)
748    {
749      switch (r_type)
750        {
751          /* In most cases R_68K_GOTx relocations require the very same
752             handling as R_68K_GOT32O relocation.  In cases when we need
753             to distinguish between the two, we use explicitly compare against
754             r_type.  */
755        case R_68K_GOT32:
756        case R_68K_GOT16:
757        case R_68K_GOT8:
758        case R_68K_GOT32O:
759        case R_68K_GOT16O:
760        case R_68K_GOT8O:
761          return R_68K_GOT32O;
762    
763        case R_68K_TLS_GD32:
764        case R_68K_TLS_GD16:
765        case R_68K_TLS_GD8:
766          return R_68K_TLS_GD32;
767    
768        case R_68K_TLS_LDM32:
769        case R_68K_TLS_LDM16:
770        case R_68K_TLS_LDM8:
771          return R_68K_TLS_LDM32;
772    
773        case R_68K_TLS_IE32:
774        case R_68K_TLS_IE16:
775        case R_68K_TLS_IE8:
776          return R_68K_TLS_IE32;
777    
778        default:
779          BFD_ASSERT (FALSE);
780          return 0;
781        }
782    }
783    
784    /* Return size of the GOT entry offset for relocation R_TYPE.  */
785    
786    static enum elf_m68k_got_offset_size
787    elf_m68k_reloc_got_offset_size (enum elf_m68k_reloc_type r_type)
788    {
789      switch (r_type)
790        {
791        case R_68K_GOT32: case R_68K_GOT16: case R_68K_GOT8:
792        case R_68K_GOT32O: case R_68K_TLS_GD32: case R_68K_TLS_LDM32:
793        case R_68K_TLS_IE32:
794          return R_32;
795    
796        case R_68K_GOT16O: case R_68K_TLS_GD16: case R_68K_TLS_LDM16:
797        case R_68K_TLS_IE16:
798          return R_16;
799    
800        case R_68K_GOT8O: case R_68K_TLS_GD8: case R_68K_TLS_LDM8:
801        case R_68K_TLS_IE8:
802          return R_8;
803    
804        default:
805          BFD_ASSERT (FALSE);
806          return 0;
807        }
808    }
809    
810    /* Return number of GOT entries we need to allocate in GOT for
811       relocation R_TYPE.  */
812    
813    static bfd_vma
814    elf_m68k_reloc_got_n_slots (enum elf_m68k_reloc_type r_type)
815    {
816      switch (elf_m68k_reloc_got_type (r_type))
817        {
818        case R_68K_GOT32O:
819        case R_68K_TLS_IE32:
820          return 1;
821    
822        case R_68K_TLS_GD32:
823        case R_68K_TLS_LDM32:
824          return 2;
825    
826        default:
827          BFD_ASSERT (FALSE);
828          return 0;
829        }
830    }
831    
832    /* Return TRUE if relocation R_TYPE is a TLS one.  */
833    
834    static bfd_boolean
835    elf_m68k_reloc_tls_p (enum elf_m68k_reloc_type r_type)
836    {
837      switch (r_type)
838        {
839        case R_68K_TLS_GD32: case R_68K_TLS_GD16: case R_68K_TLS_GD8:
840        case R_68K_TLS_LDM32: case R_68K_TLS_LDM16: case R_68K_TLS_LDM8:
841        case R_68K_TLS_LDO32: case R_68K_TLS_LDO16: case R_68K_TLS_LDO8:
842        case R_68K_TLS_IE32: case R_68K_TLS_IE16: case R_68K_TLS_IE8:
843        case R_68K_TLS_LE32: case R_68K_TLS_LE16: case R_68K_TLS_LE8:
844        case R_68K_TLS_DTPMOD32: case R_68K_TLS_DTPREL32: case R_68K_TLS_TPREL32:
845          return TRUE;
846    
847        default:
848          return FALSE;
849        }
850    }
851    
852  /* Data structure representing a single GOT.  */  /* Data structure representing a single GOT.  */
853  struct elf_m68k_got  struct elf_m68k_got
854  {  {
# Line 464  struct elf_m68k_got Line 857  struct elf_m68k_got
857       R_68K_GOT8O entries.  */       R_68K_GOT8O entries.  */
858    htab_t entries;    htab_t entries;
859    
860    /* Number of R_68K_GOT8O entries in this GOT.    /* Number of R_x slots in this GOT.  Some (e.g., TLS) entries require
861       This is used to detect the overflow of number of such entries.  */       several GOT slots.
862    bfd_vma rel_8o_n_entries;  
863         n_slots[R_8] is the count of R_8 slots in this GOT.
864    /* Cumulative count of R_68K_GOT8O and R_68K_GOT16O entries in this GOT.       n_slots[R_16] is the cumulative count of R_8 and R_16 slots
865       This is used to detect the overflow of number of such entries.  */       in this GOT.
866    bfd_vma rel_8o_16o_n_entries;       n_slots[R_32] is the cumulative count of R_8, R_16 and R_32 slots
867         in this GOT.  This is the total number of slots.  */
868      bfd_vma n_slots[R_LAST];
869    
870    /* Number of local (entry->key_.h == NULL) entries in this GOT.    /* Number of local (entry->key_.h == NULL) slots in this GOT.
871       This is only used to properly calculate size of .rela.got section;       This is only used to properly calculate size of .rela.got section;
872       see elf_m68k_partition_multi_got.  */       see elf_m68k_partition_multi_got.  */
873    bfd_vma local_n_entries;    bfd_vma local_n_slots;
874    
875    /* Offset of this GOT relative to beginning of .got section.  */    /* Offset of this GOT relative to beginning of .got section.  */
876    bfd_vma offset;    bfd_vma offset;
# Line 514  struct elf_m68k_link_hash_table Line 909  struct elf_m68k_link_hash_table
909  {  {
910    struct elf_link_hash_table root;    struct elf_link_hash_table root;
911    
912    /* Small local sym to section mapping cache.  */    /* Small local sym cache.  */
913    struct sym_sec_cache sym_sec;    struct sym_cache sym_cache;
914    
915    /* The PLT format used by this link, or NULL if the format has not    /* The PLT format used by this link, or NULL if the format has not
916       yet been chosen.  */       yet been chosen.  */
# Line 594  elf_m68k_link_hash_table_create (abfd) Line 989  elf_m68k_link_hash_table_create (abfd)
989        return NULL;        return NULL;
990      }      }
991    
992    ret->sym_sec.abfd = NULL;    ret->sym_cache.abfd = NULL;
993    ret->plt_info = NULL;    ret->plt_info = NULL;
994    ret->local_gp_p = FALSE;    ret->local_gp_p = FALSE;
995    ret->use_neg_got_offsets_p = FALSE;    ret->use_neg_got_offsets_p = FALSE;
# Line 882  elf32_m68k_print_private_bfd_data (bfd * Line 1277  elf32_m68k_print_private_bfd_data (bfd *
1277    
1278     Notes:     Notes:
1279    
1280     GOT entry type: We have 3 types of GOT entries.     GOT entry type: We have several types of GOT entries.
1281     * R_68K_GOT8O type is used in entries for symbols that have     * R_8 type is used in entries for symbols that have at least one
1282     at least one R_68K_GOT8O relocation.  We can have at most 0x40     R_68K_GOT8O or R_68K_TLS_*8 relocation.  We can have at most 0x40
1283     such entries in one GOT.     such entries in one GOT.
1284     * R_68K_GOT16O type is used in entries for symbols that have     * R_16 type is used in entries for symbols that have at least one
1285     at least one R_68K_GOT16O relocation and no R_68K_GOT8O relocations.     R_68K_GOT16O or R_68K_TLS_*16 relocation and no R_8 relocations.
1286     We can have at most 0x4000 such entries in one GOT.     We can have at most 0x4000 such entries in one GOT.
1287     * R_68K_GOT32O type is used in all other cases.  We can have as many     * R_32 type is used in all other cases.  We can have as many
1288     such entries in one GOT as we like.     such entries in one GOT as we'd like.
1289     When counting relocations we have to include the count of the smaller     When counting relocations we have to include the count of the smaller
1290     ranged relocations in the counts of the larger ranged ones in order     ranged relocations in the counts of the larger ranged ones in order
1291     to correctly detect overflow.     to correctly detect overflow.
1292    
1293     Sorting the GOT: In each GOT starting offsets are assigned to     Sorting the GOT: In each GOT starting offsets are assigned to
1294     R_68K_GOT8O entries, which are followed by R_68K_GOT16O entries, and     R_8 entries, which are followed by R_16 entries, and
1295     R_68K_GOT32O entries go at the end.  See finalize_got_offsets for details.     R_32 entries go at the end.  See finalize_got_offsets for details.
1296    
1297     Negative GOT offsets: To double usable offset range of GOTs we use     Negative GOT offsets: To double usable offset range of GOTs we use
1298     negative offsets.  As we assign entries with GOT offsets relative to     negative offsets.  As we assign entries with GOT offsets relative to
# Line 921  elf32_m68k_print_private_bfd_data (bfd * Line 1316  elf32_m68k_print_private_bfd_data (bfd *
1316  /* Initialize GOT.  */  /* Initialize GOT.  */
1317    
1318  static void  static void
1319  elf_m68k_init_got (struct elf_m68k_got *got,  elf_m68k_init_got (struct elf_m68k_got *got)
1320                     htab_t entries,  {
1321                     bfd_vma rel_8o_n_entries,    got->entries = NULL;
1322                     bfd_vma rel_8o_16o_n_entries,    got->n_slots[R_8] = 0;
1323                     bfd_vma local_n_entries,    got->n_slots[R_16] = 0;
1324                     bfd_vma offset)    got->n_slots[R_32] = 0;
1325  {    got->local_n_slots = 0;
1326    got->entries = entries;    got->offset = (bfd_vma) -1;
   got->rel_8o_n_entries = rel_8o_n_entries;  
   got->rel_8o_16o_n_entries = rel_8o_16o_n_entries;  
   got->local_n_entries = local_n_entries;  
   got->offset = offset;  
1327  }  }
1328    
1329  /* Destruct GOT.  */  /* Destruct GOT.  */
# Line 959  elf_m68k_create_empty_got (struct bfd_li Line 1350  elf_m68k_create_empty_got (struct bfd_li
1350    if (got == NULL)    if (got == NULL)
1351      return NULL;      return NULL;
1352    
1353    elf_m68k_init_got (got, NULL, 0, 0, 0, (bfd_vma) -1);    elf_m68k_init_got (got);
1354    
1355    return got;    return got;
1356  }  }
# Line 969  elf_m68k_create_empty_got (struct bfd_li Line 1360  elf_m68k_create_empty_got (struct bfd_li
1360  static void  static void
1361  elf_m68k_init_got_entry_key (struct elf_m68k_got_entry_key *key,  elf_m68k_init_got_entry_key (struct elf_m68k_got_entry_key *key,
1362                               struct elf_link_hash_entry *h,                               struct elf_link_hash_entry *h,
1363                               const bfd *abfd, unsigned long symndx)                               const bfd *abfd, unsigned long symndx,
1364                                 enum elf_m68k_reloc_type reloc_type)
1365  {  {
1366    if (h != NULL)    if (elf_m68k_reloc_got_type (reloc_type) == R_68K_TLS_LDM32)
1367        /* All TLS_LDM relocations share a single GOT entry.  */
1368        {
1369          key->bfd = NULL;
1370          key->symndx = 0;
1371        }
1372      else if (h != NULL)
1373        /* Global symbols are identified with their got_entry_key.  */
1374      {      {
1375        key->bfd = NULL;        key->bfd = NULL;
1376        key->symndx = elf_m68k_hash_entry (h)->got_entry_key;        key->symndx = elf_m68k_hash_entry (h)->got_entry_key;
1377        BFD_ASSERT (key->symndx != 0);        BFD_ASSERT (key->symndx != 0);
1378      }      }
1379    else    else
1380        /* Local symbols are identified by BFD they appear in and symndx.  */
1381      {      {
1382        key->bfd = abfd;        key->bfd = abfd;
1383        key->symndx = symndx;        key->symndx = symndx;
1384      }      }
1385    
1386      key->type = reloc_type;
1387  }  }
1388    
1389  /* Calculate hash of got_entry.  /* Calculate hash of got_entry.
# Line 994  elf_m68k_got_entry_hash (const void *_en Line 1396  elf_m68k_got_entry_hash (const void *_en
1396    
1397    key = &((const struct elf_m68k_got_entry *) _entry)->key_;    key = &((const struct elf_m68k_got_entry *) _entry)->key_;
1398    
1399    return key->symndx + (key->bfd != NULL    return (key->symndx
1400                          ? (int) key->bfd->id            + (key->bfd != NULL ? (int) key->bfd->id : -1)
1401                          : -1);            + elf_m68k_reloc_got_type (key->type));
1402  }  }
1403    
1404  /* Check if two got entries are equal.  */  /* Check if two got entries are equal.  */
# Line 1011  elf_m68k_got_entry_eq (const void *_entr Line 1413  elf_m68k_got_entry_eq (const void *_entr
1413    key2 = &((const struct elf_m68k_got_entry *) _entry2)->key_;    key2 = &((const struct elf_m68k_got_entry *) _entry2)->key_;
1414    
1415    return (key1->bfd == key2->bfd    return (key1->bfd == key2->bfd
1416            && key1->symndx == key2->symndx);            && key1->symndx == key2->symndx
1417              && (elf_m68k_reloc_got_type (key1->type)
1418                  == elf_m68k_reloc_got_type (key2->type)));
1419  }  }
1420    
1421  /* Maximal number of R_68K_GOT8O entries in a single GOT.  */  /* When using negative offsets, we allocate one extra R_8, one extra R_16
1422  #define ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT(INFO)              \     and one extra R_32 slots to simplify handling of 2-slot entries during
1423       offset allocation -- hence -1 for R_8 slots and -2 for R_16 slots.  */
1424    
1425    /* Maximal number of R_8 slots in a single GOT.  */
1426    #define ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT(INFO)           \
1427    (elf_m68k_hash_table (INFO)->use_neg_got_offsets_p            \    (elf_m68k_hash_table (INFO)->use_neg_got_offsets_p            \
1428     ? 0x40                                                       \     ? (0x40 - 1)                                                 \
1429     : 0x20)     : 0x20)
1430    
1431  /* Maximal number of R_68K_GOT8O and R_68K_GOT16O entries in a single GOT.  */  /* Maximal number of R_8 and R_16 slots in a single GOT.  */
1432  #define ELF_M68K_REL_8O_16O_MAX_N_ENTRIES_IN_GOT(INFO)          \  #define ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT(INFO)                \
1433    (elf_m68k_hash_table (INFO)->use_neg_got_offsets_p            \    (elf_m68k_hash_table (INFO)->use_neg_got_offsets_p            \
1434     ? 0x4000                                                     \     ? (0x4000 - 2)                                               \
1435     : 0x2000)     : 0x2000)
1436    
1437  /* SEARCH - simply search the hashtable, don't insert new entries or fail when  /* SEARCH - simply search the hashtable, don't insert new entries or fail when
# Line 1062  elf_m68k_get_got_entry (struct elf_m68k_ Line 1470  elf_m68k_get_got_entry (struct elf_m68k_
1470        if (howto == SEARCH)        if (howto == SEARCH)
1471          return NULL;          return NULL;
1472    
1473        got->entries = htab_try_create (ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT        got->entries = htab_try_create (ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT
1474                                        (info),                                        (info),
1475                                        elf_m68k_got_entry_hash,                                        elf_m68k_got_entry_hash,
1476                                        elf_m68k_got_entry_eq, NULL);                                        elf_m68k_got_entry_eq, NULL);
# Line 1100  elf_m68k_get_got_entry (struct elf_m68k_ Line 1508  elf_m68k_get_got_entry (struct elf_m68k_
1508        entry->key_ = *key;        entry->key_ = *key;
1509    
1510        entry->u.s1.refcount = 0;        entry->u.s1.refcount = 0;
1511        entry->u.s1.type = R_68K_GOT32O;  
1512          /* Mark the entry as not initialized.  */
1513          entry->key_.type = R_68K_max;
1514    
1515        *ptr = entry;        *ptr = entry;
1516      }      }
# Line 1118  elf_m68k_get_got_entry (struct elf_m68k_ Line 1528  elf_m68k_get_got_entry (struct elf_m68k_
1528  /* Update GOT counters when merging entry of WAS type with entry of NEW type.  /* Update GOT counters when merging entry of WAS type with entry of NEW type.
1529     Return the value to which ENTRY's type should be set.  */     Return the value to which ENTRY's type should be set.  */
1530    
1531  static int  static enum elf_m68k_reloc_type
1532  elf_m68k_update_got_entry_type (struct elf_m68k_got *got, int was, int new)  elf_m68k_update_got_entry_type (struct elf_m68k_got *got,
1533  {                                  enum elf_m68k_reloc_type was,
1534    if (new == R_68K_GOT8O && was != R_68K_GOT8O)                                  enum elf_m68k_reloc_type new)
1535      /* NEW overrides WAS.  */  {
1536      enum elf_m68k_got_offset_size was_size;
1537      enum elf_m68k_got_offset_size new_size;
1538      bfd_vma n_slots;
1539    
1540      if (was == R_68K_max)
1541        /* The type of the entry is not initialized yet.  */
1542      {      {
1543        ++got->rel_8o_n_entries;        /* Update all got->n_slots counters, including n_slots[R_32].  */
1544          was_size = R_LAST;
1545    
1546        if (was != R_68K_GOT16O)        was = new;
         /* Update this counter too.  */  
         ++got->rel_8o_16o_n_entries;  
1547      }      }
   else if (new == R_68K_GOT16O && was != R_68K_GOT8O && was != R_68K_GOT16O)  
     /* NEW overrides WAS.  */  
     ++got->rel_8o_16o_n_entries;  
1548    else    else
1549      /* NEW doesn't override WAS.  */      {
1550      new = was;        /* !!! We, probably, should emit an error rather then fail on assert
1551             in such a case.  */
1552          BFD_ASSERT (elf_m68k_reloc_got_type (was)
1553                      == elf_m68k_reloc_got_type (new));
1554    
1555          was_size = elf_m68k_reloc_got_offset_size (was);
1556        }
1557    
1558      new_size = elf_m68k_reloc_got_offset_size (new);
1559      n_slots = elf_m68k_reloc_got_n_slots (new);
1560    
1561    return new;    while (was_size > new_size)
1562        {
1563          --was_size;
1564          got->n_slots[was_size] += n_slots;
1565        }
1566    
1567      if (new > was)
1568        /* Relocations are ordered from bigger got offset size to lesser,
1569           so choose the relocation type with lesser offset size.  */
1570        was = new;
1571    
1572      return was;
1573  }  }
1574    
1575  /* Update GOT counters when removing an entry of type TYPE.  */  /* Update GOT counters when removing an entry of type TYPE.  */
1576    
1577  static void  static void
1578  elf_m68k_remove_got_entry_type (struct elf_m68k_got *got, int type)  elf_m68k_remove_got_entry_type (struct elf_m68k_got *got,
1579                                    enum elf_m68k_reloc_type type)
1580  {  {
1581    switch (type)    enum elf_m68k_got_offset_size os;
1582      {    bfd_vma n_slots;
     case R_68K_GOT8O:  
       BFD_ASSERT (got->rel_8o_n_entries > 0);  
   
       --got->rel_8o_n_entries;  
       /* FALLTHRU */  
1583    
1584      case R_68K_GOT16O:    n_slots = elf_m68k_reloc_got_n_slots (type);
       BFD_ASSERT (got->rel_8o_16o_n_entries >= got->rel_8o_n_entries);  
   
       --got->rel_8o_16o_n_entries;  
       /* FALLTHRU */  
1585    
1586      case R_68K_GOT32O:    /* Decrese counter of slots with offset size corresponding to TYPE
1587        break;       and all greater offset sizes.  */
1588      for (os = elf_m68k_reloc_got_offset_size (type); os <= R_32; ++os)
1589        {
1590          BFD_ASSERT (got->n_slots[os] >= n_slots);
1591    
1592      default:        got->n_slots[os] -= n_slots;
       BFD_ASSERT (FALSE);  
1593      }      }
1594  }  }
1595    
# Line 1175  static struct elf_m68k_got_entry * Line 1601  static struct elf_m68k_got_entry *
1601  elf_m68k_add_entry_to_got (struct elf_m68k_got *got,  elf_m68k_add_entry_to_got (struct elf_m68k_got *got,
1602                             struct elf_link_hash_entry *h,                             struct elf_link_hash_entry *h,
1603                             const bfd *abfd,                             const bfd *abfd,
1604                             int type, unsigned long symndx,                             enum elf_m68k_reloc_type reloc_type,
1605                               unsigned long symndx,
1606                             struct bfd_link_info *info)                             struct bfd_link_info *info)
1607  {  {
1608    struct elf_m68k_got_entry_key key_;    struct elf_m68k_got_entry_key key_;
# Line 1185  elf_m68k_add_entry_to_got (struct elf_m6 Line 1612  elf_m68k_add_entry_to_got (struct elf_m6
1612      elf_m68k_hash_entry (h)->got_entry_key      elf_m68k_hash_entry (h)->got_entry_key
1613        = elf_m68k_multi_got (info)->global_symndx++;        = elf_m68k_multi_got (info)->global_symndx++;
1614    
1615    elf_m68k_init_got_entry_key (&key_, h, abfd, symndx);    elf_m68k_init_got_entry_key (&key_, h, abfd, symndx, reloc_type);
1616    
1617    entry = elf_m68k_get_got_entry (got, &key_, FIND_OR_CREATE, info);    entry = elf_m68k_get_got_entry (got, &key_, FIND_OR_CREATE, info);
1618    if (entry == NULL)    if (entry == NULL)
1619      return NULL;      return NULL;
1620    
1621      /* Determine entry's type and update got->n_slots counters.  */
1622      entry->key_.type = elf_m68k_update_got_entry_type (got,
1623                                                         entry->key_.type,
1624                                                         reloc_type);
1625    
1626    /* Update refcount.  */    /* Update refcount.  */
1627    ++entry->u.s1.refcount;    ++entry->u.s1.refcount;
1628    
# Line 1198  elf_m68k_add_entry_to_got (struct elf_m6 Line 1630  elf_m68k_add_entry_to_got (struct elf_m6
1630      /* We see this entry for the first time.  */      /* We see this entry for the first time.  */
1631      {      {
1632        if (entry->key_.bfd != NULL)        if (entry->key_.bfd != NULL)
1633          ++got->local_n_entries;          got->local_n_slots += elf_m68k_reloc_got_n_slots (entry->key_.type);
1634      }      }
1635    
1636    /* Determine entry's type and update got->rel_*_n_entries counters.  */    BFD_ASSERT (got->n_slots[R_32] >= got->local_n_slots);
   entry->u.s1.type = elf_m68k_update_got_entry_type (got, entry->u.s1.type,  
                                                      type);  
1637    
1638    if ((got->rel_8o_n_entries    if ((got->n_slots[R_8]
1639         > ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT (info))         > ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info))
1640        || (got->rel_8o_16o_n_entries        || (got->n_slots[R_16]
1641            > ELF_M68K_REL_8O_16O_MAX_N_ENTRIES_IN_GOT (info)))            > ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT (info)))
1642      /* This BFD has too many relocation.  */      /* This BFD has too many relocation.  */
1643      {      {
1644        if (got->rel_8o_n_entries        if (got->n_slots[R_8] > ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info))
           > ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT (info))  
1645          (*_bfd_error_handler) (_("%B: GOT overflow: "          (*_bfd_error_handler) (_("%B: GOT overflow: "
1646                                   "Number of R_68K_GOT8O relocations > %d"),                                   "Number of relocations with 8-bit "
1647                                     "offset > %d"),
1648                                 abfd,                                 abfd,
1649                                 ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT (info));                                 ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info));
1650        else        else
1651          (*_bfd_error_handler) (_("%B: GOT overflow: "          (*_bfd_error_handler) (_("%B: GOT overflow: "
1652                                   "Number of R_68K_GOT8O and R_68K_GOT16O "                                   "Number of relocations with 8- or 16-bit "
1653                                   "relocations > %d"),                                   "offset > %d"),
1654                                 abfd,                                 abfd,
1655                                 ELF_M68K_REL_8O_16O_MAX_N_ENTRIES_IN_GOT (info));                                 ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT (info));
1656    
1657        return NULL;        return NULL;
1658      }      }
# Line 1369  elf_m68k_can_merge_gots_1 (void **_entry Line 1799  elf_m68k_can_merge_gots_1 (void **_entry
1799    const struct elf_m68k_got_entry *entry1;    const struct elf_m68k_got_entry *entry1;
1800    struct elf_m68k_can_merge_gots_arg *arg;    struct elf_m68k_can_merge_gots_arg *arg;
1801    const struct elf_m68k_got_entry *entry2;    const struct elf_m68k_got_entry *entry2;
1802    int type;    enum elf_m68k_reloc_type type;
1803    
1804    entry1 = (const struct elf_m68k_got_entry *) *_entry_ptr;    entry1 = (const struct elf_m68k_got_entry *) *_entry_ptr;
1805    arg = (struct elf_m68k_can_merge_gots_arg *) _arg;    arg = (struct elf_m68k_can_merge_gots_arg *) _arg;
# Line 1377  elf_m68k_can_merge_gots_1 (void **_entry Line 1807  elf_m68k_can_merge_gots_1 (void **_entry
1807    entry2 = elf_m68k_get_got_entry (arg->big, &entry1->key_, SEARCH, NULL);    entry2 = elf_m68k_get_got_entry (arg->big, &entry1->key_, SEARCH, NULL);
1808    
1809    if (entry2 != NULL)    if (entry2 != NULL)
1810        /* We found an existing entry.  Check if we should update it.  */
1811      {      {
1812        type = elf_m68k_update_got_entry_type (arg->diff, entry2->u.s1.type,        type = elf_m68k_update_got_entry_type (arg->diff,
1813                                               entry1->u.s1.type);                                               entry2->key_.type,
1814                                                 entry1->key_.type);
1815    
1816        if (type == entry2->u.s1.type)        if (type == entry2->key_.type)
1817          /* ENTRY1 doesn't update data in ENTRY2.  Skip it.          /* ENTRY1 doesn't update data in ENTRY2.  Skip it.
1818             To skip creation of difference entry we use the type,             To skip creation of difference entry we use the type,
1819             which we won't see in GOT entries for sure.  */             which we won't see in GOT entries for sure.  */
1820          type = R_68K_32;          type = R_68K_max;
1821      }      }
1822    else    else
1823        /* We didn't find the entry.  Add entry1 to DIFF.  */
1824      {      {
1825        BFD_ASSERT (entry1->u.s1.type != R_68K_32);        BFD_ASSERT (entry1->key_.type != R_68K_max);
1826    
1827        type = elf_m68k_update_got_entry_type (arg->diff, R_68K_GOT32O,        type = elf_m68k_update_got_entry_type (arg->diff,
1828                                               entry1->u.s1.type);                                               R_68K_max, entry1->key_.type);
1829    
       /* Update local counter.  */  
1830        if (entry1->key_.bfd != NULL)        if (entry1->key_.bfd != NULL)
1831          ++arg->diff->local_n_entries;          arg->diff->local_n_slots += elf_m68k_reloc_got_n_slots (type);
1832      }      }
1833    
1834    if (type != R_68K_32)    if (type != R_68K_max)
1835      /* Create an entry in DIFF.  */      /* Create an entry in DIFF.  */
1836      {      {
1837        struct elf_m68k_got_entry *entry;        struct elf_m68k_got_entry *entry;
# Line 1412  elf_m68k_can_merge_gots_1 (void **_entry Line 1844  elf_m68k_can_merge_gots_1 (void **_entry
1844            return 0;            return 0;
1845          }          }
1846    
1847        entry->u.s1.type = type;        entry->key_.type = type;
1848      }      }
1849    
1850    return 1;    return 1;
# Line 1445  elf_m68k_can_merge_gots (struct elf_m68k Line 1877  elf_m68k_can_merge_gots (struct elf_m68k
1877      }      }
1878    
1879    /* Check for overflow.  */    /* Check for overflow.  */
1880    if ((big->rel_8o_n_entries + arg_.diff->rel_8o_n_entries    if ((big->n_slots[R_8] + arg_.diff->n_slots[R_8]
1881         > ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT (info))         > ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info))
1882        || (big->rel_8o_16o_n_entries + arg_.diff->rel_8o_16o_n_entries        || (big->n_slots[R_16] + arg_.diff->n_slots[R_16]
1883            > ELF_M68K_REL_8O_16O_MAX_N_ENTRIES_IN_GOT (info)))            > ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT (info)))
1884      return FALSE;      return FALSE;
1885    
1886    return TRUE;    return TRUE;
# Line 1489  elf_m68k_merge_gots_1 (void **entry_ptr, Line 1921  elf_m68k_merge_gots_1 (void **entry_ptr,
1921    
1922    BFD_ASSERT (to->u.s1.refcount == 0);    BFD_ASSERT (to->u.s1.refcount == 0);
1923    /* All we need to merge is TYPE.  */    /* All we need to merge is TYPE.  */
1924    to->u.s1.type = from->u.s1.type;    to->key_.type = from->key_.type;
1925    
1926    return 1;    return 1;
1927  }  }
# Line 1516  elf_m68k_merge_gots (struct elf_m68k_got Line 1948  elf_m68k_merge_gots (struct elf_m68k_got
1948          return FALSE;          return FALSE;
1949    
1950        /* Merge counters.  */        /* Merge counters.  */
1951        big->rel_8o_n_entries += diff->rel_8o_n_entries;        big->n_slots[R_8] += diff->n_slots[R_8];
1952        big->rel_8o_16o_n_entries += diff->rel_8o_16o_n_entries;        big->n_slots[R_16] += diff->n_slots[R_16];
1953        big->local_n_entries += diff->local_n_entries;        big->n_slots[R_32] += diff->n_slots[R_32];
1954          big->local_n_slots += diff->local_n_slots;
1955      }      }
1956    else    else
1957      /* DIFF is empty.  */      /* DIFF is empty.  */
1958      {      {
1959        BFD_ASSERT (diff->rel_8o_n_entries == 0);        BFD_ASSERT (diff->n_slots[R_8] == 0);
1960        BFD_ASSERT (diff->rel_8o_16o_n_entries == 0);        BFD_ASSERT (diff->n_slots[R_16] == 0);
1961        BFD_ASSERT (diff->local_n_entries == 0);        BFD_ASSERT (diff->n_slots[R_32] == 0);
1962          BFD_ASSERT (diff->local_n_slots == 0);
1963      }      }
1964    
1965    BFD_ASSERT (!elf_m68k_hash_table (info)->allow_multigot_p    BFD_ASSERT (!elf_m68k_hash_table (info)->allow_multigot_p
1966                || ((big->rel_8o_n_entries                || ((big->n_slots[R_8]
1967                     <= ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT (info))                     <= ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info))
1968                    && (big->rel_8o_16o_n_entries                    && (big->n_slots[R_16]
1969                        <= ELF_M68K_REL_8O_16O_MAX_N_ENTRIES_IN_GOT (info))));                        <= ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT (info))));
1970    
1971    return TRUE;    return TRUE;
1972  }  }
1973    
1974  struct elf_m68k_finalize_got_offsets_arg  struct elf_m68k_finalize_got_offsets_arg
1975  {  {
1976    /* Offset for the next R_68K_GOT8O entry.  */    /* Ranges of the offsets for GOT entries.
1977    bfd_vma rel_8o_offset;       R_x entries receive offsets between offset1[R_x] and offset2[R_x].
1978         R_x is R_8, R_16 and R_32.  */
1979    /* Offset for the next R_68K_GOT16O entry.  */    bfd_vma *offset1;
1980    bfd_vma rel_16o_offset;    bfd_vma *offset2;
   
   /* Offset for the next R_68K_GOT32O entry.  */  
   bfd_vma rel_32o_offset;  
   
   /* Should we use negative (relative to GP) offsets for GOT entries.  */  
   bfd_boolean use_neg_got_offsets_p;  
   
   /* Offset of this GOT relative to .got section.  */  
   bfd_vma got_offset;  
1981    
1982    /* Mapping from global symndx to global symbols.    /* Mapping from global symndx to global symbols.
1983       This is used to build lists of got entries for global symbols.  */       This is used to build lists of got entries for global symbols.  */
1984    struct elf_m68k_link_hash_entry **symndx2h;    struct elf_m68k_link_hash_entry **symndx2h;
1985    
1986      bfd_vma n_ldm_entries;
1987  };  };
1988    
1989  /* Assign ENTRY an offset.  Build list of GOT entries for global symbols  /* Assign ENTRY an offset.  Build list of GOT entries for global symbols
# Line 1568  elf_m68k_finalize_got_offsets_1 (void ** Line 1995  elf_m68k_finalize_got_offsets_1 (void **
1995    struct elf_m68k_got_entry *entry;    struct elf_m68k_got_entry *entry;
1996    struct elf_m68k_finalize_got_offsets_arg *arg;    struct elf_m68k_finalize_got_offsets_arg *arg;
1997    
1998      enum elf_m68k_got_offset_size got_offset_size;
1999      bfd_vma entry_size;
2000    
2001    entry = (struct elf_m68k_got_entry *) *entry_ptr;    entry = (struct elf_m68k_got_entry *) *entry_ptr;
2002    arg = (struct elf_m68k_finalize_got_offsets_arg *) _arg;    arg = (struct elf_m68k_finalize_got_offsets_arg *) _arg;
2003    
2004    /* This should be a fresh entry created in elf_m68k_can_merge_gots.  */    /* This should be a fresh entry created in elf_m68k_can_merge_gots.  */
2005    BFD_ASSERT (entry->u.s1.refcount == 0);    BFD_ASSERT (entry->u.s1.refcount == 0);
2006    
2007    switch (entry->u.s1.type)    /* Get GOT offset size for the entry .  */
2008      {    got_offset_size = elf_m68k_reloc_got_offset_size (entry->key_.type);
     case R_68K_GOT8O:  
       entry->u.s2.offset = arg->rel_8o_offset;  
   
       if (arg->use_neg_got_offsets_p)  
         {  
           if (arg->rel_8o_offset >= arg->got_offset)  
             /* We've assigned a positive offset to this entry,  
                next entry should get (-abs(offset) - 4).  */  
             arg->rel_8o_offset = (arg->got_offset  
                                   - (arg->rel_8o_offset - arg->got_offset)  
                                   - 4);  
           else  
             /* We've assigned a negative offset to this entry,  
                next entry should get (+abs(offset) + 0).  */  
             arg->rel_8o_offset = (arg->got_offset  
                                   + (arg->got_offset - arg->rel_8o_offset));  
         }  
       else  
         /* Next entry will simply get next offset.  */  
         arg->rel_8o_offset += 4;  
   
       break;  
   
     case R_68K_GOT16O:  
       entry->u.s2.offset = arg->rel_16o_offset;  
   
       if (arg->use_neg_got_offsets_p)  
         {  
           if (arg->rel_16o_offset >= arg->got_offset)  
             /* We've assigned a positive offset to this entry,  
                next entry should get (-abs(offset) - 4).  */  
             arg->rel_16o_offset = (arg->got_offset  
                                    - (arg->rel_16o_offset - arg->got_offset)  
                                    - 4);  
           else  
             /* We've assigned a negative offset to this entry,  
                next entry should get (+abs(offset) + 0).  */  
             arg->rel_16o_offset = (arg->got_offset  
                                    + (arg->got_offset - arg->rel_16o_offset));  
         }  
       else  
         /* Next entry will simply get next offset.  */  
         arg->rel_16o_offset += 4;  
   
       break;  
   
     case R_68K_GOT32O:  
       entry->u.s2.offset = arg->rel_32o_offset;  
2009    
2010        if (arg->use_neg_got_offsets_p)    /* Calculate entry size in bytes.  */
2011          {    entry_size = 4 * elf_m68k_reloc_got_n_slots (entry->key_.type);
           if (arg->rel_32o_offset >= arg->got_offset)  
             /* We've assigned a positive offset to this entry,  
                next entry should get (-abs(offset) - 4).  */  
             arg->rel_32o_offset = (arg->got_offset  
                                    - (arg->rel_32o_offset - arg->got_offset)  
                                    - 4);  
           else  
             /* We've assigned a negative offset to this entry,  
                next entry should get (+abs(offset) + 0).  */  
             arg->rel_32o_offset = (arg->got_offset  
                                    + (arg->got_offset - arg->rel_32o_offset));  
         }  
       else  
         /* Next entry will simply get next offset.  */  
         arg->rel_32o_offset += 4;  
2012    
2013        break;    /* Check if we should switch to negative range of the offsets. */
2014      if (arg->offset1[got_offset_size] + entry_size
2015      default:        > arg->offset2[got_offset_size])
2016        BFD_ASSERT (FALSE);      {
2017        break;        /* Verify that this is the only switch to negative range for
2018      }           got_offset_size.  If this assertion fails, then we've miscalculated
2019             range for got_offset_size entries in
2020             elf_m68k_finalize_got_offsets.  */
2021          BFD_ASSERT (arg->offset2[got_offset_size]
2022                      != arg->offset2[-(int) got_offset_size - 1]);
2023    
2024          /* Switch.  */
2025          arg->offset1[got_offset_size] = arg->offset1[-(int) got_offset_size - 1];
2026          arg->offset2[got_offset_size] = arg->offset2[-(int) got_offset_size - 1];
2027    
2028          /* Verify that now we have enough room for the entry.  */
2029          BFD_ASSERT (arg->offset1[got_offset_size] + entry_size
2030                      <= arg->offset2[got_offset_size]);
2031        }
2032    
2033      /* Assign offset to entry.  */
2034      entry->u.s2.offset = arg->offset1[got_offset_size];
2035      arg->offset1[got_offset_size] += entry_size;
2036    
2037    if (entry->key_.bfd == NULL)    if (entry->key_.bfd == NULL)
2038      /* Hook up this entry into the list of got_entries of H.  */      /* Hook up this entry into the list of got_entries of H.  */
2039      {      {
2040        struct elf_m68k_link_hash_entry *h;        struct elf_m68k_link_hash_entry *h;
2041    
       BFD_ASSERT (entry->key_.symndx != 0);  
2042        h = arg->symndx2h[entry->key_.symndx];        h = arg->symndx2h[entry->key_.symndx];
2043        BFD_ASSERT (h != NULL);        if (h != NULL)
2044            {
2045              entry->u.s2.next = h->glist;
2046              h->glist = entry;
2047            }
2048          else
2049            /* This should be the entry for TLS_LDM relocation then.  */
2050            {
2051              BFD_ASSERT ((elf_m68k_reloc_got_type (entry->key_.type)
2052                           == R_68K_TLS_LDM32)
2053                          && entry->key_.symndx == 0);
2054    
2055        entry->u.s2.next = h->glist;            ++arg->n_ldm_entries;
2056        h->glist = entry;          }
2057      }      }
2058    else    else
2059      /* This entry is for local symbol.  */      /* This entry is for local symbol.  */
# Line 1673  elf_m68k_finalize_got_offsets_1 (void ** Line 2066  elf_m68k_finalize_got_offsets_1 (void **
2066     should use negative offsets.     should use negative offsets.
2067     Build list of GOT entries for global symbols along the way.     Build list of GOT entries for global symbols along the way.
2068     SYMNDX2H is mapping from global symbol indices to actual     SYMNDX2H is mapping from global symbol indices to actual
2069     global symbols.  */     global symbols.
2070       Return offset at which next GOT should start.  */
2071    
2072  static void  static void
2073  elf_m68k_finalize_got_offsets (struct elf_m68k_got *got,  elf_m68k_finalize_got_offsets (struct elf_m68k_got *got,
2074                                 bfd_boolean use_neg_got_offsets_p,                                 bfd_boolean use_neg_got_offsets_p,
2075                                 struct elf_m68k_link_hash_entry **symndx2h)                                 struct elf_m68k_link_hash_entry **symndx2h,
2076                                   bfd_vma *final_offset, bfd_vma *n_ldm_entries)
2077  {  {
2078    struct elf_m68k_finalize_got_offsets_arg arg_;    struct elf_m68k_finalize_got_offsets_arg arg_;
2079      bfd_vma offset1_[2 * R_LAST];
2080      bfd_vma offset2_[2 * R_LAST];
2081      int i;
2082      bfd_vma start_offset;
2083    
2084    BFD_ASSERT (got->offset != (bfd_vma) -1);    BFD_ASSERT (got->offset != (bfd_vma) -1);
2085    
2086    /* We set entry offsets relative to the .got section (and not the    /* We set entry offsets relative to the .got section (and not the
2087       start of a particular GOT), so that we can use them in       start of a particular GOT), so that we can use them in
2088       finish_dynamic_symbol without needing to know the GOT they come       finish_dynamic_symbol without needing to know the GOT which they come
2089       from.  */       from.  */
2090    
2091      /* Put offset1 in the middle of offset1_, same for offset2.  */
2092      arg_.offset1 = offset1_ + R_LAST;
2093      arg_.offset2 = offset2_ + R_LAST;
2094    
2095      start_offset = got->offset;
2096    
2097    if (use_neg_got_offsets_p)    if (use_neg_got_offsets_p)
2098        /* Setup both negative and positive ranges for R_8, R_16 and R_32.  */
2099        i = -(int) R_32 - 1;
2100      else
2101        /* Setup positives ranges for R_8, R_16 and R_32.  */
2102        i = (int) R_8;
2103    
2104      for (; i <= (int) R_32; ++i)
2105      {      {
2106          int j;
2107        size_t n;        size_t n;
2108    
2109        /* Put GOT pointer in the middle of GOT.  */        /* Set beginning of the range of offsets I.  */
2110        n = htab_elements (got->entries);        arg_.offset1[i] = start_offset;
       if ((n & 1) == 0)  
         /* Even number of GOT entries.  */  
         got->offset += 2 * n;  
       else  
         /* Odd number of GOT entries.  */  
         got->offset += 2 * (n - 1);  
2111    
2112        /* R_68K_GOT8O entries shall start at GOT offset.  */        /* Calculate number of slots that require I offsets.  */
2113        arg_.rel_8o_offset = got->offset;        j = (i >= 0) ? i : -i - 1;
2114          n = (j >= 1) ? got->n_slots[j - 1] : 0;
2115          n = got->n_slots[j] - n;
2116    
2117          if (use_neg_got_offsets_p && n != 0)
2118            {
2119              if (i < 0)
2120                /* We first fill the positive side of the range, so we might
2121                   end up with one empty slot at that side when we can't fit
2122                   whole 2-slot entry.  Account for that at negative side of
2123                   the interval with one additional entry.  */
2124                n = n / 2 + 1;
2125              else
2126                /* When the number of slots is odd, make positive side of the
2127                   range one entry bigger.  */
2128                n = (n + 1) / 2;
2129            }
2130    
2131        n = got->rel_8o_n_entries;        /* N is the number of slots that require I offsets.
2132        if ((n & 1) == 0)           Calculate length of the range for I offsets.  */
2133          /* Even number of R_68K_GOT8O entries.        n = 4 * n;
            The last R_68K_GOT8O entry will be at  
            (got->offset - 2 * n).  Hence the first R_68K_GOT16O  
            entry will be at offset ...  */  
         arg_.rel_16o_offset = got->offset + 2 * n;  
       else  
         /* Odd number of R_68K_GOT8O entries.  
            The last R_68K_GOT8O entry will be at  
            (got->offset + 2 * (n - 1)).  Hence the first R_68K_GOT16O  
            entry will be at offset ...  */  
         arg_.rel_16o_offset = got->offset - 2 * (n - 1) - 4;  
   
       n = got->rel_8o_16o_n_entries;  
       if ((n & 1) == 0)  
         /* Even number of R_68K_GOT8O and R_68K_GOT16O entries.  
            The last R_68K_GOT8O entry will be at  
            (got->offset - 2 * n).  Hence the first R_68K_GOT32O  
            entry will be at offset ...  */  
         arg_.rel_32o_offset = got->offset + 2 * n;  
       else  
         /* Odd number of R_68K_GOT8O and R_68K_GOT16O entries.  
            The last R_68K_GOT16O entry will be at  
            (got->offset + 2 * (n - 1)).  Hence the first R_68K_GOT32O  
            entry will be at offset ...  */  
         arg_.rel_32o_offset = got->offset - 2 * (n - 1) - 4;  
2134    
2135        arg_.use_neg_got_offsets_p = TRUE;        /* Set end of the range.  */
2136          arg_.offset2[i] = start_offset + n;
2137    
2138        arg_.got_offset = got->offset;        start_offset = arg_.offset2[i];
2139      }      }
   else  
     {  
       arg_.rel_8o_offset = got->offset;  
       arg_.rel_16o_offset = 4 * got->rel_8o_n_entries + got->offset;  
       arg_.rel_32o_offset = 4 * got->rel_8o_16o_n_entries + got->offset;  
2140    
2141        arg_.use_neg_got_offsets_p = FALSE;    if (!use_neg_got_offsets_p)
2142        /* Make sure that if we try to switch to negative offsets in
2143           elf_m68k_finalize_got_offsets_1, the assert therein will catch
2144           the bug.  */
2145        for (i = R_8; i <= R_32; ++i)
2146          arg_.offset2[-i - 1] = arg_.offset2[i];
2147    
2148        /* This shouldn't be used.  */    /* Setup got->offset.  offset1[R_8] is either in the middle or at the
2149        arg_.got_offset = (bfd_vma) -1;       beginning of GOT depending on use_neg_got_offsets_p.  */
2150      }    got->offset = arg_.offset1[R_8];
2151    
2152    arg_.symndx2h = symndx2h;    arg_.symndx2h = symndx2h;
2153      arg_.n_ldm_entries = 0;
2154    
2155      /* Assign offsets.  */
2156    htab_traverse (got->entries, elf_m68k_finalize_got_offsets_1, &arg_);    htab_traverse (got->entries, elf_m68k_finalize_got_offsets_1, &arg_);
2157    
2158    /* Calculate offset ranges we have actually assigned.  */    /* Check offset ranges we have actually assigned.  */
2159    if (use_neg_got_offsets_p)    for (i = (int) R_8; i <= (int) R_32; ++i)
2160      {      BFD_ASSERT (arg_.offset2[i] - arg_.offset1[i] <= 4);
       if (arg_.rel_8o_offset == (bfd_vma) -4  
           || arg_.rel_8o_offset < got->offset)  
         arg_.rel_8o_offset = 2 * (got->offset - arg_.rel_8o_offset) - 4;  
       else  
         arg_.rel_8o_offset = 2 * (arg_.rel_8o_offset - got->offset);  
2161    
2162        if (arg_.rel_16o_offset == (bfd_vma) -4    *final_offset = start_offset;
2163            || arg_.rel_16o_offset < got->offset)    *n_ldm_entries = arg_.n_ldm_entries;
         arg_.rel_16o_offset = 2 * (got->offset - arg_.rel_16o_offset) - 4;  
       else  
         arg_.rel_16o_offset = 2 * (arg_.rel_16o_offset - got->offset);  
   
       if (arg_.rel_32o_offset == (bfd_vma) -4  
           || arg_.rel_32o_offset < got->offset)  
         arg_.rel_32o_offset = 2 * (got->offset - arg_.rel_32o_offset) - 4;  
       else  
         arg_.rel_32o_offset = 2 * (arg_.rel_32o_offset - got->offset);  
     }  
   else  
     {  
       arg_.rel_8o_offset -= got->offset;  
       arg_.rel_16o_offset -= got->offset;  
       arg_.rel_32o_offset -= got->offset;  
     }  
   
   /* These asserts check that we got counting of entries right.  */  
   BFD_ASSERT (arg_.rel_8o_offset == 4 * got->rel_8o_n_entries);  
   BFD_ASSERT (arg_.rel_16o_offset == 4 * got->rel_8o_16o_n_entries);  
   BFD_ASSERT (arg_.rel_32o_offset == 4 * htab_elements (got->entries));  
2164  }  }
2165    
2166  struct elf_m68k_partition_multi_got_arg  struct elf_m68k_partition_multi_got_arg
# Line 1798  struct elf_m68k_partition_multi_got_arg Line 2174  struct elf_m68k_partition_multi_got_arg
2174    /* Context where memory should be allocated.  */    /* Context where memory should be allocated.  */
2175    struct bfd_link_info *info;    struct bfd_link_info *info;
2176    
2177    /* Total number of entries in the .got section.    /* Total number of slots in the .got section.
2178       This is used to calculate size of the .got and .rela.got sections.  */       This is used to calculate size of the .got and .rela.got sections.  */
2179    bfd_vma n_entries;    bfd_vma n_slots;
2180    
2181    /* Total number of local entries in the .got section.    /* Difference in numbers of allocated slots in the .got section
2182         and necessary relocations in the .rela.got section.
2183       This is used to calculate size of the .rela.got section.  */       This is used to calculate size of the .rela.got section.  */
2184    bfd_vma local_n_entries;    bfd_vma slots_relas_diff;
2185    
2186    /* Error flag.  */    /* Error flag.  */
2187    bfd_boolean error_p;    bfd_boolean error_p;
# Line 1814  struct elf_m68k_partition_multi_got_arg Line 2191  struct elf_m68k_partition_multi_got_arg
2191    struct elf_m68k_link_hash_entry **symndx2h;    struct elf_m68k_link_hash_entry **symndx2h;
2192  };  };
2193    
2194    static void
2195    elf_m68k_partition_multi_got_2 (struct elf_m68k_partition_multi_got_arg *arg)
2196    {
2197      bfd_vma n_ldm_entries;
2198    
2199      elf_m68k_finalize_got_offsets (arg->current_got,
2200                                     (elf_m68k_hash_table (arg->info)
2201                                      ->use_neg_got_offsets_p),
2202                                     arg->symndx2h,
2203                                     &arg->offset, &n_ldm_entries);
2204    
2205      arg->n_slots += arg->current_got->n_slots[R_32];
2206    
2207      if (!arg->info->shared)
2208        /* If we are generating a shared object, we need to
2209           output a R_68K_RELATIVE reloc so that the dynamic
2210           linker can adjust this GOT entry.  Overwise we
2211           don't need space in .rela.got for local symbols.  */
2212        arg->slots_relas_diff += arg->current_got->local_n_slots;
2213    
2214      /* @LDM relocations require a 2-slot GOT entry, but only
2215         one relocation.  Account for that.  */
2216      arg->slots_relas_diff += n_ldm_entries;
2217    
2218      BFD_ASSERT (arg->slots_relas_diff <= arg->n_slots);
2219    }
2220    
2221    
2222  /* Process a single BFD2GOT entry and either merge GOT to CURRENT_GOT  /* Process a single BFD2GOT entry and either merge GOT to CURRENT_GOT
2223     or start a new CURRENT_GOT.  */     or start a new CURRENT_GOT.  */
2224    
# Line 1823  elf_m68k_partition_multi_got_1 (void **_ Line 2228  elf_m68k_partition_multi_got_1 (void **_
2228    struct elf_m68k_bfd2got_entry *entry;    struct elf_m68k_bfd2got_entry *entry;
2229    struct elf_m68k_partition_multi_got_arg *arg;    struct elf_m68k_partition_multi_got_arg *arg;
2230    struct elf_m68k_got *got;    struct elf_m68k_got *got;
   struct elf_m68k_got *current_got;  
2231    struct elf_m68k_got diff_;    struct elf_m68k_got diff_;
2232    struct elf_m68k_got *diff;    struct elf_m68k_got *diff;
2233    
# Line 1840  elf_m68k_partition_multi_got_1 (void **_ Line 2244  elf_m68k_partition_multi_got_1 (void **_
2244      /* Construct diff.  */      /* Construct diff.  */
2245      {      {
2246        diff = &diff_;        diff = &diff_;
2247        elf_m68k_init_got (diff, NULL, 0, 0, 0, (bfd_vma) -1);        elf_m68k_init_got (diff);
2248    
2249        if (!elf_m68k_can_merge_gots (arg->current_got, got, arg->info, diff))        if (!elf_m68k_can_merge_gots (arg->current_got, got, arg->info, diff))
2250          {          {
# Line 1854  elf_m68k_partition_multi_got_1 (void **_ Line 2258  elf_m68k_partition_multi_got_1 (void **_
2258            if (elf_m68k_hash_table (arg->info)->allow_multigot_p)            if (elf_m68k_hash_table (arg->info)->allow_multigot_p)
2259              {              {
2260                elf_m68k_clear_got (diff);                elf_m68k_clear_got (diff);
2261                /* Schedule to finish up CURRENT_GOT and start new one.  */                /* Schedule to finish up current_got and start new one.  */
2262                diff = NULL;                diff = NULL;
2263              }              }
2264            /* else            /* else
# Line 1867  elf_m68k_partition_multi_got_1 (void **_ Line 2271  elf_m68k_partition_multi_got_1 (void **_
2271    else    else
2272      /* Diff of got against empty current_got is got itself.  */      /* Diff of got against empty current_got is got itself.  */
2273      {      {
2274        /* Create empty CURRENT_GOT to subsequent GOTs to.  */        /* Create empty current_got to put subsequent GOTs to.  */
2275        arg->current_got = elf_m68k_create_empty_got (arg->info);        arg->current_got = elf_m68k_create_empty_got (arg->info);
2276        if (arg->current_got == NULL)        if (arg->current_got == NULL)
2277          {          {
# Line 1880  elf_m68k_partition_multi_got_1 (void **_ Line 2284  elf_m68k_partition_multi_got_1 (void **_
2284        diff = got;        diff = got;
2285      }      }
2286    
   current_got = arg->current_got;  
   
2287    if (diff != NULL)    if (diff != NULL)
2288      {      {
2289        if (!elf_m68k_merge_gots (current_got, diff, arg->info))        if (!elf_m68k_merge_gots (arg->current_got, diff, arg->info))
2290          {          {
2291            arg->error_p = TRUE;            arg->error_p = TRUE;
2292            goto final_return;            goto final_return;
# Line 1893  elf_m68k_partition_multi_got_1 (void **_ Line 2295  elf_m68k_partition_multi_got_1 (void **_
2295        /* Now we can free GOT.  */        /* Now we can free GOT.  */
2296        elf_m68k_clear_got (got);        elf_m68k_clear_got (got);
2297    
2298        entry->got = current_got;        entry->got = arg->current_got;
2299      }      }
2300    else    else
2301      {      {
       /* Schedule to start a new current_got.  */  
       arg->current_got = NULL;  
       arg->offset = (current_got->offset  
                      + 4 * htab_elements (current_got->entries));  
   
2302        /* Finish up current_got.  */        /* Finish up current_got.  */
2303        {        elf_m68k_partition_multi_got_2 (arg);
         elf_m68k_finalize_got_offsets (current_got,  
                                        elf_m68k_hash_table (arg->info)  
                                        ->use_neg_got_offsets_p,  
                                        arg->symndx2h);  
2304    
2305          arg->n_entries += htab_elements (current_got->entries);        /* Schedule to start a new current_got.  */
2306          arg->local_n_entries += current_got->local_n_entries;        arg->current_got = NULL;
   
         BFD_ASSERT (arg->local_n_entries <= arg->n_entries);  
       }  
2307    
2308        /* Retry.  */        /* Retry.  */
2309        if (!elf_m68k_partition_multi_got_1 (_entry, _arg))        if (!elf_m68k_partition_multi_got_1 (_entry, _arg))
# Line 1969  elf_m68k_partition_multi_got (struct bfd Line 2359  elf_m68k_partition_multi_got (struct bfd
2359    arg_.current_got = NULL;    arg_.current_got = NULL;
2360    arg_.offset = 0;    arg_.offset = 0;
2361    arg_.info = info;    arg_.info = info;
2362    arg_.n_entries = 0;    arg_.n_slots = 0;
2363    arg_.local_n_entries = 0;    arg_.slots_relas_diff = 0;
2364    arg_.error_p = FALSE;    arg_.error_p = FALSE;
2365    
2366    if (multi_got->bfd2got != NULL)    if (multi_got->bfd2got != NULL)
# Line 1998  elf_m68k_partition_multi_got (struct bfd Line 2388  elf_m68k_partition_multi_got (struct bfd
2388          }          }
2389    
2390        /* Finish up last current_got.  */        /* Finish up last current_got.  */
2391        {        elf_m68k_partition_multi_got_2 (&arg_);
         elf_m68k_finalize_got_offsets (arg_.current_got,  
                                        elf_m68k_hash_table (info)  
                                        ->use_neg_got_offsets_p, arg_.symndx2h);  
   
         arg_.n_entries += htab_elements (arg_.current_got->entries);  
         arg_.local_n_entries += arg_.current_got->local_n_entries;  
   
         BFD_ASSERT (arg_.local_n_entries <= arg_.n_entries);  
       }  
2392    
2393        free (arg_.symndx2h);        free (arg_.symndx2h);
2394      }      }
# Line 2019  elf_m68k_partition_multi_got (struct bfd Line 2400  elf_m68k_partition_multi_got (struct bfd
2400    
2401        s = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".got");        s = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".got");
2402        if (s != NULL)        if (s != NULL)
2403          s->size = arg_.n_entries * 4;          s->size = arg_.offset;
2404        else        else
2405          BFD_ASSERT (arg_.n_entries == 0);          BFD_ASSERT (arg_.offset == 0);
2406    
2407        /* If we are generating a shared object, we need to        BFD_ASSERT (arg_.slots_relas_diff <= arg_.n_slots);
2408           output a R_68K_RELATIVE reloc so that the dynamic        arg_.n_slots -= arg_.slots_relas_diff;
          linker can adjust this GOT entry.  Overwise we  
          don't need space in .rela.got for local symbols.  */  
       if (!info->shared)  
         {  
           BFD_ASSERT (arg_.local_n_entries <= arg_.n_entries);  
           arg_.n_entries -= arg_.local_n_entries;  
         }  
2409    
2410        s = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".rela.got");        s = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".rela.got");
2411        if (s != NULL)        if (s != NULL)
2412          s->size = arg_.n_entries * sizeof (Elf32_External_Rela);          s->size = arg_.n_slots * sizeof (Elf32_External_Rela);
2413        else        else
2414          BFD_ASSERT (arg_.n_entries == 0);          BFD_ASSERT (arg_.n_slots == 0);
2415      }      }
2416    else    else
2417      BFD_ASSERT (multi_got->bfd2got == NULL);      BFD_ASSERT (multi_got->bfd2got == NULL);
# Line 2081  elf_m68k_remove_got_entry (struct elf_m6 Line 2455  elf_m68k_remove_got_entry (struct elf_m6
2455    /* Check that this entry is indeed unused.  */    /* Check that this entry is indeed unused.  */
2456    BFD_ASSERT (entry->u.s1.refcount == 0);    BFD_ASSERT (entry->u.s1.refcount == 0);
2457    
2458    elf_m68k_remove_got_entry_type (got, entry->u.s1.type);    elf_m68k_remove_got_entry_type (got, entry->key_.type);
2459    
2460    if (entry->key_.bfd != NULL)    if (entry->key_.bfd != NULL)
2461      --got->local_n_entries;      got->local_n_slots -= elf_m68k_reloc_got_n_slots (entry->key_.type);
2462    
2463      BFD_ASSERT (got->n_slots[R_32] >= got->local_n_slots);
2464    
2465    htab_clear_slot (got->entries, (void **) entry_ptr);    htab_clear_slot (got->entries, (void **) entry_ptr);
2466  }  }
# Line 2187  elf_m68k_check_relocs (abfd, info, sec, Line 2563  elf_m68k_check_relocs (abfd, info, sec,
2563                && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)                && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2564              break;              break;
2565            /* Fall through.  */            /* Fall through.  */
2566    
2567              /* Relative GOT relocations.  */
2568          case R_68K_GOT8O:          case R_68K_GOT8O:
2569          case R_68K_GOT16O:          case R_68K_GOT16O:
2570          case R_68K_GOT32O:          case R_68K_GOT32O:
2571              /* Fall through.  */
2572    
2573              /* TLS relocations.  */
2574            case R_68K_TLS_GD8:
2575            case R_68K_TLS_GD16:
2576            case R_68K_TLS_GD32:
2577            case R_68K_TLS_LDM8:
2578            case R_68K_TLS_LDM16:
2579            case R_68K_TLS_LDM32:
2580            case R_68K_TLS_IE8:
2581            case R_68K_TLS_IE16:
2582            case R_68K_TLS_IE32:
2583    
2584            /* This symbol requires a global offset table entry.  */            /* This symbol requires a global offset table entry.  */
2585    
2586            if (dynobj == NULL)            if (dynobj == NULL)
# Line 2260  elf_m68k_check_relocs (abfd, info, sec, Line 2651  elf_m68k_check_relocs (abfd, info, sec,
2651                      if (!bfd_elf_link_record_dynamic_symbol (info, h))                      if (!bfd_elf_link_record_dynamic_symbol (info, h))
2652                        return FALSE;                        return FALSE;
2653                    }                    }
   
                 /* Allocate space in the .got section.  */  
                 sgot->size += 4;  
   
                 /* Allocate relocation space.  */  
                 if (h != NULL  
                     || info->shared)  
                   srelgot->size += sizeof (Elf32_External_Rela);  
2654                }                }
2655            }            }
2656    
# Line 2410  elf_m68k_check_relocs (abfd, info, sec, Line 2793  elf_m68k_check_relocs (abfd, info, sec,
2793                      {                      {
2794                        asection *s;                        asection *s;
2795                        void *vpp;                        void *vpp;
2796                          Elf_Internal_Sym *isym;
2797    
2798                        s = (bfd_section_from_r_symndx                        isym = bfd_sym_from_r_symndx (&elf_m68k_hash_table (info)->sym_cache,
2799                             (abfd, &elf_m68k_hash_table (info)->sym_sec,                                                      abfd, r_symndx);
2800                              sec, r_symndx));                        if (isym == NULL)
                       if (s == NULL)  
2801                          return FALSE;                          return FALSE;
2802    
2803                          s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2804                          if (s == NULL)
2805                            s = sec;
2806    
2807                        vpp = &elf_section_data (s)->local_dynrel;                        vpp = &elf_section_data (s)->local_dynrel;
2808                        head = (struct elf_m68k_pcrel_relocs_copied **) vpp;                        head = (struct elf_m68k_pcrel_relocs_copied **) vpp;
2809                      }                      }
# Line 2546  elf_m68k_gc_sweep_hook (bfd *abfd, Line 2933  elf_m68k_gc_sweep_hook (bfd *abfd,
2933          case R_68K_GOT8O:          case R_68K_GOT8O:
2934          case R_68K_GOT16O:          case R_68K_GOT16O:
2935          case R_68K_GOT32O:          case R_68K_GOT32O:
2936              /* Fall through.  */
2937    
2938              /* TLS relocations.  */
2939            case R_68K_TLS_GD8:
2940            case R_68K_TLS_GD16:
2941            case R_68K_TLS_GD32:
2942            case R_68K_TLS_LDM8:
2943            case R_68K_TLS_LDM16:
2944            case R_68K_TLS_LDM32:
2945            case R_68K_TLS_IE8:
2946            case R_68K_TLS_IE16:
2947            case R_68K_TLS_IE32:
2948    
2949            if (got == NULL)            if (got == NULL)
2950              {              {
2951                got = elf_m68k_get_bfd2got_entry (elf_m68k_multi_got (info),                got = elf_m68k_get_bfd2got_entry (elf_m68k_multi_got (info),
# Line 2558  elf_m68k_gc_sweep_hook (bfd *abfd, Line 2958  elf_m68k_gc_sweep_hook (bfd *abfd,
2958              struct elf_m68k_got_entry **got_entry_ptr;              struct elf_m68k_got_entry **got_entry_ptr;
2959              struct elf_m68k_got_entry *got_entry;              struct elf_m68k_got_entry *got_entry;
2960    
2961              elf_m68k_init_got_entry_key (&key_, h, abfd, r_symndx);              elf_m68k_init_got_entry_key (&key_, h, abfd, r_symndx,
2962                                             ELF32_R_TYPE (rel->r_info));
2963              got_entry_ptr = elf_m68k_find_got_entry_ptr (got, &key_);              got_entry_ptr = elf_m68k_find_got_entry_ptr (got, &key_);
2964    
2965              got_entry = *got_entry_ptr;              got_entry = *got_entry_ptr;
# Line 3006  elf_m68k_discard_copies (h, inf) Line 3407  elf_m68k_discard_copies (h, inf)
3407    return TRUE;    return TRUE;
3408  }  }
3409    
3410    
3411    /* Install relocation RELA.  */
3412    
3413    static void
3414    elf_m68k_install_rela (bfd *output_bfd,
3415                           asection *srela,
3416                           Elf_Internal_Rela *rela)
3417    {
3418      bfd_byte *loc;
3419    
3420      loc = srela->contents;
3421      loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
3422      bfd_elf32_swap_reloca_out (output_bfd, rela, loc);
3423    }
3424    
3425    /* Return the base VMA address which should be subtracted from real addresses
3426       when resolving @dtpoff relocation.
3427       This is PT_TLS segment p_vaddr.  */
3428    
3429    static bfd_vma
3430    dtpoff_base (struct bfd_link_info *info)
3431    {
3432      /* If tls_sec is NULL, we should have signalled an error already.  */
3433      if (elf_hash_table (info)->tls_sec == NULL)
3434        return 0;
3435      return elf_hash_table (info)->tls_sec->vma;
3436    }
3437    
3438    /* Return the relocation value for @tpoff relocation
3439       if STT_TLS virtual address is ADDRESS.  */
3440    
3441    static bfd_vma
3442    tpoff (struct bfd_link_info *info, bfd_vma address)
3443    {
3444      struct elf_link_hash_table *htab = elf_hash_table (info);
3445      bfd_vma base;
3446    
3447      /* If tls_sec is NULL, we should have signalled an error already.  */
3448      if (htab->tls_sec == NULL)
3449        return 0;
3450      base = align_power ((bfd_vma) 8, htab->tls_sec->alignment_power);
3451      return address - htab->tls_sec->vma + base;
3452    }
3453    
3454  /* Relocate an M68K ELF section.  */  /* Relocate an M68K ELF section.  */
3455    
3456  static bfd_boolean  static bfd_boolean
# Line 3168  elf_m68k_relocate_section (output_bfd, i Line 3613  elf_m68k_relocate_section (output_bfd, i
3613          case R_68K_GOT8O:          case R_68K_GOT8O:
3614          case R_68K_GOT16O:          case R_68K_GOT16O:
3615          case R_68K_GOT32O:          case R_68K_GOT32O:
3616    
3617            case R_68K_TLS_LDM32:
3618            case R_68K_TLS_LDM16:
3619            case R_68K_TLS_LDM8:
3620    
3621            case R_68K_TLS_GD8:
3622            case R_68K_TLS_GD16:
3623            case R_68K_TLS_GD32:
3624    
3625            case R_68K_TLS_IE8:
3626            case R_68K_TLS_IE16:
3627            case R_68K_TLS_IE32:
3628    
3629            /* Relocation is the offset of the entry for this symbol in            /* Relocation is the offset of the entry for this symbol in
3630               the global offset table.  */               the global offset table.  */
3631    
# Line 3191  elf_m68k_relocate_section (output_bfd, i Line 3649  elf_m68k_relocate_section (output_bfd, i
3649                }                }
3650    
3651              /* Get GOT offset for this symbol.  */              /* Get GOT offset for this symbol.  */
3652              elf_m68k_init_got_entry_key (&key_, h, input_bfd, r_symndx);              elf_m68k_init_got_entry_key (&key_, h, input_bfd, r_symndx,
3653                                             r_type);
3654              off_ptr = &elf_m68k_get_got_entry (got, &key_, MUST_FIND,              off_ptr = &elf_m68k_get_got_entry (got, &key_, MUST_FIND,
3655                                                 NULL)->u.s2.offset;                                                 NULL)->u.s2.offset;
3656              off = *off_ptr;              off = *off_ptr;
3657    
3658              if (h != NULL)              /* The offset must always be a multiple of 4.  We use
3659                   the least significant bit to record whether we have
3660                   already generated the necessary reloc.  */
3661                if ((off & 1) != 0)
3662                  off &= ~1;
3663                else
3664                {                {
3665                  bfd_boolean dyn;                  if (h != NULL
3666                        /* @TLSLDM relocations are bounded to the module, in
3667                  dyn = elf_hash_table (info)->dynamic_sections_created;                         which the symbol is defined -- not to the symbol
3668                  if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)                         itself.  */
3669                      || (info->shared                      && elf_m68k_reloc_got_type (r_type) != R_68K_TLS_LDM32)
                         && SYMBOL_REFERENCES_LOCAL (info, h))  
                     || (ELF_ST_VISIBILITY (h->other)  
                         && h->root.type == bfd_link_hash_undefweak))  
3670                    {                    {
3671                      /* This is actually a static link, or it is a                      bfd_boolean dyn;
3672                         -Bsymbolic link and the symbol is defined  
3673                         locally, or the symbol was forced to be local                      dyn = elf_hash_table (info)->dynamic_sections_created;
3674                         because of a version file..  We must initialize                      if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
3675                         this entry in the global offset table.  Since                          || (info->shared
3676                         the offset must always be a multiple of 4, we                              && SYMBOL_REFERENCES_LOCAL (info, h))
3677                         use the least significant bit to record whether                          || (ELF_ST_VISIBILITY (h->other)
3678                         we have initialized it already.                              && h->root.type == bfd_link_hash_undefweak))
   
                        When doing a dynamic link, we create a .rela.got  
                        relocation entry to initialize the value.  This  
                        is done in the finish_dynamic_symbol routine.  */  
                     if ((off & 1) != 0)  
                       off &= ~1;  
                     else  
3679                        {                        {
3680                          bfd_put_32 (output_bfd, relocation,                          /* This is actually a static link, or it is a
3681                                      sgot->contents + off);                             -Bsymbolic link and the symbol is defined
3682                               locally, or the symbol was forced to be local
3683                               because of a version file..  We must initialize
3684                               this entry in the global offset table.  Since
3685                               the offset must always be a multiple of 4, we
3686                               use the least significant bit to record whether
3687                               we have initialized it already.
3688    
3689                               When doing a dynamic link, we create a .rela.got
3690                               relocation entry to initialize the value.  This
3691                               is done in the finish_dynamic_symbol routine.  */
3692    
3693                            if (elf_m68k_reloc_got_type (r_type) == R_68K_GOT32O)
3694                              bfd_put_32 (output_bfd, relocation,
3695                                          sgot->contents + off);
3696                            else if (elf_m68k_reloc_got_type (r_type)
3697                                     == R_68K_TLS_GD32)
3698                              /* Mark it as belonging to module 1,
3699                                 the executable.  */
3700                              {
3701                                bfd_put_32 (output_bfd, 1,
3702                                            sgot->contents + off);
3703                                bfd_put_32 (output_bfd, (relocation
3704                                                         - dtpoff_base (info)),
3705                                            sgot->contents + off + 4);
3706                              }
3707                            else if (elf_m68k_reloc_got_type (r_type)
3708                                     == R_68K_TLS_IE32)
3709                              bfd_put_32 (output_bfd, tpoff (info, relocation),
3710                                          sgot->contents + off);
3711                            else
3712                              BFD_ASSERT (FALSE);
3713    
3714                          *off_ptr |= 1;                          *off_ptr |= 1;
3715                        }                        }
3716                        else
3717                          unresolved_reloc = FALSE;
3718                    }                    }
3719                  else                  else if (info->shared) /* && h == NULL */
                   unresolved_reloc = FALSE;  
               }  
             else  
               {  
                 /* The offset must always be a multiple of 4.  We use  
                    the least significant bit to record whether we have  
                    already generated the necessary reloc.  */  
                 if ((off & 1) != 0)  
                   off &= ~1;  
                 else  
3720                    {                    {
3721                      bfd_put_32 (output_bfd, relocation, sgot->contents + off);                      asection *srela;
3722                        Elf_Internal_Rela outrel;
3723    
3724                        srela = bfd_get_section_by_name (dynobj, ".rela.got");
3725                        BFD_ASSERT (srela != NULL);
3726    
3727                      if (info->shared)                      if (elf_m68k_reloc_got_type (r_type) == R_68K_GOT32O)
3728                        {                        {
3729                          asection *s;                          /* Emit RELATIVE relocation to initialize GOT slot
3730                          Elf_Internal_Rela outrel;                             at run-time.  */
3731                          bfd_byte *loc;                          outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
3732                            outrel.r_addend = relocation;
3733                            outrel.r_offset = (sgot->output_section->vma
3734                                               + sgot->output_offset
3735                                               + off);
3736    
3737                          s = bfd_get_section_by_name (dynobj, ".rela.got");                          elf_m68k_install_rela (output_bfd, srela, &outrel);
3738                          BFD_ASSERT (s != NULL);                        }
3739                        else if (elf_m68k_reloc_got_type (r_type)
3740                                 == R_68K_TLS_LDM32)
3741                          {
3742                            /* If we don't know the module number, create
3743                               a relocation for it.  */
3744                            outrel.r_info = ELF32_R_INFO (0, R_68K_TLS_DTPMOD32);
3745                            outrel.r_addend = 0;
3746                            outrel.r_offset = (sgot->output_section->vma
3747                                               + sgot->output_offset
3748                                               + off);
3749    
3750                            elf_m68k_install_rela (output_bfd, srela, &outrel);
3751                          }
3752                        else if (elf_m68k_reloc_got_type (r_type)
3753                                 == R_68K_TLS_GD32)
3754                          {
3755                            /* If we don't know the module number, create
3756                               a relocation for it.  */
3757                            outrel.r_info = ELF32_R_INFO (0, R_68K_TLS_DTPMOD32);
3758                            outrel.r_addend = 0;
3759                          outrel.r_offset = (sgot->output_section->vma                          outrel.r_offset = (sgot->output_section->vma
3760                                             + sgot->output_offset                                             + sgot->output_offset
3761                                             + off);                                             + off);
3762                          outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);  
3763                          outrel.r_addend = relocation;                          elf_m68k_install_rela (output_bfd, srela, &outrel);
3764                          loc = s->contents;  
3765                          loc += s->reloc_count++ * sizeof (Elf32_External_Rela);                          bfd_put_32 (output_bfd, (relocation
3766                          bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);                                                   - dtpoff_base (info)),
3767                                        sgot->contents + off + 4);
3768                          }
3769                        else if (elf_m68k_reloc_got_type (r_type)
3770                                 == R_68K_TLS_IE32)
3771                          {
3772                            outrel.r_info = ELF32_R_INFO (0, R_68K_TLS_TPREL32);
3773                            outrel.r_addend = relocation - dtpoff_base (info);
3774                            outrel.r_offset = (sgot->output_section->vma
3775                                               + sgot->output_offset
3776                                               + off);
3777    
3778                            elf_m68k_install_rela (output_bfd, srela, &outrel);
3779                        }                        }
3780                        else
3781                          BFD_ASSERT (FALSE);
3782    
3783                        bfd_put_32 (output_bfd, outrel.r_addend,
3784                                    sgot->contents + off);
3785    
3786                        *off_ptr |= 1;
3787                      }
3788                    else /* h == NULL && !info->shared */
3789                      {
3790                        if (elf_m68k_reloc_got_type (r_type) == R_68K_GOT32O)
3791                          bfd_put_32 (output_bfd, relocation,
3792                                      sgot->contents + off);
3793                        else if (elf_m68k_reloc_got_type (r_type)
3794                                 == R_68K_TLS_LDM32)
3795                          /* If this is a static link, put the number of the
3796                             only module in the GOT slot.  */
3797                          bfd_put_32 (output_bfd, 1, sgot->contents + off);
3798                        else if (elf_m68k_reloc_got_type (r_type)
3799                                 == R_68K_TLS_GD32)
3800                          {
3801                            /* If we are not emitting relocations for a
3802                               general dynamic reference, then we must be in a
3803                               static link or an executable link with the
3804                               symbol binding locally.  Mark it as belonging
3805                               to module 1, the executable.  */
3806                            bfd_put_32 (output_bfd, 1, sgot->contents + off);
3807                            bfd_put_32 (output_bfd, (relocation
3808                                                     - dtpoff_base (info)),
3809                                        sgot->contents + off + 4);
3810                          }
3811                        else if (elf_m68k_reloc_got_type (r_type)
3812                                 == R_68K_TLS_IE32)
3813                          bfd_put_32 (output_bfd, tpoff (info, relocation),
3814                                      sgot->contents + off);
3815                        else
3816                          BFD_ASSERT (FALSE);
3817    
3818                      *off_ptr |= 1;                      *off_ptr |= 1;
3819                    }                    }
3820                }                }
3821    
3822              if (r_type == R_68K_GOT8O              /* We don't use elf_m68k_reloc_got_type in the condition below
3823                   because this is the only place where difference between
3824                   R_68K_GOTx and R_68K_GOTxO relocations matters.  */
3825                if (r_type == R_68K_GOT32O
3826                  || r_type == R_68K_GOT16O                  || r_type == R_68K_GOT16O
3827                  || r_type == R_68K_GOT32O)                  || r_type == R_68K_GOT8O
3828                    || elf_m68k_reloc_got_type (r_type) == R_68K_TLS_GD32
3829                    || elf_m68k_reloc_got_type (r_type) == R_68K_TLS_LDM32
3830                    || elf_m68k_reloc_got_type (r_type) == R_68K_TLS_IE32)
3831                {                {
3832                  /* GOT pointer is adjusted to point to the start/middle                  /* GOT pointer is adjusted to point to the start/middle
3833                     of local GOT.  Adjust the offset accordingly.  */                     of local GOT.  Adjust the offset accordingly.  */
# Line 3292  elf_m68k_relocate_section (output_bfd, i Line 3852  elf_m68k_relocate_section (output_bfd, i
3852            }            }
3853            break;            break;
3854    
3855            case R_68K_TLS_LDO32:
3856            case R_68K_TLS_LDO16:
3857            case R_68K_TLS_LDO8:
3858              relocation -= dtpoff_base (info);
3859              break;
3860    
3861            case R_68K_TLS_LE32:
3862            case R_68K_TLS_LE16:
3863            case R_68K_TLS_LE8:
3864              if (info->shared)
3865                {
3866                  (*_bfd_error_handler)
3867                    (_("%B(%A+0x%lx): R_68K_TLS_LE32 relocation not permitted "
3868                       "in shared object"),
3869                     input_bfd, input_section, (long) rel->r_offset, howto->name);
3870    
3871                  return FALSE;
3872                }
3873              else
3874                relocation = tpoff (info, relocation);
3875    
3876              break;
3877    
3878          case R_68K_PLT8:          case R_68K_PLT8:
3879          case R_68K_PLT16:          case R_68K_PLT16:
3880          case R_68K_PLT32:          case R_68K_PLT32:
# Line 3487  elf_m68k_relocate_section (output_bfd, i Line 4070  elf_m68k_relocate_section (output_bfd, i
4070            return FALSE;            return FALSE;
4071          }          }
4072    
4073          if (r_symndx != 0
4074              && r_type != R_68K_NONE
4075              && (h == NULL
4076                  || h->root.type == bfd_link_hash_defined
4077                  || h->root.type == bfd_link_hash_defweak))
4078            {
4079              char sym_type;
4080    
4081              sym_type = (sym != NULL) ? ELF32_ST_TYPE (sym->st_info) : h->type;
4082    
4083              if (elf_m68k_reloc_tls_p (r_type) != (sym_type == STT_TLS))
4084                {
4085                  const char *name;
4086    
4087                  if (h != NULL)
4088                    name = h->root.root.string;
4089                  else
4090                    {
4091                      name = (bfd_elf_string_from_elf_section
4092                              (input_bfd, symtab_hdr->sh_link, sym->st_name));
4093                      if (name == NULL || *name == '\0')
4094                        name = bfd_section_name (input_bfd, sec);
4095                    }
4096    
4097                  (*_bfd_error_handler)
4098                    ((sym_type == STT_TLS
4099                      ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
4100                      : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
4101                     input_bfd,
4102                     input_section,
4103                     (long) rel->r_offset,
4104                     howto->name,
4105                     name);
4106                }
4107            }
4108    
4109        r = _bfd_final_link_relocate (howto, input_bfd, input_section,        r = _bfd_final_link_relocate (howto, input_bfd, input_section,
4110                                      contents, rel->r_offset,                                      contents, rel->r_offset,
4111                                      relocation, rel->r_addend);                                      relocation, rel->r_addend);
# Line 3652  elf_m68k_finish_dynamic_symbol (output_b Line 4271  elf_m68k_finish_dynamic_symbol (output_b
4271        while (got_entry != NULL)        while (got_entry != NULL)
4272          {          {
4273            Elf_Internal_Rela rela;            Elf_Internal_Rela rela;
4274            bfd_byte *loc;            bfd_vma got_entry_offset;
4275    
4276              got_entry_offset = got_entry->u.s2.offset &~ (bfd_vma) 1;
4277    
4278            rela.r_offset = (sgot->output_section->vma            rela.r_offset = (sgot->output_section->vma
4279                             + sgot->output_offset                             + sgot->output_offset
4280                             + (got_entry->u.s2.offset &~ (bfd_vma) 1));                             + got_entry_offset);
4281    
4282            /* If this is a -Bsymbolic link, and the symbol is defined            /* If this is a -Bsymbolic link, and the symbol is defined
4283               locally, we just want to emit a RELATIVE reloc.  Likewise if               locally, we just want to emit a RELATIVE reloc.  Likewise if
4284               the symbol was forced to be local because of a version file.               the symbol was forced to be local because of a version file.
4285               The entry in the global offset table will already have been               The entry in the global offset table already have been
4286               initialized in the relocate_section function.  */               initialized in the relocate_section function.  */
4287            if (info->shared            if (info->shared
4288                && SYMBOL_REFERENCES_LOCAL (info, h))                && SYMBOL_REFERENCES_LOCAL (info, h))
4289              {              {
               rela.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);  
4290                rela.r_addend = bfd_get_signed_32 (output_bfd,                rela.r_addend = bfd_get_signed_32 (output_bfd,
4291                                                   (sgot->contents                                                   (sgot->contents
4292                                                    + (got_entry->u.s2.offset                                                    + got_entry_offset));
4293                                                       &~ (bfd_vma) 1)));  
4294                  switch (elf_m68k_reloc_got_type (got_entry->key_.type))
4295                    {
4296                    case R_68K_GOT32O:
4297                      rela.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
4298                      break;
4299    
4300                    case R_68K_TLS_GD32:
4301                      rela.r_info = ELF32_R_INFO (0, R_68K_TLS_DTPMOD32);
4302                      break;
4303    
4304                    case R_68K_TLS_IE32:
4305                      rela.r_info = ELF32_R_INFO (0, R_68K_TLS_TPREL32);
4306                      break;
4307    
4308                    default:
4309                      BFD_ASSERT (FALSE);
4310                      break;
4311                    }
4312    
4313                    elf_m68k_install_rela (output_bfd, srela, &rela);
4314              }              }
4315            else            else
4316              {              {
4317                bfd_put_32 (output_bfd, (bfd_vma) 0,                /* Put zeros to GOT slots that will be initialized
4318                            sgot->contents + (got_entry->u.s2.offset                   at run-time.  */
4319                                              &~ (bfd_vma) 1));                {
4320                rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_GLOB_DAT);                  bfd_vma n_slots;
4321    
4322                    n_slots = elf_m68k_reloc_got_n_slots (got_entry->key_.type);
4323                    while (n_slots--)
4324                      bfd_put_32 (output_bfd, (bfd_vma) 0,
4325                                  (sgot->contents + got_entry_offset
4326                                   + 4 * n_slots));
4327                  }
4328    
4329                rela.r_addend = 0;                rela.r_addend = 0;
             }  
4330    
4331            loc = srela->contents;                switch (elf_m68k_reloc_got_type (got_entry->key_.type))
4332            loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);                  {
4333            bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);                  case R_68K_GOT32O:
4334                      rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_GLOB_DAT);
4335                      elf_m68k_install_rela (output_bfd, srela, &rela);
4336                      break;
4337    
4338                    case R_68K_TLS_GD32:
4339                      rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_TLS_DTPMOD32);
4340                      elf_m68k_install_rela (output_bfd, srela, &rela);
4341    
4342                      rela.r_offset += 4;
4343                      rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_TLS_DTPREL32);
4344                      elf_m68k_install_rela (output_bfd, srela, &rela);
4345                      break;
4346    
4347                    case R_68K_TLS_IE32:
4348                      rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_TLS_TPREL32);
4349                      elf_m68k_install_rela (output_bfd, srela, &rela);
4350                      break;
4351    
4352                    default:
4353                      BFD_ASSERT (FALSE);
4354                      break;
4355                    }
4356                }
4357    
4358            got_entry = got_entry->u.s2.next;            got_entry = got_entry->u.s2.next;
4359          }          }

Legend:
Removed from v.20  
changed lines
  Added in v.21

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26