Print this page
10267 ld and GCC disagree about i386 local dynamic TLS
*** 413,427 ****
* 0x0c
*/
0x90
};
! static uchar_t tlsinstr_gd_ie_movgs[] = {
/*
! * movl %gs:0x0,%eax
*/
! 0x65, 0xa1, 0x00, 0x00, 0x00, 00
};
#define TLS_GD_IE_MOV 0x8b /* movl opcode */
#define TLS_GD_IE_POP 0x58 /* popl + reg */
--- 413,438 ----
* 0x0c
*/
0x90
};
! static uchar_t tlsinstr_ld_le_movgs[] = {
/*
! * 0x00 movl %gs:0x0,%eax
*/
! 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00,
! };
!
! /*
! * 0x00 nopl 0(%eax,%eax) -- the intel recommended 5-byte nop
! * See Intel® 64 and IA-32 Architectures Software Developer’s Manual
! * Volume 2B: Instruction Set Reference, M-U
! * Table 4-12, Recommended Multi-Byte Sequence of NOP Instruction
! */
! static uchar_t tlsinstr_nop5[] = {
!
! 0x0f, 0x1f, 0x44, 0x00, 0x00
};
#define TLS_GD_IE_MOV 0x8b /* movl opcode */
#define TLS_GD_IE_POP 0x58 /* popl + reg */
*** 526,536 ****
return (FIX_RELOC);
case R_386_TLS_GD_PLT:
case R_386_PLT32:
/*
! * Fixup done via the TLS_GD relocation
*/
DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
R_386_NONE, arsp, ld_reloc_sym_name));
return (FIX_DONE);
--- 537,548 ----
return (FIX_RELOC);
case R_386_TLS_GD_PLT:
case R_386_PLT32:
/*
! * Fixup done via the TLS_GD/TLS_LDM relocation processing
! * and ld_reloc_plt() handling __tls_get_addr().
*/
DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
R_386_NONE, arsp, ld_reloc_sym_name));
return (FIX_DONE);
*** 540,560 ****
/*
* Transition:
* call __tls_get_addr()
* to:
! * nop
! * nop
! * nop
! * nop
! * nop
! */
! *(offset - 1) = TLS_NOP;
! *(offset) = TLS_NOP;
! *(offset + 1) = TLS_NOP;
! *(offset + 2) = TLS_NOP;
! *(offset + 3) = TLS_NOP;
return (FIX_DONE);
case R_386_TLS_LDM:
DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
R_386_NONE, arsp, ld_reloc_sym_name));
--- 552,565 ----
/*
* Transition:
* call __tls_get_addr()
* to:
! * nopl 0x0(%eax,%eax)
! */
! (void) memcpy(offset - 1, tlsinstr_nop5,
! sizeof (tlsinstr_nop5));
return (FIX_DONE);
case R_386_TLS_LDM:
DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
R_386_NONE, arsp, ld_reloc_sym_name));
*** 567,578 ****
*
* to:
*
* 0x00 movl %gs:0, %eax
*/
! (void) memcpy(offset - 2, tlsinstr_gd_ie_movgs,
! sizeof (tlsinstr_gd_ie_movgs));
return (FIX_DONE);
case R_386_TLS_LDO_32:
/*
* Instructions:
--- 572,592 ----
*
* to:
*
* 0x00 movl %gs:0, %eax
*/
! (void) memcpy(offset - 2, tlsinstr_ld_le_movgs,
! sizeof (tlsinstr_ld_le_movgs));
!
! /*
! * We implicitly treat this as if a R_386_TLS_LDM_PLT for the
! * __tls_get_addr call followed it as the GNU compiler
! * doesn't generate one. This is safe, because if one _does_
! * exist we'll just write the nop again.
! */
! (void) memcpy(offset + 4, tlsinstr_nop5,
! sizeof (tlsinstr_nop5));
return (FIX_DONE);
case R_386_TLS_LDO_32:
/*
* Instructions: