Fix SH TLS support
kaz Kojima
kkojima@rr.iij4u.or.jp
Mon Feb 10 11:07:00 GMT 2003
More information about the Binutils mailing list
Mon Feb 10 11:07:00 GMT 2003
- Previous message (by thread): [PATHC] Add machine type for Cirrus EP9312 chip
- Next message (by thread): [PATCH] Cirrus EP9312 support, additional
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi, SH uses R_SH_TLS_TPOFF32 relocation as a kind of copy relocation for TLS and sh_elf_check_relocation set a flag to show whether it's required or not. It should be recorded per entry of dyn_relocs but currently done per symbol. The attached testcase causes an abort of the current SH linker in sh_elf_relocate_section for this reason. This testcase reveals also an another bug that a bad symbol index is set for R_SH_TLS_TPOFF32. I'd like to commit the following patch to fix them. It affects TLS relocation only. Regards, kaz -- 2003-02-10 Kaz kojima <kkojima@rr.iij4u.or.jp> [bfd] * elf32-sh.c (elf_sh_dyn_relocs): Add tls_tpoff32 field. (elf_sh_link_hash_entry): Remove tls_tpoff32 field. (sh_elf_link_hash_newfunc): Remove the initialization of tls_tpoff32 field. (allocate_dynrelocs): Keep dyn_relocs if it includes the entry for which tls_tpoff32 flag is set. (sh_elf_relocate_section): Covert to LE only if the dyn_relocs of the symbol includes the entry matched with the input_section and having tls_tpoff32 flag on. When linking statically, set symbol index of R_SH_TLS_TPOFF32 relocation to zero if the symbol is defined in this executable. (sh_elf_check_relocs): Set tls_tpoff32 flag appropriately. [ld/testsuite] * ld-sh/tlstpoff-1.d: New. * ld-sh/tlstpoff-2.d: New. * ld-sh/tlstpoff1.s: New. * ld-sh/tlstpoff2.s: New. diff -u3prN ORIG/src/bfd/elf32-sh.c LOCAL/src/bfd/elf32-sh.c --- ORIG/src/bfd/elf32-sh.c Fri Jan 24 08:38:56 2003 +++ LOCAL/src/bfd/elf32-sh.c Mon Feb 10 11:27:45 2003 @@ -3500,6 +3500,9 @@ struct elf_sh_dyn_relocs /* Number of pc-relative relocs copied for the input section. */ bfd_size_type pc_count; + + /* If TRUE, R_SH_TLS_TPOFF32 relocation is generated. */ + bfd_boolean tls_tpoff32; }; /* sh ELF linker hash entry. */ @@ -3524,9 +3527,6 @@ struct elf_sh_link_hash_entry enum { GOT_UNKNOWN = 0, GOT_NORMAL, GOT_TLS_GD, GOT_TLS_IE } tls_type; - - /* If TRUE, R_SH_TLS_TPOFF32 relocation is generated. */ - bfd_boolean tls_tpoff32; }; #define sh_elf_hash_entry(ent) ((struct elf_sh_link_hash_entry *)(ent)) @@ -3630,7 +3630,6 @@ sh_elf_link_hash_newfunc (entry, table, ret->datalabel_got.refcount = ret->root.got.refcount; #endif ret->tls_type = GOT_UNKNOWN; - ret->tls_tpoff32 = FALSE; } return (struct bfd_hash_entry *) ret; @@ -4207,8 +4206,9 @@ allocate_dynrelocs (h, inf) } else { - if (sh_elf_hash_entry (h)->tls_tpoff32) - goto keep; + for (p = eh->dyn_relocs; p; p = p->next) + if (p->tls_tpoff32) + goto keep; /* For the non-shared case, discard space for relocs against symbols which turn out to need copy relocs or are not @@ -5256,10 +5256,18 @@ sh_elf_relocate_section (output_bfd, inf tls_type = sh_elf_hash_entry (h)->tls_type; if (! info->shared && (h->dynindx == -1 - || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) - && (tls_type == GOT_TLS_IE - || sh_elf_hash_entry (h)->tls_tpoff32)) - r_type = R_SH_TLS_LE_32; + || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) + { + struct elf_sh_dyn_relocs *p; + + /* If TPOFF32 relocation can be created, convert it. */ + for (p = sh_elf_hash_entry (h)->dyn_relocs; p; p = p->next) + if (p->sec == input_section && p->tls_tpoff32) + { + r_type = R_SH_TLS_LE_32; + break; + } + } } if (r_type == R_SH_TLS_GD_32 && tls_type == GOT_TLS_IE) @@ -5368,7 +5376,13 @@ sh_elf_relocate_section (output_bfd, inf BFD_ASSERT (sreloc != NULL); } - indx = (h && h->dynindx != -1) ? h->dynindx : 0; + if (h == NULL + || h->dynindx == -1 + || (! info->shared + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) + indx = 0; + else + indx = h->dynindx; outrel.r_offset = (input_section->output_section->vma + input_section->output_offset + rel->r_offset); @@ -5415,7 +5429,13 @@ sh_elf_relocate_section (output_bfd, inf outrel.r_offset = (sgot->output_section->vma + sgot->output_offset + off); - indx = (h && h->dynindx != -1) ? h->dynindx : 0; + if (h == NULL + || h->dynindx == -1 + || (! info->shared + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) + indx = 0; + else + indx = h->dynindx; dr_type = (r_type == R_SH_TLS_GD_32 ? R_SH_TLS_DTPMOD32 : R_SH_TLS_TPOFF32); if (dr_type == R_SH_TLS_TPOFF32 && indx == 0) @@ -6596,6 +6616,7 @@ sh_elf_check_relocs (abfd, info, sec, re p->sec = sec; p->count = 0; p->pc_count = 0; + p->tls_tpoff32 = FALSE; } p->count += 1; @@ -6693,11 +6714,11 @@ sh_elf_check_relocs (abfd, info, sec, re p->sec = sec; p->count = 0; p->pc_count = 0; + p->tls_tpoff32 = FALSE; } p->count += 1; - if (h) - sh_elf_hash_entry (h)->tls_tpoff32 = TRUE; + p->tls_tpoff32 = TRUE; } break; diff -u3prN ORIG/src/ld/testsuite/ld-sh/tlstpoff-1.d LOCAL/src/ld/testsuite/ld-sh/tlstpoff-1.d --- ORIG/src/ld/testsuite/ld-sh/tlstpoff-1.d Thu Jan 1 09:00:00 1970 +++ LOCAL/src/ld/testsuite/ld-sh/tlstpoff-1.d Mon Feb 10 11:18:28 2003 @@ -0,0 +1,31 @@ +#source: tlstpoff1.s +#source: tlstpoff2.s +#as: -little +#ld: -EL -e foo +#objdump: -drj.text +#target: sh*-*-linux* sh*-*-netbsd* + +.*: +file format elf32-sh.* + +Disassembly of section \.text: + +[0-9a-f]+ <foo>: + [0-9a-f]+: c6 2f mov.l r12,@-r15 + [0-9a-f]+: 07 c7 mova [0-9a-f]+ <foo\+0x20>,r0 + [0-9a-f]+: 06 dc mov.l [0-9a-f]+ <foo\+0x20>,r12 ! 0x[0-9a-f]+ + [0-9a-f]+: 0c 3c add r0,r12 + [0-9a-f]+: 02 d0 mov.l [0-9a-f]+ <foo\+0x14>,r0 ! 0xc + [0-9a-f]+: 12 01 stc gbr,r1 + [0-9a-f]+: ce 00 mov.l @\(r0,r12\),r0 + [0-9a-f]+: 03 a0 bra [0-9a-f]+ <foo\+0x18> + [0-9a-f]+: 0c 31 add r0,r1 + [0-9a-f]+: 09 00 nop + [0-9a-f]+: 0c 00 .*[ ]*.* + [0-9a-f]+: 00 00 .*[ ]*.* + [0-9a-f]+: 12 60 mov.l @r1,r0 + [0-9a-f]+: 0b 00 rts + [0-9a-f]+: f6 6c mov.l @r15\+,r12 + [0-9a-f]+: 09 00 nop + [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.* + [0-9a-f]+: [0-9a-f]+ [0-9a-f]+ .*[ ]*.* +#pass diff -u3prN ORIG/src/ld/testsuite/ld-sh/tlstpoff-2.d LOCAL/src/ld/testsuite/ld-sh/tlstpoff-2.d --- ORIG/src/ld/testsuite/ld-sh/tlstpoff-2.d Thu Jan 1 09:00:00 1970 +++ LOCAL/src/ld/testsuite/ld-sh/tlstpoff-2.d Mon Feb 10 11:29:26 2003 @@ -0,0 +1,12 @@ +#source: tlstpoff1.s +#source: tlstpoff2.s +#as: -little +#ld: -EL -e foo +#readelf: -r +#target: sh*-*-linux* sh*-*-netbsd* + +Relocation section '\.rela\.dyn' at offset 0x[0-9a-f]+ contains 2 entries: + Offset +Info +Type +Sym\.Value +Sym\. Name \+ Addend +0+[0-9a-f]+ 00000097 R_SH_TLS_TPOFF32 +0+04 +0+[0-9a-f]+ 00000097 R_SH_TLS_TPOFF32 +0+04 + diff -u3prN ORIG/src/ld/testsuite/ld-sh/tlstpoff1.s LOCAL/src/ld/testsuite/ld-sh/tlstpoff1.s --- ORIG/src/ld/testsuite/ld-sh/tlstpoff1.s Thu Jan 1 09:00:00 1970 +++ LOCAL/src/ld/testsuite/ld-sh/tlstpoff1.s Mon Feb 10 08:56:12 2003 @@ -0,0 +1,23 @@ + .text + .align 5 + .global foo + .type foo, @function +foo: + mov.l r12,@-r15 + mova .L1,r0 + mov.l .L1,r12 + add r0,r12 + mov.l 1f,r0 + stc gbr,r1 + mov.l @(r0,r12),r0 + bra 2f + add r0,r1 + .align 2 +1: .long x@GOTTPOFF +2: + mov.l @r1,r0 + rts + mov.l @r15+,r12 + + .align 2 +.L1: .long _GLOBAL_OFFSET_TABLE_ diff -u3prN ORIG/src/ld/testsuite/ld-sh/tlstpoff2.s LOCAL/src/ld/testsuite/ld-sh/tlstpoff2.s --- ORIG/src/ld/testsuite/ld-sh/tlstpoff2.s Thu Jan 1 09:00:00 1970 +++ LOCAL/src/ld/testsuite/ld-sh/tlstpoff2.s Mon Feb 10 11:12:03 2003 @@ -0,0 +1,26 @@ + .section .tbss,"awT",@nobits + .global x +y: .space 4 +x: .space 4 + + .section barfn,"ax",@progbits + .align 1 + .type bar, @function +bar: + mova .L1,r0 + mov.l .L1,r12 + add r0,r12 + mov.l 1f,r0 + stc gbr,r1 + mov.l @(r0,r12),r0 + bra 2f + add r0,r1 + .align 2 +1: .long x@GOTTPOFF +2: + mov.l @r1,r0 + rts + mov.l @r15+,r12 + + .align 2 +.L1: .long _GLOBAL_OFFSET_TABLE_
- Previous message (by thread): [PATHC] Add machine type for Cirrus EP9312 chip
- Next message (by thread): [PATCH] Cirrus EP9312 support, additional
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list