0001 #include "dso.h"
0002 #include "symbol.h"
0003 #include "symsrc.h"
0004
0005 #include <errno.h>
0006 #include <unistd.h>
0007 #include <stdio.h>
0008 #include <fcntl.h>
0009 #include <string.h>
0010 #include <stdlib.h>
0011 #include <byteswap.h>
0012 #include <sys/stat.h>
0013 #include <linux/zalloc.h>
0014 #include <internal/lib.h>
0015
0016 static bool check_need_swap(int file_endian)
0017 {
0018 const int data = 1;
0019 u8 *check = (u8 *)&data;
0020 int host_endian;
0021
0022 if (check[0] == 1)
0023 host_endian = ELFDATA2LSB;
0024 else
0025 host_endian = ELFDATA2MSB;
0026
0027 return host_endian != file_endian;
0028 }
0029
0030 #define NOTE_ALIGN(sz) (((sz) + 3) & ~3)
0031
0032 #define NT_GNU_BUILD_ID 3
0033
0034 static int read_build_id(void *note_data, size_t note_len, struct build_id *bid,
0035 bool need_swap)
0036 {
0037 size_t size = sizeof(bid->data);
0038 struct {
0039 u32 n_namesz;
0040 u32 n_descsz;
0041 u32 n_type;
0042 } *nhdr;
0043 void *ptr;
0044
0045 ptr = note_data;
0046 while (ptr < (note_data + note_len)) {
0047 const char *name;
0048 size_t namesz, descsz;
0049
0050 nhdr = ptr;
0051 if (need_swap) {
0052 nhdr->n_namesz = bswap_32(nhdr->n_namesz);
0053 nhdr->n_descsz = bswap_32(nhdr->n_descsz);
0054 nhdr->n_type = bswap_32(nhdr->n_type);
0055 }
0056
0057 namesz = NOTE_ALIGN(nhdr->n_namesz);
0058 descsz = NOTE_ALIGN(nhdr->n_descsz);
0059
0060 ptr += sizeof(*nhdr);
0061 name = ptr;
0062 ptr += namesz;
0063 if (nhdr->n_type == NT_GNU_BUILD_ID &&
0064 nhdr->n_namesz == sizeof("GNU")) {
0065 if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
0066 size_t sz = min(size, descsz);
0067 memcpy(bid->data, ptr, sz);
0068 memset(bid->data + sz, 0, size - sz);
0069 bid->size = sz;
0070 return 0;
0071 }
0072 }
0073 ptr += descsz;
0074 }
0075
0076 return -1;
0077 }
0078
0079 int filename__read_debuglink(const char *filename __maybe_unused,
0080 char *debuglink __maybe_unused,
0081 size_t size __maybe_unused)
0082 {
0083 return -1;
0084 }
0085
0086
0087
0088
0089 int filename__read_build_id(const char *filename, struct build_id *bid)
0090 {
0091 FILE *fp;
0092 int ret = -1;
0093 bool need_swap = false;
0094 u8 e_ident[EI_NIDENT];
0095 size_t buf_size;
0096 void *buf;
0097 int i;
0098
0099 fp = fopen(filename, "r");
0100 if (fp == NULL)
0101 return -1;
0102
0103 if (fread(e_ident, sizeof(e_ident), 1, fp) != 1)
0104 goto out;
0105
0106 if (memcmp(e_ident, ELFMAG, SELFMAG) ||
0107 e_ident[EI_VERSION] != EV_CURRENT)
0108 goto out;
0109
0110 need_swap = check_need_swap(e_ident[EI_DATA]);
0111
0112
0113 fseek(fp, 0, SEEK_SET);
0114
0115 if (e_ident[EI_CLASS] == ELFCLASS32) {
0116 Elf32_Ehdr ehdr;
0117 Elf32_Phdr *phdr;
0118
0119 if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
0120 goto out;
0121
0122 if (need_swap) {
0123 ehdr.e_phoff = bswap_32(ehdr.e_phoff);
0124 ehdr.e_phentsize = bswap_16(ehdr.e_phentsize);
0125 ehdr.e_phnum = bswap_16(ehdr.e_phnum);
0126 }
0127
0128 buf_size = ehdr.e_phentsize * ehdr.e_phnum;
0129 buf = malloc(buf_size);
0130 if (buf == NULL)
0131 goto out;
0132
0133 fseek(fp, ehdr.e_phoff, SEEK_SET);
0134 if (fread(buf, buf_size, 1, fp) != 1)
0135 goto out_free;
0136
0137 for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
0138 void *tmp;
0139 long offset;
0140
0141 if (need_swap) {
0142 phdr->p_type = bswap_32(phdr->p_type);
0143 phdr->p_offset = bswap_32(phdr->p_offset);
0144 phdr->p_filesz = bswap_32(phdr->p_filesz);
0145 }
0146
0147 if (phdr->p_type != PT_NOTE)
0148 continue;
0149
0150 buf_size = phdr->p_filesz;
0151 offset = phdr->p_offset;
0152 tmp = realloc(buf, buf_size);
0153 if (tmp == NULL)
0154 goto out_free;
0155
0156 buf = tmp;
0157 fseek(fp, offset, SEEK_SET);
0158 if (fread(buf, buf_size, 1, fp) != 1)
0159 goto out_free;
0160
0161 ret = read_build_id(buf, buf_size, bid, need_swap);
0162 if (ret == 0)
0163 ret = bid->size;
0164 break;
0165 }
0166 } else {
0167 Elf64_Ehdr ehdr;
0168 Elf64_Phdr *phdr;
0169
0170 if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
0171 goto out;
0172
0173 if (need_swap) {
0174 ehdr.e_phoff = bswap_64(ehdr.e_phoff);
0175 ehdr.e_phentsize = bswap_16(ehdr.e_phentsize);
0176 ehdr.e_phnum = bswap_16(ehdr.e_phnum);
0177 }
0178
0179 buf_size = ehdr.e_phentsize * ehdr.e_phnum;
0180 buf = malloc(buf_size);
0181 if (buf == NULL)
0182 goto out;
0183
0184 fseek(fp, ehdr.e_phoff, SEEK_SET);
0185 if (fread(buf, buf_size, 1, fp) != 1)
0186 goto out_free;
0187
0188 for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
0189 void *tmp;
0190 long offset;
0191
0192 if (need_swap) {
0193 phdr->p_type = bswap_32(phdr->p_type);
0194 phdr->p_offset = bswap_64(phdr->p_offset);
0195 phdr->p_filesz = bswap_64(phdr->p_filesz);
0196 }
0197
0198 if (phdr->p_type != PT_NOTE)
0199 continue;
0200
0201 buf_size = phdr->p_filesz;
0202 offset = phdr->p_offset;
0203 tmp = realloc(buf, buf_size);
0204 if (tmp == NULL)
0205 goto out_free;
0206
0207 buf = tmp;
0208 fseek(fp, offset, SEEK_SET);
0209 if (fread(buf, buf_size, 1, fp) != 1)
0210 goto out_free;
0211
0212 ret = read_build_id(buf, buf_size, bid, need_swap);
0213 if (ret == 0)
0214 ret = bid->size;
0215 break;
0216 }
0217 }
0218 out_free:
0219 free(buf);
0220 out:
0221 fclose(fp);
0222 return ret;
0223 }
0224
0225 int sysfs__read_build_id(const char *filename, struct build_id *bid)
0226 {
0227 int fd;
0228 int ret = -1;
0229 struct stat stbuf;
0230 size_t buf_size;
0231 void *buf;
0232
0233 fd = open(filename, O_RDONLY);
0234 if (fd < 0)
0235 return -1;
0236
0237 if (fstat(fd, &stbuf) < 0)
0238 goto out;
0239
0240 buf_size = stbuf.st_size;
0241 buf = malloc(buf_size);
0242 if (buf == NULL)
0243 goto out;
0244
0245 if (read(fd, buf, buf_size) != (ssize_t) buf_size)
0246 goto out_free;
0247
0248 ret = read_build_id(buf, buf_size, bid, false);
0249 out_free:
0250 free(buf);
0251 out:
0252 close(fd);
0253 return ret;
0254 }
0255
0256 int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
0257 enum dso_binary_type type)
0258 {
0259 int fd = open(name, O_RDONLY);
0260 if (fd < 0)
0261 goto out_errno;
0262
0263 ss->name = strdup(name);
0264 if (!ss->name)
0265 goto out_close;
0266
0267 ss->fd = fd;
0268 ss->type = type;
0269
0270 return 0;
0271 out_close:
0272 close(fd);
0273 out_errno:
0274 dso->load_errno = errno;
0275 return -1;
0276 }
0277
0278 bool symsrc__possibly_runtime(struct symsrc *ss __maybe_unused)
0279 {
0280
0281 return true;
0282 }
0283
0284 bool symsrc__has_symtab(struct symsrc *ss __maybe_unused)
0285 {
0286 return false;
0287 }
0288
0289 void symsrc__destroy(struct symsrc *ss)
0290 {
0291 zfree(&ss->name);
0292 close(ss->fd);
0293 }
0294
0295 int dso__synthesize_plt_symbols(struct dso *dso __maybe_unused,
0296 struct symsrc *ss __maybe_unused)
0297 {
0298 return 0;
0299 }
0300
0301 static int fd__is_64_bit(int fd)
0302 {
0303 u8 e_ident[EI_NIDENT];
0304
0305 if (lseek(fd, 0, SEEK_SET))
0306 return -1;
0307
0308 if (readn(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident))
0309 return -1;
0310
0311 if (memcmp(e_ident, ELFMAG, SELFMAG) ||
0312 e_ident[EI_VERSION] != EV_CURRENT)
0313 return -1;
0314
0315 return e_ident[EI_CLASS] == ELFCLASS64;
0316 }
0317
0318 enum dso_type dso__type_fd(int fd)
0319 {
0320 Elf64_Ehdr ehdr;
0321 int ret;
0322
0323 ret = fd__is_64_bit(fd);
0324 if (ret < 0)
0325 return DSO__TYPE_UNKNOWN;
0326
0327 if (ret)
0328 return DSO__TYPE_64BIT;
0329
0330 if (readn(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
0331 return DSO__TYPE_UNKNOWN;
0332
0333 if (ehdr.e_machine == EM_X86_64)
0334 return DSO__TYPE_X32BIT;
0335
0336 return DSO__TYPE_32BIT;
0337 }
0338
0339 int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,
0340 struct symsrc *ss,
0341 struct symsrc *runtime_ss __maybe_unused,
0342 int kmodule __maybe_unused)
0343 {
0344 struct build_id bid;
0345 int ret;
0346
0347 ret = fd__is_64_bit(ss->fd);
0348 if (ret >= 0)
0349 dso->is_64_bit = ret;
0350
0351 if (filename__read_build_id(ss->name, &bid) > 0)
0352 dso__set_build_id(dso, &bid);
0353 return 0;
0354 }
0355
0356 int file__read_maps(int fd __maybe_unused, bool exe __maybe_unused,
0357 mapfn_t mapfn __maybe_unused, void *data __maybe_unused,
0358 bool *is_64_bit __maybe_unused)
0359 {
0360 return -1;
0361 }
0362
0363 int kcore_extract__create(struct kcore_extract *kce __maybe_unused)
0364 {
0365 return -1;
0366 }
0367
0368 void kcore_extract__delete(struct kcore_extract *kce __maybe_unused)
0369 {
0370 }
0371
0372 int kcore_copy(const char *from_dir __maybe_unused,
0373 const char *to_dir __maybe_unused)
0374 {
0375 return -1;
0376 }
0377
0378 void symbol__elf_init(void)
0379 {
0380 }
0381
0382 char *dso__demangle_sym(struct dso *dso __maybe_unused,
0383 int kmodule __maybe_unused,
0384 const char *elf_name __maybe_unused)
0385 {
0386 return NULL;
0387 }