Linux Audio

Check our new training course

Embedded Linux training

Mar 31-Apr 8, 2025
Register
Loading...
Note: File does not exist in v6.2.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * linux/arch/sparc/mm/extable.c
  4 */
  5
  6#include <linux/module.h>
  7#include <linux/extable.h>
  8#include <linux/uaccess.h>
  9
 10void sort_extable(struct exception_table_entry *start,
 11		  struct exception_table_entry *finish)
 12{
 13}
 14
 15/* Caller knows they are in a range if ret->fixup == 0 */
 16const struct exception_table_entry *
 17search_extable(const struct exception_table_entry *base,
 18	       const size_t num,
 19	       unsigned long value)
 20{
 21	int i;
 22
 23	/* Single insn entries are encoded as:
 24	 *	word 1:	insn address
 25	 *	word 2:	fixup code address
 26	 *
 27	 * Range entries are encoded as:
 28	 *	word 1: first insn address
 29	 *	word 2: 0
 30	 *	word 3: last insn address + 4 bytes
 31	 *	word 4: fixup code address
 32	 *
 33	 * Deleted entries are encoded as:
 34	 *	word 1: unused
 35	 *	word 2: -1
 36	 *
 37	 * See asm/uaccess.h for more details.
 38	 */
 39
 40	/* 1. Try to find an exact match. */
 41	for (i = 0; i < num; i++) {
 42		if (base[i].fixup == 0) {
 43			/* A range entry, skip both parts. */
 44			i++;
 45			continue;
 46		}
 47
 48		/* A deleted entry; see trim_init_extable */
 49		if (base[i].fixup == -1)
 50			continue;
 51
 52		if (base[i].insn == value)
 53			return &base[i];
 54	}
 55
 56	/* 2. Try to find a range match. */
 57	for (i = 0; i < (num - 1); i++) {
 58		if (base[i].fixup)
 59			continue;
 60
 61		if (base[i].insn <= value && base[i + 1].insn > value)
 62			return &base[i];
 63
 64		i++;
 65	}
 66
 67        return NULL;
 68}
 69
 70#ifdef CONFIG_MODULES
 71/* We could memmove them around; easier to mark the trimmed ones. */
 72void trim_init_extable(struct module *m)
 73{
 74	unsigned int i;
 75	bool range;
 76
 77	for (i = 0; i < m->num_exentries; i += range ? 2 : 1) {
 78		range = m->extable[i].fixup == 0;
 79
 80		if (within_module_init(m->extable[i].insn, m)) {
 81			m->extable[i].fixup = -1;
 82			if (range)
 83				m->extable[i+1].fixup = -1;
 84		}
 85		if (range)
 86			i++;
 87	}
 88}
 89#endif /* CONFIG_MODULES */
 90
 91/* Special extable search, which handles ranges.  Returns fixup */
 92unsigned long search_extables_range(unsigned long addr, unsigned long *g2)
 93{
 94	const struct exception_table_entry *entry;
 95
 96	entry = search_exception_tables(addr);
 97	if (!entry)
 98		return 0;
 99
100	/* Inside range?  Fix g2 and return correct fixup */
101	if (!entry->fixup) {
102		*g2 = (addr - entry->insn) / 4;
103		return (entry + 1)->fixup;
104	}
105
106	return entry->fixup;
107}