linux/arch/mips/kernel/module.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *
   4 *  Copyright (C) 2001 Rusty Russell.
   5 *  Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
   6 *  Copyright (C) 2005 Thiemo Seufer
   7 */
   8
   9#undef DEBUG
  10
  11#include <linux/extable.h>
  12#include <linux/moduleloader.h>
  13#include <linux/elf.h>
  14#include <linux/mm.h>
  15#include <linux/numa.h>
  16#include <linux/vmalloc.h>
  17#include <linux/slab.h>
  18#include <linux/fs.h>
  19#include <linux/string.h>
  20#include <linux/kernel.h>
  21#include <linux/spinlock.h>
  22#include <linux/jump_label.h>
  23
  24
  25struct mips_hi16 {
  26        struct mips_hi16 *next;
  27        Elf_Addr *addr;
  28        Elf_Addr value;
  29};
  30
  31static LIST_HEAD(dbe_list);
  32static DEFINE_SPINLOCK(dbe_lock);
  33
  34#ifdef MODULE_START
  35void *module_alloc(unsigned long size)
  36{
  37        return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END,
  38                                GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
  39                                __builtin_return_address(0));
  40}
  41#endif
  42
  43static void apply_r_mips_32(u32 *location, u32 base, Elf_Addr v)
  44{
  45        *location = base + v;
  46}
  47
  48static int apply_r_mips_26(struct module *me, u32 *location, u32 base,
  49                           Elf_Addr v)
  50{
  51        if (v % 4) {
  52                pr_err("module %s: dangerous R_MIPS_26 relocation\n",
  53                       me->name);
  54                return -ENOEXEC;
  55        }
  56
  57        if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
  58                pr_err("module %s: relocation overflow\n",
  59                       me->name);
  60                return -ENOEXEC;
  61        }
  62
  63        *location = (*location & ~0x03ffffff) |
  64                    ((base + (v >> 2)) & 0x03ffffff);
  65
  66        return 0;
  67}
  68
  69static int apply_r_mips_hi16(struct module *me, u32 *location, Elf_Addr v,
  70                             bool rela)
  71{
  72        struct mips_hi16 *n;
  73
  74        if (rela) {
  75                *location = (*location & 0xffff0000) |
  76                            ((((long long) v + 0x8000LL) >> 16) & 0xffff);
  77                return 0;
  78        }
  79
  80        /*
  81         * We cannot relocate this one now because we don't know the value of
  82         * the carry we need to add.  Save the information, and let LO16 do the
  83         * actual relocation.
  84         */
  85        n = kmalloc(sizeof *n, GFP_KERNEL);
  86        if (!n)
  87                return -ENOMEM;
  88
  89        n->addr = (Elf_Addr *)location;
  90        n->value = v;
  91        n->next = me->arch.r_mips_hi16_list;
  92        me->arch.r_mips_hi16_list = n;
  93
  94        return 0;
  95}
  96
  97static void free_relocation_chain(struct mips_hi16 *l)
  98{
  99        struct mips_hi16 *next;
 100
 101        while (l) {
 102                next = l->next;
 103                kfree(l);
 104                l = next;
 105        }
 106}
 107
 108static int apply_r_mips_lo16(struct module *me, u32 *location,
 109                             u32 base, Elf_Addr v, bool rela)
 110{
 111        unsigned long insnlo = base;
 112        struct mips_hi16 *l;
 113        Elf_Addr val, vallo;
 114
 115        if (rela) {
 116                *location = (*location & 0xffff0000) | (v & 0xffff);
 117                return 0;
 118        }
 119
 120        /* Sign extend the addend we extract from the lo insn.  */
 121        vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
 122
 123        if (me->arch.r_mips_hi16_list != NULL) {
 124                l = me->arch.r_mips_hi16_list;
 125                while (l != NULL) {
 126                        struct mips_hi16 *next;
 127                        unsigned long insn;
 128
 129                        /*
 130                         * The value for the HI16 had best be the same.
 131                         */
 132                        if (v != l->value)
 133                                goto out_danger;
 134
 135                        /*
 136                         * Do the HI16 relocation.  Note that we actually don't
 137                         * need to know anything about the LO16 itself, except
 138                         * where to find the low 16 bits of the addend needed
 139                         * by the LO16.
 140                         */
 141                        insn = *l->addr;
 142                        val = ((insn & 0xffff) << 16) + vallo;
 143                        val += v;
 144
 145                        /*
 146                         * Account for the sign extension that will happen in
 147                         * the low bits.
 148                         */
 149                        val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
 150
 151                        insn = (insn & ~0xffff) | val;
 152                        *l->addr = insn;
 153
 154                        next = l->next;
 155                        kfree(l);
 156                        l = next;
 157                }
 158
 159                me->arch.r_mips_hi16_list = NULL;
 160        }
 161
 162        /*
 163         * Ok, we're done with the HI16 relocs.  Now deal with the LO16.
 164         */
 165        val = v + vallo;
 166        insnlo = (insnlo & ~0xffff) | (val & 0xffff);
 167        *location = insnlo;
 168
 169        return 0;
 170
 171out_danger:
 172        free_relocation_chain(l);
 173        me->arch.r_mips_hi16_list = NULL;
 174
 175        pr_err("module %s: dangerous R_MIPS_LO16 relocation\n", me->name);
 176
 177        return -ENOEXEC;
 178}
 179
 180static int apply_r_mips_pc(struct module *me, u32 *location, u32 base,
 181                           Elf_Addr v, unsigned int bits)
 182{
 183        unsigned long mask = GENMASK(bits - 1, 0);
 184        unsigned long se_bits;
 185        long offset;
 186
 187        if (v % 4) {
 188                pr_err("module %s: dangerous R_MIPS_PC%u relocation\n",
 189                       me->name, bits);
 190                return -ENOEXEC;
 191        }
 192
 193        /* retrieve & sign extend implicit addend if any */
 194        offset = base & mask;
 195        offset |= (offset & BIT(bits - 1)) ? ~mask : 0;
 196
 197        offset += ((long)v - (long)location) >> 2;
 198
 199        /* check the sign bit onwards are identical - ie. we didn't overflow */
 200        se_bits = (offset & BIT(bits - 1)) ? ~0ul : 0;
 201        if ((offset & ~mask) != (se_bits & ~mask)) {
 202                pr_err("module %s: relocation overflow\n", me->name);
 203                return -ENOEXEC;
 204        }
 205
 206        *location = (*location & ~mask) | (offset & mask);
 207
 208        return 0;
 209}
 210
 211static int apply_r_mips_pc16(struct module *me, u32 *location, u32 base,
 212                             Elf_Addr v)
 213{
 214        return apply_r_mips_pc(me, location, base, v, 16);
 215}
 216
 217static int apply_r_mips_pc21(struct module *me, u32 *location, u32 base,
 218                             Elf_Addr v)
 219{
 220        return apply_r_mips_pc(me, location, base, v, 21);
 221}
 222
 223static int apply_r_mips_pc26(struct module *me, u32 *location, u32 base,
 224                             Elf_Addr v)
 225{
 226        return apply_r_mips_pc(me, location, base, v, 26);
 227}
 228
 229static int apply_r_mips_64(u32 *location, Elf_Addr v, bool rela)
 230{
 231        if (WARN_ON(!rela))
 232                return -EINVAL;
 233
 234        *(Elf_Addr *)location = v;
 235
 236        return 0;
 237}
 238
 239static int apply_r_mips_higher(u32 *location, Elf_Addr v, bool rela)
 240{
 241        if (WARN_ON(!rela))
 242                return -EINVAL;
 243
 244        *location = (*location & 0xffff0000) |
 245                    ((((long long)v + 0x80008000LL) >> 32) & 0xffff);
 246
 247        return 0;
 248}
 249
 250static int apply_r_mips_highest(u32 *location, Elf_Addr v, bool rela)
 251{
 252        if (WARN_ON(!rela))
 253                return -EINVAL;
 254
 255        *location = (*location & 0xffff0000) |
 256                    ((((long long)v + 0x800080008000LL) >> 48) & 0xffff);
 257
 258        return 0;
 259}
 260
 261/**
 262 * reloc_handler() - Apply a particular relocation to a module
 263 * @type: type of the relocation to apply
 264 * @me: the module to apply the reloc to
 265 * @location: the address at which the reloc is to be applied
 266 * @base: the existing value at location for REL-style; 0 for RELA-style
 267 * @v: the value of the reloc, with addend for RELA-style
 268 * @rela: indication of is this a RELA (true) or REL (false) relocation
 269 *
 270 * Each implemented relocation function applies a particular type of
 271 * relocation to the module @me. Relocs that may be found in either REL or RELA
 272 * variants can be handled by making use of the @base & @v parameters which are
 273 * set to values which abstract the difference away from the particular reloc
 274 * implementations.
 275 *
 276 * Return: 0 upon success, else -ERRNO
 277 */
 278static int reloc_handler(u32 type, struct module *me, u32 *location, u32 base,
 279                         Elf_Addr v, bool rela)
 280{
 281        switch (type) {
 282        case R_MIPS_NONE:
 283                break;
 284        case R_MIPS_32:
 285                apply_r_mips_32(location, base, v);
 286                break;
 287        case R_MIPS_26:
 288                return apply_r_mips_26(me, location, base, v);
 289        case R_MIPS_HI16:
 290                return apply_r_mips_hi16(me, location, v, rela);
 291        case R_MIPS_LO16:
 292                return apply_r_mips_lo16(me, location, base, v, rela);
 293        case R_MIPS_PC16:
 294                return apply_r_mips_pc16(me, location, base, v);
 295        case R_MIPS_PC21_S2:
 296                return apply_r_mips_pc21(me, location, base, v);
 297        case R_MIPS_PC26_S2:
 298                return apply_r_mips_pc26(me, location, base, v);
 299        case R_MIPS_64:
 300                return apply_r_mips_64(location, v, rela);
 301        case R_MIPS_HIGHER:
 302                return apply_r_mips_higher(location, v, rela);
 303        case R_MIPS_HIGHEST:
 304                return apply_r_mips_highest(location, v, rela);
 305        default:
 306                pr_err("%s: Unknown relocation type %u\n", me->name, type);
 307                return -EINVAL;
 308        }
 309
 310        return 0;
 311}
 312
 313static int __apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
 314                            unsigned int symindex, unsigned int relsec,
 315                            struct module *me, bool rela)
 316{
 317        union {
 318                Elf_Mips_Rel *rel;
 319                Elf_Mips_Rela *rela;
 320        } r;
 321        Elf_Sym *sym;
 322        u32 *location, base;
 323        unsigned int i, type;
 324        Elf_Addr v;
 325        int err = 0;
 326        size_t reloc_sz;
 327
 328        pr_debug("Applying relocate section %u to %u\n", relsec,
 329               sechdrs[relsec].sh_info);
 330
 331        r.rel = (void *)sechdrs[relsec].sh_addr;
 332        reloc_sz = rela ? sizeof(*r.rela) : sizeof(*r.rel);
 333        me->arch.r_mips_hi16_list = NULL;
 334        for (i = 0; i < sechdrs[relsec].sh_size / reloc_sz; i++) {
 335                /* This is where to make the change */
 336                location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
 337                        + r.rel->r_offset;
 338                /* This is the symbol it is referring to */
 339                sym = (Elf_Sym *)sechdrs[symindex].sh_addr
 340                        + ELF_MIPS_R_SYM(*r.rel);
 341                if (sym->st_value >= -MAX_ERRNO) {
 342                        /* Ignore unresolved weak symbol */
 343                        if (ELF_ST_BIND(sym->st_info) == STB_WEAK)
 344                                continue;
 345                        pr_warn("%s: Unknown symbol %s\n",
 346                                me->name, strtab + sym->st_name);
 347                        err = -ENOENT;
 348                        goto out;
 349                }
 350
 351                type = ELF_MIPS_R_TYPE(*r.rel);
 352
 353                if (rela) {
 354                        v = sym->st_value + r.rela->r_addend;
 355                        base = 0;
 356                        r.rela = &r.rela[1];
 357                } else {
 358                        v = sym->st_value;
 359                        base = *location;
 360                        r.rel = &r.rel[1];
 361                }
 362
 363                err = reloc_handler(type, me, location, base, v, rela);
 364                if (err)
 365                        goto out;
 366        }
 367
 368out:
 369        /*
 370         * Normally the hi16 list should be deallocated at this point. A
 371         * malformed binary however could contain a series of R_MIPS_HI16
 372         * relocations not followed by a R_MIPS_LO16 relocation, or if we hit
 373         * an error processing a reloc we might have gotten here before
 374         * reaching the R_MIPS_LO16. In either case, free up the list and
 375         * return an error.
 376         */
 377        if (me->arch.r_mips_hi16_list) {
 378                free_relocation_chain(me->arch.r_mips_hi16_list);
 379                me->arch.r_mips_hi16_list = NULL;
 380                err = err ?: -ENOEXEC;
 381        }
 382
 383        return err;
 384}
 385
 386int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
 387                   unsigned int symindex, unsigned int relsec,
 388                   struct module *me)
 389{
 390        return __apply_relocate(sechdrs, strtab, symindex, relsec, me, false);
 391}
 392
 393#ifdef CONFIG_MODULES_USE_ELF_RELA
 394int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
 395                       unsigned int symindex, unsigned int relsec,
 396                       struct module *me)
 397{
 398        return __apply_relocate(sechdrs, strtab, symindex, relsec, me, true);
 399}
 400#endif /* CONFIG_MODULES_USE_ELF_RELA */
 401
 402/* Given an address, look for it in the module exception tables. */
 403const struct exception_table_entry *search_module_dbetables(unsigned long addr)
 404{
 405        unsigned long flags;
 406        const struct exception_table_entry *e = NULL;
 407        struct mod_arch_specific *dbe;
 408
 409        spin_lock_irqsave(&dbe_lock, flags);
 410        list_for_each_entry(dbe, &dbe_list, dbe_list) {
 411                e = search_extable(dbe->dbe_start,
 412                                   dbe->dbe_end - dbe->dbe_start, addr);
 413                if (e)
 414                        break;
 415        }
 416        spin_unlock_irqrestore(&dbe_lock, flags);
 417
 418        /* Now, if we found one, we are running inside it now, hence
 419           we cannot unload the module, hence no refcnt needed. */
 420        return e;
 421}
 422
 423/* Put in dbe list if necessary. */
 424int module_finalize(const Elf_Ehdr *hdr,
 425                    const Elf_Shdr *sechdrs,
 426                    struct module *me)
 427{
 428        const Elf_Shdr *s;
 429        char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
 430
 431        /* Make jump label nops. */
 432        jump_label_apply_nops(me);
 433
 434        INIT_LIST_HEAD(&me->arch.dbe_list);
 435        for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
 436                if (strcmp("__dbe_table", secstrings + s->sh_name) != 0)
 437                        continue;
 438                me->arch.dbe_start = (void *)s->sh_addr;
 439                me->arch.dbe_end = (void *)s->sh_addr + s->sh_size;
 440                spin_lock_irq(&dbe_lock);
 441                list_add(&me->arch.dbe_list, &dbe_list);
 442                spin_unlock_irq(&dbe_lock);
 443        }
 444        return 0;
 445}
 446
 447void module_arch_cleanup(struct module *mod)
 448{
 449        spin_lock_irq(&dbe_lock);
 450        list_del(&mod->arch.dbe_list);
 451        spin_unlock_irq(&dbe_lock);
 452}
 453