Print this page
10267 ld and GCC disagree about i386 local dynamic TLS

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/sgs/libld/common/machrel.intel.c
          +++ new/usr/src/cmd/sgs/libld/common/machrel.intel.c
↓ open down ↓ 407 lines elided ↑ open up ↑
 408  408           * 0x06 addl $0x0, %eax
 409  409           */
 410  410          0x05, 0x00, 0x00, 0x00, 0x00,
 411  411          /*
 412  412           * 0x0b nop
 413  413           * 0x0c
 414  414           */
 415  415          0x90
 416  416  };
 417  417  
 418      -static uchar_t tlsinstr_gd_ie_movgs[] = {
      418 +static uchar_t tlsinstr_ld_le_movgs[] = {
 419  419          /*
 420      -         *      movl %gs:0x0,%eax
      420 +         * 0x00 movl %gs:0x0,%eax
 421  421           */
 422      -        0x65, 0xa1, 0x00, 0x00, 0x00, 00
      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
 423  434  };
 424  435  
 425  436  #define TLS_GD_IE_MOV   0x8b    /* movl opcode */
 426  437  #define TLS_GD_IE_POP   0x58    /* popl + reg */
 427  438  
 428  439  #define TLS_GD_LE_MOVL  0xb8    /* movl + reg */
 429  440  
 430  441  #define TLS_NOP         0x90    /* NOP instruction */
 431  442  
 432  443  #define MODRM_MSK_MOD   0xc0
↓ open down ↓ 88 lines elided ↑ open up ↑
 521  532                   * sequence.
 522  533                   */
 523  534                  offset -= 3;
 524  535                  (void) memcpy(offset, tlsinstr_gd_le,
 525  536                      sizeof (tlsinstr_gd_le));
 526  537                  return (FIX_RELOC);
 527  538  
 528  539          case R_386_TLS_GD_PLT:
 529  540          case R_386_PLT32:
 530  541                  /*
 531      -                 * Fixup done via the TLS_GD relocation
      542 +                 * Fixup done via the TLS_GD/TLS_LDM relocation processing
      543 +                 * and ld_reloc_plt() handling __tls_get_addr().
 532  544                   */
 533  545                  DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
 534  546                      R_386_NONE, arsp, ld_reloc_sym_name));
 535  547                  return (FIX_DONE);
 536  548  
 537  549          case R_386_TLS_LDM_PLT:
 538  550                  DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
 539  551                      R_386_NONE, arsp, ld_reloc_sym_name));
 540  552  
 541  553                  /*
 542  554                   * Transition:
 543  555                   *      call __tls_get_addr()
 544  556                   * 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;
      557 +                 *      nopl 0x0(%eax,%eax)
      558 +                 */
      559 +                (void) memcpy(offset - 1, tlsinstr_nop5,
      560 +                    sizeof (tlsinstr_nop5));
 556  561                  return (FIX_DONE);
 557  562  
 558  563          case R_386_TLS_LDM:
 559  564                  DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
 560  565                      R_386_NONE, arsp, ld_reloc_sym_name));
 561  566  
 562  567                  /*
 563  568                   * Transition:
 564  569                   *
 565  570                   *  0x00 leal x1@tlsldm(%ebx), %eax
 566  571                   *  0x06 call ___tls_get_addr
 567  572                   *
 568  573                   * to:
 569  574                   *
 570  575                   *  0x00 movl %gs:0, %eax
 571  576                   */
 572      -                (void) memcpy(offset - 2, tlsinstr_gd_ie_movgs,
 573      -                    sizeof (tlsinstr_gd_ie_movgs));
      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));
 574  588                  return (FIX_DONE);
 575  589  
 576  590          case R_386_TLS_LDO_32:
 577  591                  /*
 578  592                   *  Instructions:
 579  593                   *
 580  594                   *  0x10 leal x1@dtpoff(%eax), %edx     R_386_TLS_LDO_32
 581  595                   *              to
 582  596                   *  0x10 leal x1@ntpoff(%eax), %edx     R_386_TLS_LE
 583  597                   *
↓ open down ↓ 145 lines elided ↑ open up ↑
 729  743          ofl_flag_t      flags = ofl->ofl_flags;
 730  744  
 731  745          if (aplist_nitems(ofl->ofl_actrels.rc_list) != 0)
 732  746                  DBG_CALL(Dbg_reloc_doact_title(ofl->ofl_lml));
 733  747  
 734  748          /*
 735  749           * Process active relocations.
 736  750           */
 737  751          REL_CACHE_TRAVERSE(&ofl->ofl_actrels, idx, rcbp, arsp) {
 738  752                  uchar_t         *addr;
 739      -                Xword           value;
      753 +                Xword           value;
 740  754                  Sym_desc        *sdp;
 741  755                  const char      *ifl_name;
 742  756                  Xword           refaddr;
 743  757                  int             moved = 0;
 744  758                  Gotref          gref;
 745  759                  Os_desc         *osp;
 746  760  
 747  761                  /*
 748  762                   * If the section this relocation is against has been discarded
 749  763                   * (-zignore), then discard (skip) the relocation itself.
↓ open down ↓ 958 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX