Print this page
10366 ld(1) should support GNU-style linker sets
10367 ld(1) tests should be a real test suite
10368 want an ld(1) regression test for i386 LD tls transition (10267)

*** 34,43 **** --- 34,44 ---- #define ELF_TARGET_AMD64 #include <stdio.h> #include <string.h> #include <debug.h> + #include <alloca.h> #include "msg.h" #include "_libld.h" /* * AVL tree comparator function:
*** 690,702 **** */ if (usdp->sd_flags & FLG_SY_MAPREF) usdp->sd_flags |= FLG_SY_MAPUSED; DBG_CALL(Dbg_syms_updated(ofl, usdp, uname)); ! } else ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_RESERVE), uname, usdp->sd_file->ifl_name); } else { /* * If the symbol does not exist create it. */ if ((sym = libld_calloc(sizeof (Sym), 1)) == NULL) --- 691,704 ---- */ if (usdp->sd_flags & FLG_SY_MAPREF) usdp->sd_flags |= FLG_SY_MAPUSED; DBG_CALL(Dbg_syms_updated(ofl, usdp, uname)); ! } else { ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_RESERVE), uname, usdp->sd_file->ifl_name); + } } else { /* * If the symbol does not exist create it. */ if ((sym = libld_calloc(sizeof (Sym), 1)) == NULL)
*** 883,906 **** --- 885,981 ---- ld_eprintf(ofl, ERR_NONE, MSG_INTL(format[type]), demangle(sdp->sd_name), name1, name2, name3); } /* + * If an undef symbol exists naming a bound for the output section, + * turn it into a defined symbol with the correct value. + * + * We set an arbitrary 1KB limit on the resulting symbol names. + */ + static void + sym_add_bounds(Ofl_desc *ofl, Os_desc *osp, Word bound) + { + Sym_desc *bsdp; + char symn[1024]; + size_t nsz; + + switch (bound) { + case SDAUX_ID_SECBOUND_START: + nsz = snprintf(symn, sizeof (symn), "%s%s", + MSG_ORIG(MSG_SYM_SECBOUND_START), osp->os_name + 1); + if (nsz > sizeof (symn)) + return; + break; + case SDAUX_ID_SECBOUND_STOP: + nsz = snprintf(symn, sizeof (symn), "%s%s", + MSG_ORIG(MSG_SYM_SECBOUND_STOP), osp->os_name + 1); + if (nsz > sizeof (symn)) + return; + break; + default: + assert(0); + } + + if ((bsdp = ld_sym_find(symn, SYM_NOHASH, NULL, ofl)) != NULL) { + if ((bsdp->sd_shndx != SHN_UNDEF) && + (bsdp->sd_ref == REF_REL_NEED)) { + ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_RESERVE), + symn, bsdp->sd_file->ifl_name); + return; + } + + DBG_CALL(Dbg_syms_updated(ofl, bsdp, symn)); + + bsdp->sd_aux->sa_symspec = bound; + bsdp->sd_aux->sa_boundsec = osp; + bsdp->sd_flags |= FLG_SY_SPECSEC; + bsdp->sd_ref = REF_REL_NEED; + bsdp->sd_sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE); + bsdp->sd_sym->st_other = STV_PROTECTED; + bsdp->sd_isc = NULL; + bsdp->sd_sym->st_size = 0; + bsdp->sd_sym->st_value = 0; + bsdp->sd_shndx = bsdp->sd_sym->st_shndx = SHN_ABS; + } + } + + /* * At this point all symbol input processing has been completed, therefore * complete the symbol table entries by generating any necessary internal * symbols. */ uintptr_t ld_sym_spec(Ofl_desc *ofl) { Sym_desc *sdp; + Sg_desc *sgp; + Aliste idx1; if (ofl->ofl_flags & FLG_OF_RELOBJ) return (1); DBG_CALL(Dbg_syms_spec_title(ofl->ofl_lml)); + /* + * For each section in the output file, look for symbols named for the + * __start/__stop patterns. If references exist, flesh the symbols to + * be defined. + * + * the symbols are given values at the same time as the other special + * symbols. + */ + for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) { + Os_desc *osp; + Aliste idx2; + + for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) { + sym_add_bounds(ofl, osp, SDAUX_ID_SECBOUND_START); + sym_add_bounds(ofl, osp, SDAUX_ID_SECBOUND_STOP); + } + } + if (sym_add_spec(MSG_ORIG(MSG_SYM_ETEXT), MSG_ORIG(MSG_SYM_ETEXT_U), SDAUX_ID_ETEXT, 0, (FLG_SY_DEFAULT | FLG_SY_EXPDEF), ofl) == S_ERROR) return (S_ERROR); if (sym_add_spec(MSG_ORIG(MSG_SYM_EDATA), MSG_ORIG(MSG_SYM_EDATA_U),