brintos

brintos / linux-shallow public Read only

0
0
Text · 2.2 KiB · 31679c3 Raw
106 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <linux/types.h>3#include <linux/string.h>4#include <limits.h>5#include <stdlib.h>6 7#include <internal/lib.h> // page_size8#include "../../../util/machine.h"9#include "../../../util/map.h"10#include "../../../util/symbol.h"11#include <linux/ctype.h>12 13#include <symbol/kallsyms.h>14 15#if defined(__x86_64__)16 17struct extra_kernel_map_info {18	int cnt;19	int max_cnt;20	struct extra_kernel_map *maps;21	bool get_entry_trampolines;22	u64 entry_trampoline;23};24 25static int add_extra_kernel_map(struct extra_kernel_map_info *mi, u64 start,26				u64 end, u64 pgoff, const char *name)27{28	if (mi->cnt >= mi->max_cnt) {29		void *buf;30		size_t sz;31 32		mi->max_cnt = mi->max_cnt ? mi->max_cnt * 2 : 32;33		sz = sizeof(struct extra_kernel_map) * mi->max_cnt;34		buf = realloc(mi->maps, sz);35		if (!buf)36			return -1;37		mi->maps = buf;38	}39 40	mi->maps[mi->cnt].start = start;41	mi->maps[mi->cnt].end   = end;42	mi->maps[mi->cnt].pgoff = pgoff;43	strlcpy(mi->maps[mi->cnt].name, name, KMAP_NAME_LEN);44 45	mi->cnt += 1;46 47	return 0;48}49 50static int find_extra_kernel_maps(void *arg, const char *name, char type,51				  u64 start)52{53	struct extra_kernel_map_info *mi = arg;54 55	if (!mi->entry_trampoline && kallsyms2elf_binding(type) == STB_GLOBAL &&56	    !strcmp(name, "_entry_trampoline")) {57		mi->entry_trampoline = start;58		return 0;59	}60 61	if (is_entry_trampoline(name)) {62		u64 end = start + page_size;63 64		return add_extra_kernel_map(mi, start, end, 0, name);65	}66 67	return 0;68}69 70int machine__create_extra_kernel_maps(struct machine *machine,71				      struct dso *kernel)72{73	struct extra_kernel_map_info mi = { .cnt = 0, };74	char filename[PATH_MAX];75	int ret;76	int i;77 78	machine__get_kallsyms_filename(machine, filename, PATH_MAX);79 80	if (symbol__restricted_filename(filename, "/proc/kallsyms"))81		return 0;82 83	ret = kallsyms__parse(filename, &mi, find_extra_kernel_maps);84	if (ret)85		goto out_free;86 87	if (!mi.entry_trampoline)88		goto out_free;89 90	for (i = 0; i < mi.cnt; i++) {91		struct extra_kernel_map *xm = &mi.maps[i];92 93		xm->pgoff = mi.entry_trampoline;94		ret = machine__create_extra_kernel_map(machine, kernel, xm);95		if (ret)96			goto out_free;97	}98 99	machine->trampolines_mapped = mi.cnt;100out_free:101	free(mi.maps);102	return ret;103}104 105#endif106