00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "bfd.h"
00026 #include "sysdep.h"
00027 #include "bfdlink.h"
00028 #include "libbfd.h"
00029 #include "elf-bfd.h"
00030 #include "elf/m68k.h"
00031
00032 static reloc_howto_type *reloc_type_lookup
00033 PARAMS ((bfd *, bfd_reloc_code_real_type));
00034 static void rtype_to_howto
00035 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
00036 static struct bfd_hash_entry *elf_m68k_link_hash_newfunc
00037 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
00038 static struct bfd_link_hash_table *elf_m68k_link_hash_table_create
00039 PARAMS ((bfd *));
00040 static bfd_boolean elf_m68k_check_relocs
00041 PARAMS ((bfd *, struct bfd_link_info *, asection *,
00042 const Elf_Internal_Rela *));
00043 static asection *elf_m68k_gc_mark_hook
00044 PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
00045 struct elf_link_hash_entry *, Elf_Internal_Sym *));
00046 static bfd_boolean elf_m68k_gc_sweep_hook
00047 PARAMS ((bfd *, struct bfd_link_info *, asection *,
00048 const Elf_Internal_Rela *));
00049 static bfd_boolean elf_m68k_adjust_dynamic_symbol
00050 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
00051 static bfd_boolean elf_m68k_size_dynamic_sections
00052 PARAMS ((bfd *, struct bfd_link_info *));
00053 static bfd_boolean elf_m68k_discard_copies
00054 PARAMS ((struct elf_link_hash_entry *, PTR));
00055 static bfd_boolean elf_m68k_relocate_section
00056 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
00057 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
00058 static bfd_boolean elf_m68k_finish_dynamic_symbol
00059 PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
00060 Elf_Internal_Sym *));
00061 static bfd_boolean elf_m68k_finish_dynamic_sections
00062 PARAMS ((bfd *, struct bfd_link_info *));
00063
00064 static bfd_boolean elf32_m68k_set_private_flags
00065 PARAMS ((bfd *, flagword));
00066 static bfd_boolean elf32_m68k_merge_private_bfd_data
00067 PARAMS ((bfd *, bfd *));
00068 static bfd_boolean elf32_m68k_print_private_bfd_data
00069 PARAMS ((bfd *, PTR));
00070 static enum elf_reloc_type_class elf32_m68k_reloc_type_class
00071 PARAMS ((const Elf_Internal_Rela *));
00072
00073 static reloc_howto_type howto_table[] = {
00074 HOWTO(R_68K_NONE, 0, 0, 0, FALSE,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_NONE", FALSE, 0, 0x00000000,FALSE),
00075 HOWTO(R_68K_32, 0, 2,32, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_32", FALSE, 0, 0xffffffff,FALSE),
00076 HOWTO(R_68K_16, 0, 1,16, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_16", FALSE, 0, 0x0000ffff,FALSE),
00077 HOWTO(R_68K_8, 0, 0, 8, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_8", FALSE, 0, 0x000000ff,FALSE),
00078 HOWTO(R_68K_PC32, 0, 2,32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PC32", FALSE, 0, 0xffffffff,TRUE),
00079 HOWTO(R_68K_PC16, 0, 1,16, TRUE, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PC16", FALSE, 0, 0x0000ffff,TRUE),
00080 HOWTO(R_68K_PC8, 0, 0, 8, TRUE, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PC8", FALSE, 0, 0x000000ff,TRUE),
00081 HOWTO(R_68K_GOT32, 0, 2,32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_GOT32", FALSE, 0, 0xffffffff,TRUE),
00082 HOWTO(R_68K_GOT16, 0, 1,16, TRUE, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT16", FALSE, 0, 0x0000ffff,TRUE),
00083 HOWTO(R_68K_GOT8, 0, 0, 8, TRUE, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT8", FALSE, 0, 0x000000ff,TRUE),
00084 HOWTO(R_68K_GOT32O, 0, 2,32, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_GOT32O", FALSE, 0, 0xffffffff,FALSE),
00085 HOWTO(R_68K_GOT16O, 0, 1,16, FALSE,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT16O", FALSE, 0, 0x0000ffff,FALSE),
00086 HOWTO(R_68K_GOT8O, 0, 0, 8, FALSE,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT8O", FALSE, 0, 0x000000ff,FALSE),
00087 HOWTO(R_68K_PLT32, 0, 2,32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PLT32", FALSE, 0, 0xffffffff,TRUE),
00088 HOWTO(R_68K_PLT16, 0, 1,16, TRUE, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT16", FALSE, 0, 0x0000ffff,TRUE),
00089 HOWTO(R_68K_PLT8, 0, 0, 8, TRUE, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT8", FALSE, 0, 0x000000ff,TRUE),
00090 HOWTO(R_68K_PLT32O, 0, 2,32, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PLT32O", FALSE, 0, 0xffffffff,FALSE),
00091 HOWTO(R_68K_PLT16O, 0, 1,16, FALSE,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT16O", FALSE, 0, 0x0000ffff,FALSE),
00092 HOWTO(R_68K_PLT8O, 0, 0, 8, FALSE,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT8O", FALSE, 0, 0x000000ff,FALSE),
00093 HOWTO(R_68K_COPY, 0, 0, 0, FALSE,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_COPY", FALSE, 0, 0xffffffff,FALSE),
00094 HOWTO(R_68K_GLOB_DAT, 0, 2,32, FALSE,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_GLOB_DAT", FALSE, 0, 0xffffffff,FALSE),
00095 HOWTO(R_68K_JMP_SLOT, 0, 2,32, FALSE,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_JMP_SLOT", FALSE, 0, 0xffffffff,FALSE),
00096 HOWTO(R_68K_RELATIVE, 0, 2,32, FALSE,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_RELATIVE", FALSE, 0, 0xffffffff,FALSE),
00097
00098 HOWTO (R_68K_GNU_VTINHERIT,
00099 0,
00100 2,
00101 0,
00102 FALSE,
00103 0,
00104 complain_overflow_dont,
00105 NULL,
00106 "R_68K_GNU_VTINHERIT",
00107 FALSE,
00108 0,
00109 0,
00110 FALSE),
00111
00112 HOWTO (R_68K_GNU_VTENTRY,
00113 0,
00114 2,
00115 0,
00116 FALSE,
00117 0,
00118 complain_overflow_dont,
00119 _bfd_elf_rel_vtable_reloc_fn,
00120 "R_68K_GNU_VTENTRY",
00121 FALSE,
00122 0,
00123 0,
00124 FALSE),
00125 };
00126
00127 static void
00128 rtype_to_howto (abfd, cache_ptr, dst)
00129 bfd *abfd ATTRIBUTE_UNUSED;
00130 arelent *cache_ptr;
00131 Elf_Internal_Rela *dst;
00132 {
00133 BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_68K_max);
00134 cache_ptr->howto = &howto_table[ELF32_R_TYPE(dst->r_info)];
00135 }
00136
00137 #define elf_info_to_howto rtype_to_howto
00138
00139 static const struct
00140 {
00141 bfd_reloc_code_real_type bfd_val;
00142 int elf_val;
00143 } reloc_map[] = {
00144 { BFD_RELOC_NONE, R_68K_NONE },
00145 { BFD_RELOC_32, R_68K_32 },
00146 { BFD_RELOC_16, R_68K_16 },
00147 { BFD_RELOC_8, R_68K_8 },
00148 { BFD_RELOC_32_PCREL, R_68K_PC32 },
00149 { BFD_RELOC_16_PCREL, R_68K_PC16 },
00150 { BFD_RELOC_8_PCREL, R_68K_PC8 },
00151 { BFD_RELOC_32_GOT_PCREL, R_68K_GOT32 },
00152 { BFD_RELOC_16_GOT_PCREL, R_68K_GOT16 },
00153 { BFD_RELOC_8_GOT_PCREL, R_68K_GOT8 },
00154 { BFD_RELOC_32_GOTOFF, R_68K_GOT32O },
00155 { BFD_RELOC_16_GOTOFF, R_68K_GOT16O },
00156 { BFD_RELOC_8_GOTOFF, R_68K_GOT8O },
00157 { BFD_RELOC_32_PLT_PCREL, R_68K_PLT32 },
00158 { BFD_RELOC_16_PLT_PCREL, R_68K_PLT16 },
00159 { BFD_RELOC_8_PLT_PCREL, R_68K_PLT8 },
00160 { BFD_RELOC_32_PLTOFF, R_68K_PLT32O },
00161 { BFD_RELOC_16_PLTOFF, R_68K_PLT16O },
00162 { BFD_RELOC_8_PLTOFF, R_68K_PLT8O },
00163 { BFD_RELOC_NONE, R_68K_COPY },
00164 { BFD_RELOC_68K_GLOB_DAT, R_68K_GLOB_DAT },
00165 { BFD_RELOC_68K_JMP_SLOT, R_68K_JMP_SLOT },
00166 { BFD_RELOC_68K_RELATIVE, R_68K_RELATIVE },
00167 { BFD_RELOC_CTOR, R_68K_32 },
00168 { BFD_RELOC_VTABLE_INHERIT, R_68K_GNU_VTINHERIT },
00169 { BFD_RELOC_VTABLE_ENTRY, R_68K_GNU_VTENTRY },
00170 };
00171
00172 static reloc_howto_type *
00173 reloc_type_lookup (abfd, code)
00174 bfd *abfd ATTRIBUTE_UNUSED;
00175 bfd_reloc_code_real_type code;
00176 {
00177 unsigned int i;
00178 for (i = 0; i < sizeof (reloc_map) / sizeof (reloc_map[0]); i++)
00179 {
00180 if (reloc_map[i].bfd_val == code)
00181 return &howto_table[reloc_map[i].elf_val];
00182 }
00183 return 0;
00184 }
00185
00186 #define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup
00187 #define ELF_ARCH bfd_arch_m68k
00188
00189
00190
00191
00192
00193
00194 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
00195
00196
00197
00198 #define PLT_ENTRY_SIZE 20
00199
00200
00201
00202
00203 static const bfd_byte elf_m68k_plt0_entry[PLT_ENTRY_SIZE] =
00204 {
00205 0x2f, 0x3b, 0x01, 0x70,
00206 0, 0, 0, 0,
00207 0x4e, 0xfb, 0x01, 0x71,
00208 0, 0, 0, 0,
00209 0, 0, 0, 0
00210 };
00211
00212
00213
00214 static const bfd_byte elf_m68k_plt_entry[PLT_ENTRY_SIZE] =
00215 {
00216 0x4e, 0xfb, 0x01, 0x71,
00217 0, 0, 0, 0,
00218 0x2f, 0x3c,
00219 0, 0, 0, 0,
00220 0x60, 0xff,
00221 0, 0, 0, 0
00222 };
00223
00224 #define CPU32_FLAG(abfd) (elf_elfheader (abfd)->e_flags & EF_CPU32)
00225
00226 #define PLT_CPU32_ENTRY_SIZE 24
00227
00228 static const bfd_byte elf_cpu32_plt0_entry[PLT_CPU32_ENTRY_SIZE] =
00229 {
00230 0x2f, 0x3b, 0x01, 0x70,
00231 0, 0, 0, 0,
00232 0x22, 0x7b, 0x01, 0x70,
00233 0, 0, 0, 0,
00234 0x4e, 0xd1,
00235 0, 0, 0, 0,
00236 0, 0
00237 };
00238
00239 static const bfd_byte elf_cpu32_plt_entry[PLT_CPU32_ENTRY_SIZE] =
00240 {
00241 0x22, 0x7b, 0x01, 0x70,
00242 0, 0, 0, 0,
00243 0x4e, 0xd1,
00244 0x2f, 0x3c,
00245 0, 0, 0, 0,
00246 0x60, 0xff,
00247 0, 0, 0, 0,
00248 0, 0
00249 };
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 struct elf_m68k_pcrel_relocs_copied
00261 {
00262
00263 struct elf_m68k_pcrel_relocs_copied *next;
00264
00265 asection *section;
00266
00267 bfd_size_type count;
00268 };
00269
00270
00271
00272 struct elf_m68k_link_hash_entry
00273 {
00274 struct elf_link_hash_entry root;
00275
00276
00277 struct elf_m68k_pcrel_relocs_copied *pcrel_relocs_copied;
00278 };
00279
00280 #define elf_m68k_hash_entry(ent) ((struct elf_m68k_link_hash_entry *) (ent))
00281
00282
00283
00284 struct elf_m68k_link_hash_table
00285 {
00286 struct elf_link_hash_table root;
00287
00288
00289 struct sym_sec_cache sym_sec;
00290 };
00291
00292
00293
00294 #define elf_m68k_hash_table(p) \
00295 ((struct elf_m68k_link_hash_table *) (p)->hash)
00296
00297
00298
00299 static struct bfd_hash_entry *
00300 elf_m68k_link_hash_newfunc (entry, table, string)
00301 struct bfd_hash_entry *entry;
00302 struct bfd_hash_table *table;
00303 const char *string;
00304 {
00305 struct bfd_hash_entry *ret = entry;
00306
00307
00308
00309 if (ret == NULL)
00310 ret = bfd_hash_allocate (table,
00311 sizeof (struct elf_m68k_link_hash_entry));
00312 if (ret == NULL)
00313 return ret;
00314
00315
00316 ret = _bfd_elf_link_hash_newfunc (ret, table, string);
00317 if (ret != NULL)
00318 elf_m68k_hash_entry (ret)->pcrel_relocs_copied = NULL;
00319
00320 return ret;
00321 }
00322
00323
00324
00325 static struct bfd_link_hash_table *
00326 elf_m68k_link_hash_table_create (abfd)
00327 bfd *abfd;
00328 {
00329 struct elf_m68k_link_hash_table *ret;
00330 bfd_size_type amt = sizeof (struct elf_m68k_link_hash_table);
00331
00332 ret = (struct elf_m68k_link_hash_table *) bfd_malloc (amt);
00333 if (ret == (struct elf_m68k_link_hash_table *) NULL)
00334 return NULL;
00335
00336 if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
00337 elf_m68k_link_hash_newfunc))
00338 {
00339 free (ret);
00340 return NULL;
00341 }
00342
00343 ret->sym_sec.abfd = NULL;
00344
00345 return &ret->root.root;
00346 }
00347
00348
00349 static bfd_boolean
00350 elf32_m68k_set_private_flags (abfd, flags)
00351 bfd *abfd;
00352 flagword flags;
00353 {
00354 elf_elfheader (abfd)->e_flags = flags;
00355 elf_flags_init (abfd) = TRUE;
00356 return TRUE;
00357 }
00358
00359
00360
00361 static bfd_boolean
00362 elf32_m68k_merge_private_bfd_data (ibfd, obfd)
00363 bfd *ibfd;
00364 bfd *obfd;
00365 {
00366 flagword out_flags;
00367 flagword in_flags;
00368
00369 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
00370 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
00371 return TRUE;
00372
00373 in_flags = elf_elfheader (ibfd)->e_flags;
00374 out_flags = elf_elfheader (obfd)->e_flags;
00375
00376 if (!elf_flags_init (obfd))
00377 {
00378 elf_flags_init (obfd) = TRUE;
00379 elf_elfheader (obfd)->e_flags = in_flags;
00380 }
00381
00382 return TRUE;
00383 }
00384
00385
00386 static bfd_boolean
00387 elf32_m68k_print_private_bfd_data (abfd, ptr)
00388 bfd *abfd;
00389 PTR ptr;
00390 {
00391 FILE *file = (FILE *) ptr;
00392
00393 BFD_ASSERT (abfd != NULL && ptr != NULL);
00394
00395
00396 _bfd_elf_print_private_bfd_data (abfd, ptr);
00397
00398
00399
00400
00401 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
00402
00403 if (elf_elfheader (abfd)->e_flags & EF_CPU32)
00404 fprintf (file, _(" [cpu32]"));
00405
00406 if (elf_elfheader (abfd)->e_flags & EF_M68000)
00407 fprintf (file, _(" [m68000]"));
00408
00409 fputc ('\n', file);
00410
00411 return TRUE;
00412 }
00413
00414
00415
00416
00417 static bfd_boolean
00418 elf_m68k_check_relocs (abfd, info, sec, relocs)
00419 bfd *abfd;
00420 struct bfd_link_info *info;
00421 asection *sec;
00422 const Elf_Internal_Rela *relocs;
00423 {
00424 bfd *dynobj;
00425 Elf_Internal_Shdr *symtab_hdr;
00426 struct elf_link_hash_entry **sym_hashes;
00427 bfd_signed_vma *local_got_refcounts;
00428 const Elf_Internal_Rela *rel;
00429 const Elf_Internal_Rela *rel_end;
00430 asection *sgot;
00431 asection *srelgot;
00432 asection *sreloc;
00433
00434 if (info->relocatable)
00435 return TRUE;
00436
00437 dynobj = elf_hash_table (info)->dynobj;
00438 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
00439 sym_hashes = elf_sym_hashes (abfd);
00440 local_got_refcounts = elf_local_got_refcounts (abfd);
00441
00442 sgot = NULL;
00443 srelgot = NULL;
00444 sreloc = NULL;
00445
00446 rel_end = relocs + sec->reloc_count;
00447 for (rel = relocs; rel < rel_end; rel++)
00448 {
00449 unsigned long r_symndx;
00450 struct elf_link_hash_entry *h;
00451
00452 r_symndx = ELF32_R_SYM (rel->r_info);
00453
00454 if (r_symndx < symtab_hdr->sh_info)
00455 h = NULL;
00456 else
00457 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
00458
00459 switch (ELF32_R_TYPE (rel->r_info))
00460 {
00461 case R_68K_GOT8:
00462 case R_68K_GOT16:
00463 case R_68K_GOT32:
00464 if (h != NULL
00465 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
00466 break;
00467
00468 case R_68K_GOT8O:
00469 case R_68K_GOT16O:
00470 case R_68K_GOT32O:
00471
00472
00473 if (dynobj == NULL)
00474 {
00475
00476 elf_hash_table (info)->dynobj = dynobj = abfd;
00477 if (!_bfd_elf_create_got_section (dynobj, info))
00478 return FALSE;
00479 }
00480
00481 if (sgot == NULL)
00482 {
00483 sgot = bfd_get_section_by_name (dynobj, ".got");
00484 BFD_ASSERT (sgot != NULL);
00485 }
00486
00487 if (srelgot == NULL
00488 && (h != NULL || info->shared))
00489 {
00490 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
00491 if (srelgot == NULL)
00492 {
00493 srelgot = bfd_make_section (dynobj, ".rela.got");
00494 if (srelgot == NULL
00495 || !bfd_set_section_flags (dynobj, srelgot,
00496 (SEC_ALLOC
00497 | SEC_LOAD
00498 | SEC_HAS_CONTENTS
00499 | SEC_IN_MEMORY
00500 | SEC_LINKER_CREATED
00501 | SEC_READONLY))
00502 || !bfd_set_section_alignment (dynobj, srelgot, 2))
00503 return FALSE;
00504 }
00505 }
00506
00507 if (h != NULL)
00508 {
00509 if (h->got.refcount == 0)
00510 {
00511
00512 if (h->dynindx == -1
00513 && !h->forced_local)
00514 {
00515 if (!bfd_elf_link_record_dynamic_symbol (info, h))
00516 return FALSE;
00517 }
00518
00519
00520 sgot->size += 4;
00521
00522 srelgot->size += sizeof (Elf32_External_Rela);
00523 }
00524 h->got.refcount++;
00525 }
00526 else
00527 {
00528
00529 if (local_got_refcounts == NULL)
00530 {
00531 bfd_size_type size;
00532
00533 size = symtab_hdr->sh_info;
00534 size *= sizeof (bfd_signed_vma);
00535 local_got_refcounts = ((bfd_signed_vma *)
00536 bfd_zalloc (abfd, size));
00537 if (local_got_refcounts == NULL)
00538 return FALSE;
00539 elf_local_got_refcounts (abfd) = local_got_refcounts;
00540 }
00541 if (local_got_refcounts[r_symndx] == 0)
00542 {
00543 sgot->size += 4;
00544 if (info->shared)
00545 {
00546
00547
00548
00549 srelgot->size += sizeof (Elf32_External_Rela);
00550 }
00551 }
00552 local_got_refcounts[r_symndx]++;
00553 }
00554 break;
00555
00556 case R_68K_PLT8:
00557 case R_68K_PLT16:
00558 case R_68K_PLT32:
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568 if (h == NULL)
00569 continue;
00570
00571 h->needs_plt = 1;
00572 h->plt.refcount++;
00573 break;
00574
00575 case R_68K_PLT8O:
00576 case R_68K_PLT16O:
00577 case R_68K_PLT32O:
00578
00579
00580 if (h == NULL)
00581 {
00582
00583
00584
00585 bfd_set_error (bfd_error_bad_value);
00586 return FALSE;
00587 }
00588
00589
00590 if (h->dynindx == -1
00591 && !h->forced_local)
00592 {
00593 if (!bfd_elf_link_record_dynamic_symbol (info, h))
00594 return FALSE;
00595 }
00596
00597 h->needs_plt = 1;
00598 h->plt.refcount++;
00599 break;
00600
00601 case R_68K_PC8:
00602 case R_68K_PC16:
00603 case R_68K_PC32:
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614 if (!(info->shared
00615 && (sec->flags & SEC_ALLOC) != 0
00616 && h != NULL
00617 && (!info->symbolic
00618 || h->root.type == bfd_link_hash_defweak
00619 || !h->def_regular)))
00620 {
00621 if (h != NULL)
00622 {
00623
00624
00625
00626 h->plt.refcount++;
00627 }
00628 break;
00629 }
00630
00631 case R_68K_8:
00632 case R_68K_16:
00633 case R_68K_32:
00634 if (h != NULL)
00635 {
00636
00637
00638 h->plt.refcount++;
00639 }
00640
00641
00642
00643 if (info->shared
00644 && (sec->flags & SEC_ALLOC) != 0)
00645 {
00646
00647
00648
00649 if (sreloc == NULL)
00650 {
00651 const char *name;
00652
00653 name = (bfd_elf_string_from_elf_section
00654 (abfd,
00655 elf_elfheader (abfd)->e_shstrndx,
00656 elf_section_data (sec)->rel_hdr.sh_name));
00657 if (name == NULL)
00658 return FALSE;
00659
00660 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
00661 && strcmp (bfd_get_section_name (abfd, sec),
00662 name + 5) == 0);
00663
00664 sreloc = bfd_get_section_by_name (dynobj, name);
00665 if (sreloc == NULL)
00666 {
00667 sreloc = bfd_make_section (dynobj, name);
00668 if (sreloc == NULL
00669 || !bfd_set_section_flags (dynobj, sreloc,
00670 (SEC_ALLOC
00671 | SEC_LOAD
00672 | SEC_HAS_CONTENTS
00673 | SEC_IN_MEMORY
00674 | SEC_LINKER_CREATED
00675 | SEC_READONLY))
00676 || !bfd_set_section_alignment (dynobj, sreloc, 2))
00677 return FALSE;
00678 }
00679 elf_section_data (sec)->sreloc = sreloc;
00680 }
00681
00682 if (sec->flags & SEC_READONLY
00683
00684
00685 && !(ELF32_R_TYPE (rel->r_info) == R_68K_PC8
00686 || ELF32_R_TYPE (rel->r_info) == R_68K_PC16
00687 || ELF32_R_TYPE (rel->r_info) == R_68K_PC32))
00688 info->flags |= DF_TEXTREL;
00689
00690 sreloc->size += sizeof (Elf32_External_Rela);
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700 if (ELF32_R_TYPE (rel->r_info) == R_68K_PC8
00701 || ELF32_R_TYPE (rel->r_info) == R_68K_PC16
00702 || ELF32_R_TYPE (rel->r_info) == R_68K_PC32)
00703 {
00704 struct elf_m68k_pcrel_relocs_copied *p;
00705 struct elf_m68k_pcrel_relocs_copied **head;
00706
00707 if (h != NULL)
00708 {
00709 struct elf_m68k_link_hash_entry *eh
00710 = elf_m68k_hash_entry (h);
00711 head = &eh->pcrel_relocs_copied;
00712 }
00713 else
00714 {
00715 asection *s;
00716 s = (bfd_section_from_r_symndx
00717 (abfd, &elf_m68k_hash_table (info)->sym_sec,
00718 sec, r_symndx));
00719 if (s == NULL)
00720 return FALSE;
00721
00722 head = ((struct elf_m68k_pcrel_relocs_copied **)
00723 &elf_section_data (s)->local_dynrel);
00724 }
00725
00726 for (p = *head; p != NULL; p = p->next)
00727 if (p->section == sreloc)
00728 break;
00729
00730 if (p == NULL)
00731 {
00732 p = ((struct elf_m68k_pcrel_relocs_copied *)
00733 bfd_alloc (dynobj, (bfd_size_type) sizeof *p));
00734 if (p == NULL)
00735 return FALSE;
00736 p->next = *head;
00737 *head = p;
00738 p->section = sreloc;
00739 p->count = 0;
00740 }
00741
00742 ++p->count;
00743 }
00744 }
00745
00746 break;
00747
00748
00749
00750 case R_68K_GNU_VTINHERIT:
00751 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
00752 return FALSE;
00753 break;
00754
00755
00756
00757 case R_68K_GNU_VTENTRY:
00758 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
00759 return FALSE;
00760 break;
00761
00762 default:
00763 break;
00764 }
00765 }
00766
00767 return TRUE;
00768 }
00769
00770
00771
00772
00773 static asection *
00774 elf_m68k_gc_mark_hook (sec, info, rel, h, sym)
00775 asection *sec;
00776 struct bfd_link_info *info ATTRIBUTE_UNUSED;
00777 Elf_Internal_Rela *rel;
00778 struct elf_link_hash_entry *h;
00779 Elf_Internal_Sym *sym;
00780 {
00781 if (h != NULL)
00782 {
00783 switch (ELF32_R_TYPE (rel->r_info))
00784 {
00785 case R_68K_GNU_VTINHERIT:
00786 case R_68K_GNU_VTENTRY:
00787 break;
00788
00789 default:
00790 switch (h->root.type)
00791 {
00792 default:
00793 break;
00794
00795 case bfd_link_hash_defined:
00796 case bfd_link_hash_defweak:
00797 return h->root.u.def.section;
00798
00799 case bfd_link_hash_common:
00800 return h->root.u.c.p->section;
00801 }
00802 }
00803 }
00804 else
00805 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
00806
00807 return NULL;
00808 }
00809
00810
00811
00812 static bfd_boolean
00813 elf_m68k_gc_sweep_hook (abfd, info, sec, relocs)
00814 bfd *abfd;
00815 struct bfd_link_info *info;
00816 asection *sec;
00817 const Elf_Internal_Rela *relocs;
00818 {
00819 Elf_Internal_Shdr *symtab_hdr;
00820 struct elf_link_hash_entry **sym_hashes;
00821 bfd_signed_vma *local_got_refcounts;
00822 const Elf_Internal_Rela *rel, *relend;
00823 bfd *dynobj;
00824 asection *sgot;
00825 asection *srelgot;
00826
00827 dynobj = elf_hash_table (info)->dynobj;
00828 if (dynobj == NULL)
00829 return TRUE;
00830
00831 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
00832 sym_hashes = elf_sym_hashes (abfd);
00833 local_got_refcounts = elf_local_got_refcounts (abfd);
00834
00835 sgot = bfd_get_section_by_name (dynobj, ".got");
00836 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
00837
00838 relend = relocs + sec->reloc_count;
00839 for (rel = relocs; rel < relend; rel++)
00840 {
00841 unsigned long r_symndx;
00842 struct elf_link_hash_entry *h = NULL;
00843
00844 r_symndx = ELF32_R_SYM (rel->r_info);
00845 if (r_symndx >= symtab_hdr->sh_info)
00846 {
00847 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
00848 while (h->root.type == bfd_link_hash_indirect
00849 || h->root.type == bfd_link_hash_warning)
00850 h = (struct elf_link_hash_entry *) h->root.u.i.link;
00851 }
00852
00853 switch (ELF32_R_TYPE (rel->r_info))
00854 {
00855 case R_68K_GOT8:
00856 case R_68K_GOT16:
00857 case R_68K_GOT32:
00858 case R_68K_GOT8O:
00859 case R_68K_GOT16O:
00860 case R_68K_GOT32O:
00861 if (h != NULL)
00862 {
00863 if (h->got.refcount > 0)
00864 {
00865 --h->got.refcount;
00866 if (h->got.refcount == 0)
00867 {
00868
00869 sgot->size -= 4;
00870 srelgot->size -= sizeof (Elf32_External_Rela);
00871 }
00872 }
00873 }
00874 else if (local_got_refcounts != NULL)
00875 {
00876 if (local_got_refcounts[r_symndx] > 0)
00877 {
00878 --local_got_refcounts[r_symndx];
00879 if (local_got_refcounts[r_symndx] == 0)
00880 {
00881
00882 sgot->size -= 4;
00883 if (info->shared)
00884 srelgot->size -= sizeof (Elf32_External_Rela);
00885 }
00886 }
00887 }
00888 break;
00889
00890 case R_68K_PLT8:
00891 case R_68K_PLT16:
00892 case R_68K_PLT32:
00893 case R_68K_PLT8O:
00894 case R_68K_PLT16O:
00895 case R_68K_PLT32O:
00896 case R_68K_PC8:
00897 case R_68K_PC16:
00898 case R_68K_PC32:
00899 case R_68K_8:
00900 case R_68K_16:
00901 case R_68K_32:
00902 if (h != NULL)
00903 {
00904 if (h->plt.refcount > 0)
00905 --h->plt.refcount;
00906 }
00907 break;
00908
00909 default:
00910 break;
00911 }
00912 }
00913
00914 return TRUE;
00915 }
00916
00917
00918
00919
00920
00921
00922
00923 static bfd_boolean
00924 elf_m68k_adjust_dynamic_symbol (info, h)
00925 struct bfd_link_info *info;
00926 struct elf_link_hash_entry *h;
00927 {
00928 bfd *dynobj;
00929 asection *s;
00930 unsigned int power_of_two;
00931
00932 dynobj = elf_hash_table (info)->dynobj;
00933
00934
00935 BFD_ASSERT (dynobj != NULL
00936 && (h->needs_plt
00937 || h->u.weakdef != NULL
00938 || (h->def_dynamic
00939 && h->ref_regular
00940 && !h->def_regular)));
00941
00942
00943
00944
00945 if (h->type == STT_FUNC
00946 || h->needs_plt)
00947 {
00948 if ((h->plt.refcount <= 0
00949 || SYMBOL_CALLS_LOCAL (info, h)
00950 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
00951 && h->root.type == bfd_link_hash_undefweak))
00952
00953
00954
00955 && h->dynindx == -1)
00956 {
00957
00958
00959
00960
00961
00962 h->plt.offset = (bfd_vma) -1;
00963 h->needs_plt = 0;
00964 return TRUE;
00965 }
00966
00967
00968 if (h->dynindx == -1
00969 && !h->forced_local)
00970 {
00971 if (! bfd_elf_link_record_dynamic_symbol (info, h))
00972 return FALSE;
00973 }
00974
00975 s = bfd_get_section_by_name (dynobj, ".plt");
00976 BFD_ASSERT (s != NULL);
00977
00978
00979
00980 if (s->size == 0)
00981 {
00982 if (CPU32_FLAG (dynobj))
00983 s->size += PLT_CPU32_ENTRY_SIZE;
00984 else
00985 s->size += PLT_ENTRY_SIZE;
00986 }
00987
00988
00989
00990
00991
00992
00993 if (!info->shared
00994 && !h->def_regular)
00995 {
00996 h->root.u.def.section = s;
00997 h->root.u.def.value = s->size;
00998 }
00999
01000 h->plt.offset = s->size;
01001
01002
01003 if (CPU32_FLAG (dynobj))
01004 s->size += PLT_CPU32_ENTRY_SIZE;
01005 else
01006 s->size += PLT_ENTRY_SIZE;
01007
01008
01009
01010 s = bfd_get_section_by_name (dynobj, ".got.plt");
01011 BFD_ASSERT (s != NULL);
01012 s->size += 4;
01013
01014
01015 s = bfd_get_section_by_name (dynobj, ".rela.plt");
01016 BFD_ASSERT (s != NULL);
01017 s->size += sizeof (Elf32_External_Rela);
01018
01019 return TRUE;
01020 }
01021
01022
01023
01024 h->plt.offset = (bfd_vma) -1;
01025
01026
01027
01028
01029 if (h->u.weakdef != NULL)
01030 {
01031 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
01032 || h->u.weakdef->root.type == bfd_link_hash_defweak);
01033 h->root.u.def.section = h->u.weakdef->root.u.def.section;
01034 h->root.u.def.value = h->u.weakdef->root.u.def.value;
01035 return TRUE;
01036 }
01037
01038
01039
01040
01041
01042
01043
01044
01045 if (info->shared)
01046 return TRUE;
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058 s = bfd_get_section_by_name (dynobj, ".dynbss");
01059 BFD_ASSERT (s != NULL);
01060
01061
01062
01063
01064
01065 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
01066 {
01067 asection *srel;
01068
01069 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
01070 BFD_ASSERT (srel != NULL);
01071 srel->size += sizeof (Elf32_External_Rela);
01072 h->needs_copy = 1;
01073 }
01074
01075
01076
01077 power_of_two = bfd_log2 (h->size);
01078 if (power_of_two > 3)
01079 power_of_two = 3;
01080
01081
01082 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
01083 if (power_of_two > bfd_get_section_alignment (dynobj, s))
01084 {
01085 if (!bfd_set_section_alignment (dynobj, s, power_of_two))
01086 return FALSE;
01087 }
01088
01089
01090 h->root.u.def.section = s;
01091 h->root.u.def.value = s->size;
01092
01093
01094 s->size += h->size;
01095
01096 return TRUE;
01097 }
01098
01099
01100
01101 static bfd_boolean
01102 elf_m68k_size_dynamic_sections (output_bfd, info)
01103 bfd *output_bfd ATTRIBUTE_UNUSED;
01104 struct bfd_link_info *info;
01105 {
01106 bfd *dynobj;
01107 asection *s;
01108 bfd_boolean plt;
01109 bfd_boolean relocs;
01110
01111 dynobj = elf_hash_table (info)->dynobj;
01112 BFD_ASSERT (dynobj != NULL);
01113
01114 if (elf_hash_table (info)->dynamic_sections_created)
01115 {
01116
01117 if (info->executable)
01118 {
01119 s = bfd_get_section_by_name (dynobj, ".interp");
01120 BFD_ASSERT (s != NULL);
01121 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
01122 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
01123 }
01124 }
01125 else
01126 {
01127
01128
01129
01130
01131
01132 s = bfd_get_section_by_name (dynobj, ".rela.got");
01133 if (s != NULL)
01134 s->size = 0;
01135 }
01136
01137
01138
01139
01140
01141
01142
01143 if (info->shared)
01144 elf_link_hash_traverse (elf_hash_table (info),
01145 elf_m68k_discard_copies,
01146 (PTR) info);
01147
01148
01149
01150
01151 plt = FALSE;
01152 relocs = FALSE;
01153 for (s = dynobj->sections; s != NULL; s = s->next)
01154 {
01155 const char *name;
01156 bfd_boolean strip;
01157
01158 if ((s->flags & SEC_LINKER_CREATED) == 0)
01159 continue;
01160
01161
01162
01163 name = bfd_get_section_name (dynobj, s);
01164
01165 strip = FALSE;
01166
01167 if (strcmp (name, ".plt") == 0)
01168 {
01169 if (s->size == 0)
01170 {
01171
01172
01173 strip = TRUE;
01174 }
01175 else
01176 {
01177
01178 plt = TRUE;
01179 }
01180 }
01181 else if (strncmp (name, ".rela", 5) == 0)
01182 {
01183 if (s->size == 0)
01184 {
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194 strip = TRUE;
01195 }
01196 else
01197 {
01198 relocs = TRUE;
01199
01200
01201
01202 s->reloc_count = 0;
01203 }
01204 }
01205 else if (strncmp (name, ".got", 4) != 0)
01206 {
01207
01208 continue;
01209 }
01210
01211 if (strip)
01212 {
01213 _bfd_strip_section_from_output (info, s);
01214 continue;
01215 }
01216
01217
01218
01219
01220
01221
01222
01223 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
01224 if (s->contents == NULL && s->size != 0)
01225 return FALSE;
01226 }
01227
01228 if (elf_hash_table (info)->dynamic_sections_created)
01229 {
01230
01231
01232
01233
01234
01235 #define add_dynamic_entry(TAG, VAL) \
01236 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
01237
01238 if (!info->shared)
01239 {
01240 if (!add_dynamic_entry (DT_DEBUG, 0))
01241 return FALSE;
01242 }
01243
01244 if (plt)
01245 {
01246 if (!add_dynamic_entry (DT_PLTGOT, 0)
01247 || !add_dynamic_entry (DT_PLTRELSZ, 0)
01248 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
01249 || !add_dynamic_entry (DT_JMPREL, 0))
01250 return FALSE;
01251 }
01252
01253 if (relocs)
01254 {
01255 if (!add_dynamic_entry (DT_RELA, 0)
01256 || !add_dynamic_entry (DT_RELASZ, 0)
01257 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
01258 return FALSE;
01259 }
01260
01261 if ((info->flags & DF_TEXTREL) != 0)
01262 {
01263 if (!add_dynamic_entry (DT_TEXTREL, 0))
01264 return FALSE;
01265 }
01266 }
01267 #undef add_dynamic_entry
01268
01269 return TRUE;
01270 }
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285 static bfd_boolean
01286 elf_m68k_discard_copies (h, inf)
01287 struct elf_link_hash_entry *h;
01288 PTR inf;
01289 {
01290 struct bfd_link_info *info = (struct bfd_link_info *) inf;
01291 struct elf_m68k_pcrel_relocs_copied *s;
01292
01293 if (h->root.type == bfd_link_hash_warning)
01294 h = (struct elf_link_hash_entry *) h->root.u.i.link;
01295
01296 if (!h->def_regular
01297 || (!info->symbolic
01298 && !h->forced_local))
01299 {
01300 if ((info->flags & DF_TEXTREL) == 0)
01301 {
01302
01303 for (s = elf_m68k_hash_entry (h)->pcrel_relocs_copied;
01304 s != NULL;
01305 s = s->next)
01306 if ((s->section->flags & SEC_READONLY) != 0)
01307 {
01308 info->flags |= DF_TEXTREL;
01309 break;
01310 }
01311 }
01312
01313 return TRUE;
01314 }
01315
01316 for (s = elf_m68k_hash_entry (h)->pcrel_relocs_copied;
01317 s != NULL;
01318 s = s->next)
01319 s->section->size -= s->count * sizeof (Elf32_External_Rela);
01320
01321 return TRUE;
01322 }
01323
01324
01325
01326 static bfd_boolean
01327 elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
01328 contents, relocs, local_syms, local_sections)
01329 bfd *output_bfd;
01330 struct bfd_link_info *info;
01331 bfd *input_bfd;
01332 asection *input_section;
01333 bfd_byte *contents;
01334 Elf_Internal_Rela *relocs;
01335 Elf_Internal_Sym *local_syms;
01336 asection **local_sections;
01337 {
01338 bfd *dynobj;
01339 Elf_Internal_Shdr *symtab_hdr;
01340 struct elf_link_hash_entry **sym_hashes;
01341 bfd_vma *local_got_offsets;
01342 asection *sgot;
01343 asection *splt;
01344 asection *sreloc;
01345 Elf_Internal_Rela *rel;
01346 Elf_Internal_Rela *relend;
01347
01348 if (info->relocatable)
01349 return TRUE;
01350
01351 dynobj = elf_hash_table (info)->dynobj;
01352 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
01353 sym_hashes = elf_sym_hashes (input_bfd);
01354 local_got_offsets = elf_local_got_offsets (input_bfd);
01355
01356 sgot = NULL;
01357 splt = NULL;
01358 sreloc = NULL;
01359
01360 rel = relocs;
01361 relend = relocs + input_section->reloc_count;
01362 for (; rel < relend; rel++)
01363 {
01364 int r_type;
01365 reloc_howto_type *howto;
01366 unsigned long r_symndx;
01367 struct elf_link_hash_entry *h;
01368 Elf_Internal_Sym *sym;
01369 asection *sec;
01370 bfd_vma relocation;
01371 bfd_boolean unresolved_reloc;
01372 bfd_reloc_status_type r;
01373
01374 r_type = ELF32_R_TYPE (rel->r_info);
01375 if (r_type < 0 || r_type >= (int) R_68K_max)
01376 {
01377 bfd_set_error (bfd_error_bad_value);
01378 return FALSE;
01379 }
01380 howto = howto_table + r_type;
01381
01382 r_symndx = ELF32_R_SYM (rel->r_info);
01383
01384 h = NULL;
01385 sym = NULL;
01386 sec = NULL;
01387 unresolved_reloc = FALSE;
01388
01389 if (r_symndx < symtab_hdr->sh_info)
01390 {
01391 sym = local_syms + r_symndx;
01392 sec = local_sections[r_symndx];
01393 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
01394 }
01395 else
01396 {
01397 bfd_boolean warned;
01398
01399 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
01400 r_symndx, symtab_hdr, sym_hashes,
01401 h, sec, relocation,
01402 unresolved_reloc, warned);
01403 }
01404
01405 switch (r_type)
01406 {
01407 case R_68K_GOT8:
01408 case R_68K_GOT16:
01409 case R_68K_GOT32:
01410
01411
01412 if (h != NULL
01413 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
01414 break;
01415
01416 case R_68K_GOT8O:
01417 case R_68K_GOT16O:
01418 case R_68K_GOT32O:
01419
01420
01421
01422 {
01423 bfd_vma off;
01424
01425 if (sgot == NULL)
01426 {
01427 sgot = bfd_get_section_by_name (dynobj, ".got");
01428 BFD_ASSERT (sgot != NULL);
01429 }
01430
01431 if (h != NULL)
01432 {
01433 bfd_boolean dyn;
01434
01435 off = h->got.offset;
01436 BFD_ASSERT (off != (bfd_vma) -1);
01437
01438 dyn = elf_hash_table (info)->dynamic_sections_created;
01439 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
01440 || (info->shared
01441 && (info->symbolic
01442 || h->dynindx == -1
01443 || h->forced_local)
01444 && h->def_regular))
01445 {
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458 if ((off & 1) != 0)
01459 off &= ~1;
01460 else
01461 {
01462 bfd_put_32 (output_bfd, relocation,
01463 sgot->contents + off);
01464 h->got.offset |= 1;
01465 }
01466 }
01467 else
01468 unresolved_reloc = FALSE;
01469 }
01470 else
01471 {
01472 BFD_ASSERT (local_got_offsets != NULL
01473 && local_got_offsets[r_symndx] != (bfd_vma) -1);
01474
01475 off = local_got_offsets[r_symndx];
01476
01477
01478
01479
01480 if ((off & 1) != 0)
01481 off &= ~1;
01482 else
01483 {
01484 bfd_put_32 (output_bfd, relocation, sgot->contents + off);
01485
01486 if (info->shared)
01487 {
01488 asection *s;
01489 Elf_Internal_Rela outrel;
01490 bfd_byte *loc;
01491
01492 s = bfd_get_section_by_name (dynobj, ".rela.got");
01493 BFD_ASSERT (s != NULL);
01494
01495 outrel.r_offset = (sgot->output_section->vma
01496 + sgot->output_offset
01497 + off);
01498 outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
01499 outrel.r_addend = relocation;
01500 loc = s->contents;
01501 loc += s->reloc_count++ * sizeof (Elf32_External_Rela);
01502 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
01503 }
01504
01505 local_got_offsets[r_symndx] |= 1;
01506 }
01507 }
01508
01509 relocation = sgot->output_offset + off;
01510 if (r_type == R_68K_GOT8O
01511 || r_type == R_68K_GOT16O
01512 || r_type == R_68K_GOT32O)
01513 {
01514
01515 rel->r_addend = 0;
01516 }
01517 else
01518 relocation += sgot->output_section->vma;
01519 }
01520 break;
01521
01522 case R_68K_PLT8:
01523 case R_68K_PLT16:
01524 case R_68K_PLT32:
01525
01526
01527
01528
01529
01530 if (h == NULL)
01531 break;
01532
01533 if (h->plt.offset == (bfd_vma) -1
01534 || !elf_hash_table (info)->dynamic_sections_created)
01535 {
01536
01537
01538
01539 break;
01540 }
01541
01542 if (splt == NULL)
01543 {
01544 splt = bfd_get_section_by_name (dynobj, ".plt");
01545 BFD_ASSERT (splt != NULL);
01546 }
01547
01548 relocation = (splt->output_section->vma
01549 + splt->output_offset
01550 + h->plt.offset);
01551 unresolved_reloc = FALSE;
01552 break;
01553
01554 case R_68K_PLT8O:
01555 case R_68K_PLT16O:
01556 case R_68K_PLT32O:
01557
01558
01559 BFD_ASSERT (h != NULL && h->plt.offset != (bfd_vma) -1);
01560
01561 if (splt == NULL)
01562 {
01563 splt = bfd_get_section_by_name (dynobj, ".plt");
01564 BFD_ASSERT (splt != NULL);
01565 }
01566
01567 relocation = h->plt.offset;
01568 unresolved_reloc = FALSE;
01569
01570
01571 rel->r_addend = 0;
01572
01573 break;
01574
01575 case R_68K_PC8:
01576 case R_68K_PC16:
01577 case R_68K_PC32:
01578 if (h == NULL
01579 || (info->shared
01580 && h->forced_local))
01581 break;
01582
01583 case R_68K_8:
01584 case R_68K_16:
01585 case R_68K_32:
01586 if (info->shared
01587 && r_symndx != 0
01588 && (input_section->flags & SEC_ALLOC) != 0
01589 && (h == NULL
01590 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
01591 || h->root.type != bfd_link_hash_undefweak)
01592 && ((r_type != R_68K_PC8
01593 && r_type != R_68K_PC16
01594 && r_type != R_68K_PC32)
01595 || (h != NULL
01596 && h->dynindx != -1
01597 && (!info->symbolic
01598 || !h->def_regular))))
01599 {
01600 Elf_Internal_Rela outrel;
01601 bfd_byte *loc;
01602 bfd_boolean skip, relocate;
01603
01604
01605
01606
01607
01608 skip = FALSE;
01609 relocate = FALSE;
01610
01611 outrel.r_offset =
01612 _bfd_elf_section_offset (output_bfd, info, input_section,
01613 rel->r_offset);
01614 if (outrel.r_offset == (bfd_vma) -1)
01615 skip = TRUE;
01616 else if (outrel.r_offset == (bfd_vma) -2)
01617 skip = TRUE, relocate = TRUE;
01618 outrel.r_offset += (input_section->output_section->vma
01619 + input_section->output_offset);
01620
01621 if (skip)
01622 memset (&outrel, 0, sizeof outrel);
01623 else if (h != NULL
01624 && h->dynindx != -1
01625 && (r_type == R_68K_PC8
01626 || r_type == R_68K_PC16
01627 || r_type == R_68K_PC32
01628 || !info->shared
01629 || !info->symbolic
01630 || !h->def_regular))
01631 {
01632 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
01633 outrel.r_addend = rel->r_addend;
01634 }
01635 else
01636 {
01637
01638 if (r_type == R_68K_32)
01639 {
01640 relocate = TRUE;
01641 outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
01642 outrel.r_addend = relocation + rel->r_addend;
01643 }
01644 else
01645 {
01646 long indx;
01647
01648 if (bfd_is_abs_section (sec))
01649 indx = 0;
01650 else if (sec == NULL || sec->owner == NULL)
01651 {
01652 bfd_set_error (bfd_error_bad_value);
01653 return FALSE;
01654 }
01655 else
01656 {
01657 asection *osec;
01658
01659 osec = sec->output_section;
01660 indx = elf_section_data (osec)->dynindx;
01661 BFD_ASSERT (indx > 0);
01662 }
01663
01664 outrel.r_info = ELF32_R_INFO (indx, r_type);
01665 outrel.r_addend = relocation + rel->r_addend;
01666 }
01667 }
01668
01669 sreloc = elf_section_data (input_section)->sreloc;
01670 if (sreloc == NULL)
01671 abort ();
01672
01673 loc = sreloc->contents;
01674 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
01675 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
01676
01677
01678
01679
01680
01681 if (!relocate)
01682 continue;
01683 }
01684
01685 break;
01686
01687 case R_68K_GNU_VTINHERIT:
01688 case R_68K_GNU_VTENTRY:
01689
01690 continue;
01691
01692 default:
01693 break;
01694 }
01695
01696
01697
01698
01699 if (unresolved_reloc
01700 && !((input_section->flags & SEC_DEBUGGING) != 0
01701 && h->def_dynamic))
01702 {
01703 (*_bfd_error_handler)
01704 (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
01705 input_bfd,
01706 input_section,
01707 (long) rel->r_offset,
01708 h->root.root.string);
01709 return FALSE;
01710 }
01711
01712 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
01713 contents, rel->r_offset,
01714 relocation, rel->r_addend);
01715
01716 if (r != bfd_reloc_ok)
01717 {
01718 const char *name;
01719
01720 if (h != NULL)
01721 name = h->root.root.string;
01722 else
01723 {
01724 name = bfd_elf_string_from_elf_section (input_bfd,
01725 symtab_hdr->sh_link,
01726 sym->st_name);
01727 if (name == NULL)
01728 return FALSE;
01729 if (*name == '\0')
01730 name = bfd_section_name (input_bfd, sec);
01731 }
01732
01733 if (r == bfd_reloc_overflow)
01734 {
01735 if (!(info->callbacks->reloc_overflow
01736 (info, (h ? &h->root : NULL), name, howto->name,
01737 (bfd_vma) 0, input_bfd, input_section,
01738 rel->r_offset)))
01739 return FALSE;
01740 }
01741 else
01742 {
01743 (*_bfd_error_handler)
01744 (_("%B(%A+0x%lx): reloc against `%s': error %d"),
01745 input_bfd, input_section,
01746 (long) rel->r_offset, name, (int) r);
01747 return FALSE;
01748 }
01749 }
01750 }
01751
01752 return TRUE;
01753 }
01754
01755
01756
01757
01758 static bfd_boolean
01759 elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
01760 bfd *output_bfd;
01761 struct bfd_link_info *info;
01762 struct elf_link_hash_entry *h;
01763 Elf_Internal_Sym *sym;
01764 {
01765 bfd *dynobj;
01766 int plt_off1, plt_off2, plt_off3;
01767
01768 dynobj = elf_hash_table (info)->dynobj;
01769
01770 if (h->plt.offset != (bfd_vma) -1)
01771 {
01772 asection *splt;
01773 asection *sgot;
01774 asection *srela;
01775 bfd_vma plt_index;
01776 bfd_vma got_offset;
01777 Elf_Internal_Rela rela;
01778 bfd_byte *loc;
01779
01780
01781
01782
01783 BFD_ASSERT (h->dynindx != -1);
01784
01785 splt = bfd_get_section_by_name (dynobj, ".plt");
01786 sgot = bfd_get_section_by_name (dynobj, ".got.plt");
01787 srela = bfd_get_section_by_name (dynobj, ".rela.plt");
01788 BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
01789
01790
01791
01792
01793
01794 if ( CPU32_FLAG (output_bfd))
01795 plt_index = h->plt.offset / PLT_CPU32_ENTRY_SIZE - 1;
01796 else
01797 plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
01798
01799
01800
01801
01802 got_offset = (plt_index + 3) * 4;
01803
01804 if ( CPU32_FLAG (output_bfd))
01805 {
01806
01807 memcpy (splt->contents + h->plt.offset, elf_cpu32_plt_entry,
01808 PLT_CPU32_ENTRY_SIZE);
01809 plt_off1 = 4;
01810 plt_off2 = 12;
01811 plt_off3 = 18;
01812 }
01813 else
01814 {
01815
01816 memcpy (splt->contents + h->plt.offset, elf_m68k_plt_entry,
01817 PLT_ENTRY_SIZE);
01818 plt_off1 = 4;
01819 plt_off2 = 10;
01820 plt_off3 = 16;
01821 }
01822
01823
01824 bfd_put_32 (output_bfd,
01825 (sgot->output_section->vma
01826 + sgot->output_offset
01827 + got_offset
01828 - (splt->output_section->vma
01829 + h->plt.offset + 2)),
01830 splt->contents + h->plt.offset + plt_off1);
01831
01832 bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
01833 splt->contents + h->plt.offset + plt_off2);
01834 bfd_put_32 (output_bfd, - (h->plt.offset + plt_off3),
01835 splt->contents + h->plt.offset + plt_off3);
01836
01837
01838 bfd_put_32 (output_bfd,
01839 (splt->output_section->vma
01840 + splt->output_offset
01841 + h->plt.offset
01842 + 8),
01843 sgot->contents + got_offset);
01844
01845
01846 rela.r_offset = (sgot->output_section->vma
01847 + sgot->output_offset
01848 + got_offset);
01849 rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_JMP_SLOT);
01850 rela.r_addend = 0;
01851 loc = srela->contents + plt_index * sizeof (Elf32_External_Rela);
01852 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
01853
01854 if (!h->def_regular)
01855 {
01856
01857
01858 sym->st_shndx = SHN_UNDEF;
01859 }
01860 }
01861
01862 if (h->got.offset != (bfd_vma) -1)
01863 {
01864 asection *sgot;
01865 asection *srela;
01866 Elf_Internal_Rela rela;
01867 bfd_byte *loc;
01868
01869
01870
01871
01872 sgot = bfd_get_section_by_name (dynobj, ".got");
01873 srela = bfd_get_section_by_name (dynobj, ".rela.got");
01874 BFD_ASSERT (sgot != NULL && srela != NULL);
01875
01876 rela.r_offset = (sgot->output_section->vma
01877 + sgot->output_offset
01878 + (h->got.offset &~ (bfd_vma) 1));
01879
01880
01881
01882
01883
01884
01885 if (info->shared
01886 && (info->symbolic
01887 || h->dynindx == -1
01888 || h->forced_local)
01889 && h->def_regular)
01890 {
01891 rela.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
01892 rela.r_addend = bfd_get_signed_32 (output_bfd,
01893 (sgot->contents
01894 + (h->got.offset &~ (bfd_vma) 1)));
01895 }
01896 else
01897 {
01898 bfd_put_32 (output_bfd, (bfd_vma) 0,
01899 sgot->contents + (h->got.offset &~ (bfd_vma) 1));
01900 rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_GLOB_DAT);
01901 rela.r_addend = 0;
01902 }
01903
01904 loc = srela->contents;
01905 loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
01906 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
01907 }
01908
01909 if (h->needs_copy)
01910 {
01911 asection *s;
01912 Elf_Internal_Rela rela;
01913 bfd_byte *loc;
01914
01915
01916
01917 BFD_ASSERT (h->dynindx != -1
01918 && (h->root.type == bfd_link_hash_defined
01919 || h->root.type == bfd_link_hash_defweak));
01920
01921 s = bfd_get_section_by_name (h->root.u.def.section->owner,
01922 ".rela.bss");
01923 BFD_ASSERT (s != NULL);
01924
01925 rela.r_offset = (h->root.u.def.value
01926 + h->root.u.def.section->output_section->vma
01927 + h->root.u.def.section->output_offset);
01928 rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_COPY);
01929 rela.r_addend = 0;
01930 loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
01931 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
01932 }
01933
01934
01935 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
01936 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
01937 sym->st_shndx = SHN_ABS;
01938
01939 return TRUE;
01940 }
01941
01942
01943
01944 static bfd_boolean
01945 elf_m68k_finish_dynamic_sections (output_bfd, info)
01946 bfd *output_bfd;
01947 struct bfd_link_info *info;
01948 {
01949 bfd *dynobj;
01950 asection *sgot;
01951 asection *sdyn;
01952
01953 dynobj = elf_hash_table (info)->dynobj;
01954
01955 sgot = bfd_get_section_by_name (dynobj, ".got.plt");
01956 BFD_ASSERT (sgot != NULL);
01957 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
01958
01959 if (elf_hash_table (info)->dynamic_sections_created)
01960 {
01961 asection *splt;
01962 Elf32_External_Dyn *dyncon, *dynconend;
01963
01964 splt = bfd_get_section_by_name (dynobj, ".plt");
01965 BFD_ASSERT (splt != NULL && sdyn != NULL);
01966
01967 dyncon = (Elf32_External_Dyn *) sdyn->contents;
01968 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
01969 for (; dyncon < dynconend; dyncon++)
01970 {
01971 Elf_Internal_Dyn dyn;
01972 const char *name;
01973 asection *s;
01974
01975 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
01976
01977 switch (dyn.d_tag)
01978 {
01979 default:
01980 break;
01981
01982 case DT_PLTGOT:
01983 name = ".got";
01984 goto get_vma;
01985 case DT_JMPREL:
01986 name = ".rela.plt";
01987 get_vma:
01988 s = bfd_get_section_by_name (output_bfd, name);
01989 BFD_ASSERT (s != NULL);
01990 dyn.d_un.d_ptr = s->vma;
01991 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
01992 break;
01993
01994 case DT_PLTRELSZ:
01995 s = bfd_get_section_by_name (output_bfd, ".rela.plt");
01996 BFD_ASSERT (s != NULL);
01997 dyn.d_un.d_val = s->size;
01998 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
01999 break;
02000
02001 case DT_RELASZ:
02002
02003
02004
02005
02006
02007
02008
02009 s = bfd_get_section_by_name (output_bfd, ".rela.plt");
02010 if (s != NULL)
02011 dyn.d_un.d_val -= s->size;
02012 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
02013 break;
02014 }
02015 }
02016
02017
02018 if (splt->size > 0)
02019 {
02020 if (!CPU32_FLAG (output_bfd))
02021 {
02022 memcpy (splt->contents, elf_m68k_plt0_entry, PLT_ENTRY_SIZE);
02023 bfd_put_32 (output_bfd,
02024 (sgot->output_section->vma
02025 + sgot->output_offset + 4
02026 - (splt->output_section->vma + 2)),
02027 splt->contents + 4);
02028 bfd_put_32 (output_bfd,
02029 (sgot->output_section->vma
02030 + sgot->output_offset + 8
02031 - (splt->output_section->vma + 10)),
02032 splt->contents + 12);
02033 elf_section_data (splt->output_section)->this_hdr.sh_entsize
02034 = PLT_ENTRY_SIZE;
02035 }
02036 else
02037 {
02038 memcpy (splt->contents, elf_cpu32_plt0_entry, PLT_CPU32_ENTRY_SIZE);
02039 bfd_put_32 (output_bfd,
02040 (sgot->output_section->vma
02041 + sgot->output_offset + 4
02042 - (splt->output_section->vma + 2)),
02043 splt->contents + 4);
02044 bfd_put_32 (output_bfd,
02045 (sgot->output_section->vma
02046 + sgot->output_offset + 8
02047 - (splt->output_section->vma + 10)),
02048 splt->contents + 12);
02049 elf_section_data (splt->output_section)->this_hdr.sh_entsize
02050 = PLT_CPU32_ENTRY_SIZE;
02051 }
02052 }
02053 }
02054
02055
02056 if (sgot->size > 0)
02057 {
02058 if (sdyn == NULL)
02059 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
02060 else
02061 bfd_put_32 (output_bfd,
02062 sdyn->output_section->vma + sdyn->output_offset,
02063 sgot->contents);
02064 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4);
02065 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
02066 }
02067
02068 elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
02069
02070 return TRUE;
02071 }
02072
02073
02074
02075
02076
02077
02078
02079
02080 bfd_boolean
02081 bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
02082 bfd *abfd;
02083 struct bfd_link_info *info;
02084 asection *datasec;
02085 asection *relsec;
02086 char **errmsg;
02087 {
02088 Elf_Internal_Shdr *symtab_hdr;
02089 Elf_Internal_Sym *isymbuf = NULL;
02090 Elf_Internal_Rela *internal_relocs = NULL;
02091 Elf_Internal_Rela *irel, *irelend;
02092 bfd_byte *p;
02093 bfd_size_type amt;
02094
02095 BFD_ASSERT (! info->relocatable);
02096
02097 *errmsg = NULL;
02098
02099 if (datasec->reloc_count == 0)
02100 return TRUE;
02101
02102 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
02103
02104
02105 internal_relocs = (_bfd_elf_link_read_relocs
02106 (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
02107 info->keep_memory));
02108 if (internal_relocs == NULL)
02109 goto error_return;
02110
02111 amt = (bfd_size_type) datasec->reloc_count * 12;
02112 relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
02113 if (relsec->contents == NULL)
02114 goto error_return;
02115
02116 p = relsec->contents;
02117
02118 irelend = internal_relocs + datasec->reloc_count;
02119 for (irel = internal_relocs; irel < irelend; irel++, p += 12)
02120 {
02121 asection *targetsec;
02122
02123
02124
02125
02126
02127
02128
02129
02130 if (ELF32_R_TYPE (irel->r_info) != (int) R_68K_32)
02131 {
02132 *errmsg = _("unsupported reloc type");
02133 bfd_set_error (bfd_error_bad_value);
02134 goto error_return;
02135 }
02136
02137
02138 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
02139 {
02140
02141 Elf_Internal_Sym *isym;
02142
02143
02144 if (isymbuf == NULL)
02145 {
02146 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
02147 if (isymbuf == NULL)
02148 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
02149 symtab_hdr->sh_info, 0,
02150 NULL, NULL, NULL);
02151 if (isymbuf == NULL)
02152 goto error_return;
02153 }
02154
02155 isym = isymbuf + ELF32_R_SYM (irel->r_info);
02156 targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
02157 }
02158 else
02159 {
02160 unsigned long indx;
02161 struct elf_link_hash_entry *h;
02162
02163
02164 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
02165 h = elf_sym_hashes (abfd)[indx];
02166 BFD_ASSERT (h != NULL);
02167 if (h->root.type == bfd_link_hash_defined
02168 || h->root.type == bfd_link_hash_defweak)
02169 targetsec = h->root.u.def.section;
02170 else
02171 targetsec = NULL;
02172 }
02173
02174 bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
02175 memset (p + 4, 0, 8);
02176 if (targetsec != NULL)
02177 strncpy ((char *) p + 4, targetsec->output_section->name, 8);
02178 }
02179
02180 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
02181 free (isymbuf);
02182 if (internal_relocs != NULL
02183 && elf_section_data (datasec)->relocs != internal_relocs)
02184 free (internal_relocs);
02185 return TRUE;
02186
02187 error_return:
02188 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
02189 free (isymbuf);
02190 if (internal_relocs != NULL
02191 && elf_section_data (datasec)->relocs != internal_relocs)
02192 free (internal_relocs);
02193 return FALSE;
02194 }
02195
02196 static enum elf_reloc_type_class
02197 elf32_m68k_reloc_type_class (rela)
02198 const Elf_Internal_Rela *rela;
02199 {
02200 switch ((int) ELF32_R_TYPE (rela->r_info))
02201 {
02202 case R_68K_RELATIVE:
02203 return reloc_class_relative;
02204 case R_68K_JMP_SLOT:
02205 return reloc_class_plt;
02206 case R_68K_COPY:
02207 return reloc_class_copy;
02208 default:
02209 return reloc_class_normal;
02210 }
02211 }
02212
02213
02214
02215
02216 static bfd_vma
02217 elf_m68k_plt_sym_val (bfd_vma i, const asection *plt,
02218 const arelent *rel ATTRIBUTE_UNUSED)
02219 {
02220 if (CPU32_FLAG (plt->owner))
02221 return plt->vma + (i + 1) * PLT_CPU32_ENTRY_SIZE;
02222 return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
02223 }
02224
02225 #define TARGET_BIG_SYM bfd_elf32_m68k_vec
02226 #define TARGET_BIG_NAME "elf32-m68k"
02227 #define ELF_MACHINE_CODE EM_68K
02228 #define ELF_MAXPAGESIZE 0x2000
02229 #define elf_backend_create_dynamic_sections \
02230 _bfd_elf_create_dynamic_sections
02231 #define bfd_elf32_bfd_link_hash_table_create \
02232 elf_m68k_link_hash_table_create
02233 #define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link
02234
02235 #define elf_backend_check_relocs elf_m68k_check_relocs
02236 #define elf_backend_adjust_dynamic_symbol \
02237 elf_m68k_adjust_dynamic_symbol
02238 #define elf_backend_size_dynamic_sections \
02239 elf_m68k_size_dynamic_sections
02240 #define elf_backend_relocate_section elf_m68k_relocate_section
02241 #define elf_backend_finish_dynamic_symbol \
02242 elf_m68k_finish_dynamic_symbol
02243 #define elf_backend_finish_dynamic_sections \
02244 elf_m68k_finish_dynamic_sections
02245 #define elf_backend_gc_mark_hook elf_m68k_gc_mark_hook
02246 #define elf_backend_gc_sweep_hook elf_m68k_gc_sweep_hook
02247 #define bfd_elf32_bfd_merge_private_bfd_data \
02248 elf32_m68k_merge_private_bfd_data
02249 #define bfd_elf32_bfd_set_private_flags \
02250 elf32_m68k_set_private_flags
02251 #define bfd_elf32_bfd_print_private_bfd_data \
02252 elf32_m68k_print_private_bfd_data
02253 #define elf_backend_reloc_type_class elf32_m68k_reloc_type_class
02254 #define elf_backend_plt_sym_val elf_m68k_plt_sym_val
02255
02256 #define elf_backend_can_gc_sections 1
02257 #define elf_backend_can_refcount 1
02258 #define elf_backend_want_got_plt 1
02259 #define elf_backend_plt_readonly 1
02260 #define elf_backend_want_plt_sym 0
02261 #define elf_backend_got_header_size 12
02262 #define elf_backend_rela_normal 1
02263
02264 #include "elf32-target.h"