This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: MIPS : offset address in .rel.dyn for the different symbols may become the same
- From: Richard Sandiford <rsandifo at nildram dot co dot uk>
- To: "Yuji Ogihara" <Yuji dot Ogihara at jp dot sony dot com>
- Cc: <binutils at sourceware dot org>
- Date: Tue, 29 May 2007 22:29:57 +0100
- Subject: Re: MIPS : offset address in .rel.dyn for the different symbols may become the same
- References: <003a01c79b8f$8b3f7990$3391042b@xogihara>
"Yuji Ogihara" <Yuji.Ogihara@jp.sony.com> writes:
> Hello.
>
> I am using the MIPS toolchain as follows.
>
> + binutils 2.17.50.0.16.20070511
> - configured/builded with
> --host=i686-pc-linux-gnu
> --target=mips-xxx-linux
> --build=i686-pc-linux-gnu
>
> + gcc 4.1.1
> - configured/builded with
> --host=mips-xxx-linux
> --build=i686-pc-linux-gnu
> --with-arch=mips2
>
> I believe I found the problem of the TLS relocation offset address,
> in elf binaries created by the procedure below.
>
> I have no idea whether this is the issue of the linker, or the compiler,
> or my procedure below , or else.
>
> So if somebody has any information about this, would you please give
> it to me ?
>
> + Three files which use the TLS, to create the shared library
>
> /* -------- t0.c ------- */
> #include <stdio.h>
>
> __thread int __tsd_0_0 = 1 ;
>
> void t0(void)
> {
> printf("t0:0_0=%d\n",__tsd_0_0) ;
> }
>
>
> /* -------- t1.c ------- */
> #include <stdio.h>
>
> extern __thread int __tsd_0_0 ;
> extern __thread int __tsd_2_0 ;
> extern __thread int __tsd_2_1 ;
>
> void t1(void)
> {
> printf("t1:0_0=%d\n",__tsd_0_0) ;
> printf("t1:2_0=%d\n",__tsd_2_0) ;
> printf("t1:2_1=%d\n",__tsd_2_1) ;
> }
>
>
> /* --------- t2.c ----------*/
> __thread int __tsd_2_0 = 2;
> __thread int __tsd_2_1 = 3;
>
> + Building
> ----------
>
> # mips-xxx-linux-gcc -Wall -O2 -fPIC -o t0.o -c t0.c
> # mips-xxx-linux-gcc -Wall -O2 -fPIC -o t1.o -c t1.c
> -ftls-model=initial-exec
> # mips-xxx-linux-gcc -Wall -O2 -fPIC -o t2.o -c t2.c
> # mips-xxx-linux-gcc -shared -o libxxx.so t0.o t1.o t2.o
>
> - Note
> - Only t1.c uses the -ftls-model=initial-exec option.
> - The link order to create this so should be t0.o,t1.o,t2.o .
>
> + Results of the readelf
> ------------------------
>
> # mips-xxx-linux-readelf -r libxxx.so
>
> Relocation section '.rel.dyn' at offset 0x5a0 contains 8 entries:
> Offset Info Type Sym.Value Sym. Name
> 00000000 00000000 R_MIPS_NONE
> 00010990 00000003 R_MIPS_REL32
> 00010994 00000003 R_MIPS_REL32
> 000109e0 0000072f R_MIPS_TLS_TPREL3 00000008 __tsd_2_1 <<== (1)
> 000109d4 00000a2f R_MIPS_TLS_TPREL3 00000004 __tsd_2_0
> 000109d8 00000b26 R_MIPS_TLS_DTPMOD 00000000 __tsd_0_0
> 000109dc 00000b27 R_MIPS_TLS_DTPREL 00000000 __tsd_0_0
> 000109e0 00000b2f R_MIPS_TLS_TPREL3 00000000 __tsd_0_0 <<== (2)
>
> The offset address in the relocation section of (1) and (2) are
> the same , even if they are different symbols.
> I believe those address are differnt from each other.
Thanks for the nicely-reduced testcase, it was a big help.
I can reproduce this with binutils CVS. It's yet another case in which
we're getting confused about whether TLS information is stored in the
mips_got_entry structure or in the symbol's hash table entry. In the
"master" GOT, we keep entries for each input bfd distinct, so that we
can easily split the master GOT into multiple GOTs later on. Thus if
one input bfd uses only IE accesses for a symbol, and another uses only
GD accesses, there will be two separate master GOT entries, each with
just one TLS type. We store the accrued TLS information in the hash
table in such cases; it is the hash table entry that tells us that
both access models are needed.
The testcase exposes one situation in which we weren't making the
distinction correctly. Please let me know if this patch fixes things
for you.
Richard
bfd/
* elfxx-mips.c (mips_elf_initialize_tls_index): When processing a
type (3) single-GOT entry, read tls_type from the hash table entry
rather than the GOT entry.
Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.206
diff -u -p -r1.206 elfxx-mips.c
--- bfd/elfxx-mips.c 15 May 2007 13:55:54 -0000 1.206
+++ bfd/elfxx-mips.c 29 May 2007 21:13:04 -0000
@@ -3186,6 +3186,7 @@ mips_elf_initialize_tls_index (void **en
struct mips_got_entry *entry = (struct mips_got_entry *)*entryp;
struct mips_got_info *g = p;
bfd_vma next_index;
+ unsigned char tls_type;
/* We're only interested in TLS symbols. */
if (entry->tls_type == 0)
@@ -3201,6 +3202,7 @@ mips_elf_initialize_tls_index (void **en
return 1;
entry->d.h->tls_type |= GOT_TLS_OFFSET_DONE;
entry->d.h->tls_got_offset = next_index;
+ tls_type = entry->d.h->tls_type;
}
else
{
@@ -3217,12 +3219,13 @@ mips_elf_initialize_tls_index (void **en
g->tls_ldm_offset = next_index;
}
entry->gotidx = next_index;
+ tls_type = entry->tls_type;
}
/* Account for the entries we've just allocated. */
- if (entry->tls_type & (GOT_TLS_GD | GOT_TLS_LDM))
+ if (tls_type & (GOT_TLS_GD | GOT_TLS_LDM))
g->tls_assigned_gotno += 2;
- if (entry->tls_type & GOT_TLS_IE)
+ if (tls_type & GOT_TLS_IE)
g->tls_assigned_gotno += 1;
return 1;