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

*** 117,126 **** --- 117,177 ---- instr[i - 1] = SDT_NOP; return (0); } + + /* + * We're relying on the fact that the call we're replacing is + * call (e8) plus 4 bytes of address, making a 5 byte instruction + */ + #define NOP_INSTR 0x90 + #define SMAP_NOPS 5 + + /* + * Currently the only call replaced as a hot inline + * is smap_enable() and smap_disable(). If more are needed + * we should probably come up with an sdt probe like prefix + * and look for those instead of exact call names. + */ + static int + smap_reloc_resolve(struct module *mp, char *symname, uint8_t *instr) + { + uint_t symlen; + hotinline_desc_t *hid; + + if (strcmp(symname, "smap_enable") == 0 || + strcmp(symname, "smap_disable") == 0) { + + #ifdef KOBJ_DEBUG + if (kobj_debug & D_RELOCATIONS) { + _kobj_printf(ops, "smap_reloc_resolve: %s relocating " + "enable/disable_smap\n", mp->filename); + } + #endif + + hid = kobj_alloc(sizeof (hotinline_desc_t), KM_WAIT); + symlen = strlen(symname) + 1; + hid->hid_symname = kobj_alloc(symlen, KM_WAIT); + bcopy(symname, hid->hid_symname, symlen); + + /* + * We backtrack one byte here to consume the call + * instruction itself. + */ + hid->hid_instr_offset = (uintptr_t)instr - 1; + hid->hid_next = mp->hi_calls; + mp->hi_calls = hid; + + memset((void *)hid->hid_instr_offset, NOP_INSTR, SMAP_NOPS); + + return (0); + } + + return (1); + } + int do_relocate(struct module *mp, char *reltbl, int nreloc, int relocsize, Addr baseaddr) { unsigned long stndx;
*** 218,227 **** --- 269,283 ---- */ if (symref->st_shndx == SHN_UNDEF && sdt_reloc_resolve(mp, mp->strings + symref->st_name, (uint8_t *)off) == 0) continue; + + if (symref->st_shndx == SHN_UNDEF && + smap_reloc_resolve(mp, mp->strings + + symref->st_name, (uint8_t *)off) == 0) + continue; if (symref->st_shndx == SHN_UNDEF && tnf_reloc_resolve(mp->strings + symref->st_name, &symref->st_value, &addend, off, &probelist, &taglist) != 0) {