^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2015 Imagination Technologies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author: Alex Smith <alex.smith@imgtec.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This tool is used to generate the real VDSO images from the raw image. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * first patches up the MIPS ABI flags and GNU attributes sections defined in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * elf.S to have the correct name and type. It then generates a C source file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * to be compiled into the kernel containing the VDSO image data and a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * mips_vdso_image struct for it, including symbol offsets extracted from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * We need to be passed both a stripped and unstripped VDSO image. The stripped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * image is compiled into the kernel, but we must also patch up the unstripped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * image's ABI flags sections so that it can be installed and used for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * debugging.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <sys/mman.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <byteswap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <stdarg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <stdbool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* Define these in case the system elf.h is not new enough to have them. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #ifndef SHT_GNU_ATTRIBUTES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) # define SHT_GNU_ATTRIBUTES 0x6ffffff5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #ifndef SHT_MIPS_ABIFLAGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) # define SHT_MIPS_ABIFLAGS 0x7000002a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) ABI_O32 = (1 << 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ABI_N32 = (1 << 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ABI_N64 = (1 << 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) ABI_ALL = ABI_O32 | ABI_N32 | ABI_N64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* Symbols the kernel requires offsets for. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) const char *offset_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) unsigned int abis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) } vdso_symbols[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) { "__vdso_sigreturn", "off_sigreturn", ABI_O32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) { "__vdso_rt_sigreturn", "off_rt_sigreturn", ABI_ALL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static const char *program_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static const char *vdso_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static unsigned char elf_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static unsigned int elf_abi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static bool need_swap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static FILE *out_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) # define HOST_ORDER ELFDATA2LSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) # define HOST_ORDER ELFDATA2MSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define BUILD_SWAP(bits) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static uint##bits##_t swap_uint##bits(uint##bits##_t val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return need_swap ? bswap_##bits(val) : val; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) BUILD_SWAP(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) BUILD_SWAP(32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) BUILD_SWAP(64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define __FUNC(name, bits) name##bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define _FUNC(name, bits) __FUNC(name, bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define FUNC(name) _FUNC(name, ELF_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define __ELF(x, bits) Elf##bits##_##x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define _ELF(x, bits) __ELF(x, bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define ELF(x) _ELF(x, ELF_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * Include genvdso.h twice with ELF_BITS defined differently to get functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * for both ELF32 and ELF64.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define ELF_BITS 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #include "genvdso.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #undef ELF_BITS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define ELF_BITS 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #include "genvdso.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #undef ELF_BITS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static void *map_vdso(const char *path, size_t *_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct stat stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) void *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) const Elf32_Ehdr *ehdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) fd = open(path, O_RDWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) fprintf(stderr, "%s: Failed to open '%s': %s\n", program_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) path, strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (fstat(fd, &stat) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) fprintf(stderr, "%s: Failed to stat '%s': %s\n", program_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) path, strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) addr = mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (addr == MAP_FAILED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) fprintf(stderr, "%s: Failed to map '%s': %s\n", program_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) path, strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* ELF32/64 header formats are the same for the bits we're checking. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ehdr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) fprintf(stderr, "%s: '%s' is not an ELF file\n", program_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) elf_class = ehdr->e_ident[EI_CLASS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) switch (elf_class) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) case ELFCLASS32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) case ELFCLASS64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) fprintf(stderr, "%s: '%s' has invalid ELF class\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) program_name, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) switch (ehdr->e_ident[EI_DATA]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) case ELFDATA2LSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case ELFDATA2MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) need_swap = ehdr->e_ident[EI_DATA] != HOST_ORDER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) fprintf(stderr, "%s: '%s' has invalid ELF data order\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) program_name, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (swap_uint16(ehdr->e_machine) != EM_MIPS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) "%s: '%s' has invalid ELF machine (expected EM_MIPS)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) program_name, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) } else if (swap_uint16(ehdr->e_type) != ET_DYN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) "%s: '%s' has invalid ELF type (expected ET_DYN)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) program_name, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) *_size = stat.st_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static bool patch_vdso(const char *path, void *vdso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (elf_class == ELFCLASS64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return patch_vdso64(path, vdso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return patch_vdso32(path, vdso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static bool get_symbols(const char *path, void *vdso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (elf_class == ELFCLASS64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return get_symbols64(path, vdso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return get_symbols32(path, vdso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int main(int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) const char *dbg_vdso_path, *vdso_path, *out_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) void *dbg_vdso, *vdso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) size_t dbg_vdso_size, vdso_size, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) program_name = argv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (argc < 4 || argc > 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) "Usage: %s <debug VDSO> <stripped VDSO> <output file> [<name>]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) program_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) dbg_vdso_path = argv[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) vdso_path = argv[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) out_path = argv[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) vdso_name = (argc > 4) ? argv[4] : "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) dbg_vdso = map_vdso(dbg_vdso_path, &dbg_vdso_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (!dbg_vdso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) vdso = map_vdso(vdso_path, &vdso_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (!vdso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* Patch both the VDSOs' ABI flags sections. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (!patch_vdso(dbg_vdso_path, dbg_vdso))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (!patch_vdso(vdso_path, vdso))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (msync(dbg_vdso, dbg_vdso_size, MS_SYNC) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) fprintf(stderr, "%s: Failed to sync '%s': %s\n", program_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) dbg_vdso_path, strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) } else if (msync(vdso, vdso_size, MS_SYNC) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) fprintf(stderr, "%s: Failed to sync '%s': %s\n", program_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) vdso_path, strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) out_file = fopen(out_path, "w");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (!out_file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) fprintf(stderr, "%s: Failed to open '%s': %s\n", program_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) out_path, strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) fprintf(out_file, "/* Automatically generated - do not edit */\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) fprintf(out_file, "#include <linux/linkage.h>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) fprintf(out_file, "#include <linux/mm.h>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) fprintf(out_file, "#include <asm/vdso.h>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) fprintf(out_file, "static int vdso_mremap(\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) fprintf(out_file, " const struct vm_special_mapping *sm,\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) fprintf(out_file, " struct vm_area_struct *new_vma)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) fprintf(out_file, "{\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) fprintf(out_file, " unsigned long new_size =\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) fprintf(out_file, " new_vma->vm_end - new_vma->vm_start;\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) fprintf(out_file, " if (vdso_image.size != new_size)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) fprintf(out_file, " return -EINVAL;\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) fprintf(out_file, " current->mm->context.vdso =\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) fprintf(out_file, " (void *)(new_vma->vm_start);\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) fprintf(out_file, " return 0;\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) fprintf(out_file, "}\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* Write out the stripped VDSO data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) fprintf(out_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) "static unsigned char vdso_data[PAGE_ALIGN(%zu)] __page_aligned_data = {\n\t",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) vdso_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) for (i = 0; i < vdso_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (!(i % 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) fprintf(out_file, "\n\t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) fprintf(out_file, "0x%02x, ", ((unsigned char *)vdso)[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) fprintf(out_file, "\n};\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* Preallocate a page array. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) fprintf(out_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) "static struct page *vdso_pages[PAGE_ALIGN(%zu) / PAGE_SIZE];\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) vdso_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) fprintf(out_file, "struct mips_vdso_image vdso_image%s%s = {\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) (vdso_name[0]) ? "_" : "", vdso_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) fprintf(out_file, "\t.data = vdso_data,\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) fprintf(out_file, "\t.size = PAGE_ALIGN(%zu),\n", vdso_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) fprintf(out_file, "\t.mapping = {\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) fprintf(out_file, "\t\t.name = \"[vdso]\",\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) fprintf(out_file, "\t\t.pages = vdso_pages,\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) fprintf(out_file, "\t\t.mremap = vdso_mremap,\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) fprintf(out_file, "\t},\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* Calculate and write symbol offsets to <output file> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (!get_symbols(dbg_vdso_path, dbg_vdso)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) unlink(out_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) fclose(out_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) fprintf(out_file, "};\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) fclose(out_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return EXIT_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }