Bug 22270 - SH PIC TLS code doesn't match SH TLS implementation in ld
Summary: SH PIC TLS code doesn't match SH TLS implementation in ld
Status: NEW
Alias: None
Product: glibc
Classification: Unclassified
Component: dynamic-link (show other bugs)
Version: 2.27
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-10-09 01:07 UTC by H.J. Lu
Modified: 2018-01-24 16:30 UTC (History)
1 user (show)

See Also:
Host:
Target: sh
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2017-10-09 01:07:21 UTC
SH ld has

             else
                {
                  int target;

                  /* IE->LE transition:
                     mov.l 1f,r0; stc gbr,rN; mov.l @(r0,r12),rM;
                     bra 2f; add ...; .align 2; 1: x@GOTTPOFF; 2:
                     We change it into:
                     mov.l .Ln,rM; stc gbr,rN; nop; ...;
                     1: x@TPOFF; 2:.  */

                  offset = rel->r_offset;
                  BFD_ASSERT (offset >= 16);
                  /* Size of IE instructions is 10 or 12.  */
                  offset -= 10;
                  insn = bfd_get_16 (input_bfd, contents + offset + 0);
                  if ((insn & 0xf0ff) == 0x0012)
                    {
                      BFD_ASSERT (offset >= 2);
                      offset -= 2;
                      insn = bfd_get_16 (input_bfd, contents + offset + 0);
                    }

                  BFD_ASSERT ((insn & 0xff00) == 0xd000);
                  target = insn & 0x00ff;
                  insn = bfd_get_16 (input_bfd, contents + offset + 2);
                  BFD_ASSERT ((insn & 0xf0ff) == 0x0012);
                  insn = bfd_get_16 (input_bfd, contents + offset + 4);
                  BFD_ASSERT ((insn & 0xf0ff) == 0x00ce);
                  insn = 0xd000 | (insn & 0x0f00) | target;
                  bfd_put_16 (output_bfd, insn, contents + offset + 0);
                  bfd_put_16 (output_bfd, 0x0009, contents + offset + 4);
                }

But SH syscall in glibc has

.text; .globl __sched_yield; .type __sched_yield,@function; .align 5; __sched_yield: .cfi_startproc; ; mov.l 1f,r3; trapa #0x10; or r0,r0; or r0,r0; or r0,r0; or r0,r0; or r0,r0; bra 2f; nop; .align 2; 1: .long (158); 2:; mov r0,r1; mov #-12,r2; shad r2,r1; not r1,r1; tst r1,r1; bf .Lpseudo_end; neg r0,r1; mov r12,r2; .cfi_register r12, r2; mov.l 0f,r12; mova 0f,r0; add r0,r12; mov.l 1f,r0; stc gbr, r4; mov.l @(r0,r12),r0; mov r2,r12; .cfi_restore r12; add r4,r0; mov.l r1,@r0; bra .Lpseudo_end; mov #-1,r0; .align 2; 0: .long _GLOBAL_OFFSET_TABLE_; 1: .long __libc_errno@GOTTPOFF; .Lpseudo_end:
 rts ; nop
.cfi_endproc; .size __sched_yield,.-__sched_yield

The TLS code sequences don't match.