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