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.