diff options
author | Richard Lowe <richlowe@richlowe.net> | 2021-01-29 16:57:27 -0600 |
---|---|---|
committer | Richard Lowe <richlowe@richlowe.net> | 2021-02-08 14:43:30 -0600 |
commit | a8facf2616619e45ebfa3de1fa4def4b433a0245 (patch) | |
tree | 72788480751c348a0ccfe50eac21272dda91a3c8 /usr/src | |
parent | a8e9db1c816399e66d096a343815a6e845a7a0cd (diff) | |
download | illumos-joyent-a8facf2616619e45ebfa3de1fa4def4b433a0245.tar.gz |
13481 ld(1) should skip GCC local aliases when building symsort sections
Reviewed by: C Fraire <cfraire@me.com>
Reviewed by: Jason King <jason.brian.king+illumos@gmail.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/sgs/libld/common/libld.msg | 2 | ||||
-rw-r--r-- | usr/src/cmd/sgs/libld/common/syms.c | 65 | ||||
-rw-r--r-- | usr/src/cmd/sgs/tools/SUNWonld-README | 1 |
3 files changed, 58 insertions, 10 deletions
diff --git a/usr/src/cmd/sgs/libld/common/libld.msg b/usr/src/cmd/sgs/libld/common/libld.msg index 390fc7e31a..182afd2478 100644 --- a/usr/src/cmd/sgs/libld/common/libld.msg +++ b/usr/src/cmd/sgs/libld/common/libld.msg @@ -883,6 +883,8 @@ @ MSG_SYM_L_START "START_" @ MSG_SYM_L_START_U "_START_" +@ MSG_SYM_LOCALALIAS ".localalias" + @ MSG_SYM_SECBOUND_START "__start_" @ MSG_SYM_SECBOUND_STOP "__stop_" diff --git a/usr/src/cmd/sgs/libld/common/syms.c b/usr/src/cmd/sgs/libld/common/syms.c index ed2191761b..a40f8ae5cd 100644 --- a/usr/src/cmd/sgs/libld/common/syms.c +++ b/usr/src/cmd/sgs/libld/common/syms.c @@ -33,6 +33,9 @@ #define ELF_TARGET_AMD64 +/* We deliberately choose a locale unaware ctype */ +#include <sys/ctype.h> + #include <stdio.h> #include <string.h> #include <debug.h> @@ -318,6 +321,41 @@ ld_sym_find(const char *name, Word hash, avl_index_t *where, Ofl_desc *ofl) } /* + * GCC sometimes emits local aliases for otherwise global symbols, such that + * it has a guaranteed way to refer to a symbol from the current object + * regardless of interposition. + * + * The only way we can match on these aliases is by them ending either + * ".localalias" or ".localalias.N" where N is any integer. + */ +static inline Boolean +is_gcc_localalias(Sym_desc *sdp) +{ + char *p; + + if (ELF_ST_BIND(sdp->sd_sym->st_info) != STB_LOCAL) + return (FALSE); + + if ((p = strstr(sdp->sd_name, MSG_ORIG(MSG_SYM_LOCALALIAS))) != NULL) { + p += MSG_SYM_LOCALALIAS_SIZE; + switch (*p++) { + case '\0': /* unnumbered */ + return (TRUE); + case '.': /* numbered? */ + if (*p == '\0') /* no integer */ + return (FALSE); + while (ISDIGIT(*p)) /* skip integer */ + p++; + if (*p != '\0') /* non-integer chars */ + return (FALSE); + return (TRUE); + } + } + + return (FALSE); +} + +/* * Enter a new symbol into the link editors internal symbol table. * If the symbol is from an input file, information regarding the input file * and input section is also recorded. Otherwise (file == NULL) the symbol @@ -2040,7 +2078,6 @@ ld_sym_process(Is_desc *isc, Ifl_desc *ifl, Ofl_desc *ofl) uchar_t osabi = ifl->ifl_ehdr->e_ident[EI_OSABI]; Half mach = ifl->ifl_ehdr->e_machine; Half etype = ifl->ifl_ehdr->e_type; - int etype_rel; const char *symsecname, *strsecname; Word symsecndx; avl_index_t where; @@ -2117,13 +2154,12 @@ ld_sym_process(Is_desc *isc, Ifl_desc *ifl, Ofl_desc *ofl) if ((ifl->ifl_oldndx = libld_malloc((size_t)(total * sizeof (Sym_desc *)))) == NULL) return (S_ERROR); - etype_rel = (etype == ET_REL); - if (etype_rel && local) { + if ((etype == ET_REL) && (local != 0)) { if ((ifl->ifl_locs = libld_calloc(sizeof (Sym_desc), local)) == NULL) return (S_ERROR); /* LINTED */ - ifl->ifl_locscnt = (Word)local; + ifl->ifl_locscnt = local; } ifl->ifl_symscnt = total; @@ -2131,7 +2167,7 @@ ld_sym_process(Is_desc *isc, Ifl_desc *ifl, Ofl_desc *ofl) * If there are local symbols to save add them to the symbol table * index array. */ - if (local) { + if (local != 0) { int allow_ldynsym = OFL_ALLOW_LDYNSYM(ofl); Sym_desc *last_file_sdp = NULL; int last_file_ndx = 0; @@ -2215,8 +2251,9 @@ ld_sym_process(Is_desc *isc, Ifl_desc *ifl, Ofl_desc *ofl) /* Will not appear in output object */ symtab_enter = 0; } - } else if (etype == ET_DYN) + } else if (etype == ET_DYN) { continue; + } /* * Fill in the remaining symbol descriptor information. @@ -2313,7 +2350,7 @@ ld_sym_process(Is_desc *isc, Ifl_desc *ifl, Ofl_desc *ofl) * to make sure the section boundaries encompass it. * If they don't, the ELF file is corrupt. */ - if (etype_rel) { + if (etype == ET_REL) { if (SYM_LOC_BADADDR(sdp, sym, type)) { issue_badaddr_msg(ifl, ofl, sdp, sym, shndx); @@ -2349,6 +2386,14 @@ ld_sym_process(Is_desc *isc, Ifl_desc *ifl, Ofl_desc *ofl) } } + /* + * If this symbol comes from a relocatable object and + * looks like a GCC local function alias, don't + * include it in dynsort sections, since the global + * name will always be preferable. + */ + if ((etype == ET_REL) && is_gcc_localalias(sdp)) + sdp->sd_flags |= FLG_SY_NODYNSORT; /* * Sanity check for TLS @@ -2729,10 +2774,10 @@ ld_sym_process(Is_desc *isc, Ifl_desc *ifl, Ofl_desc *ofl) if ((sdp = ld_sym_enter(name, nsym, hash, ifl, ofl, ndx, shndx, sdflags, &where)) == (Sym_desc *)S_ERROR) return (S_ERROR); - } else if (ld_sym_resolve(sdp, nsym, ifl, ofl, ndx, shndx, - sdflags) == S_ERROR) + sdflags) == S_ERROR) { return (S_ERROR); + } /* * Now that we have a symbol descriptor, retain the descriptor @@ -2790,7 +2835,7 @@ ld_sym_process(Is_desc *isc, Ifl_desc *ifl, Ofl_desc *ofl) * case, we don't check it, because it was already checked * as part of its own file. */ - if (etype_rel && (sdp->sd_file == ifl)) { + if ((etype == ET_REL) && (sdp->sd_file == ifl)) { Sym *tsym = sdp->sd_sym; if (SYM_LOC_BADADDR(sdp, tsym, diff --git a/usr/src/cmd/sgs/tools/SUNWonld-README b/usr/src/cmd/sgs/tools/SUNWonld-README index 731e52c973..a414a6bfe8 100644 --- a/usr/src/cmd/sgs/tools/SUNWonld-README +++ b/usr/src/cmd/sgs/tools/SUNWonld-README @@ -1669,3 +1669,4 @@ Bugid Risk Synopsis 10581 ld(1) should know kernel modules are a thing 11057 hidden undefined weak symbols should not leave relocations 11067 debug statistics crash ld(1) when -z allextract +13481 ld(1) should skip GCC local aliases when building symsort sections |