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