Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

OS-1551 ld should tolerate SHT_PROGBITS for .eh_frame sections on amd64

  • Loading branch information...
commit 204e4609aaaae0eacdaafa3d4ee89b5bef963f22 1 parent e1c569f
@bcantrill bcantrill authored
View
40 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)) {
View
2  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
View
15 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;
View
2  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
Please sign in to comment.
Something went wrong with that request. Please try again.