398 */
399 0x03, 0x80, 0x00, 0x00, 0x00, 0x00
400 };
401
402 static uchar_t tlsinstr_gd_le[] = {
403 /*
404 * 0x00 movl %gs:0x0, %eax
405 */
406 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00,
407 /*
408 * 0x06 addl $0x0, %eax
409 */
410 0x05, 0x00, 0x00, 0x00, 0x00,
411 /*
412 * 0x0b nop
413 * 0x0c
414 */
415 0x90
416 };
417
418 static uchar_t tlsinstr_gd_ie_movgs[] = {
419 /*
420 * movl %gs:0x0,%eax
421 */
422 0x65, 0xa1, 0x00, 0x00, 0x00, 00
423 };
424
425 #define TLS_GD_IE_MOV 0x8b /* movl opcode */
426 #define TLS_GD_IE_POP 0x58 /* popl + reg */
427
428 #define TLS_GD_LE_MOVL 0xb8 /* movl + reg */
429
430 #define TLS_NOP 0x90 /* NOP instruction */
431
432 #define MODRM_MSK_MOD 0xc0
433 #define MODRM_MSK_RO 0x38
434 #define MODRM_MSK_RM 0x07
435
436 #define SIB_MSK_SS 0xc0
437 #define SIB_MSK_IND 0x38
438 #define SIB_MSK_BS 0x07
439
440 static Fixupret
441 tls_fixups(Ofl_desc *ofl, Rel_desc *arsp)
442 {
511 * 0xc
512 */
513 DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
514 R_386_TLS_LE, arsp, ld_reloc_sym_name));
515
516 arsp->rel_rtype = R_386_TLS_LE;
517 arsp->rel_roffset += 4;
518
519 /*
520 * Adjust 'offset' to beginning of instruction
521 * sequence.
522 */
523 offset -= 3;
524 (void) memcpy(offset, tlsinstr_gd_le,
525 sizeof (tlsinstr_gd_le));
526 return (FIX_RELOC);
527
528 case R_386_TLS_GD_PLT:
529 case R_386_PLT32:
530 /*
531 * Fixup done via the TLS_GD relocation
532 */
533 DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
534 R_386_NONE, arsp, ld_reloc_sym_name));
535 return (FIX_DONE);
536
537 case R_386_TLS_LDM_PLT:
538 DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
539 R_386_NONE, arsp, ld_reloc_sym_name));
540
541 /*
542 * Transition:
543 * call __tls_get_addr()
544 * to:
545 * nop
546 * nop
547 * nop
548 * nop
549 * nop
550 */
551 *(offset - 1) = TLS_NOP;
552 *(offset) = TLS_NOP;
553 *(offset + 1) = TLS_NOP;
554 *(offset + 2) = TLS_NOP;
555 *(offset + 3) = TLS_NOP;
556 return (FIX_DONE);
557
558 case R_386_TLS_LDM:
559 DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
560 R_386_NONE, arsp, ld_reloc_sym_name));
561
562 /*
563 * Transition:
564 *
565 * 0x00 leal x1@tlsldm(%ebx), %eax
566 * 0x06 call ___tls_get_addr
567 *
568 * to:
569 *
570 * 0x00 movl %gs:0, %eax
571 */
572 (void) memcpy(offset - 2, tlsinstr_gd_ie_movgs,
573 sizeof (tlsinstr_gd_ie_movgs));
574 return (FIX_DONE);
575
576 case R_386_TLS_LDO_32:
577 /*
578 * Instructions:
579 *
580 * 0x10 leal x1@dtpoff(%eax), %edx R_386_TLS_LDO_32
581 * to
582 * 0x10 leal x1@ntpoff(%eax), %edx R_386_TLS_LE
583 *
584 */
585 offset -= 2;
586
587 DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
588 R_386_TLS_LE, arsp, ld_reloc_sym_name));
589 arsp->rel_rtype = R_386_TLS_LE;
590 return (FIX_RELOC);
591
592 case R_386_TLS_GOTIE:
593 /*
|
398 */
399 0x03, 0x80, 0x00, 0x00, 0x00, 0x00
400 };
401
402 static uchar_t tlsinstr_gd_le[] = {
403 /*
404 * 0x00 movl %gs:0x0, %eax
405 */
406 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00,
407 /*
408 * 0x06 addl $0x0, %eax
409 */
410 0x05, 0x00, 0x00, 0x00, 0x00,
411 /*
412 * 0x0b nop
413 * 0x0c
414 */
415 0x90
416 };
417
418 static uchar_t tlsinstr_ld_le_movgs[] = {
419 /*
420 * 0x00 movl %gs:0x0,%eax
421 */
422 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00,
423 };
424
425 /*
426 * 0x00 nopl 0(%eax,%eax) -- the intel recommended 5-byte nop
427 * See Intel® 64 and IA-32 Architectures Software Developer’s Manual
428 * Volume 2B: Instruction Set Reference, M-U
429 * Table 4-12, Recommended Multi-Byte Sequence of NOP Instruction
430 */
431 static uchar_t tlsinstr_nop5[] = {
432
433 0x0f, 0x1f, 0x44, 0x00, 0x00
434 };
435
436 #define TLS_GD_IE_MOV 0x8b /* movl opcode */
437 #define TLS_GD_IE_POP 0x58 /* popl + reg */
438
439 #define TLS_GD_LE_MOVL 0xb8 /* movl + reg */
440
441 #define TLS_NOP 0x90 /* NOP instruction */
442
443 #define MODRM_MSK_MOD 0xc0
444 #define MODRM_MSK_RO 0x38
445 #define MODRM_MSK_RM 0x07
446
447 #define SIB_MSK_SS 0xc0
448 #define SIB_MSK_IND 0x38
449 #define SIB_MSK_BS 0x07
450
451 static Fixupret
452 tls_fixups(Ofl_desc *ofl, Rel_desc *arsp)
453 {
522 * 0xc
523 */
524 DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
525 R_386_TLS_LE, arsp, ld_reloc_sym_name));
526
527 arsp->rel_rtype = R_386_TLS_LE;
528 arsp->rel_roffset += 4;
529
530 /*
531 * Adjust 'offset' to beginning of instruction
532 * sequence.
533 */
534 offset -= 3;
535 (void) memcpy(offset, tlsinstr_gd_le,
536 sizeof (tlsinstr_gd_le));
537 return (FIX_RELOC);
538
539 case R_386_TLS_GD_PLT:
540 case R_386_PLT32:
541 /*
542 * Fixup done via the TLS_GD/TLS_LDM relocation processing
543 * and ld_reloc_plt() handling __tls_get_addr().
544 */
545 DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
546 R_386_NONE, arsp, ld_reloc_sym_name));
547 return (FIX_DONE);
548
549 case R_386_TLS_LDM_PLT:
550 DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
551 R_386_NONE, arsp, ld_reloc_sym_name));
552
553 /*
554 * Transition:
555 * call __tls_get_addr()
556 * to:
557 * nopl 0x0(%eax,%eax)
558 */
559 (void) memcpy(offset - 1, tlsinstr_nop5,
560 sizeof (tlsinstr_nop5));
561 return (FIX_DONE);
562
563 case R_386_TLS_LDM:
564 DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
565 R_386_NONE, arsp, ld_reloc_sym_name));
566
567 /*
568 * Transition:
569 *
570 * 0x00 leal x1@tlsldm(%ebx), %eax
571 * 0x06 call ___tls_get_addr
572 *
573 * to:
574 *
575 * 0x00 movl %gs:0, %eax
576 */
577 (void) memcpy(offset - 2, tlsinstr_ld_le_movgs,
578 sizeof (tlsinstr_ld_le_movgs));
579
580 /*
581 * We implicitly treat this as if a R_386_TLS_LDM_PLT for the
582 * __tls_get_addr call followed it as the GNU compiler
583 * doesn't generate one. This is safe, because if one _does_
584 * exist we'll just write the nop again.
585 */
586 (void) memcpy(offset + 4, tlsinstr_nop5,
587 sizeof (tlsinstr_nop5));
588 return (FIX_DONE);
589
590 case R_386_TLS_LDO_32:
591 /*
592 * Instructions:
593 *
594 * 0x10 leal x1@dtpoff(%eax), %edx R_386_TLS_LDO_32
595 * to
596 * 0x10 leal x1@ntpoff(%eax), %edx R_386_TLS_LE
597 *
598 */
599 offset -= 2;
600
601 DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
602 R_386_TLS_LE, arsp, ld_reloc_sym_name));
603 arsp->rel_rtype = R_386_TLS_LE;
604 return (FIX_RELOC);
605
606 case R_386_TLS_GOTIE:
607 /*
|