diff options
author | Richard Lowe <richlowe@richlowe.net> | 2013-03-21 15:19:00 -0400 |
---|---|---|
committer | Richard Lowe <richlowe@richlowe.net> | 2013-04-19 22:38:17 -0400 |
commit | ef16f6b5e980be84e2248939502c5aa269ef026d (patch) | |
tree | ef1826a97a6899af795b13362982e3fe5ac0b7c6 /usr/src | |
parent | 9e647765f079a9527bc9430bd6805745b590091b (diff) | |
download | illumos-joyent-ef16f6b5e980be84e2248939502c5aa269ef026d.tar.gz |
3616 SHF_GROUP sections should not be discarded via other COMDAT mechanisms
3709 need sloppy relocation for GNU .debug_macro
Reviewed by: Joshua M. Clulow <josh@sysmgr.org>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Gordon Ross <gwr@nexenta.com>
Approved by: Garrett D'Amore <garrett@damore.org>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/sgs/libld/common/_libld.h | 4 | ||||
-rw-r--r-- | usr/src/cmd/sgs/libld/common/files.c | 8 | ||||
-rw-r--r-- | usr/src/cmd/sgs/libld/common/groups.c | 52 | ||||
-rw-r--r-- | usr/src/cmd/sgs/libld/common/libld.msg | 5 | ||||
-rw-r--r-- | usr/src/cmd/sgs/libld/common/place.c | 11 | ||||
-rw-r--r-- | usr/src/cmd/sgs/libld/common/sections.c | 46 | ||||
-rw-r--r-- | usr/src/cmd/sgs/packages/common/SUNWonld-README | 2 |
7 files changed, 128 insertions, 0 deletions
diff --git a/usr/src/cmd/sgs/libld/common/_libld.h b/usr/src/cmd/sgs/libld/common/_libld.h index 87b05ec13e..146dd54b8c 100644 --- a/usr/src/cmd/sgs/libld/common/_libld.h +++ b/usr/src/cmd/sgs/libld/common/_libld.h @@ -688,6 +688,7 @@ extern Sdf_desc *sdf_find(const char *, APlist *); #define ld_bswap_Xword ld64_bswap_Xword #define ld_cap_add_family ld64_cap_add_family #define ld_cap_move_symtoobj ld64_cap_move_symtoobj +#define ld_comdat_validate ld64_comdat_validate #define ld_disp_errmsg ld64_disp_errmsg #define ld_ent_check ld64_ent_check #define ld_ent_lookup ld64_ent_lookup @@ -785,6 +786,7 @@ extern Sdf_desc *sdf_find(const char *, APlist *); #define ld_bswap_Xword ld32_bswap_Xword #define ld_cap_add_family ld32_cap_add_family #define ld_cap_move_symtoobj ld32_cap_move_symtoobj +#define ld_comdat_validate ld32_comdat_validate #define ld_disp_errmsg ld32_disp_errmsg #define ld_ent_check ld32_ent_check #define ld_ent_lookup ld32_ent_lookup @@ -892,6 +894,8 @@ extern uintptr_t ld_cap_add_family(Ofl_desc *, Sym_desc *, Sym_desc *, Cap_group *, APlist **); extern void ld_cap_move_symtoobj(Ofl_desc *); +extern void ld_comdat_validate(Ofl_desc *, Ifl_desc *); + extern void ld_disp_errmsg(const char *, Rel_desc *, Ofl_desc *); extern void ld_ent_check(Ofl_desc *); diff --git a/usr/src/cmd/sgs/libld/common/files.c b/usr/src/cmd/sgs/libld/common/files.c index 99e6e89f9d..d731e935d4 100644 --- a/usr/src/cmd/sgs/libld/common/files.c +++ b/usr/src/cmd/sgs/libld/common/files.c @@ -2821,6 +2821,14 @@ process_elf(Ifl_desc *ifl, Elf *elf, Ofl_desc *ofl) } /* + * Now group information has been processed, we can safely validate + * that nothing is fishy about the section COMDAT description. We + * need to do this prior to placing the section (where any + * SHT_SUNW_COMDAT sections will be restored to being PROGBITS) + */ + ld_comdat_validate(ofl, ifl); + + /* * Now that all of the input sections have been processed, place * them in the appropriate output sections. */ diff --git a/usr/src/cmd/sgs/libld/common/groups.c b/usr/src/cmd/sgs/libld/common/groups.c index faedb90934..e4853ba823 100644 --- a/usr/src/cmd/sgs/libld/common/groups.c +++ b/usr/src/cmd/sgs/libld/common/groups.c @@ -118,6 +118,47 @@ ld_get_group(Ofl_desc *ofl, Is_desc *isp) return (NULL); } +/* + * When creating a .debug_macro section, in an attempt to make certain DWARF + * macro information shareable, the GNU compiler must construct group sections + * with a repeatable signature symbol while nevertheless having no actual + * symbol to refer to (because it relates to macros). + * + * We use this as yet another way to clue ourselves in that sloppy relocation + * will likely be required. + * + * The format of these gensym'd names is: + * wm<offset size>.<encoded path name>.<lineno>.<32byte hash> + * Where the encoded file name may be absent. + */ +static boolean_t +is_header_gensym(const char *name) +{ + const char *c = NULL; + size_t len = strlen(name); + + /* No room for leader, hash, and periods */ + if (len < 37) + return (B_FALSE); + + if ((strncmp(name, "wm4.", 4) != 0) && + strncmp(name, "wm8.", 4) != 0) + return (B_FALSE); + + c = &name[len - 33]; + if (*c++ != '.') + return (B_FALSE); + + for (; *c != '\0'; c++) { + if (!(((*c >= 'a') && (*c <= 'f')) || + ((*c >= '0') && (*c <= '9')))) { + return (B_FALSE); + } + } + + return (B_TRUE); +} + uintptr_t ld_group_process(Is_desc *gisc, Ofl_desc *ofl) { @@ -221,6 +262,17 @@ ld_group_process(Is_desc *gisc, Ofl_desc *ofl) } /* + * If the signature symbol is a name generated by the GNU compiler to + * refer to a header, we need sloppy relocation. + */ + if (is_header_gensym(str)) { + if ((ofl->ofl_flags1 & FLG_OF1_NRLXREL) == 0) + ofl->ofl_flags1 |= FLG_OF1_RLXREL; + DBG_CALL(Dbg_sec_gnu_comdat(ofl->ofl_lml, gisc, TRUE, + (ofl->ofl_flags1 & FLG_OF1_RLXREL) != 0)); + } + + /* * Validate the section indices within the group. If this is a COMDAT * group, mark each section as COMDAT. */ diff --git a/usr/src/cmd/sgs/libld/common/libld.msg b/usr/src/cmd/sgs/libld/common/libld.msg index f0c5266aec..761a293aed 100644 --- a/usr/src/cmd/sgs/libld/common/libld.msg +++ b/usr/src/cmd/sgs/libld/common/libld.msg @@ -471,6 +471,9 @@ @ MSG_SCN_NONALLOC "%s: non-allocatable section '%s' directed to a \ loadable segment: %s" +@ MSG_SCN_MULTICOMDAT "file %s: section [%u]%s: cannot be susceptible to multiple \ + COMDAT mechanisms: %s" + # Symbol processing errors @ MSG_SYM_NOSECDEF "symbol '%s' in file %s has no section definition" @@ -748,6 +751,8 @@ @ MSG_STR_CDIR_ELSE "$else" @ MSG_STR_CDIR_ENDIF "$endif" +@ MSG_STR_GROUP "GROUP" +@ MSG_STR_SUNW_COMDAT "SUNW_COMDAT" @ MSG_FMT_ARMEM "%s(%s)" @ MSG_FMT_COLPATH "%s:%s" diff --git a/usr/src/cmd/sgs/libld/common/place.c b/usr/src/cmd/sgs/libld/common/place.c index d56e205717..cadc43f977 100644 --- a/usr/src/cmd/sgs/libld/common/place.c +++ b/usr/src/cmd/sgs/libld/common/place.c @@ -238,6 +238,17 @@ add_comdat(Ofl_desc *ofl, Os_desc *osp, Is_desc *isp) Isd_node isd, *isdp; avl_tree_t *avlt; avl_index_t where; + Group_desc *gr; + + /* + * Sections to which COMDAT groups apply are FLG_IS_COMDAT but are + * discarded separately by the group logic so should never be + * discarded here. + */ + if ((isp->is_shdr->sh_flags & SHF_GROUP) && + ((gr = ld_get_group(ofl, isp)) != NULL) && + (gr->gd_data[0] & GRP_COMDAT)) + return (1); /* * Create a COMDAT avl tree for this output section if required. diff --git a/usr/src/cmd/sgs/libld/common/sections.c b/usr/src/cmd/sgs/libld/common/sections.c index 8601c40362..01ee18aab3 100644 --- a/usr/src/cmd/sgs/libld/common/sections.c +++ b/usr/src/cmd/sgs/libld/common/sections.c @@ -3463,3 +3463,49 @@ ld_make_text(Ofl_desc *ofl, size_t size) return (isec); } + +void +ld_comdat_validate(Ofl_desc *ofl, Ifl_desc *ifl) +{ + int i; + + for (i = 0; i < ifl->ifl_shnum; i++) { + Is_desc *isp = ifl->ifl_isdesc[i]; + int types = 0; + char buf[1024] = ""; + Group_desc *gr = NULL; + + if ((isp == NULL) || (isp->is_flags & FLG_IS_COMDAT) == 0) + continue; + + if (isp->is_shdr->sh_type == SHT_SUNW_COMDAT) { + types++; + (void) strlcpy(buf, MSG_ORIG(MSG_STR_SUNW_COMDAT), + sizeof (buf)); + } + + if (strncmp(MSG_ORIG(MSG_SCN_GNU_LINKONCE), isp->is_name, + MSG_SCN_GNU_LINKONCE_SIZE) == 0) { + types++; + if (types > 1) + (void) strlcat(buf, ", ", sizeof (buf)); + (void) strlcat(buf, MSG_ORIG(MSG_SCN_GNU_LINKONCE), + sizeof (buf)); + } + + if ((isp->is_shdr->sh_flags & SHF_GROUP) && + ((gr = ld_get_group(ofl, isp)) != NULL) && + (gr->gd_data[0] & GRP_COMDAT)) { + types++; + if (types > 1) + (void) strlcat(buf, ", ", sizeof (buf)); + (void) strlcat(buf, MSG_ORIG(MSG_STR_GROUP), + sizeof (buf)); + } + + if (types > 1) + ld_eprintf(ofl, ERR_FATAL, + MSG_INTL(MSG_SCN_MULTICOMDAT), ifl->ifl_name, + EC_WORD(isp->is_scnndx), isp->is_name, buf); + } +} diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README index fa55c5d1e9..2a6d570955 100644 --- a/usr/src/cmd/sgs/packages/common/SUNWonld-README +++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README @@ -1644,3 +1644,5 @@ Bugid Risk Synopsis 3439 discarded sections shouldn't end up on output lists 3436 relocatable objects also need sloppy relocation 3451 archive libraries with no symbols shouldn't require a string table +3616 SHF_GROUP sections should not be discarded via other COMDAT mechanisms +3709 need sloppy relocation for GNU .debug_macro |