summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrie <none@none>2005-09-15 10:30:34 -0700
committerrie <none@none>2005-09-15 10:30:34 -0700
commitdd94ecef63e3f299c1915ec8109e20b0c2bc0457 (patch)
treece472cc8651f4dc1207bff829e30f029630d8183
parent3cac8019b3348d73726cdcdce300b35ef15e156a (diff)
downloadillumos-gate-dd94ecef63e3f299c1915ec8109e20b0c2bc0457.tar.gz
6318401 mis-aligned TLS variable
6324019 ld.so.1: malloc alignment is insufficient for new compilers
-rw-r--r--usr/src/cmd/sgs/include/libld.h7
-rw-r--r--usr/src/cmd/sgs/libld/common/outfile.c48
-rw-r--r--usr/src/cmd/sgs/libld/common/place.c27
-rw-r--r--usr/src/cmd/sgs/libld/common/syms.c4
-rw-r--r--usr/src/cmd/sgs/libld/common/update.c63
-rw-r--r--usr/src/cmd/sgs/packages/common/SUNWonld-README9
-rw-r--r--usr/src/cmd/sgs/rtld/common/malloc.c2
7 files changed, 84 insertions, 76 deletions
diff --git a/usr/src/cmd/sgs/include/libld.h b/usr/src/cmd/sgs/include/libld.h
index c47864ea25..d3a9595514 100644
--- a/usr/src/cmd/sgs/include/libld.h
+++ b/usr/src/cmd/sgs/include/libld.h
@@ -266,7 +266,7 @@ struct ofl_desc {
#define FLG_OF_SEGSORT 0x00020000 /* segment sorting is required */
#define FLG_OF_TEXTREL 0x00040000 /* text relocations have been found */
#define FLG_OF_MULDEFS 0x00080000 /* multiple symbols are allowed */
-#define FLG_OF_OUTMMAP 0x00100000 /* output image is mmaped to file */
+#define FLG_OF_TLSPHDR 0x00100000 /* a TLS program header is required */
#define FLG_OF_BLDGOT 0x00200000 /* build GOT table */
#define FLG_OF_VERDEF 0x00400000 /* record version definitions */
#define FLG_OF_VERNEED 0x00800000 /* record version dependencies */
@@ -317,7 +317,7 @@ struct ofl_desc {
#define FLG_OF1_TLSOREL 0x00100000 /* output relocation against .tlsbss */
/* section */
#define FLG_OF1_DEMANGL 0x00200000 /* demangle C++ sym name diagnostics */
-#define FLG_OF1_GRPSECT 0x00400000 /* GROUP sections are present */
+
#define FLG_OF1_NOHDR 0x00800000 /* no elf header/phdr alignment */
/* needed */
#define FLG_OF1_VADDR 0x01000000 /* vaddr was explicitly set */
@@ -526,8 +526,7 @@ struct os_desc { /* Output section descriptor */
#define FLG_OS_ORDER_KEY 0x01 /* include a sort key section */
#define FLG_OS_OUTREL 0x02 /* output rel against this section */
-#define FLG_OS_TLSNONEMPTY 0x04 /* non empty TLS sections */
-#define FLG_OS_SECTREF 0x08 /* isps are not affected by -zignore */
+#define FLG_OS_SECTREF 0x04 /* isps are not affected by -zignore */
/*
* For sorting sections.
diff --git a/usr/src/cmd/sgs/libld/common/outfile.c b/usr/src/cmd/sgs/libld/common/outfile.c
index e76b5c93e2..5d6723c0b3 100644
--- a/usr/src/cmd/sgs/libld/common/outfile.c
+++ b/usr/src/cmd/sgs/libld/common/outfile.c
@@ -24,7 +24,7 @@
* All Rights Reserved
*
*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -242,13 +242,13 @@ create_outfile(Ofl_desc * ofl)
Os_desc * osp;
Is_desc * isp;
Elf_Scn * scn;
+ Elf_Data * tlsdata = 0;
Shdr * shdr;
- Word ptype, flags = ofl->ofl_flags;
+ Word flags = ofl->ofl_flags;
size_t ndx = 0, fndx = 0;
Elf_Cmd cmd;
Boolean fixalign = FALSE;
- int fd, nseg = 0, shidx = 0, dataidx = 0, ptloadidx = 0,
- tlsidx = 0;
+ int fd, nseg = 0, shidx = 0, dataidx = 0, ptloadidx = 0;
/*
* If FLG_OF1_NOHDR was set in map_parse() or FLG_OF1_VADDR was set,
@@ -291,15 +291,14 @@ create_outfile(Ofl_desc * ofl)
DBG_CALL(Dbg_util_nl());
for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) {
+ int frst = 0;
+ Phdr *phdr = &(sgp->sg_phdr);
+ Word ptype = phdr->p_type;
+
/*
* Count the number of segments that will go in the program
* header table. If a segment is empty, ignore it.
*/
- int frst = 0;
- Phdr * phdr = &(sgp->sg_phdr);
-
- ptype = phdr->p_type;
-
if (!(flags & FLG_OF_RELOBJ)) {
if (ptype == PT_PHDR) {
/*
@@ -324,7 +323,7 @@ create_outfile(Ofl_desc * ofl)
if (flags & FLG_OF_DYNAMIC)
nseg++;
} else if (ptype == PT_TLS) {
- if (ofl->ofl_ostlsseg.head)
+ if (flags & FLG_OF_TLSPHDR)
nseg++;
#if (defined(__i386) || defined(__amd64)) && defined(_ELF64)
} else if (ptype == PT_SUNW_UNWIND) {
@@ -406,6 +405,19 @@ create_outfile(Ofl_desc * ofl)
if ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0)
osp->os_shdr->sh_flags &= ~SHF_GROUP;
+ /*
+ * If this is a TLS section, save it so that the PT_TLS
+ * program header information can be established after
+ * the output image has been initialy created. At this
+ * point, all TLS input sections are ordered as they
+ * will appear in the output image.
+ */
+ if ((ofl->ofl_flags & FLG_OF_TLSPHDR) &&
+ (osp->os_shdr->sh_flags & SHF_TLS)) {
+ if (list_appendc(&ofl->ofl_ostlsseg, osp) == 0)
+ return (S_ERROR);
+ }
+
dataidx = 0;
for (LIST_TRAVERSE(&(osp->os_isdescs), lnp3, isp)) {
Elf_Data * data;
@@ -476,15 +488,17 @@ create_outfile(Ofl_desc * ofl)
isp->is_indata = data;
/*
- * Make sure that the first tls section is
- * aligned on pointer size alignment.
+ * Save the first TLS data buffer, as this is
+ * the start of the TLS segment. Realign this
+ * buffer based on the alignment requirements
+ * of all the TLS input sections.
*/
- if ((tlsidx == 0) &&
- ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) &&
+ if ((ofl->ofl_flags & FLG_OF_TLSPHDR) &&
(isp->is_shdr->sh_flags & SHF_TLS)) {
- data->d_align = lcm(M_WORD_ALIGN,
- isp->is_shdr->sh_addralign);
- tlsidx = 1;
+ if (tlsdata == 0)
+ tlsdata = data;
+ tlsdata->d_align = lcm(tlsdata->d_align,
+ isp->is_shdr->sh_addralign);
}
#if defined(_ELF64) && defined(_ILP32)
diff --git a/usr/src/cmd/sgs/libld/common/place.c b/usr/src/cmd/sgs/libld/common/place.c
index 39f6a76951..5bfdebd23a 100644
--- a/usr/src/cmd/sgs/libld/common/place.c
+++ b/usr/src/cmd/sgs/libld/common/place.c
@@ -117,7 +117,6 @@ place_section(Ofl_desc * ofl, Is_desc * isp, int ident, Word link)
isp->is_flags |= FLG_IS_DISCARD;
return ((Os_desc *)0);
}
- ofl->ofl_flags1 |= FLG_OF1_GRPSECT;
}
}
@@ -335,16 +334,12 @@ place_section(Ofl_desc * ofl, Is_desc * isp, int ident, Word link)
set_addralign(ofl, osp, isp);
/*
- * If this section is a non-empty TLS section and
- * if the osp is not yet recorded in ofl_osttlsseg,
- * record it.
+ * If this section is a non-empty TLS section indicate
+ * that a PT_TLS program header is required.
*/
- if ((shflags & SHF_TLS) && (shdr->sh_size != 0) &&
- ((osp->os_flags & FLG_OS_TLSNONEMPTY) == 0)) {
- osp->os_flags |= FLG_OS_TLSNONEMPTY;
- if (list_appendc(&ofl->ofl_ostlsseg, osp) == 0)
- return ((Os_desc *)S_ERROR);
- }
+ if ((shflags & SHF_TLS) && shdr->sh_size &&
+ ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0))
+ ofl->ofl_flags |= FLG_OF_TLSPHDR;
/*
* If is_txtndx is 0 then this section was not
@@ -515,14 +510,12 @@ place_section(Ofl_desc * ofl, Is_desc * isp, int ident, Word link)
}
/*
- * If this section is a TLS section - keep track of it
- * for the latter building of the PT_TLS segment.
+ * If this section is a non-empty TLS section indicate that a PT_TLS
+ * program header is required.
*/
- if ((shflags & SHF_TLS) && (shdr->sh_size != 0)) {
- osp->os_flags |= FLG_OS_TLSNONEMPTY;
- if (list_appendc(&ofl->ofl_ostlsseg, osp) == 0)
- return ((Os_desc *)S_ERROR);
- }
+ if ((shflags & SHF_TLS) && shdr->sh_size &&
+ ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0))
+ ofl->ofl_flags |= FLG_OF_TLSPHDR;
/*
* If a non-allocatable section is going to be put into a loadable
diff --git a/usr/src/cmd/sgs/libld/common/syms.c b/usr/src/cmd/sgs/libld/common/syms.c
index 1f73bbc855..d0e991a341 100644
--- a/usr/src/cmd/sgs/libld/common/syms.c
+++ b/usr/src/cmd/sgs/libld/common/syms.c
@@ -492,7 +492,7 @@ sym_enter(const char *name, Sym *osym, Word hash, Ifl_desc *ifl, Ofl_desc *ofl,
* and without underscores. This routine is called, after all other symbol
* resolution has completed, to generate a reserved absolute symbol (the
* underscore version). Special symbols are updated with the appropriate
- * values in sym_update(). If the user has already defined this symbol
+ * values in update_osym(). If the user has already defined this symbol
* issue a warning and leave the symbol as is. If the non-underscore symbol
* is referenced then turn it into a weak alias of the underscored symbol.
*
@@ -1201,7 +1201,7 @@ sym_validate(Ofl_desc *ofl)
align = &tlsalign;
}
*size = (Xword)S_ROUND(*size, sym->st_value) +
- sym->st_size;
+ sym->st_size;
if (sym->st_value > *align)
*align = sym->st_value;
}
diff --git a/usr/src/cmd/sgs/libld/common/update.c b/usr/src/cmd/sgs/libld/common/update.c
index baef7f4889..81e1631e90 100644
--- a/usr/src/cmd/sgs/libld/common/update.c
+++ b/usr/src/cmd/sgs/libld/common/update.c
@@ -24,7 +24,7 @@
* All Rights Reserved
*
*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -780,8 +780,7 @@ update_osym(Ofl_desc *ofl)
sdp->sd_isc = ofl->ofl_istlsbss;
sdp->sd_flags |= FLG_SY_COMMEXP;
/*
- * TLS symbols are relative to
- * the TLS segment.
+ * TLS symbols are relative to the TLS segment.
*/
symptr->st_value -= ofl->ofl_tlsphdr->p_vaddr;
}
@@ -2759,46 +2758,40 @@ update_outfile(Ofl_desc *ofl)
continue;
}
#endif
-
if (phdr->p_type == PT_TLS) {
- Os_desc *_osp;
- Shdr *firstshdr;
- Shdr *fshdr;
- Shdr *bssshdr;
+ Os_desc *tlsosp;
+ Shdr *firstshdr = 0, *lastfilshdr, *lastmemshdr;
- if ((ofl->ofl_ostlsseg.head == NULL) ||
- (flags & FLG_OF_RELOBJ))
+ if (ofl->ofl_ostlsseg.head == NULL)
continue;
- _osp = (Os_desc *)
- (ofl->ofl_ostlsseg.head->data);
- firstshdr = fshdr = bssshdr = _osp->os_shdr;
- phdr->p_flags = PF_R | PF_W;
- phdr->p_memsz = 0;
- phdr->p_filesz = 0;
- for (LIST_TRAVERSE(&ofl->ofl_ostlsseg,
- lnp2, _osp)) {
- Shdr *_shdr;
- _shdr = _osp->os_shdr;
- if (_shdr->sh_addr < firstshdr->sh_addr)
- firstshdr = _shdr;
- if ((_shdr->sh_addr + _shdr->sh_size) >
- (bssshdr->sh_addr + bssshdr->sh_size))
- bssshdr = _shdr;
- if (_shdr->sh_type != SHT_NOBITS) {
- if ((_shdr->sh_addr + _shdr->sh_size) >
- (fshdr->sh_addr +
- fshdr->sh_size))
- fshdr = _shdr;
+
+ for (LIST_TRAVERSE(&ofl->ofl_ostlsseg, lnp2, tlsosp)) {
+ Shdr *tlsshdr = tlsosp->os_shdr;
+
+ if (firstshdr == 0) {
+ firstshdr = lastfilshdr = lastmemshdr =
+ tlsosp->os_shdr;
+ continue;
}
+
+ if (tlsshdr->sh_type == SHT_NOBITS)
+ lastmemshdr = tlsshdr;
+ else
+ lastfilshdr = tlsshdr;
}
+
+ phdr->p_flags = PF_R | PF_W;
phdr->p_vaddr = firstshdr->sh_addr;
phdr->p_offset = firstshdr->sh_offset;
- phdr->p_filesz = fshdr->sh_offset +
- fshdr->sh_size - phdr->p_offset;
- phdr->p_memsz = bssshdr->sh_offset +
- bssshdr->sh_size - phdr->p_offset;
+ phdr->p_align = firstshdr->sh_addralign;
+ phdr->p_filesz = lastfilshdr->sh_offset +
+ lastfilshdr->sh_size - phdr->p_offset;
+ phdr->p_memsz = lastmemshdr->sh_offset +
+ lastmemshdr->sh_size - phdr->p_offset;
+
DBG_CALL(Dbg_seg_entry(ofl->ofl_e_machine,
- segndx, sgp));
+ segndx, sgp));
+
ofl->ofl_tlsphdr = phdr;
ofl->ofl_phdr[phdrndx++] = *phdr;
continue;
diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README
index 9b73e54e2e..9fc3ec07d5 100644
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README
@@ -1509,4 +1509,13 @@ All the above change is incorporated in the following patches:
--------------------------------------------------------------------------------
6314115 Checkpoint refuses to start, crashes on start, after application of
linker patch 112963-22
+--------------------------------------------------------------------------------
+All the above change is incorporated in the following patches:
+ Solaris/SunOS 5.9_sparc patch T112963-24
+ Solaris/SunOS 5.9_x86 patch T113986-20
+ Solaris/SunOS 5.8_sparc patch T109147-39
+ Solaris/SunOS 5.8_x86 patch T109148-39
+--------------------------------------------------------------------------------
6318306 a dlsym() from a filter should be redirected to an associated filtee
+6318401 mis-aligned TLS variable
+6324019 ld.so.1: malloc alignment is insufficient for new compilers
diff --git a/usr/src/cmd/sgs/rtld/common/malloc.c b/usr/src/cmd/sgs/rtld/common/malloc.c
index cd2a770a4a..5189291e29 100644
--- a/usr/src/cmd/sgs/rtld/common/malloc.c
+++ b/usr/src/cmd/sgs/rtld/common/malloc.c
@@ -68,7 +68,7 @@ struct page {
#define HDR_BLOCK (sizeof (struct block) - sizeof (void *))
#define HDR_PAGE (sizeof (struct page) - sizeof (void *))
-#define MINSZ sizeof (void *)
+#define MINSZ 8
static struct page *memstart;