Print this page
9059 Simplify SMAP relocations with krtld
Portions contributed by: John Levon <john.levon@joyent.com>


2162         }
2163 
2164         kobj_notify(KOBJ_NOTIFY_MODUNLOADING, modp);
2165 
2166         /*
2167          * Null out mod_mp first, so consumers (debuggers) know not to look
2168          * at the module structure any more.
2169          */
2170         mutex_enter(&mod_lock);
2171         modp->mod_mp = NULL;
2172         mutex_exit(&mod_lock);
2173 
2174         kobj_notify(KOBJ_NOTIFY_MODUNLOADED, modp);
2175         free_module_data(mp);
2176 }
2177 
2178 static void
2179 free_module_data(struct module *mp)
2180 {
2181         struct module_list *lp, *tmp;

2182         int ksyms_exported = 0;
2183 
2184         lp = mp->head;
2185         while (lp) {
2186                 tmp = lp;
2187                 lp = lp->next;
2188                 kobj_free((char *)tmp, sizeof (*tmp));
2189         }
2190 









2191         rw_enter(&ksyms_lock, RW_WRITER);
2192         if (mp->symspace) {
2193                 if (vmem_contains(ksyms_arena, mp->symspace, mp->symsize)) {
2194                         vmem_free(ksyms_arena, mp->symspace, mp->symsize);
2195                         ksyms_exported = 1;
2196                 } else {
2197                         if (mp->flags & KOBJ_NOKSYMS)
2198                                 ksyms_exported = 1;
2199                         kobj_free(mp->symspace, mp->symsize);
2200                 }
2201         }
2202         rw_exit(&ksyms_lock);
2203 
2204         if (mp->ctfdata) {
2205                 if (vmem_contains(ctf_arena, mp->ctfdata, mp->ctfsize))
2206                         vmem_free(ctf_arena, mp->ctfdata, mp->ctfsize);
2207                 else
2208                         kobj_free(mp->ctfdata, mp->ctfsize);
2209         }
2210 


3016                 if (ELF_ST_TYPE(sp->st_info) == STT_TLS) {
3017                         _kobj_printf(ops, "%s: TLS symbol ",
3018                             mp->filename);
3019                         _kobj_printf(ops, "not supported '%s'\n",
3020                             name);
3021                         err = DOSYM_UNDEF;
3022                         continue;
3023                 }
3024 
3025                 if (ELF_ST_BIND(sp->st_info) != STB_LOCAL) {
3026                         if ((sp1 = kobj_lookup_all(mp, name, 0)) != NULL) {
3027                                 sp->st_shndx = SHN_ABS;
3028                                 sp->st_value = sp1->st_value;
3029                                 continue;
3030                         }
3031                 }
3032 
3033                 if (sp->st_shndx == SHN_UNDEF) {
3034                         resolved = 0;
3035 




3036                         if (strncmp(name, sdt_prefix, strlen(sdt_prefix)) == 0)
3037                                 continue;





3038 

3039                         /*
3040                          * If it's not a weak reference and it's
3041                          * not a primary object, it's an error.
3042                          * (Primary objects may take more than
3043                          * one pass to resolve)
3044                          */
3045                         if (!(mp->flags & KOBJ_PRIM) &&
3046                             ELF_ST_BIND(sp->st_info) != STB_WEAK) {
3047                                 _kobj_printf(ops, "%s: undefined symbol",
3048                                     mp->filename);
3049                                 _kobj_printf(ops, " '%s'\n", name);
3050                                 /*
3051                                  * Try to determine whether this symbol
3052                                  * represents a dependency on obsolete
3053                                  * unsafe driver support.  This is just
3054                                  * to make the warning more informative.
3055                                  */
3056                                 if (strcmp(name, "sleep") == 0 ||
3057                                     strcmp(name, "unsleep") == 0 ||
3058                                     strcmp(name, "wakeup") == 0 ||




2162         }
2163 
2164         kobj_notify(KOBJ_NOTIFY_MODUNLOADING, modp);
2165 
2166         /*
2167          * Null out mod_mp first, so consumers (debuggers) know not to look
2168          * at the module structure any more.
2169          */
2170         mutex_enter(&mod_lock);
2171         modp->mod_mp = NULL;
2172         mutex_exit(&mod_lock);
2173 
2174         kobj_notify(KOBJ_NOTIFY_MODUNLOADED, modp);
2175         free_module_data(mp);
2176 }
2177 
2178 static void
2179 free_module_data(struct module *mp)
2180 {
2181         struct module_list *lp, *tmp;
2182         hotinline_desc_t *hid, *next;
2183         int ksyms_exported = 0;
2184 
2185         lp = mp->head;
2186         while (lp) {
2187                 tmp = lp;
2188                 lp = lp->next;
2189                 kobj_free((char *)tmp, sizeof (*tmp));
2190         }
2191 
2192         /* release hotinlines */
2193         hid = mp->hi_calls;
2194         while (hid != NULL) {
2195                 next = hid->hid_next;
2196                 kobj_free(hid->hid_symname, strlen(hid->hid_symname) + 1);
2197                 kobj_free(hid, sizeof (hotinline_desc_t));
2198                 hid = next;
2199         }
2200 
2201         rw_enter(&ksyms_lock, RW_WRITER);
2202         if (mp->symspace) {
2203                 if (vmem_contains(ksyms_arena, mp->symspace, mp->symsize)) {
2204                         vmem_free(ksyms_arena, mp->symspace, mp->symsize);
2205                         ksyms_exported = 1;
2206                 } else {
2207                         if (mp->flags & KOBJ_NOKSYMS)
2208                                 ksyms_exported = 1;
2209                         kobj_free(mp->symspace, mp->symsize);
2210                 }
2211         }
2212         rw_exit(&ksyms_lock);
2213 
2214         if (mp->ctfdata) {
2215                 if (vmem_contains(ctf_arena, mp->ctfdata, mp->ctfsize))
2216                         vmem_free(ctf_arena, mp->ctfdata, mp->ctfsize);
2217                 else
2218                         kobj_free(mp->ctfdata, mp->ctfsize);
2219         }
2220 


3026                 if (ELF_ST_TYPE(sp->st_info) == STT_TLS) {
3027                         _kobj_printf(ops, "%s: TLS symbol ",
3028                             mp->filename);
3029                         _kobj_printf(ops, "not supported '%s'\n",
3030                             name);
3031                         err = DOSYM_UNDEF;
3032                         continue;
3033                 }
3034 
3035                 if (ELF_ST_BIND(sp->st_info) != STB_LOCAL) {
3036                         if ((sp1 = kobj_lookup_all(mp, name, 0)) != NULL) {
3037                                 sp->st_shndx = SHN_ABS;
3038                                 sp->st_value = sp1->st_value;
3039                                 continue;
3040                         }
3041                 }
3042 
3043                 if (sp->st_shndx == SHN_UNDEF) {
3044                         resolved = 0;
3045 
3046                         /*
3047                          * Skip over sdt probes and smap calls,
3048                          * they're relocated later.
3049                          */
3050                         if (strncmp(name, sdt_prefix, strlen(sdt_prefix)) == 0)
3051                                 continue;
3052 #if defined(__x86)
3053                         if (strcmp(name, "smap_enable") == 0 ||
3054                             strcmp(name, "smap_disable") == 0)
3055                                 continue;
3056 #endif /* defined(__x86) */
3057 
3058 
3059                         /*
3060                          * If it's not a weak reference and it's
3061                          * not a primary object, it's an error.
3062                          * (Primary objects may take more than
3063                          * one pass to resolve)
3064                          */
3065                         if (!(mp->flags & KOBJ_PRIM) &&
3066                             ELF_ST_BIND(sp->st_info) != STB_WEAK) {
3067                                 _kobj_printf(ops, "%s: undefined symbol",
3068                                     mp->filename);
3069                                 _kobj_printf(ops, " '%s'\n", name);
3070                                 /*
3071                                  * Try to determine whether this symbol
3072                                  * represents a dependency on obsolete
3073                                  * unsafe driver support.  This is just
3074                                  * to make the warning more informative.
3075                                  */
3076                                 if (strcmp(name, "sleep") == 0 ||
3077                                     strcmp(name, "unsleep") == 0 ||
3078                                     strcmp(name, "wakeup") == 0 ||