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
00031
00032 #define USE_REL 1
00033
00034 #include "elf/i386.h"
00035
00036 static reloc_howto_type elf_howto_table[]=
00037 {
00038 HOWTO(R_386_NONE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
00039 bfd_elf_generic_reloc, "R_386_NONE",
00040 TRUE, 0x00000000, 0x00000000, FALSE),
00041 HOWTO(R_386_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00042 bfd_elf_generic_reloc, "R_386_32",
00043 TRUE, 0xffffffff, 0xffffffff, FALSE),
00044 HOWTO(R_386_PC32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
00045 bfd_elf_generic_reloc, "R_386_PC32",
00046 TRUE, 0xffffffff, 0xffffffff, TRUE),
00047 HOWTO(R_386_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00048 bfd_elf_generic_reloc, "R_386_GOT32",
00049 TRUE, 0xffffffff, 0xffffffff, FALSE),
00050 HOWTO(R_386_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
00051 bfd_elf_generic_reloc, "R_386_PLT32",
00052 TRUE, 0xffffffff, 0xffffffff, TRUE),
00053 HOWTO(R_386_COPY, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00054 bfd_elf_generic_reloc, "R_386_COPY",
00055 TRUE, 0xffffffff, 0xffffffff, FALSE),
00056 HOWTO(R_386_GLOB_DAT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00057 bfd_elf_generic_reloc, "R_386_GLOB_DAT",
00058 TRUE, 0xffffffff, 0xffffffff, FALSE),
00059 HOWTO(R_386_JUMP_SLOT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00060 bfd_elf_generic_reloc, "R_386_JUMP_SLOT",
00061 TRUE, 0xffffffff, 0xffffffff, FALSE),
00062 HOWTO(R_386_RELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00063 bfd_elf_generic_reloc, "R_386_RELATIVE",
00064 TRUE, 0xffffffff, 0xffffffff, FALSE),
00065 HOWTO(R_386_GOTOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00066 bfd_elf_generic_reloc, "R_386_GOTOFF",
00067 TRUE, 0xffffffff, 0xffffffff, FALSE),
00068 HOWTO(R_386_GOTPC, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
00069 bfd_elf_generic_reloc, "R_386_GOTPC",
00070 TRUE, 0xffffffff, 0xffffffff, TRUE),
00071
00072
00073
00074
00075
00076 #define R_386_standard (R_386_GOTPC + 1)
00077 #define R_386_ext_offset (R_386_TLS_TPOFF - R_386_standard)
00078
00079
00080 HOWTO(R_386_TLS_TPOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00081 bfd_elf_generic_reloc, "R_386_TLS_TPOFF",
00082 TRUE, 0xffffffff, 0xffffffff, FALSE),
00083 HOWTO(R_386_TLS_IE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00084 bfd_elf_generic_reloc, "R_386_TLS_IE",
00085 TRUE, 0xffffffff, 0xffffffff, FALSE),
00086 HOWTO(R_386_TLS_GOTIE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00087 bfd_elf_generic_reloc, "R_386_TLS_GOTIE",
00088 TRUE, 0xffffffff, 0xffffffff, FALSE),
00089 HOWTO(R_386_TLS_LE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00090 bfd_elf_generic_reloc, "R_386_TLS_LE",
00091 TRUE, 0xffffffff, 0xffffffff, FALSE),
00092 HOWTO(R_386_TLS_GD, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00093 bfd_elf_generic_reloc, "R_386_TLS_GD",
00094 TRUE, 0xffffffff, 0xffffffff, FALSE),
00095 HOWTO(R_386_TLS_LDM, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00096 bfd_elf_generic_reloc, "R_386_TLS_LDM",
00097 TRUE, 0xffffffff, 0xffffffff, FALSE),
00098 HOWTO(R_386_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
00099 bfd_elf_generic_reloc, "R_386_16",
00100 TRUE, 0xffff, 0xffff, FALSE),
00101 HOWTO(R_386_PC16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield,
00102 bfd_elf_generic_reloc, "R_386_PC16",
00103 TRUE, 0xffff, 0xffff, TRUE),
00104 HOWTO(R_386_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
00105 bfd_elf_generic_reloc, "R_386_8",
00106 TRUE, 0xff, 0xff, FALSE),
00107 HOWTO(R_386_PC8, 0, 0, 8, TRUE, 0, complain_overflow_signed,
00108 bfd_elf_generic_reloc, "R_386_PC8",
00109 TRUE, 0xff, 0xff, TRUE),
00110
00111 #define R_386_ext (R_386_PC8 + 1 - R_386_ext_offset)
00112 #define R_386_tls_offset (R_386_TLS_LDO_32 - R_386_ext)
00113
00114 HOWTO(R_386_TLS_LDO_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00115 bfd_elf_generic_reloc, "R_386_TLS_LDO_32",
00116 TRUE, 0xffffffff, 0xffffffff, FALSE),
00117 HOWTO(R_386_TLS_IE_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00118 bfd_elf_generic_reloc, "R_386_TLS_IE_32",
00119 TRUE, 0xffffffff, 0xffffffff, FALSE),
00120 HOWTO(R_386_TLS_LE_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00121 bfd_elf_generic_reloc, "R_386_TLS_LE_32",
00122 TRUE, 0xffffffff, 0xffffffff, FALSE),
00123 HOWTO(R_386_TLS_DTPMOD32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00124 bfd_elf_generic_reloc, "R_386_TLS_DTPMOD32",
00125 TRUE, 0xffffffff, 0xffffffff, FALSE),
00126 HOWTO(R_386_TLS_DTPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00127 bfd_elf_generic_reloc, "R_386_TLS_DTPOFF32",
00128 TRUE, 0xffffffff, 0xffffffff, FALSE),
00129 HOWTO(R_386_TLS_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
00130 bfd_elf_generic_reloc, "R_386_TLS_TPOFF32",
00131 TRUE, 0xffffffff, 0xffffffff, FALSE),
00132
00133
00134 #define R_386_tls (R_386_TLS_TPOFF32 + 1 - R_386_tls_offset)
00135 #define R_386_vt_offset (R_386_GNU_VTINHERIT - R_386_tls)
00136
00137
00138 HOWTO (R_386_GNU_VTINHERIT,
00139 0,
00140 2,
00141 0,
00142 FALSE,
00143 0,
00144 complain_overflow_dont,
00145 NULL,
00146 "R_386_GNU_VTINHERIT",
00147 FALSE,
00148 0,
00149 0,
00150 FALSE),
00151
00152
00153 HOWTO (R_386_GNU_VTENTRY,
00154 0,
00155 2,
00156 0,
00157 FALSE,
00158 0,
00159 complain_overflow_dont,
00160 _bfd_elf_rel_vtable_reloc_fn,
00161 "R_386_GNU_VTENTRY",
00162 FALSE,
00163 0,
00164 0,
00165 FALSE)
00166
00167 #define R_386_vt (R_386_GNU_VTENTRY + 1 - R_386_vt_offset)
00168
00169 };
00170
00171 #ifdef DEBUG_GEN_RELOC
00172 #define TRACE(str) \
00173 fprintf (stderr, "i386 bfd reloc lookup %d (%s)\n", code, str)
00174 #else
00175 #define TRACE(str)
00176 #endif
00177
00178 static reloc_howto_type *
00179 elf_i386_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
00180 bfd_reloc_code_real_type code)
00181 {
00182 switch (code)
00183 {
00184 case BFD_RELOC_NONE:
00185 TRACE ("BFD_RELOC_NONE");
00186 return &elf_howto_table[R_386_NONE];
00187
00188 case BFD_RELOC_32:
00189 TRACE ("BFD_RELOC_32");
00190 return &elf_howto_table[R_386_32];
00191
00192 case BFD_RELOC_CTOR:
00193 TRACE ("BFD_RELOC_CTOR");
00194 return &elf_howto_table[R_386_32];
00195
00196 case BFD_RELOC_32_PCREL:
00197 TRACE ("BFD_RELOC_PC32");
00198 return &elf_howto_table[R_386_PC32];
00199
00200 case BFD_RELOC_386_GOT32:
00201 TRACE ("BFD_RELOC_386_GOT32");
00202 return &elf_howto_table[R_386_GOT32];
00203
00204 case BFD_RELOC_386_PLT32:
00205 TRACE ("BFD_RELOC_386_PLT32");
00206 return &elf_howto_table[R_386_PLT32];
00207
00208 case BFD_RELOC_386_COPY:
00209 TRACE ("BFD_RELOC_386_COPY");
00210 return &elf_howto_table[R_386_COPY];
00211
00212 case BFD_RELOC_386_GLOB_DAT:
00213 TRACE ("BFD_RELOC_386_GLOB_DAT");
00214 return &elf_howto_table[R_386_GLOB_DAT];
00215
00216 case BFD_RELOC_386_JUMP_SLOT:
00217 TRACE ("BFD_RELOC_386_JUMP_SLOT");
00218 return &elf_howto_table[R_386_JUMP_SLOT];
00219
00220 case BFD_RELOC_386_RELATIVE:
00221 TRACE ("BFD_RELOC_386_RELATIVE");
00222 return &elf_howto_table[R_386_RELATIVE];
00223
00224 case BFD_RELOC_386_GOTOFF:
00225 TRACE ("BFD_RELOC_386_GOTOFF");
00226 return &elf_howto_table[R_386_GOTOFF];
00227
00228 case BFD_RELOC_386_GOTPC:
00229 TRACE ("BFD_RELOC_386_GOTPC");
00230 return &elf_howto_table[R_386_GOTPC];
00231
00232
00233 case BFD_RELOC_386_TLS_TPOFF:
00234 TRACE ("BFD_RELOC_386_TLS_TPOFF");
00235 return &elf_howto_table[R_386_TLS_TPOFF - R_386_ext_offset];
00236
00237 case BFD_RELOC_386_TLS_IE:
00238 TRACE ("BFD_RELOC_386_TLS_IE");
00239 return &elf_howto_table[R_386_TLS_IE - R_386_ext_offset];
00240
00241 case BFD_RELOC_386_TLS_GOTIE:
00242 TRACE ("BFD_RELOC_386_TLS_GOTIE");
00243 return &elf_howto_table[R_386_TLS_GOTIE - R_386_ext_offset];
00244
00245 case BFD_RELOC_386_TLS_LE:
00246 TRACE ("BFD_RELOC_386_TLS_LE");
00247 return &elf_howto_table[R_386_TLS_LE - R_386_ext_offset];
00248
00249 case BFD_RELOC_386_TLS_GD:
00250 TRACE ("BFD_RELOC_386_TLS_GD");
00251 return &elf_howto_table[R_386_TLS_GD - R_386_ext_offset];
00252
00253 case BFD_RELOC_386_TLS_LDM:
00254 TRACE ("BFD_RELOC_386_TLS_LDM");
00255 return &elf_howto_table[R_386_TLS_LDM - R_386_ext_offset];
00256
00257 case BFD_RELOC_16:
00258 TRACE ("BFD_RELOC_16");
00259 return &elf_howto_table[R_386_16 - R_386_ext_offset];
00260
00261 case BFD_RELOC_16_PCREL:
00262 TRACE ("BFD_RELOC_16_PCREL");
00263 return &elf_howto_table[R_386_PC16 - R_386_ext_offset];
00264
00265 case BFD_RELOC_8:
00266 TRACE ("BFD_RELOC_8");
00267 return &elf_howto_table[R_386_8 - R_386_ext_offset];
00268
00269 case BFD_RELOC_8_PCREL:
00270 TRACE ("BFD_RELOC_8_PCREL");
00271 return &elf_howto_table[R_386_PC8 - R_386_ext_offset];
00272
00273
00274 case BFD_RELOC_386_TLS_LDO_32:
00275 TRACE ("BFD_RELOC_386_TLS_LDO_32");
00276 return &elf_howto_table[R_386_TLS_LDO_32 - R_386_tls_offset];
00277
00278 case BFD_RELOC_386_TLS_IE_32:
00279 TRACE ("BFD_RELOC_386_TLS_IE_32");
00280 return &elf_howto_table[R_386_TLS_IE_32 - R_386_tls_offset];
00281
00282 case BFD_RELOC_386_TLS_LE_32:
00283 TRACE ("BFD_RELOC_386_TLS_LE_32");
00284 return &elf_howto_table[R_386_TLS_LE_32 - R_386_tls_offset];
00285
00286 case BFD_RELOC_386_TLS_DTPMOD32:
00287 TRACE ("BFD_RELOC_386_TLS_DTPMOD32");
00288 return &elf_howto_table[R_386_TLS_DTPMOD32 - R_386_tls_offset];
00289
00290 case BFD_RELOC_386_TLS_DTPOFF32:
00291 TRACE ("BFD_RELOC_386_TLS_DTPOFF32");
00292 return &elf_howto_table[R_386_TLS_DTPOFF32 - R_386_tls_offset];
00293
00294 case BFD_RELOC_386_TLS_TPOFF32:
00295 TRACE ("BFD_RELOC_386_TLS_TPOFF32");
00296 return &elf_howto_table[R_386_TLS_TPOFF32 - R_386_tls_offset];
00297
00298 case BFD_RELOC_VTABLE_INHERIT:
00299 TRACE ("BFD_RELOC_VTABLE_INHERIT");
00300 return &elf_howto_table[R_386_GNU_VTINHERIT - R_386_vt_offset];
00301
00302 case BFD_RELOC_VTABLE_ENTRY:
00303 TRACE ("BFD_RELOC_VTABLE_ENTRY");
00304 return &elf_howto_table[R_386_GNU_VTENTRY - R_386_vt_offset];
00305
00306 default:
00307 break;
00308 }
00309
00310 TRACE ("Unknown");
00311 return 0;
00312 }
00313
00314 static void
00315 elf_i386_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
00316 arelent *cache_ptr,
00317 Elf_Internal_Rela *dst)
00318 {
00319 unsigned int r_type = ELF32_R_TYPE (dst->r_info);
00320 unsigned int indx;
00321
00322 if ((indx = r_type) >= R_386_standard
00323 && ((indx = r_type - R_386_ext_offset) - R_386_standard
00324 >= R_386_ext - R_386_standard)
00325 && ((indx = r_type - R_386_tls_offset) - R_386_ext
00326 >= R_386_tls - R_386_ext)
00327 && ((indx = r_type - R_386_vt_offset) - R_386_tls
00328 >= R_386_vt - R_386_tls))
00329 {
00330 (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
00331 abfd, (int) r_type);
00332 indx = R_386_NONE;
00333 }
00334 cache_ptr->howto = &elf_howto_table[indx];
00335 }
00336
00337
00338
00339
00340
00341
00342
00343 static bfd_boolean
00344 elf_i386_is_local_label_name (bfd *abfd, const char *name)
00345 {
00346 if (name[0] == '.' && name[1] == 'X')
00347 return TRUE;
00348
00349 return _bfd_elf_is_local_label_name (abfd, name);
00350 }
00351
00352
00353
00354 static bfd_boolean
00355 elf_i386_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
00356 {
00357 int offset;
00358 size_t size;
00359
00360 if (note->namesz == 8 && strcmp (note->namedata, "FreeBSD") == 0)
00361 {
00362 int pr_version = bfd_get_32 (abfd, note->descdata);
00363
00364 if (pr_version != 1)
00365 return FALSE;
00366
00367
00368 elf_tdata (abfd)->core_signal = bfd_get_32 (abfd, note->descdata + 20);
00369
00370
00371 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
00372
00373
00374 offset = 28;
00375 size = bfd_get_32 (abfd, note->descdata + 8);
00376 }
00377 else
00378 {
00379 switch (note->descsz)
00380 {
00381 default:
00382 return FALSE;
00383
00384 case 144:
00385
00386 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
00387
00388
00389 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
00390
00391
00392 offset = 72;
00393 size = 68;
00394
00395 break;
00396 }
00397 }
00398
00399
00400 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
00401 size, note->descpos + offset);
00402 }
00403
00404 static bfd_boolean
00405 elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
00406 {
00407 if (note->namesz == 8 && strcmp (note->namedata, "FreeBSD") == 0)
00408 {
00409 int pr_version = bfd_get_32 (abfd, note->descdata);
00410
00411 if (pr_version != 1)
00412 return FALSE;
00413
00414 elf_tdata (abfd)->core_program
00415 = _bfd_elfcore_strndup (abfd, note->descdata + 8, 17);
00416 elf_tdata (abfd)->core_command
00417 = _bfd_elfcore_strndup (abfd, note->descdata + 25, 81);
00418 }
00419 else
00420 {
00421 switch (note->descsz)
00422 {
00423 default:
00424 return FALSE;
00425
00426 case 124:
00427 elf_tdata (abfd)->core_program
00428 = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
00429 elf_tdata (abfd)->core_command
00430 = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
00431 }
00432 }
00433
00434
00435
00436
00437 {
00438 char *command = elf_tdata (abfd)->core_command;
00439 int n = strlen (command);
00440
00441 if (0 < n && command[n - 1] == ' ')
00442 command[n - 1] = '\0';
00443 }
00444
00445 return TRUE;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
00466
00467
00468
00469
00470
00471 #define ELIMINATE_COPY_RELOCS 1
00472
00473
00474
00475 #define PLT_ENTRY_SIZE 16
00476
00477
00478
00479
00480 static const bfd_byte elf_i386_plt0_entry[PLT_ENTRY_SIZE] =
00481 {
00482 0xff, 0x35,
00483 0, 0, 0, 0,
00484 0xff, 0x25,
00485 0, 0, 0, 0,
00486 0, 0, 0, 0
00487 };
00488
00489
00490
00491
00492 static const bfd_byte elf_i386_plt_entry[PLT_ENTRY_SIZE] =
00493 {
00494 0xff, 0x25,
00495 0, 0, 0, 0,
00496 0x68,
00497 0, 0, 0, 0,
00498 0xe9,
00499 0, 0, 0, 0
00500 };
00501
00502
00503
00504 static const bfd_byte elf_i386_pic_plt0_entry[PLT_ENTRY_SIZE] =
00505 {
00506 0xff, 0xb3, 4, 0, 0, 0,
00507 0xff, 0xa3, 8, 0, 0, 0,
00508 0, 0, 0, 0
00509 };
00510
00511
00512
00513 static const bfd_byte elf_i386_pic_plt_entry[PLT_ENTRY_SIZE] =
00514 {
00515 0xff, 0xa3,
00516 0, 0, 0, 0,
00517 0x68,
00518 0, 0, 0, 0,
00519 0xe9,
00520 0, 0, 0, 0
00521 };
00522
00523
00524
00525
00526
00527
00528
00529 struct elf_i386_dyn_relocs
00530 {
00531 struct elf_i386_dyn_relocs *next;
00532
00533
00534 asection *sec;
00535
00536
00537 bfd_size_type count;
00538
00539
00540 bfd_size_type pc_count;
00541 };
00542
00543
00544
00545 struct elf_i386_link_hash_entry
00546 {
00547 struct elf_link_hash_entry elf;
00548
00549
00550 struct elf_i386_dyn_relocs *dyn_relocs;
00551
00552 #define GOT_UNKNOWN 0
00553 #define GOT_NORMAL 1
00554 #define GOT_TLS_GD 2
00555 #define GOT_TLS_IE 4
00556 #define GOT_TLS_IE_POS 5
00557 #define GOT_TLS_IE_NEG 6
00558 #define GOT_TLS_IE_BOTH 7
00559 unsigned char tls_type;
00560 };
00561
00562 #define elf_i386_hash_entry(ent) ((struct elf_i386_link_hash_entry *)(ent))
00563
00564 struct elf_i386_obj_tdata
00565 {
00566 struct elf_obj_tdata root;
00567
00568
00569 char *local_got_tls_type;
00570 };
00571
00572 #define elf_i386_tdata(abfd) \
00573 ((struct elf_i386_obj_tdata *) (abfd)->tdata.any)
00574
00575 #define elf_i386_local_got_tls_type(abfd) \
00576 (elf_i386_tdata (abfd)->local_got_tls_type)
00577
00578 static bfd_boolean
00579 elf_i386_mkobject (bfd *abfd)
00580 {
00581 bfd_size_type amt = sizeof (struct elf_i386_obj_tdata);
00582 abfd->tdata.any = bfd_zalloc (abfd, amt);
00583 if (abfd->tdata.any == NULL)
00584 return FALSE;
00585 return TRUE;
00586 }
00587
00588
00589
00590 struct elf_i386_link_hash_table
00591 {
00592 struct elf_link_hash_table elf;
00593
00594
00595 asection *sgot;
00596 asection *sgotplt;
00597 asection *srelgot;
00598 asection *splt;
00599 asection *srelplt;
00600 asection *sdynbss;
00601 asection *srelbss;
00602
00603 union {
00604 bfd_signed_vma refcount;
00605 bfd_vma offset;
00606 } tls_ldm_got;
00607
00608
00609 struct sym_sec_cache sym_sec;
00610 };
00611
00612
00613
00614 #define elf_i386_hash_table(p) \
00615 ((struct elf_i386_link_hash_table *) ((p)->hash))
00616
00617
00618
00619 static struct bfd_hash_entry *
00620 link_hash_newfunc (struct bfd_hash_entry *entry,
00621 struct bfd_hash_table *table,
00622 const char *string)
00623 {
00624
00625
00626 if (entry == NULL)
00627 {
00628 entry = bfd_hash_allocate (table,
00629 sizeof (struct elf_i386_link_hash_entry));
00630 if (entry == NULL)
00631 return entry;
00632 }
00633
00634
00635 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
00636 if (entry != NULL)
00637 {
00638 struct elf_i386_link_hash_entry *eh;
00639
00640 eh = (struct elf_i386_link_hash_entry *) entry;
00641 eh->dyn_relocs = NULL;
00642 eh->tls_type = GOT_UNKNOWN;
00643 }
00644
00645 return entry;
00646 }
00647
00648
00649
00650 static struct bfd_link_hash_table *
00651 elf_i386_link_hash_table_create (bfd *abfd)
00652 {
00653 struct elf_i386_link_hash_table *ret;
00654 bfd_size_type amt = sizeof (struct elf_i386_link_hash_table);
00655
00656 ret = bfd_malloc (amt);
00657 if (ret == NULL)
00658 return NULL;
00659
00660 if (! _bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc))
00661 {
00662 free (ret);
00663 return NULL;
00664 }
00665
00666 ret->sgot = NULL;
00667 ret->sgotplt = NULL;
00668 ret->srelgot = NULL;
00669 ret->splt = NULL;
00670 ret->srelplt = NULL;
00671 ret->sdynbss = NULL;
00672 ret->srelbss = NULL;
00673 ret->tls_ldm_got.refcount = 0;
00674 ret->sym_sec.abfd = NULL;
00675
00676 return &ret->elf.root;
00677 }
00678
00679
00680
00681
00682 static bfd_boolean
00683 create_got_section (bfd *dynobj, struct bfd_link_info *info)
00684 {
00685 struct elf_i386_link_hash_table *htab;
00686
00687 if (! _bfd_elf_create_got_section (dynobj, info))
00688 return FALSE;
00689
00690 htab = elf_i386_hash_table (info);
00691 htab->sgot = bfd_get_section_by_name (dynobj, ".got");
00692 htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
00693 if (!htab->sgot || !htab->sgotplt)
00694 abort ();
00695
00696 htab->srelgot = bfd_make_section (dynobj, ".rel.got");
00697 if (htab->srelgot == NULL
00698 || ! bfd_set_section_flags (dynobj, htab->srelgot,
00699 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
00700 | SEC_IN_MEMORY | SEC_LINKER_CREATED
00701 | SEC_READONLY))
00702 || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
00703 return FALSE;
00704 return TRUE;
00705 }
00706
00707
00708
00709
00710
00711 static bfd_boolean
00712 elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
00713 {
00714 struct elf_i386_link_hash_table *htab;
00715
00716 htab = elf_i386_hash_table (info);
00717 if (!htab->sgot && !create_got_section (dynobj, info))
00718 return FALSE;
00719
00720 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
00721 return FALSE;
00722
00723 htab->splt = bfd_get_section_by_name (dynobj, ".plt");
00724 htab->srelplt = bfd_get_section_by_name (dynobj, ".rel.plt");
00725 htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
00726 if (!info->shared)
00727 htab->srelbss = bfd_get_section_by_name (dynobj, ".rel.bss");
00728
00729 if (!htab->splt || !htab->srelplt || !htab->sdynbss
00730 || (!info->shared && !htab->srelbss))
00731 abort ();
00732
00733 return TRUE;
00734 }
00735
00736
00737
00738 static void
00739 elf_i386_copy_indirect_symbol (const struct elf_backend_data *bed,
00740 struct elf_link_hash_entry *dir,
00741 struct elf_link_hash_entry *ind)
00742 {
00743 struct elf_i386_link_hash_entry *edir, *eind;
00744
00745 edir = (struct elf_i386_link_hash_entry *) dir;
00746 eind = (struct elf_i386_link_hash_entry *) ind;
00747
00748 if (eind->dyn_relocs != NULL)
00749 {
00750 if (edir->dyn_relocs != NULL)
00751 {
00752 struct elf_i386_dyn_relocs **pp;
00753 struct elf_i386_dyn_relocs *p;
00754
00755 if (ind->root.type == bfd_link_hash_indirect)
00756 abort ();
00757
00758
00759
00760 for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
00761 {
00762 struct elf_i386_dyn_relocs *q;
00763
00764 for (q = edir->dyn_relocs; q != NULL; q = q->next)
00765 if (q->sec == p->sec)
00766 {
00767 q->pc_count += p->pc_count;
00768 q->count += p->count;
00769 *pp = p->next;
00770 break;
00771 }
00772 if (q == NULL)
00773 pp = &p->next;
00774 }
00775 *pp = edir->dyn_relocs;
00776 }
00777
00778 edir->dyn_relocs = eind->dyn_relocs;
00779 eind->dyn_relocs = NULL;
00780 }
00781
00782 if (ind->root.type == bfd_link_hash_indirect
00783 && dir->got.refcount <= 0)
00784 {
00785 edir->tls_type = eind->tls_type;
00786 eind->tls_type = GOT_UNKNOWN;
00787 }
00788
00789 if (ELIMINATE_COPY_RELOCS
00790 && ind->root.type != bfd_link_hash_indirect
00791 && dir->dynamic_adjusted)
00792 {
00793
00794
00795
00796 dir->ref_dynamic |= ind->ref_dynamic;
00797 dir->ref_regular |= ind->ref_regular;
00798 dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
00799 dir->needs_plt |= ind->needs_plt;
00800 dir->pointer_equality_needed |= ind->pointer_equality_needed;
00801 }
00802 else
00803 _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
00804 }
00805
00806 static int
00807 elf_i386_tls_transition (struct bfd_link_info *info, int r_type, int is_local)
00808 {
00809 if (info->shared)
00810 return r_type;
00811
00812 switch (r_type)
00813 {
00814 case R_386_TLS_GD:
00815 case R_386_TLS_IE_32:
00816 if (is_local)
00817 return R_386_TLS_LE_32;
00818 return R_386_TLS_IE_32;
00819 case R_386_TLS_IE:
00820 case R_386_TLS_GOTIE:
00821 if (is_local)
00822 return R_386_TLS_LE_32;
00823 return r_type;
00824 case R_386_TLS_LDM:
00825 return R_386_TLS_LE_32;
00826 }
00827
00828 return r_type;
00829 }
00830
00831
00832
00833
00834
00835 static bfd_boolean
00836 elf_i386_check_relocs (bfd *abfd,
00837 struct bfd_link_info *info,
00838 asection *sec,
00839 const Elf_Internal_Rela *relocs)
00840 {
00841 struct elf_i386_link_hash_table *htab;
00842 Elf_Internal_Shdr *symtab_hdr;
00843 struct elf_link_hash_entry **sym_hashes;
00844 const Elf_Internal_Rela *rel;
00845 const Elf_Internal_Rela *rel_end;
00846 asection *sreloc;
00847
00848 if (info->relocatable)
00849 return TRUE;
00850
00851 htab = elf_i386_hash_table (info);
00852 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
00853 sym_hashes = elf_sym_hashes (abfd);
00854
00855 sreloc = NULL;
00856
00857 rel_end = relocs + sec->reloc_count;
00858 for (rel = relocs; rel < rel_end; rel++)
00859 {
00860 unsigned int r_type;
00861 unsigned long r_symndx;
00862 struct elf_link_hash_entry *h;
00863
00864 r_symndx = ELF32_R_SYM (rel->r_info);
00865 r_type = ELF32_R_TYPE (rel->r_info);
00866
00867 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
00868 {
00869 (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
00870 abfd,
00871 r_symndx);
00872 return FALSE;
00873 }
00874
00875 if (r_symndx < symtab_hdr->sh_info)
00876 h = NULL;
00877 else
00878 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
00879
00880 r_type = elf_i386_tls_transition (info, r_type, h == NULL);
00881
00882 switch (r_type)
00883 {
00884 case R_386_TLS_LDM:
00885 htab->tls_ldm_got.refcount += 1;
00886 goto create_got;
00887
00888 case R_386_PLT32:
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898 if (h == NULL)
00899 continue;
00900
00901 h->needs_plt = 1;
00902 h->plt.refcount += 1;
00903 break;
00904
00905 case R_386_TLS_IE_32:
00906 case R_386_TLS_IE:
00907 case R_386_TLS_GOTIE:
00908 if (info->shared)
00909 info->flags |= DF_STATIC_TLS;
00910
00911
00912 case R_386_GOT32:
00913 case R_386_TLS_GD:
00914
00915 {
00916 int tls_type, old_tls_type;
00917
00918 switch (r_type)
00919 {
00920 default:
00921 case R_386_GOT32: tls_type = GOT_NORMAL; break;
00922 case R_386_TLS_GD: tls_type = GOT_TLS_GD; break;
00923 case R_386_TLS_IE_32:
00924 if (ELF32_R_TYPE (rel->r_info) == r_type)
00925 tls_type = GOT_TLS_IE_NEG;
00926 else
00927
00928
00929 tls_type = GOT_TLS_IE;
00930 break;
00931 case R_386_TLS_IE:
00932 case R_386_TLS_GOTIE:
00933 tls_type = GOT_TLS_IE_POS; break;
00934 }
00935
00936 if (h != NULL)
00937 {
00938 h->got.refcount += 1;
00939 old_tls_type = elf_i386_hash_entry(h)->tls_type;
00940 }
00941 else
00942 {
00943 bfd_signed_vma *local_got_refcounts;
00944
00945
00946 local_got_refcounts = elf_local_got_refcounts (abfd);
00947 if (local_got_refcounts == NULL)
00948 {
00949 bfd_size_type size;
00950
00951 size = symtab_hdr->sh_info;
00952 size *= (sizeof (bfd_signed_vma) + sizeof(char));
00953 local_got_refcounts = bfd_zalloc (abfd, size);
00954 if (local_got_refcounts == NULL)
00955 return FALSE;
00956 elf_local_got_refcounts (abfd) = local_got_refcounts;
00957 elf_i386_local_got_tls_type (abfd)
00958 = (char *) (local_got_refcounts + symtab_hdr->sh_info);
00959 }
00960 local_got_refcounts[r_symndx] += 1;
00961 old_tls_type = elf_i386_local_got_tls_type (abfd) [r_symndx];
00962 }
00963
00964 if ((old_tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_IE))
00965 tls_type |= old_tls_type;
00966
00967
00968 else if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
00969 && (old_tls_type != GOT_TLS_GD
00970 || (tls_type & GOT_TLS_IE) == 0))
00971 {
00972 if ((old_tls_type & GOT_TLS_IE) && tls_type == GOT_TLS_GD)
00973 tls_type = old_tls_type;
00974 else
00975 {
00976 (*_bfd_error_handler)
00977 (_("%B: `%s' accessed both as normal and "
00978 "thread local symbol"),
00979 abfd,
00980 h ? h->root.root.string : "<local>");
00981 return FALSE;
00982 }
00983 }
00984
00985 if (old_tls_type != tls_type)
00986 {
00987 if (h != NULL)
00988 elf_i386_hash_entry (h)->tls_type = tls_type;
00989 else
00990 elf_i386_local_got_tls_type (abfd) [r_symndx] = tls_type;
00991 }
00992 }
00993
00994
00995 case R_386_GOTOFF:
00996 case R_386_GOTPC:
00997 create_got:
00998 if (htab->sgot == NULL)
00999 {
01000 if (htab->elf.dynobj == NULL)
01001 htab->elf.dynobj = abfd;
01002 if (!create_got_section (htab->elf.dynobj, info))
01003 return FALSE;
01004 }
01005 if (r_type != R_386_TLS_IE)
01006 break;
01007
01008
01009 case R_386_TLS_LE_32:
01010 case R_386_TLS_LE:
01011 if (!info->shared)
01012 break;
01013 info->flags |= DF_STATIC_TLS;
01014
01015
01016 case R_386_32:
01017 case R_386_PC32:
01018 if (h != NULL && !info->shared)
01019 {
01020
01021
01022
01023
01024
01025
01026 h->non_got_ref = 1;
01027
01028
01029
01030 h->plt.refcount += 1;
01031 if (r_type != R_386_PC32)
01032 h->pointer_equality_needed = 1;
01033 }
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056 if ((info->shared
01057 && (sec->flags & SEC_ALLOC) != 0
01058 && (r_type != R_386_PC32
01059 || (h != NULL
01060 && (! info->symbolic
01061 || h->root.type == bfd_link_hash_defweak
01062 || !h->def_regular))))
01063 || (ELIMINATE_COPY_RELOCS
01064 && !info->shared
01065 && (sec->flags & SEC_ALLOC) != 0
01066 && h != NULL
01067 && (h->root.type == bfd_link_hash_defweak
01068 || !h->def_regular)))
01069 {
01070 struct elf_i386_dyn_relocs *p;
01071 struct elf_i386_dyn_relocs **head;
01072
01073
01074
01075
01076 if (sreloc == NULL)
01077 {
01078 const char *name;
01079 bfd *dynobj;
01080 unsigned int strndx = elf_elfheader (abfd)->e_shstrndx;
01081 unsigned int shnam = elf_section_data (sec)->rel_hdr.sh_name;
01082
01083 name = bfd_elf_string_from_elf_section (abfd, strndx, shnam);
01084 if (name == NULL)
01085 return FALSE;
01086
01087 if (strncmp (name, ".rel", 4) != 0
01088 || strcmp (bfd_get_section_name (abfd, sec),
01089 name + 4) != 0)
01090 {
01091 (*_bfd_error_handler)
01092 (_("%B: bad relocation section name `%s\'"),
01093 abfd, name);
01094 }
01095
01096 if (htab->elf.dynobj == NULL)
01097 htab->elf.dynobj = abfd;
01098
01099 dynobj = htab->elf.dynobj;
01100 sreloc = bfd_get_section_by_name (dynobj, name);
01101 if (sreloc == NULL)
01102 {
01103 flagword flags;
01104
01105 sreloc = bfd_make_section (dynobj, name);
01106 flags = (SEC_HAS_CONTENTS | SEC_READONLY
01107 | SEC_IN_MEMORY | SEC_LINKER_CREATED);
01108 if ((sec->flags & SEC_ALLOC) != 0)
01109 flags |= SEC_ALLOC | SEC_LOAD;
01110 if (sreloc == NULL
01111 || ! bfd_set_section_flags (dynobj, sreloc, flags)
01112 || ! bfd_set_section_alignment (dynobj, sreloc, 2))
01113 return FALSE;
01114 }
01115 elf_section_data (sec)->sreloc = sreloc;
01116 }
01117
01118
01119
01120 if (h != NULL)
01121 {
01122 head = &((struct elf_i386_link_hash_entry *) h)->dyn_relocs;
01123 }
01124 else
01125 {
01126
01127
01128
01129
01130 asection *s;
01131 s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
01132 sec, r_symndx);
01133 if (s == NULL)
01134 return FALSE;
01135
01136 head = ((struct elf_i386_dyn_relocs **)
01137 &elf_section_data (s)->local_dynrel);
01138 }
01139
01140 p = *head;
01141 if (p == NULL || p->sec != sec)
01142 {
01143 bfd_size_type amt = sizeof *p;
01144 p = bfd_alloc (htab->elf.dynobj, amt);
01145 if (p == NULL)
01146 return FALSE;
01147 p->next = *head;
01148 *head = p;
01149 p->sec = sec;
01150 p->count = 0;
01151 p->pc_count = 0;
01152 }
01153
01154 p->count += 1;
01155 if (r_type == R_386_PC32)
01156 p->pc_count += 1;
01157 }
01158 break;
01159
01160
01161
01162 case R_386_GNU_VTINHERIT:
01163 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
01164 return FALSE;
01165 break;
01166
01167
01168
01169 case R_386_GNU_VTENTRY:
01170 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
01171 return FALSE;
01172 break;
01173
01174 default:
01175 break;
01176 }
01177 }
01178
01179 return TRUE;
01180 }
01181
01182
01183
01184
01185 static asection *
01186 elf_i386_gc_mark_hook (asection *sec,
01187 struct bfd_link_info *info ATTRIBUTE_UNUSED,
01188 Elf_Internal_Rela *rel,
01189 struct elf_link_hash_entry *h,
01190 Elf_Internal_Sym *sym)
01191 {
01192 if (h != NULL)
01193 {
01194 switch (ELF32_R_TYPE (rel->r_info))
01195 {
01196 case R_386_GNU_VTINHERIT:
01197 case R_386_GNU_VTENTRY:
01198 break;
01199
01200 default:
01201 switch (h->root.type)
01202 {
01203 case bfd_link_hash_defined:
01204 case bfd_link_hash_defweak:
01205 return h->root.u.def.section;
01206
01207 case bfd_link_hash_common:
01208 return h->root.u.c.p->section;
01209
01210 default:
01211 break;
01212 }
01213 }
01214 }
01215 else
01216 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
01217
01218 return NULL;
01219 }
01220
01221
01222
01223 static bfd_boolean
01224 elf_i386_gc_sweep_hook (bfd *abfd,
01225 struct bfd_link_info *info,
01226 asection *sec,
01227 const Elf_Internal_Rela *relocs)
01228 {
01229 Elf_Internal_Shdr *symtab_hdr;
01230 struct elf_link_hash_entry **sym_hashes;
01231 bfd_signed_vma *local_got_refcounts;
01232 const Elf_Internal_Rela *rel, *relend;
01233
01234 elf_section_data (sec)->local_dynrel = NULL;
01235
01236 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
01237 sym_hashes = elf_sym_hashes (abfd);
01238 local_got_refcounts = elf_local_got_refcounts (abfd);
01239
01240 relend = relocs + sec->reloc_count;
01241 for (rel = relocs; rel < relend; rel++)
01242 {
01243 unsigned long r_symndx;
01244 unsigned int r_type;
01245 struct elf_link_hash_entry *h = NULL;
01246
01247 r_symndx = ELF32_R_SYM (rel->r_info);
01248 if (r_symndx >= symtab_hdr->sh_info)
01249 {
01250 struct elf_i386_link_hash_entry *eh;
01251 struct elf_i386_dyn_relocs **pp;
01252 struct elf_i386_dyn_relocs *p;
01253
01254 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
01255 while (h->root.type == bfd_link_hash_indirect
01256 || h->root.type == bfd_link_hash_warning)
01257 h = (struct elf_link_hash_entry *) h->root.u.i.link;
01258 eh = (struct elf_i386_link_hash_entry *) h;
01259
01260 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
01261 if (p->sec == sec)
01262 {
01263
01264 *pp = p->next;
01265 break;
01266 }
01267 }
01268
01269 r_type = ELF32_R_TYPE (rel->r_info);
01270 r_type = elf_i386_tls_transition (info, r_type, h != NULL);
01271 switch (r_type)
01272 {
01273 case R_386_TLS_LDM:
01274 if (elf_i386_hash_table (info)->tls_ldm_got.refcount > 0)
01275 elf_i386_hash_table (info)->tls_ldm_got.refcount -= 1;
01276 break;
01277
01278 case R_386_TLS_GD:
01279 case R_386_TLS_IE_32:
01280 case R_386_TLS_IE:
01281 case R_386_TLS_GOTIE:
01282 case R_386_GOT32:
01283 if (h != NULL)
01284 {
01285 if (h->got.refcount > 0)
01286 h->got.refcount -= 1;
01287 }
01288 else if (local_got_refcounts != NULL)
01289 {
01290 if (local_got_refcounts[r_symndx] > 0)
01291 local_got_refcounts[r_symndx] -= 1;
01292 }
01293 break;
01294
01295 case R_386_32:
01296 case R_386_PC32:
01297 if (info->shared)
01298 break;
01299
01300
01301 case R_386_PLT32:
01302 if (h != NULL)
01303 {
01304 if (h->plt.refcount > 0)
01305 h->plt.refcount -= 1;
01306 }
01307 break;
01308
01309 default:
01310 break;
01311 }
01312 }
01313
01314 return TRUE;
01315 }
01316
01317
01318
01319
01320
01321
01322
01323 static bfd_boolean
01324 elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
01325 struct elf_link_hash_entry *h)
01326 {
01327 struct elf_i386_link_hash_table *htab;
01328 asection *s;
01329 unsigned int power_of_two;
01330
01331
01332
01333
01334 if (h->type == STT_FUNC
01335 || h->needs_plt)
01336 {
01337 if (h->plt.refcount <= 0
01338 || SYMBOL_CALLS_LOCAL (info, h)
01339 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
01340 && h->root.type == bfd_link_hash_undefweak))
01341 {
01342
01343
01344
01345
01346
01347 h->plt.offset = (bfd_vma) -1;
01348 h->needs_plt = 0;
01349 }
01350
01351 return TRUE;
01352 }
01353 else
01354
01355
01356
01357
01358
01359 h->plt.offset = (bfd_vma) -1;
01360
01361
01362
01363
01364 if (h->u.weakdef != NULL)
01365 {
01366 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
01367 || h->u.weakdef->root.type == bfd_link_hash_defweak);
01368 h->root.u.def.section = h->u.weakdef->root.u.def.section;
01369 h->root.u.def.value = h->u.weakdef->root.u.def.value;
01370 if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
01371 h->non_got_ref = h->u.weakdef->non_got_ref;
01372 return TRUE;
01373 }
01374
01375
01376
01377
01378
01379
01380
01381
01382 if (info->shared)
01383 return TRUE;
01384
01385
01386
01387 if (!h->non_got_ref)
01388 return TRUE;
01389
01390
01391 if (info->nocopyreloc)
01392 {
01393 h->non_got_ref = 0;
01394 return TRUE;
01395 }
01396
01397 if (ELIMINATE_COPY_RELOCS)
01398 {
01399 struct elf_i386_link_hash_entry * eh;
01400 struct elf_i386_dyn_relocs *p;
01401
01402 eh = (struct elf_i386_link_hash_entry *) h;
01403 for (p = eh->dyn_relocs; p != NULL; p = p->next)
01404 {
01405 s = p->sec->output_section;
01406 if (s != NULL && (s->flags & SEC_READONLY) != 0)
01407 break;
01408 }
01409
01410
01411
01412 if (p == NULL)
01413 {
01414 h->non_got_ref = 0;
01415 return TRUE;
01416 }
01417 }
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429 htab = elf_i386_hash_table (info);
01430
01431
01432
01433
01434 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
01435 {
01436 htab->srelbss->size += sizeof (Elf32_External_Rel);
01437 h->needs_copy = 1;
01438 }
01439
01440
01441
01442 power_of_two = bfd_log2 (h->size);
01443 if (power_of_two > 3)
01444 power_of_two = 3;
01445
01446
01447 s = htab->sdynbss;
01448 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
01449 if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
01450 {
01451 if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
01452 return FALSE;
01453 }
01454
01455
01456 h->root.u.def.section = s;
01457 h->root.u.def.value = s->size;
01458
01459
01460 s->size += h->size;
01461
01462 return TRUE;
01463 }
01464
01465
01466
01467
01468 static bfd_boolean
01469 allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
01470 {
01471 struct bfd_link_info *info;
01472 struct elf_i386_link_hash_table *htab;
01473 struct elf_i386_link_hash_entry *eh;
01474 struct elf_i386_dyn_relocs *p;
01475
01476 if (h->root.type == bfd_link_hash_indirect)
01477 return TRUE;
01478
01479 if (h->root.type == bfd_link_hash_warning)
01480
01481
01482
01483 h = (struct elf_link_hash_entry *) h->root.u.i.link;
01484
01485 info = (struct bfd_link_info *) inf;
01486 htab = elf_i386_hash_table (info);
01487
01488 if (htab->elf.dynamic_sections_created
01489 && h->plt.refcount > 0)
01490 {
01491
01492
01493 if (h->dynindx == -1
01494 && !h->forced_local)
01495 {
01496 if (! bfd_elf_link_record_dynamic_symbol (info, h))
01497 return FALSE;
01498 }
01499
01500 if (info->shared
01501 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
01502 {
01503 asection *s = htab->splt;
01504
01505
01506
01507 if (s->size == 0)
01508 s->size += PLT_ENTRY_SIZE;
01509
01510 h->plt.offset = s->size;
01511
01512
01513
01514
01515
01516
01517 if (! info->shared
01518 && !h->def_regular)
01519 {
01520 h->root.u.def.section = s;
01521 h->root.u.def.value = h->plt.offset;
01522 }
01523
01524
01525 s->size += PLT_ENTRY_SIZE;
01526
01527
01528
01529 htab->sgotplt->size += 4;
01530
01531
01532 htab->srelplt->size += sizeof (Elf32_External_Rel);
01533 }
01534 else
01535 {
01536 h->plt.offset = (bfd_vma) -1;
01537 h->needs_plt = 0;
01538 }
01539 }
01540 else
01541 {
01542 h->plt.offset = (bfd_vma) -1;
01543 h->needs_plt = 0;
01544 }
01545
01546
01547
01548 if (h->got.refcount > 0
01549 && !info->shared
01550 && h->dynindx == -1
01551 && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE))
01552 h->got.offset = (bfd_vma) -1;
01553 else if (h->got.refcount > 0)
01554 {
01555 asection *s;
01556 bfd_boolean dyn;
01557 int tls_type = elf_i386_hash_entry(h)->tls_type;
01558
01559
01560
01561 if (h->dynindx == -1
01562 && !h->forced_local)
01563 {
01564 if (! bfd_elf_link_record_dynamic_symbol (info, h))
01565 return FALSE;
01566 }
01567
01568 s = htab->sgot;
01569 h->got.offset = s->size;
01570 s->size += 4;
01571
01572 if (tls_type == GOT_TLS_GD || tls_type == GOT_TLS_IE_BOTH)
01573 s->size += 4;
01574 dyn = htab->elf.dynamic_sections_created;
01575
01576
01577
01578
01579
01580 if (tls_type == GOT_TLS_IE_BOTH)
01581 htab->srelgot->size += 2 * sizeof (Elf32_External_Rel);
01582 else if ((tls_type == GOT_TLS_GD && h->dynindx == -1)
01583 || (tls_type & GOT_TLS_IE))
01584 htab->srelgot->size += sizeof (Elf32_External_Rel);
01585 else if (tls_type == GOT_TLS_GD)
01586 htab->srelgot->size += 2 * sizeof (Elf32_External_Rel);
01587 else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
01588 || h->root.type != bfd_link_hash_undefweak)
01589 && (info->shared
01590 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
01591 htab->srelgot->size += sizeof (Elf32_External_Rel);
01592 }
01593 else
01594 h->got.offset = (bfd_vma) -1;
01595
01596 eh = (struct elf_i386_link_hash_entry *) h;
01597 if (eh->dyn_relocs == NULL)
01598 return TRUE;
01599
01600
01601
01602
01603
01604
01605
01606 if (info->shared)
01607 {
01608
01609
01610
01611
01612
01613
01614 if (SYMBOL_CALLS_LOCAL (info, h))
01615 {
01616 struct elf_i386_dyn_relocs **pp;
01617
01618 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
01619 {
01620 p->count -= p->pc_count;
01621 p->pc_count = 0;
01622 if (p->count == 0)
01623 *pp = p->next;
01624 else
01625 pp = &p->next;
01626 }
01627 }
01628
01629
01630
01631 if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
01632 && h->root.type == bfd_link_hash_undefweak)
01633 eh->dyn_relocs = NULL;
01634 }
01635 else if (ELIMINATE_COPY_RELOCS)
01636 {
01637
01638
01639
01640
01641 if (!h->non_got_ref
01642 && ((h->def_dynamic
01643 && !h->def_regular)
01644 || (htab->elf.dynamic_sections_created
01645 && (h->root.type == bfd_link_hash_undefweak
01646 || h->root.type == bfd_link_hash_undefined))))
01647 {
01648
01649
01650 if (h->dynindx == -1
01651 && !h->forced_local)
01652 {
01653 if (! bfd_elf_link_record_dynamic_symbol (info, h))
01654 return FALSE;
01655 }
01656
01657
01658
01659 if (h->dynindx != -1)
01660 goto keep;
01661 }
01662
01663 eh->dyn_relocs = NULL;
01664
01665 keep: ;
01666 }
01667
01668
01669 for (p = eh->dyn_relocs; p != NULL; p = p->next)
01670 {
01671 asection *sreloc = elf_section_data (p->sec)->sreloc;
01672 sreloc->size += p->count * sizeof (Elf32_External_Rel);
01673 }
01674
01675 return TRUE;
01676 }
01677
01678
01679
01680 static bfd_boolean
01681 readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
01682 {
01683 struct elf_i386_link_hash_entry *eh;
01684 struct elf_i386_dyn_relocs *p;
01685
01686 if (h->root.type == bfd_link_hash_warning)
01687 h = (struct elf_link_hash_entry *) h->root.u.i.link;
01688
01689 eh = (struct elf_i386_link_hash_entry *) h;
01690 for (p = eh->dyn_relocs; p != NULL; p = p->next)
01691 {
01692 asection *s = p->sec->output_section;
01693
01694 if (s != NULL && (s->flags & SEC_READONLY) != 0)
01695 {
01696 struct bfd_link_info *info = (struct bfd_link_info *) inf;
01697
01698 info->flags |= DF_TEXTREL;
01699
01700
01701 return FALSE;
01702 }
01703 }
01704 return TRUE;
01705 }
01706
01707
01708
01709 static bfd_boolean
01710 elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
01711 struct bfd_link_info *info)
01712 {
01713 struct elf_i386_link_hash_table *htab;
01714 bfd *dynobj;
01715 asection *s;
01716 bfd_boolean relocs;
01717 bfd *ibfd;
01718
01719 htab = elf_i386_hash_table (info);
01720 dynobj = htab->elf.dynobj;
01721 if (dynobj == NULL)
01722 abort ();
01723
01724 if (htab->elf.dynamic_sections_created)
01725 {
01726
01727 if (info->executable)
01728 {
01729 s = bfd_get_section_by_name (dynobj, ".interp");
01730 if (s == NULL)
01731 abort ();
01732 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
01733 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
01734 }
01735 }
01736
01737
01738
01739 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
01740 {
01741 bfd_signed_vma *local_got;
01742 bfd_signed_vma *end_local_got;
01743 char *local_tls_type;
01744 bfd_size_type locsymcount;
01745 Elf_Internal_Shdr *symtab_hdr;
01746 asection *srel;
01747
01748 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
01749 continue;
01750
01751 for (s = ibfd->sections; s != NULL; s = s->next)
01752 {
01753 struct elf_i386_dyn_relocs *p;
01754
01755 for (p = *((struct elf_i386_dyn_relocs **)
01756 &elf_section_data (s)->local_dynrel);
01757 p != NULL;
01758 p = p->next)
01759 {
01760 if (!bfd_is_abs_section (p->sec)
01761 && bfd_is_abs_section (p->sec->output_section))
01762 {
01763
01764
01765
01766
01767 }
01768 else if (p->count != 0)
01769 {
01770 srel = elf_section_data (p->sec)->sreloc;
01771 srel->size += p->count * sizeof (Elf32_External_Rel);
01772 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
01773 info->flags |= DF_TEXTREL;
01774 }
01775 }
01776 }
01777
01778 local_got = elf_local_got_refcounts (ibfd);
01779 if (!local_got)
01780 continue;
01781
01782 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
01783 locsymcount = symtab_hdr->sh_info;
01784 end_local_got = local_got + locsymcount;
01785 local_tls_type = elf_i386_local_got_tls_type (ibfd);
01786 s = htab->sgot;
01787 srel = htab->srelgot;
01788 for (; local_got < end_local_got; ++local_got, ++local_tls_type)
01789 {
01790 if (*local_got > 0)
01791 {
01792 *local_got = s->size;
01793 s->size += 4;
01794 if (*local_tls_type == GOT_TLS_GD
01795 || *local_tls_type == GOT_TLS_IE_BOTH)
01796 s->size += 4;
01797 if (info->shared
01798 || *local_tls_type == GOT_TLS_GD
01799 || (*local_tls_type & GOT_TLS_IE))
01800 {
01801 if (*local_tls_type == GOT_TLS_IE_BOTH)
01802 srel->size += 2 * sizeof (Elf32_External_Rel);
01803 else
01804 srel->size += sizeof (Elf32_External_Rel);
01805 }
01806 }
01807 else
01808 *local_got = (bfd_vma) -1;
01809 }
01810 }
01811
01812 if (htab->tls_ldm_got.refcount > 0)
01813 {
01814
01815
01816 htab->tls_ldm_got.offset = htab->sgot->size;
01817 htab->sgot->size += 8;
01818 htab->srelgot->size += sizeof (Elf32_External_Rel);
01819 }
01820 else
01821 htab->tls_ldm_got.offset = -1;
01822
01823
01824
01825 elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
01826
01827
01828
01829 relocs = FALSE;
01830 for (s = dynobj->sections; s != NULL; s = s->next)
01831 {
01832 if ((s->flags & SEC_LINKER_CREATED) == 0)
01833 continue;
01834
01835 if (s == htab->splt
01836 || s == htab->sgot
01837 || s == htab->sgotplt)
01838 {
01839
01840
01841 }
01842 else if (strncmp (bfd_get_section_name (dynobj, s), ".rel", 4) == 0)
01843 {
01844 if (s->size != 0 && s != htab->srelplt)
01845 relocs = TRUE;
01846
01847
01848
01849 s->reloc_count = 0;
01850 }
01851 else
01852 {
01853
01854 continue;
01855 }
01856
01857 if (s->size == 0)
01858 {
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869 _bfd_strip_section_from_output (info, s);
01870 continue;
01871 }
01872
01873
01874
01875
01876
01877
01878 s->contents = bfd_zalloc (dynobj, s->size);
01879 if (s->contents == NULL)
01880 return FALSE;
01881 }
01882
01883 if (htab->elf.dynamic_sections_created)
01884 {
01885
01886
01887
01888
01889
01890 #define add_dynamic_entry(TAG, VAL) \
01891 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
01892
01893 if (info->executable)
01894 {
01895 if (!add_dynamic_entry (DT_DEBUG, 0))
01896 return FALSE;
01897 }
01898
01899 if (htab->splt->size != 0)
01900 {
01901 if (!add_dynamic_entry (DT_PLTGOT, 0)
01902 || !add_dynamic_entry (DT_PLTRELSZ, 0)
01903 || !add_dynamic_entry (DT_PLTREL, DT_REL)
01904 || !add_dynamic_entry (DT_JMPREL, 0))
01905 return FALSE;
01906 }
01907
01908 if (relocs)
01909 {
01910 if (!add_dynamic_entry (DT_REL, 0)
01911 || !add_dynamic_entry (DT_RELSZ, 0)
01912 || !add_dynamic_entry (DT_RELENT, sizeof (Elf32_External_Rel)))
01913 return FALSE;
01914
01915
01916
01917 if ((info->flags & DF_TEXTREL) == 0)
01918 elf_link_hash_traverse (&htab->elf, readonly_dynrelocs,
01919 (PTR) info);
01920
01921 if ((info->flags & DF_TEXTREL) != 0)
01922 {
01923 if (!add_dynamic_entry (DT_TEXTREL, 0))
01924 return FALSE;
01925 }
01926 }
01927 }
01928 #undef add_dynamic_entry
01929
01930 return TRUE;
01931 }
01932
01933
01934
01935
01936 static bfd_boolean
01937 elf_i386_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
01938 Elf_Internal_Shdr *hdr,
01939 asection *sec)
01940 {
01941 register const char *name;
01942
01943 name = bfd_get_section_name (abfd, sec);
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961 if (strcmp (name, ".reloc") == 0)
01962 hdr->sh_type = SHT_PROGBITS;
01963
01964 return TRUE;
01965 }
01966
01967
01968
01969
01970
01971 static bfd_vma
01972 dtpoff_base (struct bfd_link_info *info)
01973 {
01974
01975 if (elf_hash_table (info)->tls_sec == NULL)
01976 return 0;
01977 return elf_hash_table (info)->tls_sec->vma;
01978 }
01979
01980
01981
01982
01983 static bfd_vma
01984 tpoff (struct bfd_link_info *info, bfd_vma address)
01985 {
01986 struct elf_link_hash_table *htab = elf_hash_table (info);
01987
01988
01989 if (htab->tls_sec == NULL)
01990 return 0;
01991 return htab->tls_size + htab->tls_sec->vma - address;
01992 }
01993
01994
01995
01996 static bfd_boolean
01997 elf_i386_relocate_section (bfd *output_bfd,
01998 struct bfd_link_info *info,
01999 bfd *input_bfd,
02000 asection *input_section,
02001 bfd_byte *contents,
02002 Elf_Internal_Rela *relocs,
02003 Elf_Internal_Sym *local_syms,
02004 asection **local_sections)
02005 {
02006 struct elf_i386_link_hash_table *htab;
02007 Elf_Internal_Shdr *symtab_hdr;
02008 struct elf_link_hash_entry **sym_hashes;
02009 bfd_vma *local_got_offsets;
02010 Elf_Internal_Rela *rel;
02011 Elf_Internal_Rela *relend;
02012
02013 htab = elf_i386_hash_table (info);
02014 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
02015 sym_hashes = elf_sym_hashes (input_bfd);
02016 local_got_offsets = elf_local_got_offsets (input_bfd);
02017
02018 rel = relocs;
02019 relend = relocs + input_section->reloc_count;
02020 for (; rel < relend; rel++)
02021 {
02022 unsigned int r_type;
02023 reloc_howto_type *howto;
02024 unsigned long r_symndx;
02025 struct elf_link_hash_entry *h;
02026 Elf_Internal_Sym *sym;
02027 asection *sec;
02028 bfd_vma off;
02029 bfd_vma relocation;
02030 bfd_boolean unresolved_reloc;
02031 bfd_reloc_status_type r;
02032 unsigned int indx;
02033 int tls_type;
02034
02035 r_type = ELF32_R_TYPE (rel->r_info);
02036 if (r_type == R_386_GNU_VTINHERIT
02037 || r_type == R_386_GNU_VTENTRY)
02038 continue;
02039
02040 if ((indx = r_type) >= R_386_standard
02041 && ((indx = r_type - R_386_ext_offset) - R_386_standard
02042 >= R_386_ext - R_386_standard)
02043 && ((indx = r_type - R_386_tls_offset) - R_386_ext
02044 >= R_386_tls - R_386_ext))
02045 {
02046 (*_bfd_error_handler)
02047 (_("%B: unrecognized relocation (0x%x) in section `%A'"),
02048 input_bfd, input_section, r_type);
02049 bfd_set_error (bfd_error_bad_value);
02050 return FALSE;
02051 }
02052 howto = elf_howto_table + indx;
02053
02054 r_symndx = ELF32_R_SYM (rel->r_info);
02055
02056 if (info->relocatable)
02057 {
02058 bfd_vma val;
02059 bfd_byte *where;
02060
02061
02062
02063
02064
02065 if (r_symndx >= symtab_hdr->sh_info)
02066 continue;
02067
02068 sym = local_syms + r_symndx;
02069 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
02070 continue;
02071
02072 sec = local_sections[r_symndx];
02073 val = sec->output_offset;
02074 if (val == 0)
02075 continue;
02076
02077 where = contents + rel->r_offset;
02078 switch (howto->size)
02079 {
02080
02081 case 0:
02082 val += bfd_get_8 (input_bfd, where);
02083 bfd_put_8 (input_bfd, val, where);
02084 break;
02085 case 1:
02086 val += bfd_get_16 (input_bfd, where);
02087 bfd_put_16 (input_bfd, val, where);
02088 break;
02089 case 2:
02090 val += bfd_get_32 (input_bfd, where);
02091 bfd_put_32 (input_bfd, val, where);
02092 break;
02093 default:
02094 abort ();
02095 }
02096 continue;
02097 }
02098
02099
02100 h = NULL;
02101 sym = NULL;
02102 sec = NULL;
02103 unresolved_reloc = FALSE;
02104 if (r_symndx < symtab_hdr->sh_info)
02105 {
02106 sym = local_syms + r_symndx;
02107 sec = local_sections[r_symndx];
02108 relocation = (sec->output_section->vma
02109 + sec->output_offset
02110 + sym->st_value);
02111 if ((sec->flags & SEC_MERGE)
02112 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
02113 {
02114 asection *msec;
02115 bfd_vma addend;
02116 bfd_byte *where = contents + rel->r_offset;
02117
02118 switch (howto->size)
02119 {
02120 case 0:
02121 addend = bfd_get_8 (input_bfd, where);
02122 if (howto->pc_relative)
02123 {
02124 addend = (addend ^ 0x80) - 0x80;
02125 addend += 1;
02126 }
02127 break;
02128 case 1:
02129 addend = bfd_get_16 (input_bfd, where);
02130 if (howto->pc_relative)
02131 {
02132 addend = (addend ^ 0x8000) - 0x8000;
02133 addend += 2;
02134 }
02135 break;
02136 case 2:
02137 addend = bfd_get_32 (input_bfd, where);
02138 if (howto->pc_relative)
02139 {
02140 addend = (addend ^ 0x80000000) - 0x80000000;
02141 addend += 4;
02142 }
02143 break;
02144 default:
02145 abort ();
02146 }
02147
02148 msec = sec;
02149 addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
02150 addend -= relocation;
02151 addend += msec->output_section->vma + msec->output_offset;
02152
02153 switch (howto->size)
02154 {
02155 case 0:
02156
02157 if (howto->pc_relative)
02158 addend -= 1;
02159 bfd_put_8 (input_bfd, addend, where);
02160 break;
02161 case 1:
02162 if (howto->pc_relative)
02163 addend -= 2;
02164 bfd_put_16 (input_bfd, addend, where);
02165 break;
02166 case 2:
02167 if (howto->pc_relative)
02168 addend -= 4;
02169 bfd_put_32 (input_bfd, addend, where);
02170 break;
02171 }
02172 }
02173 }
02174 else
02175 {
02176 bfd_boolean warned;
02177
02178 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
02179 r_symndx, symtab_hdr, sym_hashes,
02180 h, sec, relocation,
02181 unresolved_reloc, warned);
02182 }
02183
02184 if (r_symndx == 0)
02185 {
02186
02187
02188
02189
02190 r_type = R_386_NONE;
02191
02192 relocation = 0;
02193 if (howto->pc_relative)
02194 relocation = (input_section->output_section->vma
02195 + input_section->output_offset
02196 + rel->r_offset);
02197 }
02198
02199 switch (r_type)
02200 {
02201 case R_386_GOT32:
02202
02203
02204 if (htab->sgot == NULL)
02205 abort ();
02206
02207 if (h != NULL)
02208 {
02209 bfd_boolean dyn;
02210
02211 off = h->got.offset;
02212 dyn = htab->elf.dynamic_sections_created;
02213 if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
02214 || (info->shared
02215 && SYMBOL_REFERENCES_LOCAL (info, h))
02216 || (ELF_ST_VISIBILITY (h->other)
02217 && h->root.type == bfd_link_hash_undefweak))
02218 {
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231 if ((off & 1) != 0)
02232 off &= ~1;
02233 else
02234 {
02235 bfd_put_32 (output_bfd, relocation,
02236 htab->sgot->contents + off);
02237 h->got.offset |= 1;
02238 }
02239 }
02240 else
02241 unresolved_reloc = FALSE;
02242 }
02243 else
02244 {
02245 if (local_got_offsets == NULL)
02246 abort ();
02247
02248 off = local_got_offsets[r_symndx];
02249
02250
02251
02252
02253 if ((off & 1) != 0)
02254 off &= ~1;
02255 else
02256 {
02257 bfd_put_32 (output_bfd, relocation,
02258 htab->sgot->contents + off);
02259
02260 if (info->shared)
02261 {
02262 asection *s;
02263 Elf_Internal_Rela outrel;
02264 bfd_byte *loc;
02265
02266 s = htab->srelgot;
02267 if (s == NULL)
02268 abort ();
02269
02270 outrel.r_offset = (htab->sgot->output_section->vma
02271 + htab->sgot->output_offset
02272 + off);
02273 outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
02274 loc = s->contents;
02275 loc += s->reloc_count++ * sizeof (Elf32_External_Rel);
02276 bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
02277 }
02278
02279 local_got_offsets[r_symndx] |= 1;
02280 }
02281 }
02282
02283 if (off >= (bfd_vma) -2)
02284 abort ();
02285
02286 relocation = htab->sgot->output_section->vma
02287 + htab->sgot->output_offset + off
02288 - htab->sgotplt->output_section->vma
02289 - htab->sgotplt->output_offset;
02290 break;
02291
02292 case R_386_GOTOFF:
02293
02294
02295
02296
02297
02298
02299 if (info->shared
02300 && !info->executable
02301 && h
02302 && h->def_regular
02303 && h->type == STT_FUNC
02304 && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
02305 {
02306 (*_bfd_error_handler)
02307 (_("%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"),
02308 input_bfd, h->root.root.string);
02309 bfd_set_error (bfd_error_bad_value);
02310 return FALSE;
02311 }
02312
02313
02314
02315
02316
02317
02318 relocation -= htab->sgotplt->output_section->vma
02319 + htab->sgotplt->output_offset;
02320 break;
02321
02322 case R_386_GOTPC:
02323
02324 relocation = htab->sgotplt->output_section->vma
02325 + htab->sgotplt->output_offset;
02326 unresolved_reloc = FALSE;
02327 break;
02328
02329 case R_386_PLT32:
02330
02331
02332
02333
02334
02335 if (h == NULL)
02336 break;
02337
02338 if (h->plt.offset == (bfd_vma) -1
02339 || htab->splt == NULL)
02340 {
02341
02342
02343
02344 break;
02345 }
02346
02347 relocation = (htab->splt->output_section->vma
02348 + htab->splt->output_offset
02349 + h->plt.offset);
02350 unresolved_reloc = FALSE;
02351 break;
02352
02353 case R_386_32:
02354 case R_386_PC32:
02355 if ((input_section->flags & SEC_ALLOC) == 0)
02356 break;
02357
02358 if ((info->shared
02359 && (h == NULL
02360 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
02361 || h->root.type != bfd_link_hash_undefweak)
02362 && (r_type != R_386_PC32
02363 || !SYMBOL_CALLS_LOCAL (info, h)))
02364 || (ELIMINATE_COPY_RELOCS
02365 && !info->shared
02366 && h != NULL
02367 && h->dynindx != -1
02368 && !h->non_got_ref
02369 && ((h->def_dynamic
02370 && !h->def_regular)
02371 || h->root.type == bfd_link_hash_undefweak
02372 || h->root.type == bfd_link_hash_undefined)))
02373 {
02374 Elf_Internal_Rela outrel;
02375 bfd_byte *loc;
02376 bfd_boolean skip, relocate;
02377 asection *sreloc;
02378
02379
02380
02381
02382
02383 skip = FALSE;
02384 relocate = FALSE;
02385
02386 outrel.r_offset =
02387 _bfd_elf_section_offset (output_bfd, info, input_section,
02388 rel->r_offset);
02389 if (outrel.r_offset == (bfd_vma) -1)
02390 skip = TRUE;
02391 else if (outrel.r_offset == (bfd_vma) -2)
02392 skip = TRUE, relocate = TRUE;
02393 outrel.r_offset += (input_section->output_section->vma
02394 + input_section->output_offset);
02395
02396 if (skip)
02397 memset (&outrel, 0, sizeof outrel);
02398 else if (h != NULL
02399 && h->dynindx != -1
02400 && (r_type == R_386_PC32
02401 || !info->shared
02402 || !info->symbolic
02403 || !h->def_regular))
02404 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
02405 else
02406 {
02407
02408 relocate = TRUE;
02409 outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
02410 }
02411
02412 sreloc = elf_section_data (input_section)->sreloc;
02413 if (sreloc == NULL)
02414 abort ();
02415
02416 loc = sreloc->contents;
02417 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rel);
02418 bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
02419
02420
02421
02422
02423
02424 if (! relocate)
02425 continue;
02426 }
02427 break;
02428
02429 case R_386_TLS_IE:
02430 if (info->shared)
02431 {
02432 Elf_Internal_Rela outrel;
02433 bfd_byte *loc;
02434 asection *sreloc;
02435
02436 outrel.r_offset = rel->r_offset
02437 + input_section->output_section->vma
02438 + input_section->output_offset;
02439 outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
02440 sreloc = elf_section_data (input_section)->sreloc;
02441 if (sreloc == NULL)
02442 abort ();
02443 loc = sreloc->contents;
02444 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rel);
02445 bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
02446 }
02447
02448
02449 case R_386_TLS_GD:
02450 case R_386_TLS_IE_32:
02451 case R_386_TLS_GOTIE:
02452 r_type = elf_i386_tls_transition (info, r_type, h == NULL);
02453 tls_type = GOT_UNKNOWN;
02454 if (h == NULL && local_got_offsets)
02455 tls_type = elf_i386_local_got_tls_type (input_bfd) [r_symndx];
02456 else if (h != NULL)
02457 {
02458 tls_type = elf_i386_hash_entry(h)->tls_type;
02459 if (!info->shared && h->dynindx == -1 && (tls_type & GOT_TLS_IE))
02460 r_type = R_386_TLS_LE_32;
02461 }
02462 if (tls_type == GOT_TLS_IE)
02463 tls_type = GOT_TLS_IE_NEG;
02464 if (r_type == R_386_TLS_GD)
02465 {
02466 if (tls_type == GOT_TLS_IE_POS)
02467 r_type = R_386_TLS_GOTIE;
02468 else if (tls_type & GOT_TLS_IE)
02469 r_type = R_386_TLS_IE_32;
02470 }
02471
02472 if (r_type == R_386_TLS_LE_32)
02473 {
02474 BFD_ASSERT (! unresolved_reloc);
02475 if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GD)
02476 {
02477 unsigned int val, type;
02478 bfd_vma roff;
02479
02480
02481 BFD_ASSERT (rel->r_offset >= 2);
02482 type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
02483 BFD_ASSERT (type == 0x8d || type == 0x04);
02484 BFD_ASSERT (rel->r_offset + 9 <= input_section->size);
02485 BFD_ASSERT (bfd_get_8 (input_bfd,
02486 contents + rel->r_offset + 4)
02487 == 0xe8);
02488 BFD_ASSERT (rel + 1 < relend);
02489 BFD_ASSERT (ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32);
02490 roff = rel->r_offset + 5;
02491 val = bfd_get_8 (input_bfd,
02492 contents + rel->r_offset - 1);
02493 if (type == 0x04)
02494 {
02495
02496
02497
02498
02499 BFD_ASSERT (rel->r_offset >= 3);
02500 BFD_ASSERT (bfd_get_8 (input_bfd,
02501 contents + rel->r_offset - 3)
02502 == 0x8d);
02503 BFD_ASSERT ((val & 0xc7) == 0x05 && val != (4 << 3));
02504 memcpy (contents + rel->r_offset - 3,
02505 "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
02506 }
02507 else
02508 {
02509 BFD_ASSERT ((val & 0xf8) == 0x80 && (val & 7) != 4);
02510 if (rel->r_offset + 10 <= input_section->size
02511 && bfd_get_8 (input_bfd,
02512 contents + rel->r_offset + 9) == 0x90)
02513 {
02514
02515
02516
02517
02518 memcpy (contents + rel->r_offset - 2,
02519 "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
02520 roff = rel->r_offset + 6;
02521 }
02522 else
02523 {
02524
02525
02526
02527
02528 memcpy (contents + rel->r_offset - 2,
02529 "\x65\xa1\0\0\0\0\x2d\0\0\0", 11);
02530 }
02531 }
02532 bfd_put_32 (output_bfd, tpoff (info, relocation),
02533 contents + roff);
02534
02535 rel++;
02536 continue;
02537 }
02538 else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_IE)
02539 {
02540 unsigned int val, type;
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551 BFD_ASSERT (rel->r_offset >= 1);
02552 val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
02553 BFD_ASSERT (rel->r_offset + 4 <= input_section->size);
02554 if (val == 0xa1)
02555 {
02556
02557 bfd_put_8 (output_bfd, 0xb8,
02558 contents + rel->r_offset - 1);
02559 }
02560 else
02561 {
02562 BFD_ASSERT (rel->r_offset >= 2);
02563 type = bfd_get_8 (input_bfd,
02564 contents + rel->r_offset - 2);
02565 switch (type)
02566 {
02567 case 0x8b:
02568
02569 BFD_ASSERT ((val & 0xc7) == 0x05);
02570 bfd_put_8 (output_bfd, 0xc7,
02571 contents + rel->r_offset - 2);
02572 bfd_put_8 (output_bfd,
02573 0xc0 | ((val >> 3) & 7),
02574 contents + rel->r_offset - 1);
02575 break;
02576 case 0x03:
02577
02578 BFD_ASSERT ((val & 0xc7) == 0x05);
02579 bfd_put_8 (output_bfd, 0x81,
02580 contents + rel->r_offset - 2);
02581 bfd_put_8 (output_bfd,
02582 0xc0 | ((val >> 3) & 7),
02583 contents + rel->r_offset - 1);
02584 break;
02585 default:
02586 BFD_FAIL ();
02587 break;
02588 }
02589 }
02590 bfd_put_32 (output_bfd, -tpoff (info, relocation),
02591 contents + rel->r_offset);
02592 continue;
02593 }
02594 else
02595 {
02596 unsigned int val, type;
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607 BFD_ASSERT (rel->r_offset >= 2);
02608 type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
02609 val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
02610 BFD_ASSERT (rel->r_offset + 4 <= input_section->size);
02611 BFD_ASSERT ((val & 0xc0) == 0x80 && (val & 7) != 4);
02612 if (type == 0x8b)
02613 {
02614
02615 bfd_put_8 (output_bfd, 0xc7,
02616 contents + rel->r_offset - 2);
02617 bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
02618 contents + rel->r_offset - 1);
02619 }
02620 else if (type == 0x2b)
02621 {
02622
02623 bfd_put_8 (output_bfd, 0x81,
02624 contents + rel->r_offset - 2);
02625 bfd_put_8 (output_bfd, 0xe8 | ((val >> 3) & 7),
02626 contents + rel->r_offset - 1);
02627 }
02628 else if (type == 0x03)
02629 {
02630
02631 bfd_put_8 (output_bfd, 0x81,
02632 contents + rel->r_offset - 2);
02633 bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
02634 contents + rel->r_offset - 1);
02635 }
02636 else
02637 BFD_FAIL ();
02638 if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTIE)
02639 bfd_put_32 (output_bfd, -tpoff (info, relocation),
02640 contents + rel->r_offset);
02641 else
02642 bfd_put_32 (output_bfd, tpoff (info, relocation),
02643 contents + rel->r_offset);
02644 continue;
02645 }
02646 }
02647
02648 if (htab->sgot == NULL)
02649 abort ();
02650
02651 if (h != NULL)
02652 off = h->got.offset;
02653 else
02654 {
02655 if (local_got_offsets == NULL)
02656 abort ();
02657
02658 off = local_got_offsets[r_symndx];
02659 }
02660
02661 if ((off & 1) != 0)
02662 off &= ~1;
02663 else
02664 {
02665 Elf_Internal_Rela outrel;
02666 bfd_byte *loc;
02667 int dr_type, indx;
02668
02669 if (htab->srelgot == NULL)
02670 abort ();
02671
02672 outrel.r_offset = (htab->sgot->output_section->vma
02673 + htab->sgot->output_offset + off);
02674
02675 indx = h && h->dynindx != -1 ? h->dynindx : 0;
02676 if (r_type == R_386_TLS_GD)
02677 dr_type = R_386_TLS_DTPMOD32;
02678 else if (tls_type == GOT_TLS_IE_POS)
02679 dr_type = R_386_TLS_TPOFF;
02680 else
02681 dr_type = R_386_TLS_TPOFF32;
02682 if (dr_type == R_386_TLS_TPOFF && indx == 0)
02683 bfd_put_32 (output_bfd, relocation - dtpoff_base (info),
02684 htab->sgot->contents + off);
02685 else if (dr_type == R_386_TLS_TPOFF32 && indx == 0)
02686 bfd_put_32 (output_bfd, dtpoff_base (info) - relocation,
02687 htab->sgot->contents + off);
02688 else
02689 bfd_put_32 (output_bfd, 0,
02690 htab->sgot->contents + off);
02691 outrel.r_info = ELF32_R_INFO (indx, dr_type);
02692 loc = htab->srelgot->contents;
02693 loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rel);
02694 bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
02695
02696 if (r_type == R_386_TLS_GD)
02697 {
02698 if (indx == 0)
02699 {
02700 BFD_ASSERT (! unresolved_reloc);
02701 bfd_put_32 (output_bfd,
02702 relocation - dtpoff_base (info),
02703 htab->sgot->contents + off + 4);
02704 }
02705 else
02706 {
02707 bfd_put_32 (output_bfd, 0,
02708 htab->sgot->contents + off + 4);
02709 outrel.r_info = ELF32_R_INFO (indx,
02710 R_386_TLS_DTPOFF32);
02711 outrel.r_offset += 4;
02712 htab->srelgot->reloc_count++;
02713 loc += sizeof (Elf32_External_Rel);
02714 bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
02715 }
02716 }
02717 else if (tls_type == GOT_TLS_IE_BOTH)
02718 {
02719 bfd_put_32 (output_bfd,
02720 indx == 0 ? relocation - dtpoff_base (info) : 0,
02721 htab->sgot->contents + off + 4);
02722 outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);
02723 outrel.r_offset += 4;
02724 htab->srelgot->reloc_count++;
02725 loc += sizeof (Elf32_External_Rel);
02726 bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
02727 }
02728
02729 if (h != NULL)
02730 h->got.offset |= 1;
02731 else
02732 local_got_offsets[r_symndx] |= 1;
02733 }
02734
02735 if (off >= (bfd_vma) -2)
02736 abort ();
02737 if (r_type == ELF32_R_TYPE (rel->r_info))
02738 {
02739 bfd_vma g_o_t = htab->sgotplt->output_section->vma
02740 + htab->sgotplt->output_offset;
02741 relocation = htab->sgot->output_section->vma
02742 + htab->sgot->output_offset + off - g_o_t;
02743 if ((r_type == R_386_TLS_IE || r_type == R_386_TLS_GOTIE)
02744 && tls_type == GOT_TLS_IE_BOTH)
02745 relocation += 4;
02746 if (r_type == R_386_TLS_IE)
02747 relocation += g_o_t;
02748 unresolved_reloc = FALSE;
02749 }
02750 else
02751 {
02752 unsigned int val, type;
02753 bfd_vma roff;
02754
02755
02756 BFD_ASSERT (rel->r_offset >= 2);
02757 type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
02758 BFD_ASSERT (type == 0x8d || type == 0x04);
02759 BFD_ASSERT (rel->r_offset + 9 <= input_section->size);
02760 BFD_ASSERT (bfd_get_8 (input_bfd, contents + rel->r_offset + 4)
02761 == 0xe8);
02762 BFD_ASSERT (rel + 1 < relend);
02763 BFD_ASSERT (ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32);
02764 roff = rel->r_offset - 3;
02765 val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
02766 if (type == 0x04)
02767 {
02768
02769
02770
02771 BFD_ASSERT (rel->r_offset >= 3);
02772 BFD_ASSERT (bfd_get_8 (input_bfd,
02773 contents + rel->r_offset - 3)
02774 == 0x8d);
02775 BFD_ASSERT ((val & 0xc7) == 0x05 && val != (4 << 3));
02776 val >>= 3;
02777 }
02778 else
02779 {
02780
02781
02782
02783 BFD_ASSERT (rel->r_offset + 10 <= input_section->size);
02784 BFD_ASSERT ((val & 0xf8) == 0x80 && (val & 7) != 4);
02785 BFD_ASSERT (bfd_get_8 (input_bfd,
02786 contents + rel->r_offset + 9)
02787 == 0x90);
02788 roff = rel->r_offset - 2;
02789 }
02790 memcpy (contents + roff,
02791 "\x65\xa1\0\0\0\0\x2b\x80\0\0\0", 12);
02792 contents[roff + 7] = 0x80 | (val & 7);
02793
02794
02795
02796
02797
02798 if (r_type == R_386_TLS_GOTIE)
02799 {
02800 contents[roff + 6] = 0x03;
02801 if (tls_type == GOT_TLS_IE_BOTH)
02802 off += 4;
02803 }
02804 bfd_put_32 (output_bfd,
02805 htab->sgot->output_section->vma
02806 + htab->sgot->output_offset + off
02807 - htab->sgotplt->output_section->vma
02808 - htab->sgotplt->output_offset,
02809 contents + roff + 8);
02810
02811 rel++;
02812 continue;
02813 }
02814 break;
02815
02816 case R_386_TLS_LDM:
02817 if (! info->shared)
02818 {
02819 unsigned int val;
02820
02821
02822
02823
02824
02825
02826 BFD_ASSERT (rel->r_offset >= 2);
02827 BFD_ASSERT (bfd_get_8 (input_bfd, contents + rel->r_offset - 2)
02828 == 0x8d);
02829 val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
02830 BFD_ASSERT ((val & 0xf8) == 0x80 && (val & 7) != 4);
02831 BFD_ASSERT (rel->r_offset + 9 <= input_section->size);
02832 BFD_ASSERT (bfd_get_8 (input_bfd, contents + rel->r_offset + 4)
02833 == 0xe8);
02834 BFD_ASSERT (rel + 1 < relend);
02835 BFD_ASSERT (ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32);
02836 memcpy (contents + rel->r_offset - 2,
02837 "\x65\xa1\0\0\0\0\x90\x8d\x74\x26", 11);
02838
02839 rel++;
02840 continue;
02841 }
02842
02843 if (htab->sgot == NULL)
02844 abort ();
02845
02846 off = htab->tls_ldm_got.offset;
02847 if (off & 1)
02848 off &= ~1;
02849 else
02850 {
02851 Elf_Internal_Rela outrel;
02852 bfd_byte *loc;
02853
02854 if (htab->srelgot == NULL)
02855 abort ();
02856
02857 outrel.r_offset = (htab->sgot->output_section->vma
02858 + htab->sgot->output_offset + off);
02859
02860 bfd_put_32 (output_bfd, 0,
02861 htab->sgot->contents + off);
02862 bfd_put_32 (output_bfd, 0,
02863 htab->sgot->contents + off + 4);
02864 outrel.r_info = ELF32_R_INFO (0, R_386_TLS_DTPMOD32);
02865 loc = htab->srelgot->contents;
02866 loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rel);
02867 bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
02868 htab->tls_ldm_got.offset |= 1;
02869 }
02870 relocation = htab->sgot->output_section->vma
02871 + htab->sgot->output_offset + off
02872 - htab->sgotplt->output_section->vma
02873 - htab->sgotplt->output_offset;
02874 unresolved_reloc = FALSE;
02875 break;
02876
02877 case R_386_TLS_LDO_32:
02878 if (info->shared || (input_section->flags & SEC_CODE) == 0)
02879 relocation -= dtpoff_base (info);
02880 else
02881
02882 relocation = -tpoff (info, relocation);
02883 break;
02884
02885 case R_386_TLS_LE_32:
02886 case R_386_TLS_LE:
02887 if (info->shared)
02888 {
02889 Elf_Internal_Rela outrel;
02890 asection *sreloc;
02891 bfd_byte *loc;
02892 int indx;
02893
02894 outrel.r_offset = rel->r_offset
02895 + input_section->output_section->vma
02896 + input_section->output_offset;
02897 if (h != NULL && h->dynindx != -1)
02898 indx = h->dynindx;
02899 else
02900 indx = 0;
02901 if (r_type == R_386_TLS_LE_32)
02902 outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF32);
02903 else
02904 outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);
02905 sreloc = elf_section_data (input_section)->sreloc;
02906 if (sreloc == NULL)
02907 abort ();
02908 loc = sreloc->contents;
02909 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rel);
02910 bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
02911 if (indx)
02912 continue;
02913 else if (r_type == R_386_TLS_LE_32)
02914 relocation = dtpoff_base (info) - relocation;
02915 else
02916 relocation -= dtpoff_base (info);
02917 }
02918 else if (r_type == R_386_TLS_LE_32)
02919 relocation = tpoff (info, relocation);
02920 else
02921 relocation = -tpoff (info, relocation);
02922 break;
02923
02924 default:
02925 break;
02926 }
02927
02928
02929
02930
02931 if (unresolved_reloc
02932 && !((input_section->flags & SEC_DEBUGGING) != 0
02933 && h->def_dynamic))
02934 {
02935 (*_bfd_error_handler)
02936 (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
02937 input_bfd,
02938 input_section,
02939 (long) rel->r_offset,
02940 h->root.root.string);
02941 return FALSE;
02942 }
02943
02944 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
02945 contents, rel->r_offset,
02946 relocation, 0);
02947
02948 if (r != bfd_reloc_ok)
02949 {
02950 const char *name;
02951
02952 if (h != NULL)
02953 name = h->root.root.string;
02954 else
02955 {
02956 name = bfd_elf_string_from_elf_section (input_bfd,
02957 symtab_hdr->sh_link,
02958 sym->st_name);
02959 if (name == NULL)
02960 return FALSE;
02961 if (*name == '\0')
02962 name = bfd_section_name (input_bfd, sec);
02963 }
02964
02965 if (r == bfd_reloc_overflow)
02966 {
02967 if (! ((*info->callbacks->reloc_overflow)
02968 (info, (h ? &h->root : NULL), name, howto->name,
02969 (bfd_vma) 0, input_bfd, input_section,
02970 rel->r_offset)))
02971 return FALSE;
02972 }
02973 else
02974 {
02975 (*_bfd_error_handler)
02976 (_("%B(%A+0x%lx): reloc against `%s': error %d"),
02977 input_bfd, input_section,
02978 (long) rel->r_offset, name, (int) r);
02979 return FALSE;
02980 }
02981 }
02982 }
02983
02984 return TRUE;
02985 }
02986
02987
02988
02989
02990 static bfd_boolean
02991 elf_i386_finish_dynamic_symbol (bfd *output_bfd,
02992 struct bfd_link_info *info,
02993 struct elf_link_hash_entry *h,
02994 Elf_Internal_Sym *sym)
02995 {
02996 struct elf_i386_link_hash_table *htab;
02997
02998 htab = elf_i386_hash_table (info);
02999
03000 if (h->plt.offset != (bfd_vma) -1)
03001 {
03002 bfd_vma plt_index;
03003 bfd_vma got_offset;
03004 Elf_Internal_Rela rel;
03005 bfd_byte *loc;
03006
03007
03008
03009
03010 if (h->dynindx == -1
03011 || htab->splt == NULL
03012 || htab->sgotplt == NULL
03013 || htab->srelplt == NULL)
03014 abort ();
03015
03016
03017
03018
03019
03020 plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
03021
03022
03023
03024
03025 got_offset = (plt_index + 3) * 4;
03026
03027
03028 if (! info->shared)
03029 {
03030 memcpy (htab->splt->contents + h->plt.offset, elf_i386_plt_entry,
03031 PLT_ENTRY_SIZE);
03032 bfd_put_32 (output_bfd,
03033 (htab->sgotplt->output_section->vma
03034 + htab->sgotplt->output_offset
03035 + got_offset),
03036 htab->splt->contents + h->plt.offset + 2);
03037 }
03038 else
03039 {
03040 memcpy (htab->splt->contents + h->plt.offset, elf_i386_pic_plt_entry,
03041 PLT_ENTRY_SIZE);
03042 bfd_put_32 (output_bfd, got_offset,
03043 htab->splt->contents + h->plt.offset + 2);
03044 }
03045
03046 bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel),
03047 htab->splt->contents + h->plt.offset + 7);
03048 bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE),
03049 htab->splt->contents + h->plt.offset + 12);
03050
03051
03052 bfd_put_32 (output_bfd,
03053 (htab->splt->output_section->vma
03054 + htab->splt->output_offset
03055 + h->plt.offset
03056 + 6),
03057 htab->sgotplt->contents + got_offset);
03058
03059
03060 rel.r_offset = (htab->sgotplt->output_section->vma
03061 + htab->sgotplt->output_offset
03062 + got_offset);
03063 rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT);
03064 loc = htab->srelplt->contents + plt_index * sizeof (Elf32_External_Rel);
03065 bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
03066
03067 if (!h->def_regular)
03068 {
03069
03070
03071
03072
03073
03074
03075
03076
03077 sym->st_shndx = SHN_UNDEF;
03078 if (!h->pointer_equality_needed)
03079 sym->st_value = 0;
03080 }
03081 }
03082
03083 if (h->got.offset != (bfd_vma) -1
03084 && elf_i386_hash_entry(h)->tls_type != GOT_TLS_GD
03085 && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE) == 0)
03086 {
03087 Elf_Internal_Rela rel;
03088 bfd_byte *loc;
03089
03090
03091
03092
03093 if (htab->sgot == NULL || htab->srelgot == NULL)
03094 abort ();
03095
03096 rel.r_offset = (htab->sgot->output_section->vma
03097 + htab->sgot->output_offset
03098 + (h->got.offset & ~(bfd_vma) 1));
03099
03100
03101
03102
03103
03104
03105 if (info->shared
03106 && SYMBOL_REFERENCES_LOCAL (info, h))
03107 {
03108 BFD_ASSERT((h->got.offset & 1) != 0);
03109 rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
03110 }
03111 else
03112 {
03113 BFD_ASSERT((h->got.offset & 1) == 0);
03114 bfd_put_32 (output_bfd, (bfd_vma) 0,
03115 htab->sgot->contents + h->got.offset);
03116 rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
03117 }
03118
03119 loc = htab->srelgot->contents;
03120 loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rel);
03121 bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
03122 }
03123
03124 if (h->needs_copy)
03125 {
03126 Elf_Internal_Rela rel;
03127 bfd_byte *loc;
03128
03129
03130
03131 if (h->dynindx == -1
03132 || (h->root.type != bfd_link_hash_defined
03133 && h->root.type != bfd_link_hash_defweak)
03134 || htab->srelbss == NULL)
03135 abort ();
03136
03137 rel.r_offset = (h->root.u.def.value
03138 + h->root.u.def.section->output_section->vma
03139 + h->root.u.def.section->output_offset);
03140 rel.r_info = ELF32_R_INFO (h->dynindx, R_386_COPY);
03141 loc = htab->srelbss->contents;
03142 loc += htab->srelbss->reloc_count++ * sizeof (Elf32_External_Rel);
03143 bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
03144 }
03145
03146
03147 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
03148 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
03149 sym->st_shndx = SHN_ABS;
03150
03151 return TRUE;
03152 }
03153
03154
03155
03156
03157 static enum elf_reloc_type_class
03158 elf_i386_reloc_type_class (const Elf_Internal_Rela *rela)
03159 {
03160 switch (ELF32_R_TYPE (rela->r_info))
03161 {
03162 case R_386_RELATIVE:
03163 return reloc_class_relative;
03164 case R_386_JUMP_SLOT:
03165 return reloc_class_plt;
03166 case R_386_COPY:
03167 return reloc_class_copy;
03168 default:
03169 return reloc_class_normal;
03170 }
03171 }
03172
03173
03174
03175 static bfd_boolean
03176 elf_i386_finish_dynamic_sections (bfd *output_bfd,
03177 struct bfd_link_info *info)
03178 {
03179 struct elf_i386_link_hash_table *htab;
03180 bfd *dynobj;
03181 asection *sdyn;
03182
03183 htab = elf_i386_hash_table (info);
03184 dynobj = htab->elf.dynobj;
03185 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
03186
03187 if (htab->elf.dynamic_sections_created)
03188 {
03189 Elf32_External_Dyn *dyncon, *dynconend;
03190
03191 if (sdyn == NULL || htab->sgot == NULL)
03192 abort ();
03193
03194 dyncon = (Elf32_External_Dyn *) sdyn->contents;
03195 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
03196 for (; dyncon < dynconend; dyncon++)
03197 {
03198 Elf_Internal_Dyn dyn;
03199 asection *s;
03200
03201 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
03202
03203 switch (dyn.d_tag)
03204 {
03205 default:
03206 continue;
03207
03208 case DT_PLTGOT:
03209 s = htab->sgotplt;
03210 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
03211 break;
03212
03213 case DT_JMPREL:
03214 s = htab->srelplt;
03215 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
03216 break;
03217
03218 case DT_PLTRELSZ:
03219 s = htab->srelplt;
03220 dyn.d_un.d_val = s->size;
03221 break;
03222
03223 case DT_RELSZ:
03224
03225
03226
03227
03228
03229
03230 s = htab->srelplt;
03231 if (s == NULL)
03232 continue;
03233 dyn.d_un.d_val -= s->size;
03234 break;
03235
03236 case DT_REL:
03237
03238
03239
03240 s = htab->srelplt;
03241 if (s == NULL)
03242 continue;
03243 if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset)
03244 continue;
03245 dyn.d_un.d_ptr += s->size;
03246 break;
03247 }
03248
03249 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
03250 }
03251
03252
03253 if (htab->splt && htab->splt->size > 0)
03254 {
03255 if (info->shared)
03256 memcpy (htab->splt->contents,
03257 elf_i386_pic_plt0_entry, PLT_ENTRY_SIZE);
03258 else
03259 {
03260 memcpy (htab->splt->contents,
03261 elf_i386_plt0_entry, PLT_ENTRY_SIZE);
03262 bfd_put_32 (output_bfd,
03263 (htab->sgotplt->output_section->vma
03264 + htab->sgotplt->output_offset
03265 + 4),
03266 htab->splt->contents + 2);
03267 bfd_put_32 (output_bfd,
03268 (htab->sgotplt->output_section->vma
03269 + htab->sgotplt->output_offset
03270 + 8),
03271 htab->splt->contents + 8);
03272 }
03273
03274
03275
03276 elf_section_data (htab->splt->output_section)
03277 ->this_hdr.sh_entsize = 4;
03278 }
03279 }
03280
03281 if (htab->sgotplt)
03282 {
03283
03284 if (htab->sgotplt->size > 0)
03285 {
03286 bfd_put_32 (output_bfd,
03287 (sdyn == NULL ? 0
03288 : sdyn->output_section->vma + sdyn->output_offset),
03289 htab->sgotplt->contents);
03290 bfd_put_32 (output_bfd, 0, htab->sgotplt->contents + 4);
03291 bfd_put_32 (output_bfd, 0, htab->sgotplt->contents + 8);
03292 }
03293
03294 elf_section_data (htab->sgotplt->output_section)->this_hdr.sh_entsize = 4;
03295 }
03296
03297 if (htab->sgot && htab->sgot->size > 0)
03298 elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4;
03299
03300 return TRUE;
03301 }
03302
03303
03304
03305
03306 static bfd_vma
03307 elf_i386_plt_sym_val (bfd_vma i, const asection *plt,
03308 const arelent *rel ATTRIBUTE_UNUSED)
03309 {
03310 return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
03311 }
03312
03313
03314 #define TARGET_LITTLE_SYM bfd_elf32_i386_vec
03315 #define TARGET_LITTLE_NAME "elf32-i386"
03316 #define ELF_ARCH bfd_arch_i386
03317 #define ELF_MACHINE_CODE EM_386
03318 #define ELF_MAXPAGESIZE 0x1000
03319
03320 #define elf_backend_can_gc_sections 1
03321 #define elf_backend_can_refcount 1
03322 #define elf_backend_want_got_plt 1
03323 #define elf_backend_plt_readonly 1
03324 #define elf_backend_want_plt_sym 0
03325 #define elf_backend_got_header_size 12
03326
03327
03328 #define elf_info_to_howto elf_i386_info_to_howto_rel
03329 #define elf_info_to_howto_rel elf_i386_info_to_howto_rel
03330
03331 #define bfd_elf32_mkobject elf_i386_mkobject
03332
03333 #define bfd_elf32_bfd_is_local_label_name elf_i386_is_local_label_name
03334 #define bfd_elf32_bfd_link_hash_table_create elf_i386_link_hash_table_create
03335 #define bfd_elf32_bfd_reloc_type_lookup elf_i386_reloc_type_lookup
03336
03337 #define elf_backend_adjust_dynamic_symbol elf_i386_adjust_dynamic_symbol
03338 #define elf_backend_check_relocs elf_i386_check_relocs
03339 #define elf_backend_copy_indirect_symbol elf_i386_copy_indirect_symbol
03340 #define elf_backend_create_dynamic_sections elf_i386_create_dynamic_sections
03341 #define elf_backend_fake_sections elf_i386_fake_sections
03342 #define elf_backend_finish_dynamic_sections elf_i386_finish_dynamic_sections
03343 #define elf_backend_finish_dynamic_symbol elf_i386_finish_dynamic_symbol
03344 #define elf_backend_gc_mark_hook elf_i386_gc_mark_hook
03345 #define elf_backend_gc_sweep_hook elf_i386_gc_sweep_hook
03346 #define elf_backend_grok_prstatus elf_i386_grok_prstatus
03347 #define elf_backend_grok_psinfo elf_i386_grok_psinfo
03348 #define elf_backend_reloc_type_class elf_i386_reloc_type_class
03349 #define elf_backend_relocate_section elf_i386_relocate_section
03350 #define elf_backend_size_dynamic_sections elf_i386_size_dynamic_sections
03351 #define elf_backend_plt_sym_val elf_i386_plt_sym_val
03352
03353 #include "elf32-target.h"
03354
03355
03356
03357 #undef TARGET_LITTLE_SYM
03358 #define TARGET_LITTLE_SYM bfd_elf32_i386_freebsd_vec
03359 #undef TARGET_LITTLE_NAME
03360 #define TARGET_LITTLE_NAME "elf32-i386-freebsd"
03361
03362
03363
03364
03365
03366 static void
03367 elf_i386_post_process_headers (bfd *abfd,
03368 struct bfd_link_info *info ATTRIBUTE_UNUSED)
03369 {
03370 Elf_Internal_Ehdr *i_ehdrp;
03371
03372 i_ehdrp = elf_elfheader (abfd);
03373
03374
03375 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
03376 #ifdef OLD_FREEBSD_ABI_LABEL
03377
03378 memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
03379 #endif
03380 }
03381
03382 #undef elf_backend_post_process_headers
03383 #define elf_backend_post_process_headers elf_i386_post_process_headers
03384 #undef elf32_bed
03385 #define elf32_bed elf32_i386_fbsd_bed
03386
03387 #include "elf32-target.h"