summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/sgs/include/debug.h5
-rw-r--r--usr/src/cmd/sgs/include/libld.h9
-rw-r--r--usr/src/cmd/sgs/include/rtld.h1
-rw-r--r--usr/src/cmd/sgs/libld/common/_libld.h11
-rw-r--r--usr/src/cmd/sgs/libld/common/libld.msg5
-rw-r--r--usr/src/cmd/sgs/libld/common/machrel.amd.c171
-rw-r--r--usr/src/cmd/sgs/libld/common/machrel.intel.c189
-rw-r--r--usr/src/cmd/sgs/libld/common/machrel.sparc.c186
-rw-r--r--usr/src/cmd/sgs/libld/common/relocate.c167
-rw-r--r--usr/src/cmd/sgs/libld/common/update.c29
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/_debug.h8
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/got.c51
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/liblddbg.msg92
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/llib-llddbg8
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/mapfile-vers3
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/move.c6
-rw-r--r--usr/src/cmd/sgs/liblddbg/common/tls.c66
-rw-r--r--usr/src/cmd/sgs/packages/common/SUNWonld-README1
-rw-r--r--usr/src/cmd/sgs/rtld/amd64/amd64_elf.c61
-rw-r--r--usr/src/cmd/sgs/rtld/common/_rtld.h4
-rw-r--r--usr/src/cmd/sgs/rtld/common/elf.c80
-rw-r--r--usr/src/cmd/sgs/rtld/common/external.c2
-rw-r--r--usr/src/cmd/sgs/rtld/common/rtld.msg14
-rw-r--r--usr/src/cmd/sgs/rtld/common/setup.c10
-rw-r--r--usr/src/cmd/sgs/rtld/common/tls.c123
-rw-r--r--usr/src/cmd/sgs/rtld/i386/i386_elf.c58
-rw-r--r--usr/src/cmd/sgs/rtld/sparc/sparc_elf.c69
-rw-r--r--usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c74
-rw-r--r--usr/src/uts/common/krtld/reloc.h13
-rw-r--r--usr/src/uts/intel/amd64/krtld/doreloc.c13
-rw-r--r--usr/src/uts/intel/amd64/krtld/kobj_reloc.c2
-rw-r--r--usr/src/uts/intel/ia32/krtld/doreloc.c18
-rw-r--r--usr/src/uts/intel/ia32/krtld/kobj_reloc.c2
-rw-r--r--usr/src/uts/sparc/krtld/doreloc.c49
-rw-r--r--usr/src/uts/sparc/krtld/kobj_reloc.c2
35 files changed, 917 insertions, 685 deletions
diff --git a/usr/src/cmd/sgs/include/debug.h b/usr/src/cmd/sgs/include/debug.h
index 61306f0ab4..c880c1de0c 100644
--- a/usr/src/cmd/sgs/include/debug.h
+++ b/usr/src/cmd/sgs/include/debug.h
@@ -642,7 +642,7 @@ extern void Dbg_file_rejected(Lm_list *, Rej_desc *);
extern void Dbg_file_reuse(Lm_list *, const char *, const char *);
extern void Dbg_file_skip(Lm_list *, const char *, const char *);
-extern void Dbg_got_display(Ofl_desc *, Gottable *);
+extern void Dbg_got_display(Ofl_desc *, Off, int);
extern void Dbg_libs_audit(Lm_list *, const char *, const char *);
extern void Dbg_libs_find(Lm_list *, const char *);
@@ -767,7 +767,8 @@ extern void Dbg_syms_updated(Ofl_desc *, Sym_desc *, const char *);
extern void Dbg_syms_up_title(Lm_list *);
extern void Dbg_tls_modactivity(Lm_list *, void *, uint_t);
-extern void Dbg_tls_static_block(Lm_list *, void *, ulong_t);
+extern void Dbg_tls_static_block(Lm_list *, void *, ulong_t, ulong_t);
+extern void Dbg_tls_static_resv(Rt_map *, ulong_t, ulong_t);
extern void Dbg_util_broadcast(Rt_map *);
extern void Dbg_util_call_array(Rt_map *, void *, int, Word);
diff --git a/usr/src/cmd/sgs/include/libld.h b/usr/src/cmd/sgs/include/libld.h
index cd62a909c2..393b43588e 100644
--- a/usr/src/cmd/sgs/include/libld.h
+++ b/usr/src/cmd/sgs/include/libld.h
@@ -132,7 +132,6 @@ typedef struct {
Gotndx gt_gndx;
} Gottable;
-
/*
* Output file processing structure
*/
@@ -274,6 +273,7 @@ struct ofl_desc {
Xword ofl_hwcap_1; /* hardware capabilities */
Xword ofl_sfcap_1; /* software capabilities */
Lm_list *ofl_lml; /* runtime link-map list */
+ Gottable *ofl_gottable; /* debugging got information */
};
#define FLG_OF_DYNAMIC 0x00000001 /* generate dynamic output module */
@@ -667,10 +667,9 @@ struct sym_desc {
List sd_GOTndxs; /* list of associated GOT entries */
Sym *sd_sym; /* pointer to symbol table entry */
Sym *sd_osym; /* copy of the original symbol entry */
- /* Used only for local partial */
- Psym_info *sd_psyminfo; /* If this is partial symbol, this */
- /* field holds the pointer to */
- /* parsym_info */
+ /* used only for local partial */
+ Psym_info *sd_psyminfo; /* for partial symbols, maintain a */
+ /* pointer to parsym_info */
const char *sd_name; /* symbols name */
Ifl_desc *sd_file; /* file where symbol is taken */
Is_desc *sd_isc; /* input section of symbol definition */
diff --git a/usr/src/cmd/sgs/include/rtld.h b/usr/src/cmd/sgs/include/rtld.h
index 61c29a126c..4d03349d4f 100644
--- a/usr/src/cmd/sgs/include/rtld.h
+++ b/usr/src/cmd/sgs/include/rtld.h
@@ -680,6 +680,7 @@ typedef struct rt_map32 {
#define MSK_RT_FILTER 0x0000f000 /* mask for all filter possibilites */
#define FL1_RT_TLSADD 0x00010000 /* objects TLS has been registered */
+#define FL1_RT_TLSSTAT 0x00020000 /* object requires static TLS */
/*
* The following range of bits are reserved to hold LML_TFLG_AUD_ values
diff --git a/usr/src/cmd/sgs/libld/common/_libld.h b/usr/src/cmd/sgs/libld/common/_libld.h
index b2f9ce39d9..2f20d7d11a 100644
--- a/usr/src/cmd/sgs/libld/common/_libld.h
+++ b/usr/src/cmd/sgs/libld/common/_libld.h
@@ -228,7 +228,8 @@ extern Sdf_desc *sdf_find(const char *, List *);
#define ld_allocate_got ld64_allocate_got
#endif
#define ld_assign_got ld64_assign_got
-#define ld_assign_gotndx ld64_assign_gotndx
+#define ld_assign_got_ndx ld64_assign_got_ndx
+#define ld_assign_got_TLS ld64_assign_got_TLS
#define ld_assign_plt_ndx ld64_assign_plt_ndx
#define ld_calc_got_offset ld64_calc_got_offset
#define ld_calc_plt_addr ld64_calc_plt_addr
@@ -322,7 +323,8 @@ extern Sdf_desc *sdf_find(const char *, List *);
#define ld_allocate_got ld32_allocate_got
#endif
#define ld_assign_got ld32_assign_got
-#define ld_assign_gotndx ld32_assign_gotndx
+#define ld_assign_got_ndx ld32_assign_got_ndx
+#define ld_assign_got_TLS ld32_assign_got_TLS
#define ld_assign_plt_ndx ld32_assign_plt_ndx
#define ld_calc_got_offset ld32_calc_got_offset
#define ld_calc_plt_addr ld32_calc_plt_addr
@@ -419,8 +421,11 @@ extern Ar_desc *ld_ar_setup(const char *, Elf *, Ofl_desc *);
extern uintptr_t ld_allocate_got(Ofl_desc *);
#endif
extern uintptr_t ld_assign_got(Ofl_desc *, Sym_desc *);
-extern uintptr_t ld_assign_gotndx(List *, Gotndx *, Gotref, Ofl_desc *,
+extern uintptr_t ld_assign_got_ndx(List *, Gotndx *, Gotref, Ofl_desc *,
Rel_desc *, Sym_desc *);
+extern uintptr_t ld_assign_got_TLS(Boolean, Rel_desc *, Ofl_desc *,
+ Sym_desc *, Gotndx *, Gotref, Word, Word,
+ Word, Word);
extern void ld_assign_plt_ndx(Sym_desc *, Ofl_desc *);
extern Xword ld_calc_got_offset(Rel_desc *, Ofl_desc *);
diff --git a/usr/src/cmd/sgs/libld/common/libld.msg b/usr/src/cmd/sgs/libld/common/libld.msg
index 82e7a176e3..0a0138e84b 100644
--- a/usr/src/cmd/sgs/libld/common/libld.msg
+++ b/usr/src/cmd/sgs/libld/common/libld.msg
@@ -223,7 +223,7 @@
relocation not currently supported"
@ MSG_REL_PICREDLOC "relocation error: %s: file %s symbol %s: \
-z redlocsym may not be used for pic code"
-@ MSG_REL_TLSIE "relocation error: %s: file %s: symbol %s: \
+@ MSG_REL_TLSLE "relocation error: %s: file %s: symbol %s: \
relocation illegal when building a shared object"
@ MSG_REL_TLSBND "relocation error: %s: file %s: symbol %s: \
bound to: %s: relocation illegal when not bound \
@@ -280,6 +280,9 @@
relocation bound to a symbol with \
STV_PROTECTED visibility"
+@ MSG_REL_TLSIE "relocation: %s: file %s: symbol %s: relocation \
+ has restricted use when building a shared object"
+
#
# TRANSLATION_NOTE
# The following 7 messages are the message to print the
diff --git a/usr/src/cmd/sgs/libld/common/machrel.amd.c b/usr/src/cmd/sgs/libld/common/machrel.amd.c
index fbe91c1fd0..6124a26893 100644
--- a/usr/src/cmd/sgs/libld/common/machrel.amd.c
+++ b/usr/src/cmd/sgs/libld/common/machrel.amd.c
@@ -1220,6 +1220,7 @@ ld_reloc_GOTOP(Boolean local, Rel_desc * rsp, Ofl_desc * ofl)
* Stub routine for common code compatibility, we shouldn't
* actually get here on amd64.
*/
+ assert(0);
return (S_ERROR);
}
@@ -1229,167 +1230,74 @@ ld_reloc_TLS(Boolean local, Rel_desc * rsp, Ofl_desc * ofl)
Word rtype = rsp->rel_rtype;
Sym_desc *sdp = rsp->rel_sym;
Word flags = ofl->ofl_flags;
- Word rflags;
Gotndx *gnp;
/*
- * all TLS relocations are illegal in a static executable.
+ * If we're building an executable - use either the IE or LE access
+ * model. If we're building a shared object process any IE model.
*/
- if ((ofl->ofl_flags & (FLG_OF_STATIC | FLG_OF_EXEC)) ==
- (FLG_OF_STATIC | FLG_OF_EXEC)) {
- eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSSTAT),
- conv_reloc_amd64_type(rsp->rel_rtype, 0),
- rsp->rel_isdesc->is_file->ifl_name,
- demangle(rsp->rel_sname));
- return (S_ERROR);
- }
-
- /*
- * Any TLS relocation must be against a STT_TLS symbol, all others
- * are illegal.
- */
- if (ELF_ST_TYPE(sdp->sd_sym->st_info) != STT_TLS) {
- Ifl_desc *ifl = rsp->rel_isdesc->is_file;
-
- eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBADSYM),
- conv_reloc_amd64_type(rsp->rel_rtype, 0),
- ifl->ifl_name, demangle(rsp->rel_sname),
- conv_sym_info_type(ifl->ifl_ehdr->e_machine,
- ELF_ST_TYPE(sdp->sd_sym->st_info), 0));
- return (S_ERROR);
- }
-
- /*
- * We're a executable - use either the IE or LE
- * access model.
- */
- if (flags & FLG_OF_EXEC) {
+ if ((flags & FLG_OF_EXEC) || (IS_TLS_IE(rtype))) {
/*
- * If we are using either IE or LE reference
- * model set the DF_STATIC_TLS flag.
+ * Set the DF_STATIC_TLS flag.
*/
ofl->ofl_dtflags |= DF_STATIC_TLS;
- if (!local) {
- Gotref gref;
- /*
- * IE access model
- */
+ if (!local || ((flags & FLG_OF_EXEC) == 0)) {
/*
- * It's not possible for LD or LE reference
- * models to reference a symbol external to
- * the current object.
+ * Assign a GOT entry for static TLS references.
*/
- if (IS_TLS_LD(rtype) || IS_TLS_LE(rtype)) {
- eprintf(ofl->ofl_lml, ERR_FATAL,
- MSG_INTL(MSG_REL_TLSBND),
- conv_reloc_amd64_type(rsp->rel_rtype, 0),
- rsp->rel_isdesc->is_file->ifl_name,
- demangle(rsp->rel_sname),
- sdp->sd_file->ifl_name);
- return (S_ERROR);
- }
+ if ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs),
+ GOT_REF_TLSIE, ofl, rsp)) == 0) {
- gref = GOT_REF_TLSIE;
+ if (ld_assign_got_TLS(local, rsp, ofl, sdp,
+ gnp, GOT_REF_TLSIE, FLG_REL_STLS,
+ rtype, R_AMD64_TPOFF64, 0) == S_ERROR)
+ return (S_ERROR);
+ }
/*
- * Assign a GOT entry for static TLS references
+ * IE access model.
*/
- if ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs),
- gref, ofl, rsp)) == 0) {
- if (ld_assign_gotndx(&(sdp->sd_GOTndxs),
- gnp, gref, ofl, rsp, sdp) == S_ERROR)
- return (S_ERROR);
- rsp->rel_rtype = R_AMD64_TPOFF64;
- if (ld_add_outrel((FLG_REL_GOT | FLG_REL_STLS),
- rsp, ofl) == S_ERROR)
- return (S_ERROR);
- rsp->rel_rtype = rtype;
- }
if (IS_TLS_IE(rtype))
return (ld_add_actrel(FLG_REL_STLS, rsp, ofl));
/*
- * If (GD or LD) reference models - fixups
- * are required.
+ * Fixups are required for other executable models.
*/
return (ld_add_actrel((FLG_REL_TLSFIX | FLG_REL_STLS),
rsp, ofl));
}
+
/*
- * LE access model
+ * LE access model.
*/
if (IS_TLS_LE(rtype))
return (ld_add_actrel(FLG_REL_STLS, rsp, ofl));
+
return (ld_add_actrel((FLG_REL_TLSFIX | FLG_REL_STLS),
rsp, ofl));
}
/*
- * Building a shared object
- */
-
- /*
- * Building a shared object - only GD & LD access models
- * will work here.
- */
- if (IS_TLS_IE(rtype) || IS_TLS_LE(rtype)) {
- eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSIE),
- conv_reloc_amd64_type(rsp->rel_rtype, 0),
- rsp->rel_isdesc->is_file->ifl_name,
- demangle(rsp->rel_sname));
- return (S_ERROR);
- }
-
- /*
- * LD access mode can only bind to local symbols.
+ * Building a shared object.
+ *
+ * Assign a GOT entry for a dynamic TLS reference.
*/
- if (!local && IS_TLS_LD(rtype)) {
- eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBND),
- conv_reloc_amd64_type(rsp->rel_rtype, 0),
- rsp->rel_isdesc->is_file->ifl_name,
- demangle(rsp->rel_sname),
- sdp->sd_file->ifl_name);
- return (S_ERROR);
- }
-
-
if (IS_TLS_LD(rtype) && ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs),
GOT_REF_TLSLD, ofl, rsp)) == 0)) {
- if (ld_assign_gotndx(&(sdp->sd_GOTndxs), gnp, GOT_REF_TLSLD,
- ofl, rsp, sdp) == S_ERROR)
- return (S_ERROR);
- rflags = FLG_REL_GOT | FLG_REL_MTLS;
- if (local)
- rflags |= FLG_REL_SCNNDX;
- rsp->rel_rtype = R_AMD64_DTPMOD64;
- if (ld_add_outrel(rflags, rsp, ofl) == S_ERROR)
+
+ if (ld_assign_got_TLS(local, rsp, ofl, sdp, gnp, GOT_REF_TLSLD,
+ FLG_REL_MTLS, rtype, R_AMD64_DTPMOD64, 0) == S_ERROR)
return (S_ERROR);
- rsp->rel_rtype = rtype;
+
} else if (IS_TLS_GD(rtype) &&
- ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs), GOT_REF_TLSGD, ofl,
- rsp)) == 0)) {
- if (ld_assign_gotndx(&(sdp->sd_GOTndxs), gnp, GOT_REF_TLSGD,
- ofl, rsp, sdp) == S_ERROR)
- return (S_ERROR);
- rflags = FLG_REL_GOT | FLG_REL_DTLS;
- if (local)
- rflags |= FLG_REL_SCNNDX;
- rsp->rel_rtype = R_AMD64_DTPMOD64;
- if (ld_add_outrel(rflags, rsp, ofl) == S_ERROR)
+ ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs), GOT_REF_TLSGD,
+ ofl, rsp)) == 0)) {
+
+ if (ld_assign_got_TLS(local, rsp, ofl, sdp, gnp, GOT_REF_TLSGD,
+ FLG_REL_DTLS, rtype, R_AMD64_DTPMOD64,
+ R_AMD64_DTPOFF64) == S_ERROR)
return (S_ERROR);
- if (local == TRUE) {
- rsp->rel_rtype = R_AMD64_DTPOFF64;
- if (ld_add_actrel((FLG_REL_GOT | FLG_REL_DTLS), rsp,
- ofl) == S_ERROR)
- return (S_ERROR);
- } else {
- rsp->rel_rtype = R_AMD64_DTPOFF64;
- if (ld_add_outrel((FLG_REL_GOT | FLG_REL_DTLS), rsp,
- ofl) == S_ERROR)
- return (S_ERROR);
- }
- rsp->rel_rtype = rtype;
}
if (IS_TLS_LD(rtype))
@@ -1452,7 +1360,7 @@ ld_calc_got_offset(Rel_desc * rdesc, Ofl_desc * ofl)
/* ARGSUSED5 */
uintptr_t
-ld_assign_gotndx(List * lst, Gotndx * pgnp, Gotref gref, Ofl_desc * ofl,
+ld_assign_got_ndx(List * lst, Gotndx * pgnp, Gotref gref, Ofl_desc * ofl,
Rel_desc * rsp, Sym_desc * sdp)
{
Xword raddend;
@@ -1536,18 +1444,19 @@ static uchar_t plt0_template[M_PLT_ENTSIZE] = {
* Initializes .got[0] with the _DYNAMIC symbol value.
*/
uintptr_t
-ld_fillin_gotplt(Ofl_desc * ofl)
+ld_fillin_gotplt(Ofl_desc *ofl)
{
Word flags = ofl->ofl_flags;
Word dtflags1 = ofl->ofl_dtflags_1;
if (ofl->ofl_osgot) {
- Sym_desc * sdp;
+ Sym_desc *sdp;
if ((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_DYNAMIC_U),
SYM_NOHASH, 0, ofl)) != NULL) {
- uchar_t *genptr =
- ((uchar_t *)ofl->ofl_osgot->os_outdata->d_buf +
+ uchar_t *genptr;
+
+ genptr = ((uchar_t *)ofl->ofl_osgot->os_outdata->d_buf +
(M_GOT_XDYNAMIC * M_GOT_ENTSIZE));
/* LINTED */
*(Xword *)genptr = sdp->sd_sym->st_value;
@@ -1565,8 +1474,8 @@ ld_fillin_gotplt(Ofl_desc * ofl)
* 0x0f NOP
*/
if ((flags & FLG_OF_DYNAMIC) && ofl->ofl_osplt) {
- uchar_t *pltent;
- Xword val1;
+ uchar_t *pltent;
+ Xword val1;
pltent = (uchar_t *)ofl->ofl_osplt->os_outdata->d_buf;
bcopy(plt0_template, pltent, sizeof (plt0_template));
diff --git a/usr/src/cmd/sgs/libld/common/machrel.intel.c b/usr/src/cmd/sgs/libld/common/machrel.intel.c
index aff9338a18..ca5a84a5be 100644
--- a/usr/src/cmd/sgs/libld/common/machrel.intel.c
+++ b/usr/src/cmd/sgs/libld/common/machrel.intel.c
@@ -70,7 +70,7 @@ ld_mach_make_dynamic(Ofl_desc *ofl, size_t *cnt)
}
void
-ld_mach_update_odynamic(Ofl_desc * ofl, Dyn ** dyn)
+ld_mach_update_odynamic(Ofl_desc *ofl, Dyn **dyn)
{
if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) && ofl->ofl_pltcnt) {
(*dyn)->d_tag = DT_PLTGOT;
@@ -1219,95 +1219,60 @@ ld_reloc_TLS(Boolean local, Rel_desc * rsp, Ofl_desc * ofl)
Word rtype = rsp->rel_rtype;
Sym_desc *sdp = rsp->rel_sym;
Word flags = ofl->ofl_flags;
- Word rflags;
Gotndx *gnp;
/*
- * all TLS relocations are illegal in a static executable.
+ * If we're building an executable - use either the IE or LE access
+ * model. If we're building a shared object process any IE model.
*/
- if ((ofl->ofl_flags & (FLG_OF_STATIC | FLG_OF_EXEC)) ==
- (FLG_OF_STATIC | FLG_OF_EXEC)) {
- eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSSTAT),
- conv_reloc_386_type(rsp->rel_rtype, 0),
- rsp->rel_isdesc->is_file->ifl_name,
- demangle(rsp->rel_sname));
- return (S_ERROR);
- }
-
- /*
- * Any TLS relocation must be against a STT_TLS symbol, all others
- * are illegal.
- */
- if (ELF_ST_TYPE(sdp->sd_sym->st_info) != STT_TLS) {
- Ifl_desc *ifl = rsp->rel_isdesc->is_file;
-
- eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBADSYM),
- conv_reloc_386_type(rsp->rel_rtype, 0),
- ifl->ifl_name, demangle(rsp->rel_sname),
- conv_sym_info_type(ifl->ifl_ehdr->e_machine,
- ELF_ST_TYPE(sdp->sd_sym->st_info), 0));
- return (S_ERROR);
- }
-
- /*
- * We're a executable - use either the IE or LE
- * access model.
- */
- if (flags & FLG_OF_EXEC) {
+ if ((flags & FLG_OF_EXEC) || (IS_TLS_IE(rtype))) {
/*
- * If we are using either IE or LE reference
- * model set the DF_STATIC_TLS flag.
+ * Set the DF_STATIC_TLS flag.
*/
ofl->ofl_dtflags |= DF_STATIC_TLS;
- if (!local) {
- Gotref gref;
- /*
- * IE access model
- */
+ if (!local || ((flags & FLG_OF_EXEC) == 0)) {
/*
- * It's not possible for LD or LE reference
- * models to reference a symbol external to
- * the current object.
+ * Assign a GOT entry for static TLS references.
*/
- if (IS_TLS_LD(rtype) || IS_TLS_LE(rtype)) {
- eprintf(ofl->ofl_lml, ERR_FATAL,
- MSG_INTL(MSG_REL_TLSBND),
- conv_reloc_386_type(rsp->rel_rtype, 0),
- rsp->rel_isdesc->is_file->ifl_name,
- demangle(rsp->rel_sname),
- sdp->sd_file->ifl_name);
- return (S_ERROR);
- }
+ if ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs),
+ GOT_REF_TLSIE, ofl, 0)) == 0) {
- gref = GOT_REF_TLSIE;
+ if (ld_assign_got_TLS(local, rsp, ofl, sdp,
+ gnp, GOT_REF_TLSIE, FLG_REL_STLS,
+ rtype, R_386_TLS_TPOFF, 0) == S_ERROR)
+ return (S_ERROR);
+ }
/*
- * Assign a GOT entry for static TLS references
+ * IE access model.
*/
- if ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs),
- gref, ofl, 0)) == 0) {
- if (ld_assign_gotndx(&(sdp->sd_GOTndxs),
- gnp, gref, ofl, rsp, sdp) == S_ERROR)
- return (S_ERROR);
- rsp->rel_rtype = R_386_TLS_TPOFF;
- if (ld_add_outrel((FLG_REL_GOT | FLG_REL_STLS),
+ if (IS_TLS_IE(rtype)) {
+ if (ld_add_actrel(FLG_REL_STLS,
rsp, ofl) == S_ERROR)
return (S_ERROR);
- rsp->rel_rtype = rtype;
+
+ /*
+ * A non-pic shared object needs to adjust the
+ * active relocation (indntpoff).
+ */
+ if (((flags & FLG_OF_EXEC) == 0) &&
+ (rtype == R_386_TLS_IE)) {
+ rsp->rel_rtype = R_386_RELATIVE;
+ return (ld_add_outrel(NULL, rsp, ofl));
+ }
+ return (1);
}
- if (IS_TLS_IE(rtype))
- return (ld_add_actrel(FLG_REL_STLS, rsp, ofl));
/*
- * If (GD or LD) reference models - fixups
- * are required.
+ * Fixups are required for other executable models.
*/
return (ld_add_actrel((FLG_REL_TLSFIX | FLG_REL_STLS),
rsp, ofl));
}
+
/*
- * LE access model
+ * LE access model.
*/
if (IS_TLS_LE(rtype) || (rtype == R_386_TLS_LDO_32))
return (ld_add_actrel(FLG_REL_STLS, rsp, ofl));
@@ -1317,75 +1282,31 @@ ld_reloc_TLS(Boolean local, Rel_desc * rsp, Ofl_desc * ofl)
}
/*
- * Building a shared object
- */
-
- /*
- * Building a shared object - only GD & LD access models
- * will work here.
- */
- if (IS_TLS_IE(rtype) || IS_TLS_LE(rtype)) {
- eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSIE),
- conv_reloc_386_type(rsp->rel_rtype, 0),
- rsp->rel_isdesc->is_file->ifl_name,
- demangle(rsp->rel_sname));
- return (S_ERROR);
- }
-
- /*
- * LD access mode can only bind to local symbols.
+ * Building a shared object.
+ *
+ * Assign a GOT entry for a dynamic TLS reference.
*/
- if (!local && IS_TLS_LD(rtype)) {
- eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBND),
- conv_reloc_386_type(rsp->rel_rtype, 0),
- rsp->rel_isdesc->is_file->ifl_name,
- demangle(rsp->rel_sname),
- sdp->sd_file->ifl_name);
- return (S_ERROR);
- }
-
-
if (IS_TLS_LD(rtype) && ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs),
GOT_REF_TLSLD, ofl, 0)) == 0)) {
- if (ld_assign_gotndx(&(sdp->sd_GOTndxs), gnp, GOT_REF_TLSLD,
- ofl, rsp, sdp) == S_ERROR)
- return (S_ERROR);
- rflags = FLG_REL_GOT | FLG_REL_MTLS;
- if (local)
- rflags |= FLG_REL_SCNNDX;
- rsp->rel_rtype = R_386_TLS_DTPMOD32;
- if (ld_add_outrel(rflags, rsp, ofl) == S_ERROR)
+
+ if (ld_assign_got_TLS(local, rsp, ofl, sdp, gnp, GOT_REF_TLSLD,
+ FLG_REL_MTLS, rtype, R_386_TLS_DTPMOD32, 0) == S_ERROR)
return (S_ERROR);
- rsp->rel_rtype = rtype;
+
} else if (IS_TLS_GD(rtype) &&
((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs), GOT_REF_TLSGD,
ofl, 0)) == 0)) {
- if (ld_assign_gotndx(&(sdp->sd_GOTndxs), gnp, GOT_REF_TLSGD,
- ofl, rsp, sdp) == S_ERROR)
- return (S_ERROR);
- rflags = FLG_REL_GOT | FLG_REL_DTLS;
- if (local)
- rflags |= FLG_REL_SCNNDX;
- rsp->rel_rtype = R_386_TLS_DTPMOD32;
- if (ld_add_outrel(rflags, rsp, ofl) == S_ERROR)
+
+ if (ld_assign_got_TLS(local, rsp, ofl, sdp, gnp, GOT_REF_TLSGD,
+ FLG_REL_DTLS, rtype, R_386_TLS_DTPMOD32,
+ R_386_TLS_DTPOFF32) == S_ERROR)
return (S_ERROR);
- if (local == TRUE) {
- rsp->rel_rtype = R_386_TLS_DTPOFF32;
- if (ld_add_actrel((FLG_REL_GOT | FLG_REL_DTLS), rsp,
- ofl) == S_ERROR)
- return (S_ERROR);
- } else {
- rsp->rel_rtype = R_386_TLS_DTPOFF32;
- if (ld_add_outrel((FLG_REL_GOT | FLG_REL_DTLS), rsp,
- ofl) == S_ERROR)
- return (S_ERROR);
- }
- rsp->rel_rtype = rtype;
}
+
/*
* For GD/LD TLS reference - TLS_{GD,LD}_CALL, this will eventually
- * cause a call to __tls_get_addr(). Let's convert this
- * relocation to that symbol now, and prepare for the PLT magic.
+ * cause a call to __tls_get_addr(). Convert this relocation to that
+ * symbol now, and prepare for the PLT magic.
*/
if ((rtype == R_386_TLS_GD_PLT) || (rtype == R_386_TLS_LDM_PLT)) {
Sym_desc * tlsgetsym;
@@ -1393,11 +1314,14 @@ ld_reloc_TLS(Boolean local, Rel_desc * rsp, Ofl_desc * ofl)
if ((tlsgetsym = ld_sym_add_u(MSG_ORIG(MSG_SYM_TLSGETADDR_UU),
ofl)) == (Sym_desc *)S_ERROR)
return (S_ERROR);
+
rsp->rel_sym = tlsgetsym;
rsp->rel_sname = tlsgetsym->sd_name;
rsp->rel_rtype = R_386_PLT32;
+
if (ld_reloc_plt(rsp, ofl) == S_ERROR)
return (S_ERROR);
+
rsp->rel_sym = sdp;
rsp->rel_sname = sdp->sd_name;
rsp->rel_rtype = rtype;
@@ -1460,7 +1384,7 @@ ld_calc_got_offset(Rel_desc * rdesc, Ofl_desc * ofl)
/* ARGSUSED4 */
uintptr_t
-ld_assign_gotndx(List * lst, Gotndx * pgnp, Gotref gref, Ofl_desc * ofl,
+ld_assign_got_ndx(List * lst, Gotndx * pgnp, Gotref gref, Ofl_desc * ofl,
Rel_desc * rsp, Sym_desc * sdp)
{
Gotndx *gnp;
@@ -1504,15 +1428,18 @@ ld_assign_plt_ndx(Sym_desc * sdp, Ofl_desc *ofl)
* Initializes .got[0] with the _DYNAMIC symbol value.
*/
uintptr_t
-ld_fillin_gotplt(Ofl_desc * ofl)
+ld_fillin_gotplt(Ofl_desc *ofl)
{
+ Word flags = ofl->ofl_flags;
+
if (ofl->ofl_osgot) {
- Sym_desc * sdp;
+ Sym_desc *sdp;
if ((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_DYNAMIC_U),
SYM_NOHASH, 0, ofl)) != NULL) {
- uchar_t *genptr = ((uchar_t *)
- ofl->ofl_osgot->os_outdata->d_buf +
+ uchar_t *genptr;
+
+ genptr = ((uchar_t *)ofl->ofl_osgot->os_outdata->d_buf +
(M_GOT_XDYNAMIC * M_GOT_ENTSIZE));
/* LINTED */
*(Word *)genptr = (Word)sdp->sd_sym->st_value;
@@ -1530,11 +1457,11 @@ ld_fillin_gotplt(Ofl_desc * ofl)
* JMP * got[2]@GOT(%ebx) # the address of rtbinder
* }
*/
- if ((ofl->ofl_flags & FLG_OF_DYNAMIC) && ofl->ofl_osplt) {
+ if ((flags & FLG_OF_DYNAMIC) && ofl->ofl_osplt) {
uchar_t *pltent;
pltent = (uchar_t *)ofl->ofl_osplt->os_outdata->d_buf;
- if (!(ofl->ofl_flags & FLG_OF_SHAROBJ)) {
+ if (!(flags & FLG_OF_SHAROBJ)) {
pltent[0] = M_SPECIAL_INST;
pltent[1] = M_PUSHL_DISP;
pltent += 2;
diff --git a/usr/src/cmd/sgs/libld/common/machrel.sparc.c b/usr/src/cmd/sgs/libld/common/machrel.sparc.c
index a39ab3c7c5..c909aa5be0 100644
--- a/usr/src/cmd/sgs/libld/common/machrel.sparc.c
+++ b/usr/src/cmd/sgs/libld/common/machrel.sparc.c
@@ -123,7 +123,7 @@ ld_mach_make_dynamic(Ofl_desc *ofl, size_t *cnt)
}
void
-ld_mach_update_odynamic(Ofl_desc * ofl, Dyn ** dyn)
+ld_mach_update_odynamic(Ofl_desc *ofl, Dyn **dyn)
{
if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) && ofl->ofl_pltcnt) {
(*dyn)->d_tag = DT_PLTGOT;
@@ -1621,53 +1621,21 @@ ld_reloc_TLS(Boolean local, Rel_desc * rsp, Ofl_desc * ofl)
Word rtype = rsp->rel_rtype;
Sym_desc *sdp = rsp->rel_sym;
Word flags = ofl->ofl_flags;
- Word rflags;
Gotndx *gnp;
/*
- * all TLS relocations are illegal in a static executable.
+ * If we're building an executable - use either the IE or LE access
+ * model. If we're building a shared object process any IE model.
*/
- if ((ofl->ofl_flags & (FLG_OF_STATIC | FLG_OF_EXEC)) ==
- (FLG_OF_STATIC | FLG_OF_EXEC)) {
- eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSSTAT),
- conv_reloc_SPARC_type(rsp->rel_rtype, 0),
- rsp->rel_isdesc->is_file->ifl_name,
- demangle(rsp->rel_sname));
- return (S_ERROR);
- }
-
- /*
- * Any TLS relocation must be against a STT_TLS symbol, all others
- * are illegal.
- */
- if (ELF_ST_TYPE(sdp->sd_sym->st_info) != STT_TLS) {
- Ifl_desc *ifl = rsp->rel_isdesc->is_file;
-
- eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBADSYM),
- conv_reloc_SPARC_type(rsp->rel_rtype, 0),
- ifl->ifl_name, demangle(rsp->rel_sname),
- conv_sym_info_type(ifl->ifl_ehdr->e_machine,
- ELF_ST_TYPE(sdp->sd_sym->st_info), 0));
- return (S_ERROR);
- }
-
- /*
- * We're a executable - use either the IE or LE
- * access model.
- */
- if (flags & FLG_OF_EXEC) {
+ if ((flags & FLG_OF_EXEC) || (IS_TLS_IE(rtype))) {
/*
- * If we are using either IE or LE reference
- * model set the DF_STATIC_TLS flag.
+ * Set the DF_STATIC_TLS flag.
*/
ofl->ofl_dtflags |= DF_STATIC_TLS;
- if (!local) {
+ if (!local || ((flags & FLG_OF_EXEC) == 0)) {
/*
- * IE access model
- */
- /*
- * When building a executable - these relocations
+ * When processing static TLS - these relocations
* can be ignored.
*/
if ((rtype == R_SPARC_TLS_IE_LD) ||
@@ -1676,22 +1644,7 @@ ld_reloc_TLS(Boolean local, Rel_desc * rsp, Ofl_desc * ofl)
return (1);
/*
- * It's not possible for LD or LE reference
- * models to reference a symbol external to
- * the current object.
- */
- if (IS_TLS_LD(rtype) || IS_TLS_LE(rtype)) {
- eprintf(ofl->ofl_lml, ERR_FATAL,
- MSG_INTL(MSG_REL_TLSBND),
- conv_reloc_SPARC_type(rsp->rel_rtype, 0),
- rsp->rel_isdesc->is_file->ifl_name,
- demangle(rsp->rel_sname),
- sdp->sd_file->ifl_name);
- return (S_ERROR);
- }
-
- /*
- * Assign a GOT entry for static TLS references
+ * Assign a GOT entry for IE static TLS references.
*/
if (((rtype == R_SPARC_TLS_GD_HI22) ||
(rtype == R_SPARC_TLS_GD_LO10) ||
@@ -1699,35 +1652,35 @@ ld_reloc_TLS(Boolean local, Rel_desc * rsp, Ofl_desc * ofl)
(rtype == R_SPARC_TLS_IE_LO10)) &&
((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs),
GOT_REF_TLSIE, ofl, rsp)) == 0)) {
- if (ld_assign_gotndx(&(sdp->sd_GOTndxs), gnp,
- GOT_REF_TLSIE, ofl, rsp, sdp) == S_ERROR)
- return (S_ERROR);
- rsp->rel_rtype = M_R_TPOFF;
- if (ld_add_outrel((FLG_REL_GOT | FLG_REL_STLS),
- rsp, ofl) == S_ERROR)
+
+ if (ld_assign_got_TLS(local, rsp, ofl, sdp,
+ gnp, GOT_REF_TLSIE, FLG_REL_STLS,
+ rtype, M_R_TPOFF, 0) == S_ERROR)
return (S_ERROR);
- rsp->rel_rtype = rtype;
}
+ /*
+ * IE access model.
+ */
if (IS_TLS_IE(rtype))
return (ld_add_actrel(FLG_REL_STLS, rsp, ofl));
/*
- * If (GD) reference models - fixups
- * are required.
+ * Fixups are required for other executable models.
*/
return (ld_add_actrel((FLG_REL_TLSFIX | FLG_REL_STLS),
rsp, ofl));
}
+
/*
- * LE access model
+ * LE access model.
*/
if (IS_TLS_LE(rtype))
return (ld_add_actrel(FLG_REL_STLS, rsp, ofl));
/*
- * When building a executable - these relocations
- * can be ignored.
+ * When processing static TLS - these relocations can be
+ * ignored.
*/
if (rtype == R_SPARC_TLS_IE_ADD)
return (1);
@@ -1737,36 +1690,9 @@ ld_reloc_TLS(Boolean local, Rel_desc * rsp, Ofl_desc * ofl)
}
/*
- * Building a shared object
- */
-
- /*
- * Building a shared object - only GD & LD access models
- * will work here.
- */
- if (IS_TLS_IE(rtype) || IS_TLS_LE(rtype)) {
- eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSIE),
- conv_reloc_SPARC_type(rsp->rel_rtype, 0),
- rsp->rel_isdesc->is_file->ifl_name,
- demangle(rsp->rel_sname));
- return (S_ERROR);
- }
-
- /*
- * LD access mode can only bind to local symbols.
- */
- if (!local && IS_TLS_LD(rtype)) {
- eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBND),
- conv_reloc_SPARC_type(rsp->rel_rtype, 0),
- rsp->rel_isdesc->is_file->ifl_name,
- demangle(rsp->rel_sname),
- sdp->sd_file->ifl_name);
- return (S_ERROR);
- }
-
- /*
- * For dynamic TLS references - ADD relocations
- * are ignored.
+ * Building a shared object.
+ *
+ * For dynamic TLS references, ADD relocations are ignored.
*/
if ((rtype == R_SPARC_TLS_GD_ADD) || (rtype == R_SPARC_TLS_LDM_ADD) ||
(rtype == R_SPARC_TLS_LDO_ADD))
@@ -1777,52 +1703,27 @@ ld_reloc_TLS(Boolean local, Rel_desc * rsp, Ofl_desc * ofl)
*/
if (((rtype == R_SPARC_TLS_LDM_HI22) ||
(rtype == R_SPARC_TLS_LDM_LO10)) &&
- ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs),
- GOT_REF_TLSLD, ofl, rsp)) == 0)) {
- if (ld_assign_gotndx(&(sdp->sd_GOTndxs), gnp, GOT_REF_TLSLD,
- ofl, rsp, sdp) == S_ERROR)
- return (S_ERROR);
- rsp->rel_rtype = M_R_DTPMOD;
- rflags = FLG_REL_GOT | FLG_REL_MTLS;
- if (local)
- rflags |= FLG_REL_SCNNDX;
+ ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs), GOT_REF_TLSLD,
+ ofl, rsp)) == 0)) {
- if (ld_add_outrel(rflags, rsp, ofl) == S_ERROR)
+ if (ld_assign_got_TLS(local, rsp, ofl, sdp, gnp, GOT_REF_TLSLD,
+ FLG_REL_MTLS, rtype, M_R_DTPMOD, 0) == S_ERROR)
return (S_ERROR);
- rsp->rel_rtype = rtype;
-
- } else if (((rtype == R_SPARC_TLS_GD_HI22) || (rtype ==
- R_SPARC_TLS_GD_LO10)) && ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs),
- GOT_REF_TLSGD, ofl, rsp)) == 0)) {
- if (ld_assign_gotndx(&(sdp->sd_GOTndxs), gnp, GOT_REF_TLSGD,
- ofl, rsp, sdp) == S_ERROR)
- return (S_ERROR);
- rsp->rel_rtype = M_R_DTPMOD;
- rflags = FLG_REL_GOT | FLG_REL_DTLS;
- if (local)
- rflags |= FLG_REL_SCNNDX;
+ } else if (((rtype == R_SPARC_TLS_GD_HI22) ||
+ (rtype == R_SPARC_TLS_GD_LO10)) &&
+ ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs), GOT_REF_TLSGD,
+ ofl, rsp)) == 0)) {
- if (ld_add_outrel(rflags, rsp, ofl) == S_ERROR)
+ if (ld_assign_got_TLS(local, rsp, ofl, sdp, gnp, GOT_REF_TLSGD,
+ FLG_REL_DTLS, rtype, M_R_DTPMOD, M_R_DTPOFF) == S_ERROR)
return (S_ERROR);
-
- if (local == TRUE) {
- rsp->rel_rtype = M_R_DTPOFF;
- if (ld_add_actrel((FLG_REL_GOT | FLG_REL_DTLS), rsp,
- ofl) == S_ERROR)
- return (S_ERROR);
- } else {
- rsp->rel_rtype = M_R_DTPOFF;
- if (ld_add_outrel((FLG_REL_GOT | FLG_REL_DTLS), rsp,
- ofl) == S_ERROR)
- return (S_ERROR);
- }
- rsp->rel_rtype = rtype;
}
+
/*
* For GD/LD TLS reference - TLS_{GD,LD}_CALL, this will eventually
- * cause a call to __tls_get_addr(). Let's convert this
- * relocation to that symbol now, and prepare for the PLT magic.
+ * cause a call to __tls_get_addr(). Convert this relocation to that
+ * symbol now, and prepare for the PLT magic.
*/
if ((rtype == R_SPARC_TLS_GD_CALL) || (rtype == R_SPARC_TLS_LDM_CALL)) {
Sym_desc * tlsgetsym;
@@ -1830,11 +1731,14 @@ ld_reloc_TLS(Boolean local, Rel_desc * rsp, Ofl_desc * ofl)
if ((tlsgetsym = ld_sym_add_u(MSG_ORIG(MSG_SYM_TLSGETADDR_U),
ofl)) == (Sym_desc *)S_ERROR)
return (S_ERROR);
+
rsp->rel_sym = tlsgetsym;
rsp->rel_sname = tlsgetsym->sd_name;
rsp->rel_rtype = R_SPARC_WPLT30;
+
if (ld_reloc_plt(rsp, ofl) == S_ERROR)
return (S_ERROR);
+
rsp->rel_sym = sdp;
rsp->rel_sname = sdp->sd_name;
rsp->rel_rtype = rtype;
@@ -1947,7 +1851,7 @@ ld_calc_got_offset(Rel_desc * rdesc, Ofl_desc * ofl)
}
uintptr_t
-ld_assign_gotndx(List * lst, Gotndx * pgnp, Gotref gref, Ofl_desc * ofl,
+ld_assign_got_ndx(List * lst, Gotndx * pgnp, Gotref gref, Ofl_desc * ofl,
Rel_desc * rsp, Sym_desc * sdp)
{
Xword raddend;
@@ -2076,20 +1980,20 @@ ld_allocate_got(Ofl_desc * ofl)
return (1);
}
-
/*
* Initializes .got[0] with the _DYNAMIC symbol value.
*/
uintptr_t
-ld_fillin_gotplt(Ofl_desc * ofl)
+ld_fillin_gotplt(Ofl_desc *ofl)
{
if (ofl->ofl_osgot) {
- Sym_desc * sdp;
+ Sym_desc *sdp;
if ((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_DYNAMIC_U),
SYM_NOHASH, 0, ofl)) != NULL) {
- uchar_t *genptr = ((uchar_t *)
- ofl->ofl_osgot->os_outdata->d_buf +
+ uchar_t *genptr;
+
+ genptr = ((uchar_t *)ofl->ofl_osgot->os_outdata->d_buf +
(-neggotoffset * M_GOT_ENTSIZE) +
(M_GOT_XDYNAMIC * M_GOT_ENTSIZE));
/* LINTED */
diff --git a/usr/src/cmd/sgs/libld/common/relocate.c b/usr/src/cmd/sgs/libld/common/relocate.c
index 065058f993..9b197006b3 100644
--- a/usr/src/cmd/sgs/libld/common/relocate.c
+++ b/usr/src/cmd/sgs/libld/common/relocate.c
@@ -518,7 +518,7 @@ ld_reloc_GOT_relative(Boolean local, Rel_desc *rsp, Ofl_desc *ofl)
ofl, rsp)) == 0) {
Word rtype = rsp->rel_rtype;
- if (ld_assign_gotndx(&(sdp->sd_GOTndxs), 0, GOT_REF_GENERIC,
+ if (ld_assign_got_ndx(&(sdp->sd_GOTndxs), 0, GOT_REF_GENERIC,
ofl, rsp, sdp) == S_ERROR)
return (S_ERROR);
@@ -571,7 +571,7 @@ ld_reloc_GOT_relative(Boolean local, Rel_desc *rsp, Ofl_desc *ofl)
rsp->rel_rtype = rtype;
}
} else {
- if (ld_assign_gotndx(&(sdp->sd_GOTndxs), gnp, GOT_REF_GENERIC,
+ if (ld_assign_got_ndx(&(sdp->sd_GOTndxs), gnp, GOT_REF_GENERIC,
ofl, rsp, sdp) == S_ERROR)
return (S_ERROR);
}
@@ -981,6 +981,88 @@ reloc_relobj(Boolean local, Rel_desc *rsp, Ofl_desc *ofl)
return (ld_add_outrel(oflags, rsp, ofl));
}
+/*
+ * Perform any generic TLS validations before passing control to machine
+ * specific routines. At this point we know we are dealing with an executable
+ * or shared object - relocatable objects have already been processed.
+ */
+static uintptr_t
+reloc_TLS(Boolean local, Rel_desc *rsp, Ofl_desc *ofl)
+{
+ Word rtype = rsp->rel_rtype, flags = ofl->ofl_flags;
+ Ifl_desc *ifl = rsp->rel_isdesc->is_file;
+ Half mach = ifl->ifl_ehdr->e_machine;
+ Sym_desc *sdp = rsp->rel_sym;
+ unsigned char type;
+
+ /*
+ * All TLS relocations are illegal in a static executable.
+ */
+ if ((flags & (FLG_OF_STATIC | FLG_OF_EXEC)) ==
+ (FLG_OF_STATIC | FLG_OF_EXEC)) {
+ eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSSTAT),
+ conv_reloc_type(mach, rtype, 0), ifl->ifl_name,
+ demangle(rsp->rel_sname));
+ return (S_ERROR);
+ }
+
+ /*
+ * Any TLS relocation must be against a STT_TLS symbol, all others
+ * are illegal.
+ */
+ if ((type = ELF_ST_TYPE(sdp->sd_sym->st_info)) != STT_TLS) {
+ eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBADSYM),
+ conv_reloc_type(mach, rtype, 0), ifl->ifl_name,
+ demangle(rsp->rel_sname),
+ conv_sym_info_type(mach, type, 0));
+ return (S_ERROR);
+ }
+
+ /*
+ * A dynamic executable can not use the LD or LE reference models to
+ * reference an external symbol. A shared object can not use the LD
+ * reference model to reference an external symbol.
+ */
+ if (!local && (IS_TLS_LD(rtype) ||
+ ((flags & FLG_OF_EXEC) && IS_TLS_LE(rtype)))) {
+ eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBND),
+ conv_reloc_type(mach, rtype, 0), ifl->ifl_name,
+ demangle(rsp->rel_sname), sdp->sd_file->ifl_name);
+ return (S_ERROR);
+ }
+
+ /*
+ * The TLS LE model is only allowed for dynamic executables. The TLS IE
+ * model is allowed for shared objects, but this model has restrictions.
+ * This model can only be used freely in dependencies that are loaded
+ * immediately as part of process initialization. However, during the
+ * initial runtime handshake with libc that establishes the thread
+ * pointer, a small backup TLS reservation is created. This area can
+ * be used by objects that are loaded after threads are initialized.
+ * However, this area is limited in size and may have already been
+ * used. This area is intended for specialized applications, and does
+ * not provide the degree of flexibility dynamic TLS can offer. Under
+ * -z verbose indicate this restriction to the user.
+ */
+ if ((flags & FLG_OF_EXEC) == 0) {
+ if (IS_TLS_LE(rtype)) {
+ eprintf(ofl->ofl_lml, ERR_FATAL,
+ MSG_INTL(MSG_REL_TLSLE),
+ conv_reloc_type(mach, rtype, 0), ifl->ifl_name,
+ demangle(rsp->rel_sname));
+ return (S_ERROR);
+
+ } else if ((IS_TLS_IE(rtype)) && (flags & FLG_OF_VERBOSE)) {
+ eprintf(ofl->ofl_lml, ERR_WARNING,
+ MSG_INTL(MSG_REL_TLSIE),
+ conv_reloc_type(mach, rtype, 0), ifl->ifl_name,
+ demangle(rsp->rel_sname));
+ }
+ }
+
+ return (ld_reloc_TLS(local, rsp, ofl));
+}
+
uintptr_t
ld_process_sym_reloc(Ofl_desc *ofl, Rel_desc *reld, Rel *reloc, Is_desc *isp,
const char *isname)
@@ -1107,7 +1189,8 @@ ld_process_sym_reloc(Ofl_desc *ofl, Rel_desc *reld, Rel *reloc, Is_desc *isp,
/*
* TLS symbols can only have TLS relocations.
*/
- if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_TLS) && !IS_TLS(rtype)) {
+ if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_TLS) &&
+ (IS_TLS_INS(rtype) == 0)) {
/*
* The above test is relaxed if the target section is
* non-allocable.
@@ -1133,7 +1216,7 @@ ld_process_sym_reloc(Ofl_desc *ofl, Rel_desc *reld, Rel *reloc, Is_desc *isp,
return (reloc_relobj(local, reld, ofl));
if (IS_TLS_INS(rtype))
- return (ld_reloc_TLS(local, reld, ofl));
+ return (reloc_TLS(local, reld, ofl));
if (IS_GOT_INS(rtype))
return (ld_reloc_GOTOP(local, reld, ofl));
@@ -1826,6 +1909,7 @@ ld_reloc_process(Ofl_desc *ofl)
{
Listnode *lnp1;
Sg_desc *sgp;
+ Os_desc *osp;
Word ndx = 0, flags = ofl->ofl_flags;
Shdr *shdr;
@@ -1872,7 +1956,7 @@ ld_reloc_process(Ofl_desc *ofl)
Aliste off;
for (ALIST_TRAVERSE(sgp->sg_osdescs, off, ospp)) {
- Os_desc *osp = *ospp;
+ osp = *ospp;
if (osp->os_relosdesc == 0)
continue;
@@ -1886,10 +1970,10 @@ ld_reloc_process(Ofl_desc *ofl)
/*
* Since the .rel[a] section is not tied to any specific
- * section, we'd of not found it above.
+ * section, we'd not have found it above.
*/
- if (ofl->ofl_osrel) {
- shdr = ofl->ofl_osrel->os_shdr;
+ if ((osp = ofl->ofl_osrel) != NULL) {
+ shdr = osp->os_shdr;
shdr->sh_link = ndx;
shdr->sh_info = 0;
}
@@ -1899,17 +1983,16 @@ ld_reloc_process(Ofl_desc *ofl)
* coalesced) so just hit them directly instead of stepping
* over the output sections.
*/
- if (ofl->ofl_osrelhead) {
- shdr = ofl->ofl_osrelhead->os_shdr;
+ if ((osp = ofl->ofl_osrelhead) != NULL) {
+ shdr = osp->os_shdr;
shdr->sh_link = ndx;
shdr->sh_info = 0;
}
- if (ofl->ofl_osplt && ofl->ofl_osplt->os_relosdesc) {
- shdr = ofl->ofl_osplt->os_relosdesc->os_shdr;
+ if (((osp = ofl->ofl_osplt) != NULL) && osp->os_relosdesc) {
+ shdr = osp->os_relosdesc->os_shdr;
shdr->sh_link = ndx;
/* LINTED */
- shdr->sh_info =
- (Word)elf_ndxscn(ofl->ofl_osplt->os_scn);
+ shdr->sh_info = (Word)elf_ndxscn(osp->os_scn);
}
}
@@ -1934,6 +2017,13 @@ ld_reloc_process(Ofl_desc *ofl)
return (S_ERROR);
}
+ /*
+ * Now that any GOT information has been written, display the debugging
+ * information if required.
+ */
+ if ((osp = ofl->ofl_osgot) != NULL)
+ DBG_CALL(Dbg_got_display(ofl, osp->os_shdr->sh_addr, 1));
+
return (1);
}
@@ -2021,9 +2111,54 @@ ld_reloc_remain_entry(Rel_desc *orsp, Os_desc *osp, Ofl_desc *ofl)
}
/*
- * The following functions are called from
- * machine functions defined in {sparc,i386,sparcv9}/machrel.c
+ * Generic encapsulation for generating a TLS got index.
*/
+uintptr_t
+ld_assign_got_TLS(Boolean local, Rel_desc *rsp, Ofl_desc *ofl, Sym_desc *sdp,
+ Gotndx *gnp, Gotref gref, Word rflag, Word ortype, Word rtype1, Word rtype2)
+{
+ Word rflags;
+
+ if (ld_assign_got_ndx(&(sdp->sd_GOTndxs), gnp, gref, ofl,
+ rsp, sdp) == S_ERROR)
+ return (S_ERROR);
+
+ rflags = FLG_REL_GOT | rflag;
+ if (local)
+ rflags |= FLG_REL_SCNNDX;
+ rsp->rel_rtype = rtype1;
+
+ if (ld_add_outrel(rflags, rsp, ofl) == S_ERROR)
+ return (S_ERROR);
+
+ if (local && (gref == GOT_REF_TLSIE)) {
+ /*
+ * If this is a local LE TLS symbol, then the symbol won't be
+ * available at runtime. The value of the local symbol will
+ * be placed in the associated got entry, and the got
+ * relocation is reassigned to a section symbol.
+ */
+ if (ld_add_actrel(rflags, rsp, ofl) == S_ERROR)
+ return (S_ERROR);
+ }
+
+ if (rtype2) {
+ rflags = FLG_REL_GOT | rflag;
+ rsp->rel_rtype = rtype2;
+
+ if (local) {
+ if (ld_add_actrel(rflags, rsp, ofl) == S_ERROR)
+ return (S_ERROR);
+ } else {
+ if (ld_add_outrel(rflags, rsp, ofl) == S_ERROR)
+ return (S_ERROR);
+ }
+ }
+
+ rsp->rel_rtype = ortype;
+
+ return (1);
+}
/*
* Move Section related function
diff --git a/usr/src/cmd/sgs/libld/common/update.c b/usr/src/cmd/sgs/libld/common/update.c
index 7f63d8d8b1..2ad3621fc3 100644
--- a/usr/src/cmd/sgs/libld/common/update.c
+++ b/usr/src/cmd/sgs/libld/common/update.c
@@ -98,7 +98,6 @@ update_osym(Ofl_desc *ofl)
Versym *versym;
Gottable *gottable; /* used for display got debugging */
/* information */
- Gottable *_gottable;
Syminfo *syminfo;
Sym_s_list *sorted_syms; /* table to hold sorted symbols */
Word ssndx; /* global index into sorted_syms */
@@ -196,8 +195,8 @@ update_osym(Ofl_desc *ofl)
* the buffer to 'cache' the GOT symbols into now.
*/
if (DBG_ENABLED) {
- if ((_gottable = gottable = libld_calloc(ofl->ofl_gotcnt,
- sizeof (Gottable))) == 0)
+ if ((ofl->ofl_gottable = gottable =
+ libld_calloc(ofl->ofl_gotcnt, sizeof (Gottable))) == 0)
return ((Addr)S_ERROR);
}
@@ -481,10 +480,10 @@ update_osym(Ofl_desc *ofl)
#endif
if (DBG_ENABLED) {
for (LIST_TRAVERSE(&sdp->sd_GOTndxs, lnp2, gnp)) {
- _gottable->gt_sym = sdp;
- _gottable->gt_gndx.gn_gotndx = gnp->gn_gotndx;
- _gottable->gt_gndx.gn_addend = gnp->gn_addend;
- _gottable++;
+ gottable->gt_sym = sdp;
+ gottable->gt_gndx.gn_gotndx = gnp->gn_gotndx;
+ gottable->gt_gndx.gn_addend = gnp->gn_addend;
+ gottable++;
}
}
@@ -902,17 +901,17 @@ update_osym(Ofl_desc *ofl)
#endif
if (DBG_ENABLED) {
for (LIST_TRAVERSE(&sdp->sd_GOTndxs, lnp2, gnp)) {
- _gottable->gt_sym = sdp;
- _gottable->gt_gndx.gn_gotndx = gnp->gn_gotndx;
- _gottable->gt_gndx.gn_addend = gnp->gn_addend;
- _gottable++;
+ gottable->gt_sym = sdp;
+ gottable->gt_gndx.gn_gotndx = gnp->gn_gotndx;
+ gottable->gt_gndx.gn_addend = gnp->gn_addend;
+ gottable++;
}
if (sdp->sd_aux && sdp->sd_aux->sa_PLTGOTndx) {
- _gottable->gt_sym = sdp;
- _gottable->gt_gndx.gn_gotndx =
+ gottable->gt_sym = sdp;
+ gottable->gt_gndx.gn_gotndx =
sdp->sd_aux->sa_PLTGOTndx;
- _gottable++;
+ gottable++;
}
}
@@ -1526,7 +1525,7 @@ update_osym(Ofl_desc *ofl)
/*
* Now display GOT debugging information if required.
*/
- DBG_CALL(Dbg_got_display(ofl, gottable));
+ DBG_CALL(Dbg_got_display(ofl, 0, 0));
/*
* Update the section headers information.
diff --git a/usr/src/cmd/sgs/liblddbg/common/_debug.h b/usr/src/cmd/sgs/liblddbg/common/_debug.h
index 9a1f172fae..451b17e967 100644
--- a/usr/src/cmd/sgs/liblddbg/common/_debug.h
+++ b/usr/src/cmd/sgs/liblddbg/common/_debug.h
@@ -105,6 +105,10 @@ typedef struct {
#define MSG_GOT_TITLE MSG_GOT_TITLE_64
#define MSG_GOT_ENTRY_RE MSG_GOT_ENTRY_RE_64
#define MSG_GOT_ENTRY_NR MSG_GOT_ENTRY_NR_64
+#define MSG_GOT_COLUMNS1 MSG_GOT_COLUMNS1_64
+#define MSG_GOT_COLUMNS2 MSG_GOT_COLUMNS2_64
+#define MSG_GOT_FORMAT1 MSG_GOT_FORMAT1_64
+#define MSG_GOT_FORMAT2 MSG_GOT_FORMAT2_64
#define MSG_PHD_VADDR MSG_PHD_VADDR_64
#define MSG_PHD_PADDR MSG_PHD_PADDR_64
@@ -155,6 +159,10 @@ typedef struct {
#define MSG_GOT_TITLE MSG_GOT_TITLE_32
#define MSG_GOT_ENTRY_RE MSG_GOT_ENTRY_RE_32
#define MSG_GOT_ENTRY_NR MSG_GOT_ENTRY_NR_32
+#define MSG_GOT_COLUMNS1 MSG_GOT_COLUMNS1_32
+#define MSG_GOT_COLUMNS2 MSG_GOT_COLUMNS2_32
+#define MSG_GOT_FORMAT1 MSG_GOT_FORMAT1_32
+#define MSG_GOT_FORMAT2 MSG_GOT_FORMAT2_32
#define MSG_PHD_VADDR MSG_PHD_VADDR_32
#define MSG_PHD_PADDR MSG_PHD_PADDR_32
diff --git a/usr/src/cmd/sgs/liblddbg/common/got.c b/usr/src/cmd/sgs/liblddbg/common/got.c
index 6079aa530a..b66dc7b9c2 100644
--- a/usr/src/cmd/sgs/liblddbg/common/got.c
+++ b/usr/src/cmd/sgs/liblddbg/common/got.c
@@ -46,10 +46,12 @@ Dbg_got_compare(Gottable *gtp1, Gottable *gtp2)
}
void
-Dbg_got_display(Ofl_desc *ofl, Gottable *gtp)
+Dbg_got_display(Ofl_desc *ofl, Off goff, int stage)
{
- Lm_list *lml = ofl->ofl_lml;
- Word gotndx;
+ Lm_list *lml = ofl->ofl_lml;
+ Gottable *gtp = ofl->ofl_gottable;
+ Word gotndx;
+ Xword *gptr;
if (DBG_NOTCLASS(DBG_C_GOT))
return;
@@ -66,35 +68,50 @@ Dbg_got_display(Ofl_desc *ofl, Gottable *gtp)
qsort((char *)gtp, ofl->ofl_gotcnt, sizeof (Gottable),
(int(*)(const void *, const void *))Dbg_got_compare);
- dbg_print(lml, MSG_ORIG(MSG_GOT_COLUMNS));
+ if (stage == 0)
+ dbg_print(lml, MSG_INTL(MSG_GOT_COLUMNS1));
+ else
+ dbg_print(lml, MSG_INTL(MSG_GOT_COLUMNS2));
- for (gotndx = 0; gotndx < ofl->ofl_gotcnt; gotndx++, gtp++) {
- Sym_desc *sdp;
+ gptr = (Xword *)ofl->ofl_osgot->os_outdata->d_buf;
+
+ for (gotndx = 0; gotndx < ofl->ofl_gotcnt; gotndx++, gtp++, gptr++) {
+ Sym_desc *sdp = gtp->gt_sym;
const char *refstr, *name;
Gotndx *gnp = &gtp->gt_gndx;
+ Lword gotaddval;
+ Off off = goff + (gotndx * M_GOT_ENTSIZE);
+ char index[INDEX_STR_SIZE];
- if ((sdp = gtp->gt_sym) == 0)
- continue;
+ (void) snprintf(index, INDEX_STR_SIZE, MSG_ORIG(MSG_GOT_INDEX),
+ EC_SWORD(gnp->gn_gotndx));
- if (sdp->sd_flags & FLG_SY_SMGOT)
+ if (sdp == 0)
+ refstr = MSG_ORIG(MSG_STR_EMPTY);
+ else if (sdp->sd_flags & FLG_SY_SMGOT)
refstr = MSG_ORIG(MSG_GOT_SMALL_PIC);
else
refstr = MSG_ORIG(MSG_GOT_BIG_PIC);
- if (sdp->sd_name)
+ if (sdp == 0)
+ name = MSG_ORIG(MSG_STR_EMPTY);
+ else if (sdp->sd_name)
name = Dbg_demangle_name(sdp->sd_name);
else
name = MSG_INTL(MSG_STR_UNKNOWN);
- if ((sdp->sd_sym->st_shndx == SHN_UNDEF) ||
+ if (stage == 0)
+ gotaddval = gnp->gn_addend;
+ else
+ gotaddval = *gptr;
+
+ if ((sdp == 0) || (sdp->sd_sym->st_shndx == SHN_UNDEF) ||
(sdp->sd_file == 0)) {
- dbg_print(lml, MSG_ORIG(MSG_GOT_FORMAT1),
- EC_SWORD(gnp->gn_gotndx), refstr,
- EC_LWORD(gnp->gn_addend), name);
+ dbg_print(lml, MSG_INTL(MSG_GOT_FORMAT1), index,
+ refstr, EC_OFF(off), EC_XWORD(gotaddval), name);
} else {
- dbg_print(lml, MSG_ORIG(MSG_GOT_FORMAT2),
- EC_SWORD(gnp->gn_gotndx), refstr,
- EC_LWORD(gnp->gn_addend),
+ dbg_print(lml, MSG_INTL(MSG_GOT_FORMAT2), index,
+ refstr, EC_OFF(off), EC_XWORD(gotaddval),
sdp->sd_file->ifl_name, name);
}
}
diff --git a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg
index f84881edd0..940e52097f 100644
--- a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg
+++ b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg
@@ -311,7 +311,7 @@
u44=%d, full=%d, far=%d, Total=%d"
@ MSG_BND_PSUM_SPARC "Summary of PLT types bound: 21d=%d, 24d=%d, \
full=%d, Total=%d"
-@ MSG_BND_PSUM_DEFAULT "Summary of PLT types bound: Total=%d"
+@ MSG_BND_PSUM_DEFAULT "Summary of PLT types bound: total=%d"
# Relocation messages
@@ -430,7 +430,7 @@
@ MSG_FIL_CONFIG_ERR_3 "unable to process file"
@ MSG_FIL_CONFIG_ERR_4 "corrupt or truncated file"
@ MSG_FIL_CONFIG_ERR_5 "incompatible ELF class, byte order, or machine \
- architecture"
+ architecture"
@ MSG_CNTL_TITLE "control list processing complete: moving lmco 0x%llx \
to lmco 0x%llx"
@@ -502,9 +502,13 @@
# Move messages
@ MSG_MOVE_FILE "file=%s processing move data"
-@ MSG_MOVE_TITLE2 " address value repeat stride symbol"
-@ MSG_MOVE_ENTRY2 " in %#10llx %#10llx %6d %6d %s"
-@ MSG_MOVE_EXPAND " %#10llx %#10llx (expanded)"
+
+@ MSG_MOVE_TITLE1 " i/o offset value repeat stride symbol"
+@ MSG_MOVE_TITLE2 " address value repeat stride symbol"
+
+@ MSG_MOVE_ENTRYIN " in %#10llx %#10llx %6d %6d %s"
+@ MSG_MOVE_ENTRYOUT " out %#10llx %#10llx %6d %6d %s"
+@ MSG_MOVE_EXPAND " %#10llx %#10llx (expanded)"
@ MSG_MOVE_ADJEXPAND "for symbol=%s roffset: new=0x%llx"
@ MSG_MOVE_ADJMOVE "for symbol=%s roffset: from=0x%llx, to=0x%llx"
@@ -513,10 +517,6 @@
@ MSG_MOVE_OUTMOVE "copying move entries for %s into .SUNW_move"
@ MSG_MOVE_INPUT "collecting move entries: file=%s"
-@ MSG_MOVE_TITLE1 "\t i/o offset\tvalue\trepeat\tstride\tsymbol"
-@ MSG_MOVE_ENTRY1IN "\t in 0x%llx\t0x%llx\t0x%x\t0x%x\t%s"
-@ MSG_MOVE_ENTRY1OUT "\t out 0x%llx\t0x%llx\t0x%x\t0x%x\t%s"
-
# Section messages
@ MSG_SEC_INPUT "section=%s; input from file=%s"
@@ -628,22 +628,23 @@
@ MSG_ORD_SORT_BEFORE "Output section to be sorted=%s"
@ MSG_ORD_SORT_AFTER "Output section sorted=%s"
-@ MSG_ORD_HDR_1 " No. of SHN_BEGIN=%u, SHN_AFTER=%u, sh_info/sh_link=%u"
+@ MSG_ORD_HDR_1 " number of SHN_BEGIN=%u, SHN_AFTER=%u, \
+ sh_info/sh_link=%u"
@ MSG_ORD_TITLE_0 " section=%s from %s is not an ordered section"
@ MSG_ORD_TITLE_1 " section=%s from %s, sh_info=SHN_BEGIN"
@ MSG_ORD_TITLE_2 " section=%s from %s, sh_info=SHN_AFTER"
@ MSG_ORD_TITLE_3 " section=%s from %s, sh_info=%s, sort_val=%d"
@ MSG_ORD_TITLE_4 " section=%s from %s, sh_link=%s, sort_val=%d"
-@ MSG_ORD_ERR_TITLE "The SHF_ORDERED section %s from %s has \
+@ MSG_ORD_ERR_TITLE "the SHF_ORDERED section %s from %s has \
an error; flag ignored"
-@ MSG_ORD_ERR_INFORANGE " The sh_info field is out of range"
-@ MSG_ORD_ERR_ORDER " The section pointed by sh_info is an ordered section"
-@ MSG_ORD_ERR_LINKRANGE " The sh_link field is out of range"
-@ MSG_ORD_ERR_FLAGS " The sh_flag is incorrect"
-@ MSG_ORD_ERR_CYCLIC " The sh_link is cyclic"
-@ MSG_ORD_ERR_LINKINV " A section pointed to by sh_link has an error"
+@ MSG_ORD_ERR_INFORANGE " the sh_info field is out of range"
+@ MSG_ORD_ERR_ORDER " the section pointed by sh_info is an ordered section"
+@ MSG_ORD_ERR_LINKRANGE " the sh_link field is out of range"
+@ MSG_ORD_ERR_FLAGS " the sh_flag is incorrect"
+@ MSG_ORD_ERR_CYCLIC " the sh_link is cyclic"
+@ MSG_ORD_ERR_LINKINV " a section pointed to by sh_link has an error"
# Link-Auditing Messages
@@ -720,10 +721,14 @@
# TLS related messages
-@ MSG_TLS_STATBLOCK1 "static TLS module: [%2d] %s"
-@ MSG_TLS_STATBLOCK2 "static TLS module: Total Static Size: %#llx"
-@ MSG_TLS_STMODENT1 " block: %#10llx soff: %#10llx flags: %#4llx"
-@ MSG_TLS_STMODENT2 " filesz: %#10llx memsz: %#10llx modid: %#4llx"
+@ MSG_TLS_STATBLOCK1 "static TLS module: [%ld] %s"
+@ MSG_TLS_STATBLOCK2 "static TLS reservation: in use %#llx: \
+ additional backup: %#llx"
+@ MSG_TLS_STATBLOCK3 "static TLS requirement: [%ld] %s: size %#llx: \
+ satisfied from backup reservation: remaining %#llx"
+@ MSG_TLS_MODENT1 " block: %#18llx soff: %#10llx flags: %#llx \
+ %s"
+@ MSG_TLS_MODENT2 " filesz: %#18llx memsz: %#10llx modid: %lld"
@ MSG_TLS_MODACT "%s TLS module: %s"
@ MSG_TLS_ADD "add"
@ MSG_TLS_REMOVE "remove"
@@ -829,22 +834,43 @@
# Global offset table entries.
-# TRANSLATION_NOTE - the following two entries provide for a series of one or
-# more 32-bit got table entries that align with the initial title.
+# TRANSLATION_NOTE - the following two entries are used by elfdump(1), and
+# provide for a series of one or more 32-bit got table entries that align with
+# the initial title.
@ MSG_GOT_TITLE_32 " index addr value \
pending relocation"
@ MSG_GOT_ENTRY_RE_32 "%10.10s 0x%08llx 0x%08llx %-24s %s"
@ MSG_GOT_ENTRY_NR_32 "%10.10s 0x%08llx 0x%08llx"
-# TRANSLATION_NOTE - the following two entries provide for a series of one or
-# more 64-bit got table entries that align with the initial title.
+# TRANSLATION_NOTE - the following two entries are used by elfdump(1), and
+# provide for a series of one or more 64-bit got table entries that align with
+# the initial title.
@ MSG_GOT_TITLE_64 " index addr \
value pending relocation"
@ MSG_GOT_ENTRY_RE_64 "%10.10s 0x%016llx 0x%016llx %-24s %s"
@ MSG_GOT_ENTRY_NR_64 "%10.10s 0x%016llx 0x%016llx"
+# TRANSLATION_NOTE - the following three entries are used by ld(1), and provide
+# for a series of one or more 32-bit got table entries that align with one of
+# the initial titles.
+
+@ MSG_GOT_COLUMNS1_32 " index ref offset addend symbol"
+@ MSG_GOT_COLUMNS2_32 " index ref offset value symbol"
+@ MSG_GOT_FORMAT1_32 "%10.10s %3s 0x%08llx 0x%08llx %s"
+@ MSG_GOT_FORMAT2_32 "%10.10s %3s 0x%08llx 0x%08llx %s:%s"
+
+# TRANSLATION_NOTE - the following three entries are used by ld(1), and provide
+# for a series of one or more 64-bit got table entries that align with one of
+# the initial titles.
+
+@ MSG_GOT_COLUMNS1_64 " index ref offset \
+ addend symbol"
+@ MSG_GOT_COLUMNS2_64 " index ref offset \
+ value symbol"
+@ MSG_GOT_FORMAT1_64 "%10.10s %3s 0x%016llx 0x%016llx %s"
+@ MSG_GOT_FORMAT2_64 "%10.10s %3s 0x%016llx 0x%016llx %s:%s"
# Version table entries.
@ MSG_VER_DEF " index version dependency"
@@ -1131,20 +1157,16 @@
@ MSG_VER_ALL " ALL %-26.26s"
@ MSG_VER_L_ALL " ALL %-26s"
-# GOT messages
+# Global offset table entries.
-@ MSG_GOT_COLUMNS "index ref addend symbol"
+@ MSG_GOT_INDEX " [%ld]"
@ MSG_GOT_SMALL_PIC "pic"
@ MSG_GOT_BIG_PIC "PIC"
-@ MSG_GOT_FORMAT1 "[%05d] %3s 0x%08llx %s"
-@ MSG_GOT_FORMAT2 "[%05d] %3s 0x%08llx %s:%s"
@ MSG_CNTL_ENTRY " [0x%llx] %s"
-@ MSG_STR_EMPTY ""
@ MSG_STR_NL "\n"
-@ MSG_GOT_INDEX " [%ld]"
@ MSG_FMT_INDEX " [%d]"
@ MSG_SUNW_OST_SGS "SUNW_OST_SGS"
@@ -1222,3 +1244,11 @@
@ MSG_CI_TLS_MODREM "TLS_MODREM"
@ MSG_CI_TLS_STATMOD "TLS_STATMOD"
@ MSG_CI_THRINIT "THRINIT"
+
+# TLS information flags
+
+@ MSG_TLS_FLAG_START "["
+@ MSG_TLS_FLAG_END "]"
+@ MSG_TLS_FLAG_SEP " "
+
+@ MSG_TLS_FLAG_STATIC " STATIC-TLS "
diff --git a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg
index 994066a1ff..447d35b14b 100644
--- a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg
+++ b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg
@@ -46,6 +46,10 @@ void Dbg_audit_symval(Lm_list *, const char *, const char *, const char *,
Addr, Addr);
void Dbg_audit_version(Lm_list *, const char *, ulong_t);
+void Dbg_tls_modactivity(Lm_list *, void *, uint_t);
+void Dbg_tls_static_block(Lm_list *, void *, ulong_t, ulong_t);
+void Dbg_tls_static_resv(Rt_map *, ulong_t, ulong_t);
+
void Dbg32_bind_global(Rt_map *, Elf32_Addr, Elf32_Off, Elf32_Word,
Pltbindtype, Rt_map *, Elf32_Addr, Elf32_Off, const char *, uint_t);
void Dbg64_bind_global(Rt_map *, Elf64_Addr, Elf64_Off, Elf64_Xword,
@@ -140,8 +144,8 @@ void Dbg64_file_reuse(Lm_list *, const char *, const char *);
void Dbg32_file_skip(Lm_list *, const char *, const char *);
void Dbg64_file_skip(Lm_list *, const char *, const char *);
-void Dbg32_got_display(Ofl_desc *, Gottable *);
-void Dbg64_got_display(Ofl_desc *, Gottable *);
+void Dbg32_got_display(Ofl_desc *, Elf32_Off, int);
+void Dbg64_got_display(Ofl_desc *, Elf64_Off, int);
void Dbg32_libs_audit(Lm_list *, const char *, const char *);
void Dbg64_libs_audit(Lm_list *, const char *, const char *);
diff --git a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers
index c37bf8407f..c39f5778bc 100644
--- a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers
+++ b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers
@@ -38,7 +38,7 @@
# Policy for Shared Library Version Names and Interface Definitions
-SUNWprivate_4.51 {
+SUNWprivate_4.52 {
global:
dbg_desc = NODIRECT; # interposed - ld.so.1(1)
dbg_print = NODIRECT; # interposed - ld(1) and ld.so.1(1)
@@ -352,6 +352,7 @@ SUNWprivate_4.51 {
Dbg_tls_modactivity;
Dbg_tls_static_block;
+ Dbg_tls_static_resv;
Dbg32_util_broadcast;
Dbg64_util_broadcast;
diff --git a/usr/src/cmd/sgs/liblddbg/common/move.c b/usr/src/cmd/sgs/liblddbg/common/move.c
index bc897c0457..17434bbfeb 100644
--- a/usr/src/cmd/sgs/liblddbg/common/move.c
+++ b/usr/src/cmd/sgs/liblddbg/common/move.c
@@ -142,9 +142,9 @@ Dbg_move_entry1(Lm_list *lml, int which, Move *mv, Sym_desc *s)
return;
if (which)
- str = MSG_INTL(MSG_MOVE_ENTRY1IN);
+ str = MSG_INTL(MSG_MOVE_ENTRYIN);
else
- str = MSG_INTL(MSG_MOVE_ENTRY1OUT);
+ str = MSG_INTL(MSG_MOVE_ENTRYOUT);
dbg_print(lml, str, EC_XWORD(mv->m_poffset), EC_LWORD(mv->m_value),
mv->m_repeat, mv->m_stride, s->sd_name);
@@ -165,6 +165,6 @@ Dbg_move_entry2(Lm_list *lml, Move *mv, Word st_name, const char *name)
else
sname = MSG_INTL(MSG_STR_UNKNOWN);
- dbg_print(lml, MSG_INTL(MSG_MOVE_ENTRY2), EC_XWORD(mv->m_poffset),
+ dbg_print(lml, MSG_INTL(MSG_MOVE_ENTRYIN), EC_XWORD(mv->m_poffset),
EC_LWORD(mv->m_value), mv->m_repeat, mv->m_stride, sname);
}
diff --git a/usr/src/cmd/sgs/liblddbg/common/tls.c b/usr/src/cmd/sgs/liblddbg/common/tls.c
index 5af330e3a3..94831f6e1f 100644
--- a/usr/src/cmd/sgs/liblddbg/common/tls.c
+++ b/usr/src/cmd/sgs/liblddbg/common/tls.c
@@ -29,39 +29,79 @@
#include <link.h>
#include <libc_int.h>
#include <rtld.h>
+#include <strings.h>
#include <debug.h>
#include "msg.h"
#include "_debug.h"
+#define FLAGSZ MSG_TLS_FLAG_START_SIZE + \
+ MSG_TLS_FLAG_STATIC_SIZE + \
+ CONV_INV_STRSIZE + MSG_TLS_FLAG_END_SIZE
+
static void
Dbg_tls_modent(Lm_list *lml, TLS_modinfo * tmodent)
{
- dbg_print(lml, MSG_INTL(MSG_TLS_STMODENT1),
+ static Val_desc vda[] = {
+ { TM_FLG_STATICTLS, MSG_ORIG(MSG_TLS_FLAG_STATIC) },
+ { 0, 0 }
+ };
+ char flagstr[FLAGSZ];
+ ulong_t flags;
+
+ if ((flags = tmodent->tm_flags) != 0) {
+ (void) strlcpy(flagstr, MSG_ORIG(MSG_TLS_FLAG_START), FLAGSZ);
+
+ if (conv_expn_field(flagstr, FLAGSZ, vda, flags, flags,
+ MSG_ORIG(MSG_TLS_FLAG_SEP), 0))
+ (void) strcat(flagstr, MSG_ORIG(MSG_TLS_FLAG_END));
+ } else
+ flagstr[0] = '\0';
+
+ dbg_print(lml, MSG_INTL(MSG_TLS_MODENT1),
EC_XWORD((uintptr_t)tmodent->tm_tlsblock),
- EC_XWORD(tmodent->tm_stattlsoffset), EC_XWORD(tmodent->tm_flags));
- dbg_print(lml, MSG_INTL(MSG_TLS_STMODENT2),
+ EC_XWORD(tmodent->tm_stattlsoffset), EC_XWORD(tmodent->tm_flags),
+ flagstr);
+ dbg_print(lml, MSG_INTL(MSG_TLS_MODENT2),
EC_XWORD(tmodent->tm_filesz), EC_XWORD(tmodent->tm_memsz),
EC_XWORD(tmodent->tm_modid));
}
void
-Dbg_tls_static_block(Lm_list *lml, void *vtlsmodlist, ulong_t tlsstatsize)
+Dbg_tls_static_block(Lm_list *lml, void *list, ulong_t size, ulong_t resv)
{
- uint_t i;
- TLS_modinfo ** tlsmodlist;
-
if (DBG_NOTCLASS(DBG_C_TLS))
return;
- tlsmodlist = (TLS_modinfo **)vtlsmodlist;
Dbg_util_nl(lml, DBG_NL_STD);
- for (i = 0; tlsmodlist[i]; i++) {
- dbg_print(lml, MSG_INTL(MSG_TLS_STATBLOCK1), i,
- tlsmodlist[i]->tm_modname);
- Dbg_tls_modent(lml, tlsmodlist[i]);
+ if (list) {
+ ulong_t ndx;
+ TLS_modinfo **tlsmodlist;
+
+ tlsmodlist = (TLS_modinfo **)list;
+
+ for (ndx = 0; tlsmodlist[ndx]; ndx++) {
+ dbg_print(lml, MSG_INTL(MSG_TLS_STATBLOCK1), ndx,
+ tlsmodlist[ndx]->tm_modname);
+ Dbg_tls_modent(lml, tlsmodlist[ndx]);
+ Dbg_util_nl(lml, DBG_NL_STD);
+ }
}
- dbg_print(lml, MSG_INTL(MSG_TLS_STATBLOCK2), EC_XWORD(tlsstatsize));
+ dbg_print(lml, MSG_INTL(MSG_TLS_STATBLOCK2), EC_XWORD(size),
+ EC_XWORD(resv));
+}
+
+void
+Dbg_tls_static_resv(Rt_map *lmp, ulong_t size, ulong_t resv)
+{
+ Lm_list *lml = LIST(lmp);
+
+ if (DBG_NOTCLASS(DBG_C_TLS))
+ return;
+
+ Dbg_util_nl(lml, DBG_NL_STD);
+ dbg_print(lml, MSG_INTL(MSG_TLS_STATBLOCK3), TLSMODID(lmp), NAME(lmp),
+ EC_XWORD(size), EC_XWORD(resv));
}
void
diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README
index 6e4676b6b5..c6ca28660f 100644
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README
@@ -1105,3 +1105,4 @@ Bugid Risk Synopsis
6429418 ld.so.1: need work-around for Nvidia drivers use of static TLS
6429504 crle(1) shows wrong defaults for non-existent 64-bit config file
6431835 data corruption on x64 in 64-bit mode while LD_PROFILE is in effect
+6423051 static TLS support within the link-editors needs a major face lift (D)
diff --git a/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c b/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c
index e69271ed54..6e502b3db0 100644
--- a/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c
+++ b/usr/src/cmd/sgs/rtld/amd64/amd64_elf.c
@@ -615,6 +615,7 @@ elf_reloc(Rt_map *lmp, uint_t plt)
relbgn = elf_reloc_relative(relbgn, relend,
relsiz, basebgn, etext, emap);
}
+
if (relbgn >= relend)
break;
rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info);
@@ -721,11 +722,22 @@ elf_reloc(Rt_map *lmp, uint_t plt)
name = (char *)0;
/*
- * TLS relocation - value for DTPMOD64
- * relocation is the TLS modid.
+ * Special case TLS relocations.
*/
- if (rtype == R_AMD64_DTPMOD64)
+ if (rtype == R_AMD64_DTPMOD64) {
+ /*
+ * Use the TLS modid.
+ */
value = TLSMODID(lmp);
+
+ } else if ((rtype == R_AMD64_TPOFF64) ||
+ (rtype == R_AMD64_TPOFF32)) {
+ if ((value = elf_static_tls(lmp, symref,
+ rel, rtype, 0, roffset, 0)) == 0) {
+ ret = 0;
+ break;
+ }
+ }
} else {
/*
* If the symbol index is equal to the previous
@@ -821,6 +833,10 @@ elf_reloc(Rt_map *lmp, uint_t plt)
NAME(lmp));
continue;
} else {
+ DBG_CALL(Dbg_reloc_in(lml,
+ ELF_DBG_RTLD, M_MACH,
+ M_REL_SHT_TYPE, rel,
+ NULL, name));
eprintf(lml, ERR_FATAL,
MSG_INTL(MSG_REL_NOSYM),
NAME(lmp),
@@ -900,29 +916,41 @@ elf_reloc(Rt_map *lmp, uint_t plt)
value -= roffset;
/*
- * TLS relocation - value for DTPMOD64
- * relocation is the TLS modid.
+ * Special case TLS relocations.
*/
- if (rtype == R_AMD64_DTPMOD64)
+ if (rtype == R_AMD64_DTPMOD64) {
+ /*
+ * Relocation value is the TLS modid.
+ */
value = TLSMODID(_lmp);
- else if ((rtype == R_AMD64_TPOFF64) ||
- (rtype == R_AMD64_TPOFF32))
- value = -(TLSSTATOFF(_lmp) - value);
+
+ } else if ((rtype == R_AMD64_TPOFF64) ||
+ (rtype == R_AMD64_TPOFF32)) {
+ if ((value = elf_static_tls(_lmp,
+ symdef, rel, rtype, name, roffset,
+ value)) == 0) {
+ ret = 0;
+ break;
+ }
+ }
}
} else {
/*
- * Special case:
- *
- * A DTPMOD32 relocation is a local binding to a TLS
- * symbol. Fill in the TLSMODID for the current object.
+ * Special cases.
*/
- if (rtype == R_AMD64_DTPMOD64)
+ if (rtype == R_AMD64_DTPMOD64) {
+ /*
+ * TLS relocation value is the TLS modid.
+ */
value = TLSMODID(lmp);
- else
+ } else
value = basebgn;
name = (char *)0;
}
+ DBG_CALL(Dbg_reloc_in(LIST(lmp), ELF_DBG_RTLD, M_MACH,
+ M_REL_SHT_TYPE, rel, NULL, name));
+
/*
* If this object has relocations in the text segment, turn
* off the write protect.
@@ -938,9 +966,6 @@ elf_reloc(Rt_map *lmp, uint_t plt)
/*
* Call relocation routine to perform required relocation.
*/
- DBG_CALL(Dbg_reloc_in(LIST(lmp), ELF_DBG_RTLD, M_MACH,
- M_REL_SHT_TYPE, rel, NULL, name));
-
switch (rtype) {
case R_AMD64_COPY:
if (elf_copy_reloc(name, symref, lmp, (void *)roffset,
diff --git a/usr/src/cmd/sgs/rtld/common/_rtld.h b/usr/src/cmd/sgs/rtld/common/_rtld.h
index 0679bbc3b1..94354aaea4 100644
--- a/usr/src/cmd/sgs/rtld/common/_rtld.h
+++ b/usr/src/cmd/sgs/rtld/common/_rtld.h
@@ -541,6 +541,8 @@ extern ulong_t elf_reloc_relative(ulong_t, ulong_t, ulong_t,
ulong_t, ulong_t, ulong_t);
extern ulong_t elf_reloc_relacount(ulong_t, ulong_t,
ulong_t, ulong_t);
+extern long elf_static_tls(Rt_map *, Sym*, void *, uchar_t, char *,
+ ulong_t, long);
extern int enter(void);
extern uint_t expand(char **, size_t *, char **, uint_t, uint_t,
Rt_map *);
@@ -627,7 +629,7 @@ extern Rt_map *setup(char **, auxv_t *, Word, char *, int, char *,
Dyn *, ulong_t, ulong_t, int fd, Phdr *, char *,
char **, int, uid_t, uid_t, gid_t, gid_t, void *,
int, uint_t);
-extern void tls_assign_soffset(Rt_map *);
+extern int tls_assign(Lm_list *, Rt_map *, Phdr *);
extern void tls_modaddrem(Rt_map *, uint_t);
extern int tls_statmod(Lm_list *, Rt_map *);
extern Rt_map **tsort(Rt_map *, int, int);
diff --git a/usr/src/cmd/sgs/rtld/common/elf.c b/usr/src/cmd/sgs/rtld/common/elf.c
index abdf6c0d3c..54be0c2aa9 100644
--- a/usr/src/cmd/sgs/rtld/common/elf.c
+++ b/usr/src/cmd/sgs/rtld/common/elf.c
@@ -2254,6 +2254,14 @@ elf_new_lm(Lm_list *lml, const char *pname, const char *oname, Dyn *ld,
MODE(lmp) |= RTLD_NOW;
MODE(lmp) &= ~RTLD_LAZY;
}
+ /*
+ * Capture any static TLS use, and enforce that
+ * this object be non-deletable.
+ */
+ if (ld->d_un.d_val & DF_STATIC_TLS) {
+ FLAGS1(lmp) |= FL1_RT_TLSSTAT;
+ MODE(lmp) |= RTLD_NODELETE;
+ }
break;
case DT_FLAGS_1:
if (ld->d_un.d_val & DF_1_DISPRELPND)
@@ -2755,16 +2763,15 @@ elf_map_so(Lm_list *lml, Aliste lmco, const char *pname, const char *oname,
}
/*
- * If this shared object contains a any special segments, record them.
+ * If this shared object contains any special segments, record them.
*/
if (swph) {
FLAGS(lmp) |= FLG_RT_SUNWBSS;
SUNWBSS(lmp) = phdr + (swph - phdr0);
}
- if (tlph) {
- PTTLS(lmp) = phdr + (tlph - phdr0);
- tls_assign_soffset(lmp);
- lml->lm_tls++;
+ if (tlph && (tls_assign(lml, lmp, (phdr + (tlph - phdr0))) == 0)) {
+ remove_so(lml, lmp);
+ return (0);
}
if (unwindph)
@@ -2776,7 +2783,6 @@ elf_map_so(Lm_list *lml, Aliste lmco, const char *pname, const char *oname,
return (lmp);
}
-
/*
* Function to correct protection settings. Segments are all mapped initially
* with permissions as given in the segment header. We need to turn on write
@@ -3169,3 +3175,65 @@ elf_reloc_bad(Rt_map *lmp, void *rel, uchar_t rtype, ulong_t roffset,
Dbg_reloc_error(lml, ELF_DBG_RTLD, M_MACH, M_REL_SHT_TYPE, rel, name);
}
+
+/*
+ * Resolve a static TLS relocation.
+ */
+long
+elf_static_tls(Rt_map *lmp, Sym *sym, void *rel, uchar_t rtype, char *name,
+ ulong_t roffset, long value)
+{
+ Lm_list *lml = LIST(lmp);
+
+ /*
+ * Relocations against a static TLS block have limited support once
+ * process initialization has completed. Any error condition should be
+ * discovered by testing for DF_STATIC_TLS as part of loading an object,
+ * however individual relocations are tested in case the dynamic flag
+ * had not been set when this object was built.
+ */
+ if (PTTLS(lmp) == 0) {
+ DBG_CALL(Dbg_reloc_in(lml, ELF_DBG_RTLD, M_MACH,
+ M_REL_SHT_TYPE, rel, NULL, name));
+ eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_BADTLS),
+ _conv_reloc_type((uint_t)rtype), NAME(lmp),
+ name ? demangle(name) : MSG_INTL(MSG_STR_UNKNOWN));
+ return (0);
+ }
+
+ /*
+ * If no static TLS has been set aside for this object, determine if
+ * any can be obtained. Enforce that any object using static TLS is
+ * non-deletable.
+ */
+ if (TLSSTATOFF(lmp) == 0) {
+ FLAGS1(lmp) |= FL1_RT_TLSSTAT;
+ MODE(lmp) |= RTLD_NODELETE;
+
+ if (tls_assign(lml, lmp, PTTLS(lmp)) == 0) {
+ DBG_CALL(Dbg_reloc_in(lml, ELF_DBG_RTLD, M_MACH,
+ M_REL_SHT_TYPE, rel, NULL, name));
+ eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_BADTLS),
+ _conv_reloc_type((uint_t)rtype), NAME(lmp),
+ name ? demangle(name) : MSG_INTL(MSG_STR_UNKNOWN));
+ return (0);
+ }
+ }
+
+ /*
+ * Typically, a static TLS offset is maintained as a symbols value.
+ * For local symbols that are not apart of the dynamic symbol table,
+ * the TLS relocation points to a section symbol, and the static TLS
+ * offset was deposited in the associated GOT table. Make sure the GOT
+ * is cleared, so that the value isn't reused in do_reloc().
+ */
+ if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) {
+ if ((ELF_ST_TYPE(sym->st_info) == STT_SECTION)) {
+ value = *(long *)roffset;
+ *(long *)roffset = 0;
+ } else {
+ value = sym->st_value;
+ }
+ }
+ return (-(TLSSTATOFF(lmp) - value));
+}
diff --git a/usr/src/cmd/sgs/rtld/common/external.c b/usr/src/cmd/sgs/rtld/common/external.c
index b811d51284..8434255623 100644
--- a/usr/src/cmd/sgs/rtld/common/external.c
+++ b/usr/src/cmd/sgs/rtld/common/external.c
@@ -381,7 +381,7 @@ rt_get_extern(Lm_list *lml, Rt_map *lmp)
* have the associated external interfaces.
*/
if (lml->lm_tls && (lml->lm_lcs[CI_TLS_STATMOD].lc_un.lc_func == 0)) {
- eprintf(lml, ERR_FATAL, MSG_INTL(MSG_ERR_TLS_NOTLS),
+ eprintf(lml, ERR_FATAL, MSG_INTL(MSG_TLS_NOSUPPORT),
NAME(lmp));
return (0);
}
diff --git a/usr/src/cmd/sgs/rtld/common/rtld.msg b/usr/src/cmd/sgs/rtld/common/rtld.msg
index 14b3bd207a..f9228905d7 100644
--- a/usr/src/cmd/sgs/rtld/common/rtld.msg
+++ b/usr/src/cmd/sgs/rtld/common/rtld.msg
@@ -100,7 +100,8 @@
called from 0x%llx"
@ MSG_REL_UNSUPSZ "relocation error: %s: file %s: symbol %s: \
offset size (%d bytes) is not supported"
-
+@ MSG_REL_BADTLS "relocation error: %s: file %s: symbol %s: \
+ file contains insufficient TLS support information"
# System call messages.
@@ -218,9 +219,18 @@
# Error TLS failures
-@ MSG_ERR_TLS_NOTLS "%s: object requires TLS, but TLS failed to initialize"
+@ MSG_TLS_NOSUPPORT "%s: TLS requirement failure : TLS support is \
+ unavailable"
+@ MSG_TLS_STATBASE "%s: static TLS failure: object is not part of primary \
+ link-map list"
+@ MSG_TLS_STATSIZE "%s: static TLS failure: object loaded after process \
+ initialization: size (%#llx) exceeds available backup \
+ reservation (%#llx)"
+@ MSG_TLS_STATINIT "%s: static TLS failure: object loaded after process \
+ initialization: can not accommodate initialized data"
# Error expand()
+
@ MSG_ERR_EXPAND1 "%s: %s: path name too long"
@ MSG_ERR_EXPAND2 "%s: %s: token %s could not be expanded"
diff --git a/usr/src/cmd/sgs/rtld/common/setup.c b/usr/src/cmd/sgs/rtld/common/setup.c
index 4313889bc7..c6453dc692 100644
--- a/usr/src/cmd/sgs/rtld/common/setup.c
+++ b/usr/src/cmd/sgs/rtld/common/setup.c
@@ -639,13 +639,13 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz,
(ulong_t)ehdr, memsize, mmaps, mmapcnt)) == 0) {
return (0);
}
- if (tlsphdr) {
- PTTLS(mlmp) = tlsphdr;
- tls_assign_soffset(mlmp);
- lml_main.lm_tls++;
- }
+ if (tlsphdr &&
+ (tls_assign(&lml_main, mlmp, tlsphdr) == 0))
+ return (0);
+
if (unwindphdr)
PTUNWIND(mlmp) = unwindphdr;
+
if (cap)
cap_assign(cap, mlmp);
}
diff --git a/usr/src/cmd/sgs/rtld/common/tls.c b/usr/src/cmd/sgs/rtld/common/tls.c
index 02ca4f6a53..10112adbaf 100644
--- a/usr/src/cmd/sgs/rtld/common/tls.c
+++ b/usr/src/cmd/sgs/rtld/common/tls.c
@@ -36,8 +36,6 @@
#include <msg.h>
#include <debug.h>
-static ulong_t tls_static_size = 0; /* static TLS buffer size */
-
#define TLSBLOCKCNT 16 /* number of blocks of tmi_bits to allocate */
/* at a time. */
typedef struct {
@@ -48,11 +46,10 @@ typedef struct {
static Tlsmodid tmid = {0, 0, 0};
-ulong_t
+static ulong_t
tls_getmodid()
{
- ulong_t ndx;
- ulong_t i;
+ ulong_t ndx, cnt;
if (tmid.tmi_bits == 0) {
if ((tmid.tmi_bits = calloc(TLSBLOCKCNT, sizeof (uint_t))) == 0)
@@ -63,18 +60,20 @@ tls_getmodid()
return (0);
}
- for (i = tmid.tmi_lowfree / (sizeof (uint_t) * 8);
- i < tmid.tmi_cnt; i++) {
- uint_t j;
+ for (cnt = tmid.tmi_lowfree / (sizeof (uint_t) * 8);
+ cnt < tmid.tmi_cnt; cnt++) {
+ uint_t bits;
+
/*
* If all bits are assigned - move on.
*/
- if ((tmid.tmi_bits[i] ^ ~((uint_t)0)) == 0)
+ if ((tmid.tmi_bits[cnt] ^ ~((uint_t)0)) == 0)
continue;
- for (ndx = 0, j = 1; j; j = j << 1, ndx++) {
- if ((tmid.tmi_bits[i] & j) == 0) {
- tmid.tmi_bits[i] |= j;
- ndx = (i * (sizeof (uint_t)) * 8) + ndx;
+
+ for (ndx = 0, bits = 1; bits; bits = bits << 1, ndx++) {
+ if ((tmid.tmi_bits[cnt] & bits) == 0) {
+ tmid.tmi_bits[cnt] |= bits;
+ ndx = (cnt * (sizeof (uint_t)) * 8) + ndx;
tmid.tmi_lowfree = ndx + 1;
return (ndx);
}
@@ -152,8 +151,8 @@ tls_modaddrem(Rt_map *lmp, uint_t flag)
(*fptr)(&tmi);
/*
- * Tag that this link-map has registered its TLS, and free up the
- * moduleid
+ * Tag that this link-map has registered its TLS, and, if this object
+ * is being removed, free up the module id.
*/
FLAGS1(lmp) |= FL1_RT_TLSADD;
@@ -161,22 +160,96 @@ tls_modaddrem(Rt_map *lmp, uint_t flag)
tls_freemodid(TLSMODID(lmp));
}
-void
-tls_assign_soffset(Rt_map *lmp)
+static ulong_t tls_static_size = 0; /* static TLS buffer size */
+static ulong_t tls_static_resv = 512; /* (extra) static TLS reservation */
+
+/*
+ * Track any static TLS use, retain the TLS header, and assign a TLS module
+ * identifier.
+ */
+int
+tls_assign(Lm_list *lml, Rt_map *lmp, Phdr *phdr)
{
+ ulong_t memsz = S_ROUND(phdr->p_memsz, M_TLSSTATALIGN);
+ ulong_t filesz = phdr->p_filesz;
+ ulong_t resv = tls_static_resv;
+
+ /*
+ * If this object explicitly references static TLS, then there are some
+ * limitations.
+ */
+ if (FLAGS1(lmp) & FL1_RT_TLSSTAT) {
+ /*
+ * Static TLS is only available to objects on the primary
+ * link-map list.
+ */
+ if ((lml->lm_flags & LML_FLG_BASELM) == 0) {
+ eprintf(lml, ERR_FATAL, MSG_INTL(MSG_TLS_STATBASE),
+ NAME(lmp));
+ return (0);
+ }
+
+ /*
+ * All TLS blocks that are processed before thread
+ * initialization, are registered with libc. This
+ * initialization is carried out through a handshake with libc
+ * prior to executing any user code (ie. before the first .init
+ * sections are called). As part of this initialization, a
+ * small backup TLS reservation is added (tls_static_resv).
+ * Only explicit static TLS references that can be satisfied by
+ * this TLS backup reservation can be satisfied.
+ */
+ if (rtld_flags2 & RT_FL2_PLMSETUP) {
+ /*
+ * Initialized static TLS can not be satisfied from the
+ * TLS backup reservation.
+ */
+ if (filesz) {
+ eprintf(lml, ERR_FATAL,
+ MSG_INTL(MSG_TLS_STATINIT), NAME(lmp));
+ return (0);
+ }
+
+ /*
+ * Make sure the backup reservation is sufficient.
+ */
+ if (memsz > tls_static_resv) {
+ eprintf(lml, ERR_FATAL,
+ MSG_INTL(MSG_TLS_STATSIZE), NAME(lmp),
+ EC_XWORD(memsz), EC_XWORD(tls_static_resv));
+ return (0);
+ }
+
+ tls_static_resv -= memsz;
+ }
+ }
+
/*
- * Only objects on the primary link-map list are associated
- * with the STATIC tls block.
+ * If we haven't yet initialized threads, or this static reservation can
+ * be satisfied from the TLS backup reservation, determine the total
+ * static TLS size, and assign this object a static TLS offset.
*/
- if (LIST(lmp)->lm_flags & LML_FLG_BASELM) {
- tls_static_size += S_ROUND(PTTLS(lmp)->p_memsz, M_TLSSTATALIGN);
+ if (((rtld_flags2 & RT_FL2_PLMSETUP) == 0) ||
+ (FLAGS1(lmp) & FL1_RT_TLSSTAT)) {
+ tls_static_size += memsz;
TLSSTATOFF(lmp) = tls_static_size;
}
/*
- * Everyone get's a dynamic TLS modid.
+ * Retain the PT_TLS header, obtain a new module identifier, and
+ * indicate that this link-map list contains a new TLS object.
*/
+ PTTLS(lmp) = phdr;
TLSMODID(lmp) = tls_getmodid();
+
+ /*
+ * Now that we have a TLS module id, generate any static TLS reservation
+ * diagnostic.
+ */
+ if (resv != tls_static_resv)
+ DBG_CALL(Dbg_tls_static_resv(lmp, memsz, tls_static_resv));
+
+ return (++lml->lm_tls);
}
int
@@ -195,6 +268,8 @@ tls_statmod(Lm_list *lml, Rt_map *lmp)
if (tlsmodcnt == 0) {
if (fptr)
(*fptr)(0, 0);
+ DBG_CALL(Dbg_tls_static_block(&lml_main, 0, 0,
+ tls_static_resv));
return (1);
}
lml->lm_tls = 0;
@@ -246,8 +321,8 @@ tls_statmod(Lm_list *lml, Rt_map *lmp)
}
DBG_CALL(Dbg_tls_static_block(&lml_main, (void *)tlsmodlist,
- tls_static_size));
- (*fptr)(tlsmodlist, tls_static_size);
+ tls_static_size, tls_static_resv));
+ (*fptr)(tlsmodlist, (tls_static_size + tls_static_resv));
/*
* We're done with the list - clean it up.
diff --git a/usr/src/cmd/sgs/rtld/i386/i386_elf.c b/usr/src/cmd/sgs/rtld/i386/i386_elf.c
index 62b665abdb..74f39c9334 100644
--- a/usr/src/cmd/sgs/rtld/i386/i386_elf.c
+++ b/usr/src/cmd/sgs/rtld/i386/i386_elf.c
@@ -583,6 +583,7 @@ elf_reloc(Rt_map *lmp, uint_t plt)
}
textrel = 1;
}
+
if (relacount) {
relbgn = elf_reloc_relacount(relbgn, relacount,
relsiz, basebgn);
@@ -678,11 +679,21 @@ elf_reloc(Rt_map *lmp, uint_t plt)
name = (char *)0;
/*
- * TLS relocation - value for DTPMOD32
- * relocation is the TLS modid.
+ * Special case TLS relocations.
*/
- if (rtype == R_386_TLS_DTPMOD32)
+ if (rtype == R_386_TLS_DTPMOD32) {
+ /*
+ * Use the TLS modid.
+ */
value = TLSMODID(lmp);
+
+ } else if (rtype == R_386_TLS_TPOFF) {
+ if ((value = elf_static_tls(lmp, symref,
+ rel, rtype, 0, roffset, 0)) == 0) {
+ ret = 0;
+ break;
+ }
+ }
} else {
/*
* If the symbol index is equal to the previous
@@ -778,6 +789,10 @@ elf_reloc(Rt_map *lmp, uint_t plt)
NAME(lmp));
continue;
} else {
+ DBG_CALL(Dbg_reloc_in(lml,
+ ELF_DBG_RTLD, M_MACH,
+ M_REL_SHT_TYPE, rel,
+ NULL, name));
eprintf(lml, ERR_FATAL,
MSG_INTL(MSG_REL_NOSYM),
NAME(lmp),
@@ -857,28 +872,40 @@ elf_reloc(Rt_map *lmp, uint_t plt)
value -= roffset;
/*
- * TLS relocation - value for DTPMOD32
- * relocation is the TLS modid.
+ * Special case TLS relocations.
*/
- if (rtype == R_386_TLS_DTPMOD32)
+ if (rtype == R_386_TLS_DTPMOD32) {
+ /*
+ * Relocation value is the TLS modid.
+ */
value = TLSMODID(_lmp);
- else if (rtype == R_386_TLS_TPOFF)
- value = -(TLSSTATOFF(_lmp) - value);
+
+ } else if (rtype == R_386_TLS_TPOFF) {
+ if ((value = elf_static_tls(_lmp,
+ symdef, rel, rtype, name, roffset,
+ value)) == 0) {
+ ret = 0;
+ break;
+ }
+ }
}
} else {
/*
- * Special case:
- *
- * A DTPMOD32 relocation is a local binding to a TLS
- * symbol. Fill in the TLSMODID for the current object.
+ * Special cases.
*/
- if (rtype == R_386_TLS_DTPMOD32)
+ if (rtype == R_386_TLS_DTPMOD32) {
+ /*
+ * TLS relocation value is the TLS modid.
+ */
value = TLSMODID(lmp);
- else
+ } else
value = basebgn;
name = (char *)0;
}
+ DBG_CALL(Dbg_reloc_in(LIST(lmp), ELF_DBG_RTLD, M_MACH,
+ M_REL_SHT_TYPE, rel, NULL, name));
+
/*
* If this object has relocations in the text segment, turn
* off the write protect.
@@ -894,9 +921,6 @@ elf_reloc(Rt_map *lmp, uint_t plt)
/*
* Call relocation routine to perform required relocation.
*/
- DBG_CALL(Dbg_reloc_in(LIST(lmp), ELF_DBG_RTLD, M_MACH,
- M_REL_SHT_TYPE, rel, NULL, name));
-
switch (rtype) {
case R_386_COPY:
if (elf_copy_reloc(name, symref, lmp, (void *)roffset,
diff --git a/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c b/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c
index 1ffa2da2e3..a364002fef 100644
--- a/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c
+++ b/usr/src/cmd/sgs/rtld/sparc/sparc_elf.c
@@ -758,11 +758,21 @@ elf_reloc(Rt_map *lmp, uint_t plt)
name = (char *)0;
/*
- * TLS relocation - value for DTPMOD relocation
- * is the TLS modid.
+ * Special case TLS relocations.
*/
- if (rtype == M_R_DTPMOD)
+ if (rtype == R_SPARC_TLS_DTPMOD32) {
+ /*
+ * Use the TLS modid.
+ */
value = TLSMODID(lmp);
+
+ } else if (rtype == R_SPARC_TLS_TPOFF32) {
+ if ((value = elf_static_tls(lmp, symref,
+ rel, rtype, 0, roffset, 0)) == 0) {
+ ret = 0;
+ break;
+ }
+ }
} else {
/*
* If the symbol index is equal to the previous
@@ -856,6 +866,10 @@ elf_reloc(Rt_map *lmp, uint_t plt)
NAME(lmp));
continue;
} else {
+ DBG_CALL(Dbg_reloc_in(lml,
+ ELF_DBG_RTLD, M_MACH,
+ M_REL_SHT_TYPE, rel,
+ NULL, name));
eprintf(lml, ERR_FATAL,
MSG_INTL(MSG_REL_NOSYM),
NAME(lmp),
@@ -935,33 +949,49 @@ elf_reloc(Rt_map *lmp, uint_t plt)
value -= roffset;
/*
- * TLS relocation - value for DTPMOD relocation
- * is the TLS modid.
+ * Special case TLS relocations.
*/
- if (rtype == M_R_DTPMOD)
+ if (rtype == R_SPARC_TLS_DTPMOD32) {
+ /*
+ * Relocation value is the TLS modid.
+ */
value = TLSMODID(_lmp);
- else if (rtype == M_R_TPOFF)
- value = -(TLSSTATOFF(_lmp) - value);
+
+ } else if (rtype == R_SPARC_TLS_TPOFF32) {
+ if ((value = elf_static_tls(_lmp,
+ symdef, rel, rtype, name, roffset,
+ value)) == 0) {
+ ret = 0;
+ break;
+ }
+ }
}
} else {
/*
- * Special cases, a register symbol associated with
- * symbol index 0 is initialized (i.e. relocated) to
- * a constant in the r_addend field rather than to a
- * symbol value.
- *
- * A DTPMOD relocation is a local binding to a TLS
- * symbol. Fill in the TLSMODID for the current object.
+ * Special cases.
*/
- if (rtype == R_SPARC_REGISTER)
+ if (rtype == R_SPARC_REGISTER) {
+ /*
+ * A register symbol associated with symbol
+ * index 0 is initialized (i.e. relocated) to
+ * a constant in the r_addend field rather than
+ * to a symbol value.
+ */
value = 0;
- else if (rtype == M_R_DTPMOD)
+
+ } else if (rtype == R_SPARC_TLS_DTPMOD32) {
+ /*
+ * TLS relocation value is the TLS modid.
+ */
value = TLSMODID(lmp);
- else
+ } else
value = basebgn;
name = (char *)0;
}
+ DBG_CALL(Dbg_reloc_in(LIST(lmp), ELF_DBG_RTLD, M_MACH,
+ M_REL_SHT_TYPE, rel, NULL, name));
+
/*
* If this object has relocations in the text segment, turn
* off the write protect.
@@ -978,9 +1008,6 @@ elf_reloc(Rt_map *lmp, uint_t plt)
/*
* Call relocation routine to perform required relocation.
*/
- DBG_CALL(Dbg_reloc_in(LIST(lmp), ELF_DBG_RTLD, M_MACH,
- M_REL_SHT_TYPE, rel, NULL, name));
-
switch (rtype) {
case R_SPARC_REGISTER:
/*
diff --git a/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c b/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c
index a078c7891e..cd54e05fc7 100644
--- a/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c
+++ b/usr/src/cmd/sgs/rtld/sparcv9/sparc_elf.c
@@ -1003,11 +1003,23 @@ elf_reloc(Rt_map *lmp, uint_t plt)
name = (char *)0;
/*
- * TLS relocation - value for DTPMOD relocation
- * is the TLS modid.
+ * Special case TLS relocations.
*/
- if (rtype == M_R_DTPMOD)
+ if ((rtype == R_SPARC_TLS_DTPMOD32) ||
+ (rtype == R_SPARC_TLS_DTPMOD64)) {
+ /*
+ * Use the TLS modid.
+ */
value = TLSMODID(lmp);
+
+ } else if ((rtype == R_SPARC_TLS_TPOFF32) ||
+ (rtype == R_SPARC_TLS_TPOFF64)) {
+ if ((value = elf_static_tls(lmp, symref,
+ rel, rtype, 0, roffset, 0)) == 0) {
+ ret = 0;
+ break;
+ }
+ }
} else {
/*
* If the symbol index is equal to the previous
@@ -1102,6 +1114,10 @@ elf_reloc(Rt_map *lmp, uint_t plt)
NAME(lmp));
continue;
} else {
+ DBG_CALL(Dbg_reloc_in(lml,
+ ELF_DBG_RTLD, M_MACH,
+ M_REL_SHT_TYPE, rel,
+ NULL, name));
eprintf(lml, ERR_FATAL,
MSG_INTL(MSG_REL_NOSYM),
NAME(lmp),
@@ -1182,33 +1198,52 @@ elf_reloc(Rt_map *lmp, uint_t plt)
value -= roffset;
/*
- * TLS relocation - value for DTPMOD relocation
- * is the TLS modid.
+ * Special case TLS relocations.
*/
- if (rtype == M_R_DTPMOD)
+ if ((rtype == R_SPARC_TLS_DTPMOD32) ||
+ (rtype == R_SPARC_TLS_DTPMOD64)) {
+ /*
+ * Relocation value is the TLS modid.
+ */
value = TLSMODID(_lmp);
- else if (rtype == M_R_TPOFF)
- value = -(TLSSTATOFF(_lmp) - value);
+
+ } else if ((rtype == R_SPARC_TLS_TPOFF64) ||
+ (rtype == R_SPARC_TLS_TPOFF32)) {
+ if ((value = elf_static_tls(_lmp,
+ symdef, rel, rtype, name, roffset,
+ value)) == 0) {
+ ret = 0;
+ break;
+ }
+ }
}
} else {
/*
- * Special cases, a regsiter symbol associated with
- * symbol index 0 is initialized (i.e. relocated) to
- * a constant in the r_addend field rather than to a
- * symbol value.
- *
- * A DTPMOD relocation is a local binding to a TLS
- * symbol. Fill in the TLSMODID for the current object.
+ * Special cases.
*/
- if (rtype == R_SPARC_REGISTER)
+ if (rtype == R_SPARC_REGISTER) {
+ /*
+ * A register symbol associated with symbol
+ * index 0 is initialized (i.e. relocated) to
+ * a constant in the r_addend field rather than
+ * to a symbol value.
+ */
value = 0;
- else if (rtype == M_R_DTPMOD)
+
+ } else if ((rtype == R_SPARC_TLS_DTPMOD32) ||
+ (rtype == R_SPARC_TLS_DTPMOD64)) {
+ /*
+ * TLS relocation value is the TLS modid.
+ */
value = TLSMODID(lmp);
- else
+ } else
value = basebgn;
name = (char *)0;
}
+ DBG_CALL(Dbg_reloc_in(LIST(lmp), ELF_DBG_RTLD, M_MACH,
+ M_REL_SHT_TYPE, rel, NULL, name));
+
/*
* If this object has relocations in the text segment, turn
* off the write protect.
@@ -1225,9 +1260,6 @@ elf_reloc(Rt_map *lmp, uint_t plt)
/*
* Call relocation routine to perform required relocation.
*/
- DBG_CALL(Dbg_reloc_in(LIST(lmp), ELF_DBG_RTLD, M_MACH,
- M_REL_SHT_TYPE, rel, NULL, name));
-
switch (rtype) {
case R_SPARC_REGISTER:
/*
diff --git a/usr/src/uts/common/krtld/reloc.h b/usr/src/uts/common/krtld/reloc.h
index b86c0b576a..c249e3eec6 100644
--- a/usr/src/uts/common/krtld/reloc.h
+++ b/usr/src/uts/common/krtld/reloc.h
@@ -63,8 +63,8 @@ extern "C" {
#define FLG_RE_WDISP16 0x00000100 /* funky sparc DISP16 rel */
#define FLG_RE_SIGN 0x00000200 /* value is signed */
#define FLG_RE_ADDRELATIVE 0x00000400 /* RELATIVE relocation */
- /* required for non-fixed */
- /* objects */
+ /* required for non- */
+ /* fixed objects */
#define FLG_RE_EXTOFFSET 0x00000800 /* extra offset required */
#define FLG_RE_REGISTER 0x00001000 /* relocation initializes */
/* a REGISTER by OLO10 */
@@ -72,7 +72,7 @@ extern "C" {
#define FLG_RE_SEGREL 0x00040000 /* segment relative */
#define FLG_RE_SECREL 0x00080000 /* section relative */
-#define FLG_RE_TLSINS 0x00100000 /* TLS instructino rel */
+
#define FLG_RE_TLSGD 0x00200000 /* TLS GD relocation */
#define FLG_RE_TLSLD 0x00400000 /* TLS LD relocation */
#define FLG_RE_TLSIE 0x00800000 /* TLS IE relocation */
@@ -133,7 +133,8 @@ extern const Rel_entry reloc_table[];
#define IS_SEC_RELATIVE(X) ((reloc_table[(X)].re_flags & \
FLG_RE_SECREL) != 0)
#define IS_TLS_INS(X) ((reloc_table[(X)].re_flags & \
- FLG_RE_TLSINS) != 0)
+ (FLG_RE_TLSGD | FLG_RE_TLSLD | \
+ FLG_RE_TLSIE | FLG_RE_TLSLE)) != 0)
#define IS_TLS_GD(X) ((reloc_table[(X)].re_flags & \
FLG_RE_TLSGD) != 0)
#define IS_TLS_LD(X) ((reloc_table[(X)].re_flags & \
@@ -142,10 +143,6 @@ extern const Rel_entry reloc_table[];
FLG_RE_TLSIE) != 0)
#define IS_TLS_LE(X) ((reloc_table[(X)].re_flags & \
FLG_RE_TLSLE) != 0)
-#define IS_TLS(X) ((reloc_table[(X)].re_flags & \
- (FLG_RE_TLSINS|FLG_RE_TLSGD| \
- FLG_RE_TLSLD|FLG_RE_TLSIE| \
- FLG_RE_TLSLE)) != 0)
#define IS_LOCALBND(X) ((reloc_table[(X)].re_flags & \
FLG_RE_LOCLBND) != 0)
diff --git a/usr/src/uts/intel/amd64/krtld/doreloc.c b/usr/src/uts/intel/amd64/krtld/doreloc.c
index ee88014938..606be961b8 100644
--- a/usr/src/uts/intel/amd64/krtld/doreloc.c
+++ b/usr/src/uts/intel/amd64/krtld/doreloc.c
@@ -65,14 +65,11 @@ const Rel_entry reloc_table[R_AMD64_NUM] = {
/* R_AMD64_DTPMOD64 */ {FLG_RE_NOTREL, 8},
/* R_AMD64_DTPOFF64 */ {FLG_RE_NOTREL, 8},
/* R_AMD64_TPOFF64 */ {FLG_RE_NOTREL, 8},
-/* R_AMD64_TLSGD */ {FLG_RE_GOTPC | FLG_RE_GOTADD |
- FLG_RE_TLSINS | FLG_RE_TLSGD, 4},
-/* R_AMD64_TLSLD */ {FLG_RE_GOTPC | FLG_RE_GOTADD |
- FLG_RE_TLSINS | FLG_RE_TLSLD, 4},
-/* R_AMD64_DTPOFF32 */ {FLG_RE_TLSINS | FLG_RE_TLSLD, 4},
-/* R_AMD64_GOTTPOFF */ {FLG_RE_GOTPC | FLG_RE_GOTADD |
- FLG_RE_TLSINS | FLG_RE_TLSIE, 4},
-/* R_AMD64_TPOFF32 */ {FLG_RE_TLSINS | FLG_RE_TLSLE, 4},
+/* R_AMD64_TLSGD */ {FLG_RE_GOTPC | FLG_RE_GOTADD | FLG_RE_TLSGD, 4},
+/* R_AMD64_TLSLD */ {FLG_RE_GOTPC | FLG_RE_GOTADD | FLG_RE_TLSLD, 4},
+/* R_AMD64_DTPOFF32 */ {FLG_RE_TLSLD, 4},
+/* R_AMD64_GOTTPOFF */ {FLG_RE_GOTPC | FLG_RE_GOTADD | FLG_RE_TLSIE, 4},
+/* R_AMD64_TPOFF32 */ {FLG_RE_TLSLE, 4},
/* R_AMD64_PC64 */ {FLG_RE_PCREL, 8},
/* R_AMD64_GOTOFF64 */ {FLG_RE_GOTREL, 8},
/* R_AMD64_GOTPC32 */ {FLG_RE_PCREL | FLG_RE_GOTPC | FLG_RE_LOCLBND, 4},
diff --git a/usr/src/uts/intel/amd64/krtld/kobj_reloc.c b/usr/src/uts/intel/amd64/krtld/kobj_reloc.c
index f2033e5223..5cf7541f13 100644
--- a/usr/src/uts/intel/amd64/krtld/kobj_reloc.c
+++ b/usr/src/uts/intel/amd64/krtld/kobj_reloc.c
@@ -158,7 +158,7 @@ do_relocate(struct module *mp, char *reltbl, Word relshtype, int nreloc,
symnum);
return (-1);
}
- if ((rtype > R_AMD64_NUM) || IS_TLS(rtype)) {
+ if ((rtype > R_AMD64_NUM) || IS_TLS_INS(rtype)) {
_kobj_printf(ops, "krtld: invalid relocation type %d",
rtype);
_kobj_printf(ops, " at 0x%llx:", off);
diff --git a/usr/src/uts/intel/ia32/krtld/doreloc.c b/usr/src/uts/intel/ia32/krtld/doreloc.c
index 0fc1d362a3..c3bb0d8ed1 100644
--- a/usr/src/uts/intel/ia32/krtld/doreloc.c
+++ b/usr/src/uts/intel/ia32/krtld/doreloc.c
@@ -57,16 +57,14 @@ const Rel_entry reloc_table[R_386_NUM] = {
/* R_386_GOTOFF */ {FLG_RE_GOTREL, 4},
/* R_386_GOTPC */ {FLG_RE_PCREL | FLG_RE_GOTPC | FLG_RE_LOCLBND, 4},
/* R_386_32PLT */ {FLG_RE_PLTREL, 4},
-/* R_386_TLS_GD_PLT */ {FLG_RE_TLSINS | FLG_RE_PLTREL |
- FLG_RE_PCREL | FLG_RE_TLSGD, 4},
-/* R_386_TLS_LDM_PLT */ {FLG_RE_TLSINS | FLG_RE_PLTREL |
- FLG_RE_PCREL | FLG_RE_TLSLD, 4},
+/* R_386_TLS_GD_PLT */ {FLG_RE_PLTREL | FLG_RE_PCREL | FLG_RE_TLSGD, 4},
+/* R_386_TLS_LDM_PLT */ {FLG_RE_PLTREL | FLG_RE_PCREL | FLG_RE_TLSLD, 4},
/* R_386_TLS_TPOFF */ {FLG_RE_NOTREL, 4},
-/* R_386_TLS_IE */ {FLG_RE_GOTADD | FLG_RE_TLSINS | FLG_RE_TLSIE, 4},
-/* R_386_TLS_GOTIE */ {FLG_RE_GOTADD | FLG_RE_TLSINS | FLG_RE_TLSIE, 4},
-/* R_386_TLS_LE */ {FLG_RE_TLSINS | FLG_RE_TLSLE, 4},
-/* R_386_TLS_GD */ {FLG_RE_GOTADD | FLG_RE_TLSINS | FLG_RE_TLSGD, 4},
-/* R_386_TLS_LDM */ {FLG_RE_GOTADD | FLG_RE_TLSLD | FLG_RE_TLSINS, 4},
+/* R_386_TLS_IE */ {FLG_RE_GOTADD | FLG_RE_TLSIE, 4},
+/* R_386_TLS_GOTIE */ {FLG_RE_GOTADD | FLG_RE_TLSIE, 4},
+/* R_386_TLS_LE */ {FLG_RE_TLSLE, 4},
+/* R_386_TLS_GD */ {FLG_RE_GOTADD | FLG_RE_TLSGD, 4},
+/* R_386_TLS_LDM */ {FLG_RE_GOTADD | FLG_RE_TLSLD, 4},
/* R_386_16 */ {FLG_RE_NOTREL, 2},
/* R_386_PC16 */ {FLG_RE_PCREL, 2},
/* R_386_8 */ {FLG_RE_NOTREL, 1},
@@ -79,7 +77,7 @@ const Rel_entry reloc_table[R_386_NUM] = {
/* R_386_UNKNOWN29 */ {FLG_RE_NOTSUP, 0},
/* R_386_UNKNOWN30 */ {FLG_RE_NOTSUP, 0},
/* R_386_UNKNOWN31 */ {FLG_RE_NOTSUP, 0},
-/* R_386_TLS_LDO_32 */ {FLG_RE_TLSINS | FLG_RE_TLSLD, 4},
+/* R_386_TLS_LDO_32 */ {FLG_RE_TLSLD, 4},
/* R_386_UNKNOWN33 */ {FLG_RE_NOTSUP, 0},
/* R_386_UNKNOWN34 */ {FLG_RE_NOTSUP, 0},
/* R_386_TLS_DTPMOD32 */ {FLG_RE_NOTREL, 4},
diff --git a/usr/src/uts/intel/ia32/krtld/kobj_reloc.c b/usr/src/uts/intel/ia32/krtld/kobj_reloc.c
index 547bf9ce9c..53955cf08d 100644
--- a/usr/src/uts/intel/ia32/krtld/kobj_reloc.c
+++ b/usr/src/uts/intel/ia32/krtld/kobj_reloc.c
@@ -155,7 +155,7 @@ do_relocate(struct module *mp, char *reltbl, Word relshtype, int nreloc,
symnum);
return (-1);
}
- if ((rtype > R_386_NUM) || IS_TLS(rtype)) {
+ if ((rtype > R_386_NUM) || IS_TLS_INS(rtype)) {
_kobj_printf(ops, "krtld: invalid relocation type %d",
rtype);
_kobj_printf(ops, " at 0x%llx:", off);
diff --git a/usr/src/uts/sparc/krtld/doreloc.c b/usr/src/uts/sparc/krtld/doreloc.c
index 7b98eee72a..70ddf91e3c 100644
--- a/usr/src/uts/sparc/krtld/doreloc.c
+++ b/usr/src/uts/sparc/krtld/doreloc.c
@@ -140,35 +140,28 @@ const Rel_entry reloc_table[R_SPARC_NUM] = {
8, 0, 0}, /* V9 */
/* R_SPARC_UA16 */ {0x0, FLG_RE_VERIFY | FLG_RE_UNALIGN,
2, 0, 0},
-/* R_SPARC_TLS_GD_HI22 */ {0x0, FLG_RE_GOTADD | FLG_RE_TLSINS | FLG_RE_TLSGD,
- 4, 10, 22},
-/* R_SPARC_TLS_GD_LO10 */ {0x3ff, FLG_RE_GOTADD | FLG_RE_TLSINS |
- FLG_RE_TLSGD | FLG_RE_SIGN, 4, 0, 13},
-/* R_SPARC_TLS_GD_ADD */ {0x0, FLG_RE_TLSINS | FLG_RE_TLSGD, 0, 0, 0},
-/* R_SPARC_TLS_GD_CALL */ {0x0, FLG_RE_TLSINS | FLG_RE_TLSGD, 0, 0, 0},
-/* R_SPARC_TLS_LDM_HI22 */ {0x0, FLG_RE_GOTADD | FLG_RE_TLSINS | FLG_RE_TLSLD,
- 4, 10, 22},
-/* R_SPARC_TLS_LDM_LO10 */ {0x3ff, FLG_RE_GOTADD | FLG_RE_TLSINS |
- FLG_RE_TLSLD | FLG_RE_SIGN, 4, 0, 13},
-/* R_SPARC_TLS_LDM_ADD */ {0x0, FLG_RE_TLSINS | FLG_RE_TLSLD, 0, 0, 0},
-/* R_SPARC_TLS_LDM_CALL */ {0x0, FLG_RE_TLSINS | FLG_RE_TLSLD, 0, 0, 0},
-/* R_SPARC_TLS_LDO_HIX22 */ {0x0, FLG_RE_VERIFY | FLG_RE_TLSINS | FLG_RE_TLSLD,
- 4, 10, 22},
-/* R_SPARC_TLS_LDO_LOX10 */ {0x3ff, FLG_RE_TLSINS | FLG_RE_SIGN | FLG_RE_TLSLD,
- 4, 0, 13},
-/* R_SPARC_TLS_LDO_ADD */ {0x0, FLG_RE_TLSINS | FLG_RE_TLSLD, 0, 0, 0},
-/* R_SPARC_TLS_IE_HI22 */ {0x0, FLG_RE_TLSINS | FLG_RE_GOTADD | FLG_RE_TLSIE,
- 4, 10, 22},
-/* R_SPARC_TLS_IE_LO10 */ {0x3ff, FLG_RE_TLSINS | FLG_RE_GOTADD |
- FLG_RE_TLSIE | FLG_RE_SIGN, 4, 0, 13},
-/* R_SPARC_TLS_IE_LD */ {0x0, FLG_RE_TLSINS | FLG_RE_TLSIE, 0, 0, 0},
-/* R_SPARC_TLS_IE_LDX */ {0x0, FLG_RE_TLSINS | FLG_RE_TLSIE, 0, 0, 0},
-/* R_SPARC_TLS_IE_ADD */ {0x0, FLG_RE_TLSINS | FLG_RE_TLSIE, 0, 0, 0},
+/* R_SPARC_TLS_GD_HI22 */ {0x0, FLG_RE_GOTADD | FLG_RE_TLSGD, 4, 10, 22},
+/* R_SPARC_TLS_GD_LO10 */ {0x3ff, FLG_RE_GOTADD | FLG_RE_TLSGD |
+ FLG_RE_SIGN, 4, 0, 13},
+/* R_SPARC_TLS_GD_ADD */ {0x0, FLG_RE_TLSGD, 0, 0, 0},
+/* R_SPARC_TLS_GD_CALL */ {0x0, FLG_RE_TLSGD, 0, 0, 0},
+/* R_SPARC_TLS_LDM_HI22 */ {0x0, FLG_RE_GOTADD | FLG_RE_TLSLD, 4, 10, 22},
+/* R_SPARC_TLS_LDM_LO10 */ {0x3ff, FLG_RE_GOTADD | FLG_RE_TLSLD |
+ FLG_RE_SIGN, 4, 0, 13},
+/* R_SPARC_TLS_LDM_ADD */ {0x0, FLG_RE_TLSLD, 0, 0, 0},
+/* R_SPARC_TLS_LDM_CALL */ {0x0, FLG_RE_TLSLD, 0, 0, 0},
+/* R_SPARC_TLS_LDO_HIX22 */ {0x0, FLG_RE_VERIFY | FLG_RE_TLSLD, 4, 10, 22},
+/* R_SPARC_TLS_LDO_LOX10 */ {0x3ff, FLG_RE_SIGN | FLG_RE_TLSLD, 4, 0, 13},
+/* R_SPARC_TLS_LDO_ADD */ {0x0, FLG_RE_TLSLD, 0, 0, 0},
+/* R_SPARC_TLS_IE_HI22 */ {0x0, FLG_RE_GOTADD | FLG_RE_TLSIE, 4, 10, 22},
+/* R_SPARC_TLS_IE_LO10 */ {0x3ff, FLG_RE_GOTADD | FLG_RE_TLSIE |
+ FLG_RE_SIGN, 4, 0, 13},
+/* R_SPARC_TLS_IE_LD */ {0x0, FLG_RE_TLSIE, 0, 0, 0},
+/* R_SPARC_TLS_IE_LDX */ {0x0, FLG_RE_TLSIE, 0, 0, 0},
+/* R_SPARC_TLS_IE_ADD */ {0x0, FLG_RE_TLSIE, 0, 0, 0},
/* R_SPARC_TLS_LE_HIX22 */ {(Xword)(-1LL),
- FLG_RE_VERIFY | FLG_RE_TLSINS | FLG_RE_TLSLE,
- 4, 10, 22},
-/* R_SPARC_TLS_LE_LOX10 */ {0x3ff, FLG_RE_TLSINS | FLG_RE_SIGN | FLG_RE_TLSLE,
- 4, 0, 13},
+ FLG_RE_VERIFY | FLG_RE_TLSLE, 4, 10, 22},
+/* R_SPARC_TLS_LE_LOX10 */ {0x3ff, FLG_RE_SIGN | FLG_RE_TLSLE, 4, 0, 13},
/* R_SPARC_TLS_DTPMOD32 */ {0x0, FLG_RE_NOTREL, 4, 0, 0},
/* R_SPARC_TLS_DTPMOD64 */ {0x0, FLG_RE_NOTREL, 8, 0, 0},
/* R_SPARC_TLS_DTPOFF32 */ {0x0, FLG_RE_NOTREL, 4, 0, 0},
diff --git a/usr/src/uts/sparc/krtld/kobj_reloc.c b/usr/src/uts/sparc/krtld/kobj_reloc.c
index 12d2a19d5a..fd3846a383 100644
--- a/usr/src/uts/sparc/krtld/kobj_reloc.c
+++ b/usr/src/uts/sparc/krtld/kobj_reloc.c
@@ -212,7 +212,7 @@ do_relocate(
"do_relocate: bad strndx %d\n", symnum);
return (-1);
}
- if ((rtype > R_SPARC_NUM) || IS_TLS(rtype)) {
+ if ((rtype > R_SPARC_NUM) || IS_TLS_INS(rtype)) {
_kobj_printf(ops, "krtld: invalid relocation type %d",
rtype);
_kobj_printf(ops, " at 0x%llx:", off);