summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/sgs/libld/common/files.c40
-rw-r--r--usr/src/cmd/sgs/libld/common/libld.msg2
-rw-r--r--usr/src/cmd/sgs/libld/common/place.c15
-rw-r--r--usr/src/uts/common/sys/elf_amd64.h2
4 files changed, 41 insertions, 18 deletions
diff --git a/usr/src/cmd/sgs/libld/common/files.c b/usr/src/cmd/sgs/libld/common/files.c
index 01052dbfee..7f85d3abad 100644
--- a/usr/src/cmd/sgs/libld/common/files.c
+++ b/usr/src/cmd/sgs/libld/common/files.c
@@ -24,6 +24,7 @@
* All Rights Reserved
*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
/*
@@ -1449,21 +1450,32 @@ process_progbits_alloc(const char *name, Ifl_desc *ifl, Shdr *shdr,
done = TRUE;
/*
- * Only accept a progbits .eh_frame on a platform
- * for which this is the expected type.
+ * Historically, the section containing the logic to
+ * unwind stack frames -- the .eh_frame section -- was
+ * of type SHT_PROGBITS. Apparently the most
+ * aesthetically galling aspect of this was not the
+ * .eh_frame section's dubious purpose or its filthy
+ * implementation, but rather its section type; with the
+ * introduction of the AMD64 ABI, a new section header
+ * type (SHT_AMD64_UNWIND) was introduced for (and
+ * dedicated to) this section. When both the Sun
+ * compilers and the GNU compilers had been modified to
+ * generate this new section type, the linker became
+ * much more pedantic about .eh_frame: it refused to
+ * link an AMD64 object that contained a .eh_frame with
+ * the legacy SHT_PROGBITS. That this was too fussy is
+ * evidenced by searching the net for the error message
+ * that it generated ("section type is SHT_PROGBITS:
+ * expected SHT_AMD64_UNWIND"), which reveals a myriad
+ * of problems, including legacy objects, hand-coded
+ * assembly and otherwise cross-platform objects
+ * created on other platforms (the GNU toolchain was
+ * only modified to create the new section type on
+ * Solaris and derivatives). We therefore always accept
+ * a .eh_frame of SHT_PROGBITS -- regardless of
+ * m_sht_unwind.
*/
- if (ld_targ.t_m.m_sht_unwind == SHT_PROGBITS)
- break;
- ld_eprintf(ofl, ERR_FATAL,
- MSG_INTL(MSG_FIL_EXEHFRMTYP), ifl->ifl_name,
- EC_WORD(ndx), name,
- conv_sec_type(ifl->ifl_ehdr->e_ident[EI_OSABI],
- ifl->ifl_ehdr->e_machine, shdr->sh_type,
- CONV_FMT_ALT_CF, &inv_buf1),
- conv_sec_type(ifl->ifl_ehdr->e_ident[EI_OSABI],
- ifl->ifl_ehdr->e_machine, ld_targ.t_m.m_sht_unwind,
- CONV_FMT_ALT_CF, &inv_buf2));
- return (FALSE);
+ break;
case 'g':
if (is_name_cmp(name, MSG_ORIG(MSG_SCN_GOT),
MSG_SCN_GOT_SIZE)) {
diff --git a/usr/src/cmd/sgs/libld/common/libld.msg b/usr/src/cmd/sgs/libld/common/libld.msg
index 16ade95f99..9dac060ce3 100644
--- a/usr/src/cmd/sgs/libld/common/libld.msg
+++ b/usr/src/cmd/sgs/libld/common/libld.msg
@@ -419,8 +419,6 @@
@ MSG_FIL_BADORDREF "file %s: section [%u]%s: contains illegal reference \
to discarded section: [%u]%s"
-@ MSG_FIL_EXEHFRMTYP "file %s: section [%u]%s: section type is %s: \
- expected %s"
# Recording name conflicts
diff --git a/usr/src/cmd/sgs/libld/common/place.c b/usr/src/cmd/sgs/libld/common/place.c
index 0f5b5a6ec2..4862e542fe 100644
--- a/usr/src/cmd/sgs/libld/common/place.c
+++ b/usr/src/cmd/sgs/libld/common/place.c
@@ -24,6 +24,7 @@
* All Rights Reserved
*
* Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
/*
@@ -978,6 +979,7 @@ ld_place_section(Ofl_desc *ofl, Is_desc *isp, Place_path_info *path_info,
* Section types are considered to match if any one of
* the following are true:
* - The type codes are the same
+ * - Both are .eh_frame sections (regardless of type code)
* - The input section is COMDAT, and the output section
* is SHT_PROGBITS.
*/
@@ -987,6 +989,7 @@ ld_place_section(Ofl_desc *ofl, Is_desc *isp, Place_path_info *path_info,
(shdr->sh_type != SHT_GROUP) &&
(shdr->sh_type != SHT_SUNW_dof) &&
((shdr->sh_type == os_shdr->sh_type) ||
+ (is_ehframe && (osp->os_flags & FLG_OS_EHFRAME)) ||
((shdr->sh_type == SHT_SUNW_COMDAT) &&
(os_shdr->sh_type == SHT_PROGBITS))) &&
((shflags & ~shflagmask) ==
@@ -1132,9 +1135,19 @@ ld_place_section(Ofl_desc *ofl, Is_desc *isp, Place_path_info *path_info,
return ((Os_desc *)S_ERROR);
}
ofl->ofl_flags |= FLG_OF_EHFRAME;
+
+ /*
+ * For .eh_frame sections, we always set the type to be the
+ * type specified by the ABI. This allows .eh_frame sections
+ * of type SHT_PROGBITS to be correctly merged with .eh_frame
+ * sections of the ABI-defined type (e.g. SHT_AMD64_UNWIND),
+ * with the output being of the ABI-defined type.
+ */
+ osp->os_shdr->sh_type = ld_targ.t_m.m_sht_unwind;
+ } else {
+ osp->os_shdr->sh_type = shdr->sh_type;
}
- osp->os_shdr->sh_type = shdr->sh_type;
osp->os_shdr->sh_flags = shdr->sh_flags;
osp->os_shdr->sh_entsize = shdr->sh_entsize;
osp->os_name = oname;
diff --git a/usr/src/uts/common/sys/elf_amd64.h b/usr/src/uts/common/sys/elf_amd64.h
index 263ea1bc51..e789a1900d 100644
--- a/usr/src/uts/common/sys/elf_amd64.h
+++ b/usr/src/uts/common/sys/elf_amd64.h
@@ -118,7 +118,7 @@ extern "C" {
* processor specific section types
*/
#define SHT_AMD64_UNWIND 0x70000001 /* unwind information */
-
+#define SHT_X86_64_UNWIND SHT_AMD64_UNWIND
/*
* NOTE: PT_SUNW_UNWIND is defined in the OS specific range