Print this page
10908 Simplify SMAP relocations with krtld

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/intel/amd64/krtld/kobj_reloc.c
          +++ new/usr/src/uts/intel/amd64/krtld/kobj_reloc.c
↓ open down ↓ 15 lines elided ↑ open up ↑
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
       26 +/*
       27 + * Copyright 2019 Joyent, Inc.
       28 + */
  26   29  
  27      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  28      -
  29   30  /*
  30   31   * x86 relocation code.
  31   32   */
  32   33  
  33   34  #include <sys/types.h>
  34   35  #include <sys/param.h>
  35   36  #include <sys/sysmacros.h>
  36   37  #include <sys/systm.h>
  37   38  #include <sys/user.h>
  38   39  #include <sys/bootconf.h>
↓ open down ↓ 73 lines elided ↑ open up ↑
 112  113          sdp->sdpd_offset = (uintptr_t)instr;
 113  114          sdp->sdpd_next = mp->sdt_probes;
 114  115          mp->sdt_probes = sdp;
 115  116  
 116  117          for (i = 0; i < SDT_NOPS; i++)
 117  118                  instr[i - 1] = SDT_NOP;
 118  119  
 119  120          return (0);
 120  121  }
 121  122  
      123 +
      124 +/*
      125 + * We're relying on the fact that the call we're replacing is
      126 + * call (e8) plus 4 bytes of address, making a 5 byte instruction
      127 + */
      128 +#define NOP_INSTR       0x90
      129 +#define SMAP_NOPS       5
      130 +
      131 +/*
      132 + * Currently the only call replaced as a hot inline
      133 + * is smap_enable() and smap_disable(). If more are needed
      134 + * we should probably come up with an sdt probe like prefix
      135 + * and look for those instead of exact call names.
      136 + */
      137 +static int
      138 +smap_reloc_resolve(struct module *mp, char *symname, uint8_t *instr)
      139 +{
      140 +        uint_t symlen;
      141 +        hotinline_desc_t *hid;
      142 +
      143 +        if (strcmp(symname, "smap_enable") == 0 ||
      144 +            strcmp(symname, "smap_disable") == 0) {
      145 +
      146 +#ifdef  KOBJ_DEBUG
      147 +                if (kobj_debug & D_RELOCATIONS) {
      148 +                        _kobj_printf(ops, "smap_reloc_resolve: %s relocating "
      149 +                            "enable/disable_smap\n", mp->filename);
      150 +                }
      151 +#endif
      152 +
      153 +                hid = kobj_alloc(sizeof (hotinline_desc_t), KM_WAIT);
      154 +                symlen = strlen(symname) + 1;
      155 +                hid->hid_symname = kobj_alloc(symlen, KM_WAIT);
      156 +                bcopy(symname, hid->hid_symname, symlen);
      157 +
      158 +                /*
      159 +                 * We backtrack one byte here to consume the call
      160 +                 * instruction itself.
      161 +                 */
      162 +                hid->hid_instr_offset = (uintptr_t)instr - 1;
      163 +                hid->hid_next = mp->hi_calls;
      164 +                mp->hi_calls = hid;
      165 +
      166 +                memset((void *)hid->hid_instr_offset, NOP_INSTR, SMAP_NOPS);
      167 +
      168 +                return (0);
      169 +        }
      170 +
      171 +        return (1);
      172 +}
      173 +
 122  174  int
 123      -/* ARGSUSED2 */
 124  175  do_relocate(struct module *mp, char *reltbl, Word relshtype, int nreloc,
 125      -        int relocsize, Addr baseaddr)
      176 +    int relocsize, Addr baseaddr)
 126  177  {
 127  178          unsigned long stndx;
 128  179          unsigned long off;      /* can't be register for tnf_reloc_resolve() */
 129  180          register unsigned long reladdr, rend;
 130  181          register unsigned int rtype;
 131  182          unsigned long value;
 132  183          Elf64_Sxword addend;
 133  184          Sym *symref;
 134  185          int err = 0;
 135  186          tnf_probe_control_t *probelist = NULL;
↓ open down ↓ 78 lines elided ↑ open up ↑
 214  265                                  /*
 215  266                                   * It's global. Allow weak references.  If
 216  267                                   * the symbol is undefined, give TNF (the
 217  268                                   * kernel probes facility) a chance to see
 218  269                                   * if it's a probe site, and fix it up if so.
 219  270                                   */
 220  271                                  if (symref->st_shndx == SHN_UNDEF &&
 221  272                                      sdt_reloc_resolve(mp, mp->strings +
 222  273                                      symref->st_name, (uint8_t *)off) == 0)
 223  274                                          continue;
      275 +
      276 +                                if (symref->st_shndx == SHN_UNDEF &&
      277 +                                    smap_reloc_resolve(mp, mp->strings +
      278 +                                    symref->st_name, (uint8_t *)off) == 0)
      279 +                                        continue;
 224  280  
 225  281                                  if (symref->st_shndx == SHN_UNDEF &&
 226  282                                      tnf_reloc_resolve(mp->strings +
 227  283                                      symref->st_name, &symref->st_value,
 228  284                                      &addend, off, &probelist, &taglist) != 0) {
 229  285                                          if (ELF_ST_BIND(symref->st_info)
 230  286                                              != STB_WEAK) {
 231  287                                                  _kobj_printf(ops,
 232  288                                                      "not found: %s\n",
 233  289                                                      mp->strings +
↓ open down ↓ 112 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX