cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

symbol-minimal.c (7488B)


      1#include "dso.h"
      2#include "symbol.h"
      3#include "symsrc.h"
      4
      5#include <errno.h>
      6#include <unistd.h>
      7#include <stdio.h>
      8#include <fcntl.h>
      9#include <string.h>
     10#include <stdlib.h>
     11#include <byteswap.h>
     12#include <sys/stat.h>
     13#include <linux/zalloc.h>
     14#include <internal/lib.h>
     15
     16static bool check_need_swap(int file_endian)
     17{
     18	const int data = 1;
     19	u8 *check = (u8 *)&data;
     20	int host_endian;
     21
     22	if (check[0] == 1)
     23		host_endian = ELFDATA2LSB;
     24	else
     25		host_endian = ELFDATA2MSB;
     26
     27	return host_endian != file_endian;
     28}
     29
     30#define NOTE_ALIGN(sz) (((sz) + 3) & ~3)
     31
     32#define NT_GNU_BUILD_ID	3
     33
     34static int read_build_id(void *note_data, size_t note_len, struct build_id *bid,
     35			 bool need_swap)
     36{
     37	size_t size = sizeof(bid->data);
     38	struct {
     39		u32 n_namesz;
     40		u32 n_descsz;
     41		u32 n_type;
     42	} *nhdr;
     43	void *ptr;
     44
     45	ptr = note_data;
     46	while (ptr < (note_data + note_len)) {
     47		const char *name;
     48		size_t namesz, descsz;
     49
     50		nhdr = ptr;
     51		if (need_swap) {
     52			nhdr->n_namesz = bswap_32(nhdr->n_namesz);
     53			nhdr->n_descsz = bswap_32(nhdr->n_descsz);
     54			nhdr->n_type = bswap_32(nhdr->n_type);
     55		}
     56
     57		namesz = NOTE_ALIGN(nhdr->n_namesz);
     58		descsz = NOTE_ALIGN(nhdr->n_descsz);
     59
     60		ptr += sizeof(*nhdr);
     61		name = ptr;
     62		ptr += namesz;
     63		if (nhdr->n_type == NT_GNU_BUILD_ID &&
     64		    nhdr->n_namesz == sizeof("GNU")) {
     65			if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
     66				size_t sz = min(size, descsz);
     67				memcpy(bid->data, ptr, sz);
     68				memset(bid->data + sz, 0, size - sz);
     69				bid->size = sz;
     70				return 0;
     71			}
     72		}
     73		ptr += descsz;
     74	}
     75
     76	return -1;
     77}
     78
     79int filename__read_debuglink(const char *filename __maybe_unused,
     80			     char *debuglink __maybe_unused,
     81			     size_t size __maybe_unused)
     82{
     83	return -1;
     84}
     85
     86/*
     87 * Just try PT_NOTE header otherwise fails
     88 */
     89int filename__read_build_id(const char *filename, struct build_id *bid)
     90{
     91	FILE *fp;
     92	int ret = -1;
     93	bool need_swap = false;
     94	u8 e_ident[EI_NIDENT];
     95	size_t buf_size;
     96	void *buf;
     97	int i;
     98
     99	fp = fopen(filename, "r");
    100	if (fp == NULL)
    101		return -1;
    102
    103	if (fread(e_ident, sizeof(e_ident), 1, fp) != 1)
    104		goto out;
    105
    106	if (memcmp(e_ident, ELFMAG, SELFMAG) ||
    107	    e_ident[EI_VERSION] != EV_CURRENT)
    108		goto out;
    109
    110	need_swap = check_need_swap(e_ident[EI_DATA]);
    111
    112	/* for simplicity */
    113	fseek(fp, 0, SEEK_SET);
    114
    115	if (e_ident[EI_CLASS] == ELFCLASS32) {
    116		Elf32_Ehdr ehdr;
    117		Elf32_Phdr *phdr;
    118
    119		if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
    120			goto out;
    121
    122		if (need_swap) {
    123			ehdr.e_phoff = bswap_32(ehdr.e_phoff);
    124			ehdr.e_phentsize = bswap_16(ehdr.e_phentsize);
    125			ehdr.e_phnum = bswap_16(ehdr.e_phnum);
    126		}
    127
    128		buf_size = ehdr.e_phentsize * ehdr.e_phnum;
    129		buf = malloc(buf_size);
    130		if (buf == NULL)
    131			goto out;
    132
    133		fseek(fp, ehdr.e_phoff, SEEK_SET);
    134		if (fread(buf, buf_size, 1, fp) != 1)
    135			goto out_free;
    136
    137		for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
    138			void *tmp;
    139			long offset;
    140
    141			if (need_swap) {
    142				phdr->p_type = bswap_32(phdr->p_type);
    143				phdr->p_offset = bswap_32(phdr->p_offset);
    144				phdr->p_filesz = bswap_32(phdr->p_filesz);
    145			}
    146
    147			if (phdr->p_type != PT_NOTE)
    148				continue;
    149
    150			buf_size = phdr->p_filesz;
    151			offset = phdr->p_offset;
    152			tmp = realloc(buf, buf_size);
    153			if (tmp == NULL)
    154				goto out_free;
    155
    156			buf = tmp;
    157			fseek(fp, offset, SEEK_SET);
    158			if (fread(buf, buf_size, 1, fp) != 1)
    159				goto out_free;
    160
    161			ret = read_build_id(buf, buf_size, bid, need_swap);
    162			if (ret == 0)
    163				ret = bid->size;
    164			break;
    165		}
    166	} else {
    167		Elf64_Ehdr ehdr;
    168		Elf64_Phdr *phdr;
    169
    170		if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
    171			goto out;
    172
    173		if (need_swap) {
    174			ehdr.e_phoff = bswap_64(ehdr.e_phoff);
    175			ehdr.e_phentsize = bswap_16(ehdr.e_phentsize);
    176			ehdr.e_phnum = bswap_16(ehdr.e_phnum);
    177		}
    178
    179		buf_size = ehdr.e_phentsize * ehdr.e_phnum;
    180		buf = malloc(buf_size);
    181		if (buf == NULL)
    182			goto out;
    183
    184		fseek(fp, ehdr.e_phoff, SEEK_SET);
    185		if (fread(buf, buf_size, 1, fp) != 1)
    186			goto out_free;
    187
    188		for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
    189			void *tmp;
    190			long offset;
    191
    192			if (need_swap) {
    193				phdr->p_type = bswap_32(phdr->p_type);
    194				phdr->p_offset = bswap_64(phdr->p_offset);
    195				phdr->p_filesz = bswap_64(phdr->p_filesz);
    196			}
    197
    198			if (phdr->p_type != PT_NOTE)
    199				continue;
    200
    201			buf_size = phdr->p_filesz;
    202			offset = phdr->p_offset;
    203			tmp = realloc(buf, buf_size);
    204			if (tmp == NULL)
    205				goto out_free;
    206
    207			buf = tmp;
    208			fseek(fp, offset, SEEK_SET);
    209			if (fread(buf, buf_size, 1, fp) != 1)
    210				goto out_free;
    211
    212			ret = read_build_id(buf, buf_size, bid, need_swap);
    213			if (ret == 0)
    214				ret = bid->size;
    215			break;
    216		}
    217	}
    218out_free:
    219	free(buf);
    220out:
    221	fclose(fp);
    222	return ret;
    223}
    224
    225int sysfs__read_build_id(const char *filename, struct build_id *bid)
    226{
    227	int fd;
    228	int ret = -1;
    229	struct stat stbuf;
    230	size_t buf_size;
    231	void *buf;
    232
    233	fd = open(filename, O_RDONLY);
    234	if (fd < 0)
    235		return -1;
    236
    237	if (fstat(fd, &stbuf) < 0)
    238		goto out;
    239
    240	buf_size = stbuf.st_size;
    241	buf = malloc(buf_size);
    242	if (buf == NULL)
    243		goto out;
    244
    245	if (read(fd, buf, buf_size) != (ssize_t) buf_size)
    246		goto out_free;
    247
    248	ret = read_build_id(buf, buf_size, bid, false);
    249out_free:
    250	free(buf);
    251out:
    252	close(fd);
    253	return ret;
    254}
    255
    256int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
    257	         enum dso_binary_type type)
    258{
    259	int fd = open(name, O_RDONLY);
    260	if (fd < 0)
    261		goto out_errno;
    262
    263	ss->name = strdup(name);
    264	if (!ss->name)
    265		goto out_close;
    266
    267	ss->fd = fd;
    268	ss->type = type;
    269
    270	return 0;
    271out_close:
    272	close(fd);
    273out_errno:
    274	dso->load_errno = errno;
    275	return -1;
    276}
    277
    278bool symsrc__possibly_runtime(struct symsrc *ss __maybe_unused)
    279{
    280	/* Assume all sym sources could be a runtime image. */
    281	return true;
    282}
    283
    284bool symsrc__has_symtab(struct symsrc *ss __maybe_unused)
    285{
    286	return false;
    287}
    288
    289void symsrc__destroy(struct symsrc *ss)
    290{
    291	zfree(&ss->name);
    292	close(ss->fd);
    293}
    294
    295int dso__synthesize_plt_symbols(struct dso *dso __maybe_unused,
    296				struct symsrc *ss __maybe_unused)
    297{
    298	return 0;
    299}
    300
    301static int fd__is_64_bit(int fd)
    302{
    303	u8 e_ident[EI_NIDENT];
    304
    305	if (lseek(fd, 0, SEEK_SET))
    306		return -1;
    307
    308	if (readn(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident))
    309		return -1;
    310
    311	if (memcmp(e_ident, ELFMAG, SELFMAG) ||
    312	    e_ident[EI_VERSION] != EV_CURRENT)
    313		return -1;
    314
    315	return e_ident[EI_CLASS] == ELFCLASS64;
    316}
    317
    318enum dso_type dso__type_fd(int fd)
    319{
    320	Elf64_Ehdr ehdr;
    321	int ret;
    322
    323	ret = fd__is_64_bit(fd);
    324	if (ret < 0)
    325		return DSO__TYPE_UNKNOWN;
    326
    327	if (ret)
    328		return DSO__TYPE_64BIT;
    329
    330	if (readn(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
    331		return DSO__TYPE_UNKNOWN;
    332
    333	if (ehdr.e_machine == EM_X86_64)
    334		return DSO__TYPE_X32BIT;
    335
    336	return DSO__TYPE_32BIT;
    337}
    338
    339int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,
    340		  struct symsrc *ss,
    341		  struct symsrc *runtime_ss __maybe_unused,
    342		  int kmodule __maybe_unused)
    343{
    344	struct build_id bid;
    345	int ret;
    346
    347	ret = fd__is_64_bit(ss->fd);
    348	if (ret >= 0)
    349		dso->is_64_bit = ret;
    350
    351	if (filename__read_build_id(ss->name, &bid) > 0)
    352		dso__set_build_id(dso, &bid);
    353	return 0;
    354}
    355
    356int file__read_maps(int fd __maybe_unused, bool exe __maybe_unused,
    357		    mapfn_t mapfn __maybe_unused, void *data __maybe_unused,
    358		    bool *is_64_bit __maybe_unused)
    359{
    360	return -1;
    361}
    362
    363int kcore_extract__create(struct kcore_extract *kce __maybe_unused)
    364{
    365	return -1;
    366}
    367
    368void kcore_extract__delete(struct kcore_extract *kce __maybe_unused)
    369{
    370}
    371
    372int kcore_copy(const char *from_dir __maybe_unused,
    373	       const char *to_dir __maybe_unused)
    374{
    375	return -1;
    376}
    377
    378void symbol__elf_init(void)
    379{
    380}
    381
    382char *dso__demangle_sym(struct dso *dso __maybe_unused,
    383			int kmodule __maybe_unused,
    384			const char *elf_name __maybe_unused)
    385{
    386	return NULL;
    387}