From owner-svn-src-head@freebsd.org Fri Feb 10 02:01:33 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C1458CD8AF1; Fri, 10 Feb 2017 02:01:33 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9BEC5D9A; Fri, 10 Feb 2017 02:01:33 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v1A21Wnh087569; Fri, 10 Feb 2017 02:01:32 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v1A21WVF087568; Fri, 10 Feb 2017 02:01:32 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201702100201.v1A21WVF087568@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Fri, 10 Feb 2017 02:01:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r313504 - head/cddl/contrib/opensolaris/lib/libdtrace/common X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Feb 2017 02:01:33 -0000 Author: markj Date: Fri Feb 10 02:01:32 2017 New Revision: 313504 URL: https://svnweb.freebsd.org/changeset/base/313504 Log: When patching USDT probes, use non-unique names for aliases of weak symbols. Aliases are normally given names that include a key that's unique for each input object file. This, for example, ensures that aliases for identically named local symbols in different object files don't conflict. However, in some cases the static linker will leave an undefined alias after merging identical weak symbols, resulting in a link error. A non-unique name allows the aliases to be merged as well. PR: 216871 X-MFC With: r313262 Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c ============================================================================== --- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c Fri Feb 10 01:59:35 2017 (r313503) +++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c Fri Feb 10 02:01:32 2017 (r313504) @@ -261,7 +261,7 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION_ sym->st_value = 0; sym->st_size = 0; sym->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_FUNC); - sym->st_other = ELF32_ST_VISIBILITY(STV_HIDDEN); + sym->st_other = 0; sym->st_shndx = SHN_UNDEF; rel++; @@ -445,7 +445,7 @@ prepare_elf64(dtrace_hdl_t *dtp, const d sym->st_value = 0; sym->st_size = 0; sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_FUNC); - sym->st_other = ELF64_ST_VISIBILITY(STV_HIDDEN); + sym->st_other = 0; sym->st_shndx = SHN_UNDEF; rel++; @@ -1187,6 +1187,7 @@ process_obj(dtrace_hdl_t *dtp, const cha static const char dt_enabled[] = "enabled"; static const char dt_symprefix[] = "$dtrace"; static const char dt_symfmt[] = "%s%ld.%s"; + static const char dt_weaksymfmt[] = "%s.%s"; char probename[DTRACE_NAMELEN]; int fd, i, ndx, eprobe, mod = 0; Elf *elf = NULL; @@ -1548,44 +1549,46 @@ process_obj(dtrace_hdl_t *dtp, const cha if (dt_symtab_lookup(data_sym, osym, isym, rela.r_offset, shdr_rel.sh_info, &fsym, - (emachine1 == EM_PPC64), elf) != 0 && - dt_symtab_lookup(data_sym, 0, osym, + (emachine1 == EM_PPC64), elf) == 0) { + if (fsym.st_name > data_str->d_size) + goto err; + + r = s = (char *) data_str->d_buf + fsym.st_name; + assert(strstr(s, dt_symprefix) == s); + s = strchr(s, '.') + 1; + } else if (dt_symtab_lookup(data_sym, 0, osym, rela.r_offset, shdr_rel.sh_info, &fsym, - (emachine1 == EM_PPC64), elf) != 0) - goto err; - - if (fsym.st_name > data_str->d_size) - goto err; + (emachine1 == EM_PPC64), elf) == 0) { + u_int bind; - assert(GELF_ST_TYPE(fsym.st_info) == STT_FUNC); - - /* - * If this is our first time encountering this symbol, - * emit an alias. - */ - s = (char *)data_str->d_buf + fsym.st_name; - - if (strncmp(s, dt_symprefix, - sizeof (dt_symprefix) - 1) != 0) { - u_int bind = GELF_ST_BIND(fsym.st_info); + bind = GELF_ST_BIND(fsym.st_info) == STB_WEAK ? + STB_WEAK : STB_GLOBAL; + /* + * Emit an alias for the symbol. It needs to be + * non-preemptible so that .SUNW_dof relocations + * may be resolved at static link time. Aliases + * of weak symbols are given a non-unique name + * so that they may be merged by the linker. + */ dsym = fsym; dsym.st_name = istr; - dsym.st_info = GELF_ST_INFO(bind == STB_LOCAL ? - STB_GLOBAL : bind, STT_FUNC); + dsym.st_info = GELF_ST_INFO(bind, STT_FUNC); dsym.st_other = GELF_ST_VISIBILITY(STV_HIDDEN); (void) gelf_update_sym(data_sym, isym, &dsym); r = (char *) data_str->d_buf + istr; - istr += 1 + sprintf(r, dt_symfmt, dt_symprefix, objkey, - s); + s = (char *) data_str->d_buf + fsym.st_name; + if (bind == STB_WEAK) + istr += sprintf(r, dt_weaksymfmt, + dt_symprefix, s); + else + istr += sprintf(r, dt_symfmt, + dt_symprefix, objkey, s); + istr++; isym++; assert(isym <= nsym); - } else { - r = s; - s = strchr(s, '.'); - assert(s != NULL); - s++; - } + } else + goto err; if ((pvp = dt_provider_lookup(dtp, pname)) == NULL) { return (dt_link_error(dtp, elf, fd, bufs,