1da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski/* 2da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * vdso2c - A vdso image preparation tool 3da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * Copyright (c) 2014 Andy Lutomirski and others 4da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * Licensed under the GPL v2 5da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * 6da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * vdso2c requires stripped and unstripped input. It would be trivial 7da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * to fully strip the input in here, but, for reasons described below, 8da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * we need to write a section table. Doing this is more or less 9da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * equivalent to dropping all non-allocatable sections, but it's 10da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * easier to let objcopy handle that instead of doing it ourselves. 11da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * If we ever need to do something fancier than what objcopy provides, 12da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * it would be straightforward to add here. 13da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * 14da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * We're keep a section table for a few reasons: 15da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * 16da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * The Go runtime had a couple of bugs: it would read the section 17da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * table to try to figure out how many dynamic symbols there were (it 18da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * shouldn't have looked at the section table at all) and, if there 19da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * were no SHT_SYNDYM section table entry, it would use an 20da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * uninitialized value for the number of symbols. An empty DYNSYM 21da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * table would work, but I see no reason not to write a valid one (and 22da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * keep full performance for old Go programs). This hack is only 23da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * needed on x86_64. 24da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * 25da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * The bug was introduced on 2012-08-31 by: 26da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * https://code.google.com/p/go/source/detail?r=56ea40aac72b 27da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * and was fixed on 2014-06-13 by: 28da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * https://code.google.com/p/go/source/detail?r=fc1cd5e12595 29da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * 30da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * Binutils has issues debugging the vDSO: it reads the section table to 31da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * find SHT_NOTE; it won't look at PT_NOTE for the in-memory vDSO, which 32da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * would break build-id if we removed the section table. Binutils 33da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * also requires that shstrndx != 0. See: 34da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * https://sourceware.org/bugzilla/show_bug.cgi?id=17064 35da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * 36da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * elfutils might not look for PT_NOTE if there is a section table at 37da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * all. I don't know whether this matters for any practical purpose. 38da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * 39da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * For simplicity, rather than hacking up a partial section table, we 40da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * just write a mostly complete one. We omit non-dynamic symbols, 41da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * though, since they're rather large. 42da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * 43da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * Once binutils gets fixed, we might be able to drop this for all but 44da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * the 64-bit vdso, since build-id only works in kernel RPMs, and 45da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * systems that update to new enough kernel RPMs will likely update 46da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * binutils in sync. build-id has never worked for home-built kernel 47da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * RPMs without manual symlinking, and I suspect that no one ever does 48da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski * that. 49da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski */ 50da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski 516f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#include <inttypes.h> 526f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#include <stdint.h> 536f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#include <unistd.h> 546f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#include <stdarg.h> 556f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#include <stdlib.h> 566f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#include <stdio.h> 576f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#include <string.h> 586f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#include <fcntl.h> 596f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#include <err.h> 606f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 616f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#include <sys/mman.h> 626f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#include <sys/types.h> 636f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 64bdfb9bcc25005d06a9c301830bdeb7ca5a0b6ef7H. Peter Anvin#include <tools/le_byteshift.h> 65bdfb9bcc25005d06a9c301830bdeb7ca5a0b6ef7H. Peter Anvin 666f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#include <linux/elf.h> 676f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#include <linux/types.h> 686f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 69011561837dad082a92c0537db2d134e66419c6adAndy Lutomirskiconst char *outfilename; 70011561837dad082a92c0537db2d134e66419c6adAndy Lutomirski 716f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski/* Symbols that we need in vdso2c. */ 7218d0a6fd227177fd243993179c90e454d0638b06Andy Lutomirskienum { 73e6577a7ce99a506b587bcd1d2cd803cb45119557Andy Lutomirski sym_vvar_start, 7418d0a6fd227177fd243993179c90e454d0638b06Andy Lutomirski sym_vvar_page, 7518d0a6fd227177fd243993179c90e454d0638b06Andy Lutomirski sym_hpet_page, 76bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski sym_VDSO_FAKE_SECTION_TABLE_START, 77bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski sym_VDSO_FAKE_SECTION_TABLE_END, 7818d0a6fd227177fd243993179c90e454d0638b06Andy Lutomirski}; 7918d0a6fd227177fd243993179c90e454d0638b06Andy Lutomirski 8018d0a6fd227177fd243993179c90e454d0638b06Andy Lutomirskiconst int special_pages[] = { 8118d0a6fd227177fd243993179c90e454d0638b06Andy Lutomirski sym_vvar_page, 8218d0a6fd227177fd243993179c90e454d0638b06Andy Lutomirski sym_hpet_page, 8318d0a6fd227177fd243993179c90e454d0638b06Andy Lutomirski}; 8418d0a6fd227177fd243993179c90e454d0638b06Andy Lutomirski 85bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirskistruct vdso_sym { 86bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski const char *name; 87bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski bool export; 88bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski}; 89bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski 90bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirskistruct vdso_sym required_syms[] = { 91e6577a7ce99a506b587bcd1d2cd803cb45119557Andy Lutomirski [sym_vvar_start] = {"vvar_start", true}, 92bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski [sym_vvar_page] = {"vvar_page", true}, 93bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski [sym_hpet_page] = {"hpet_page", true}, 94bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski [sym_VDSO_FAKE_SECTION_TABLE_START] = { 95bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski "VDSO_FAKE_SECTION_TABLE_START", false 96bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski }, 97bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski [sym_VDSO_FAKE_SECTION_TABLE_END] = { 98bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski "VDSO_FAKE_SECTION_TABLE_END", false 99bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski }, 100bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski {"VDSO32_NOTE_MASK", true}, 101bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski {"VDSO32_SYSENTER_RETURN", true}, 102bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski {"__kernel_vsyscall", true}, 103bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski {"__kernel_sigreturn", true}, 104bfad381c0d1e19cae8461e105d8d4387dd2a14feAndy Lutomirski {"__kernel_rt_sigreturn", true}, 1056f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski}; 1066f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 1076f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski__attribute__((format(printf, 1, 2))) __attribute__((noreturn)) 1086f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirskistatic void fail(const char *format, ...) 1096f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski{ 1106f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski va_list ap; 1116f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski va_start(ap, format); 1126f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski fprintf(stderr, "Error: "); 1136f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski vfprintf(stderr, format, ap); 114da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski if (outfilename) 115da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski unlink(outfilename); 1166f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski exit(1); 1176f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski va_end(ap); 1186f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski} 1196f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 120add4eed0a2abea3951206f504330ee5daf8c178aAndy Lutomirski/* 121b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirski * Evil macros for little-endian reads and writes 122add4eed0a2abea3951206f504330ee5daf8c178aAndy Lutomirski */ 123c191920f737a09a7252088f018f6747f0d2f484dH. Peter Anvin#define GLE(x, bits, ifnot) \ 124add4eed0a2abea3951206f504330ee5daf8c178aAndy Lutomirski __builtin_choose_expr( \ 125bdfb9bcc25005d06a9c301830bdeb7ca5a0b6ef7H. Peter Anvin (sizeof(*(x)) == bits/8), \ 126bdfb9bcc25005d06a9c301830bdeb7ca5a0b6ef7H. Peter Anvin (__typeof__(*(x)))get_unaligned_le##bits(x), ifnot) 127add4eed0a2abea3951206f504330ee5daf8c178aAndy Lutomirski 128bdfb9bcc25005d06a9c301830bdeb7ca5a0b6ef7H. Peter Anvinextern void bad_get_le(void); 129b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirski#define LAST_GLE(x) \ 130bdfb9bcc25005d06a9c301830bdeb7ca5a0b6ef7H. Peter Anvin __builtin_choose_expr(sizeof(*(x)) == 1, *(x), bad_get_le()) 131add4eed0a2abea3951206f504330ee5daf8c178aAndy Lutomirski 132c191920f737a09a7252088f018f6747f0d2f484dH. Peter Anvin#define GET_LE(x) \ 133b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirski GLE(x, 64, GLE(x, 32, GLE(x, 16, LAST_GLE(x)))) 134b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirski 135b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirski#define PLE(x, val, bits, ifnot) \ 136b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirski __builtin_choose_expr( \ 137b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirski (sizeof(*(x)) == bits/8), \ 138b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirski put_unaligned_le##bits((val), (x)), ifnot) 139b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirski 140b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirskiextern void bad_put_le(void); 141b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirski#define LAST_PLE(x, val) \ 142b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirski __builtin_choose_expr(sizeof(*(x)) == 1, *(x) = (val), bad_put_le()) 143b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirski 144b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirski#define PUT_LE(x, val) \ 145b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirski PLE(x, val, 64, PLE(x, val, 32, PLE(x, val, 16, LAST_PLE(x, val)))) 146b4b31f6101433e4b8ee73779b69b935af07682f8Andy Lutomirski 147add4eed0a2abea3951206f504330ee5daf8c178aAndy Lutomirski 1486f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#define NSYMS (sizeof(required_syms) / sizeof(required_syms[0])) 1496f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 150e6577a7ce99a506b587bcd1d2cd803cb45119557Andy Lutomirski#define BITSFUNC3(name, bits, suffix) name##bits##suffix 151e6577a7ce99a506b587bcd1d2cd803cb45119557Andy Lutomirski#define BITSFUNC2(name, bits, suffix) BITSFUNC3(name, bits, suffix) 152e6577a7ce99a506b587bcd1d2cd803cb45119557Andy Lutomirski#define BITSFUNC(name) BITSFUNC2(name, ELF_BITS, ) 153e6577a7ce99a506b587bcd1d2cd803cb45119557Andy Lutomirski 154e6577a7ce99a506b587bcd1d2cd803cb45119557Andy Lutomirski#define INT_BITS BITSFUNC2(int, ELF_BITS, _t) 155c1979c370273fd9f7326ffa27a63b9ddb0f495f4Andy Lutomirski 156c1979c370273fd9f7326ffa27a63b9ddb0f495f4Andy Lutomirski#define ELF_BITS_XFORM2(bits, x) Elf##bits##_##x 157c1979c370273fd9f7326ffa27a63b9ddb0f495f4Andy Lutomirski#define ELF_BITS_XFORM(bits, x) ELF_BITS_XFORM2(bits, x) 158c1979c370273fd9f7326ffa27a63b9ddb0f495f4Andy Lutomirski#define ELF(x) ELF_BITS_XFORM(ELF_BITS, x) 159c1979c370273fd9f7326ffa27a63b9ddb0f495f4Andy Lutomirski 160c1979c370273fd9f7326ffa27a63b9ddb0f495f4Andy Lutomirski#define ELF_BITS 64 1616f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#include "vdso2c.h" 162c1979c370273fd9f7326ffa27a63b9ddb0f495f4Andy Lutomirski#undef ELF_BITS 163c1979c370273fd9f7326ffa27a63b9ddb0f495f4Andy Lutomirski 164c1979c370273fd9f7326ffa27a63b9ddb0f495f4Andy Lutomirski#define ELF_BITS 32 1656f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski#include "vdso2c.h" 166c1979c370273fd9f7326ffa27a63b9ddb0f495f4Andy Lutomirski#undef ELF_BITS 1676f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 168da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirskistatic void go(void *raw_addr, size_t raw_len, 169da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski void *stripped_addr, size_t stripped_len, 170da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski FILE *outfile, const char *name) 1716f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski{ 172da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski Elf64_Ehdr *hdr = (Elf64_Ehdr *)raw_addr; 1736f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 1746f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski if (hdr->e_ident[EI_CLASS] == ELFCLASS64) { 175da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski go64(raw_addr, raw_len, stripped_addr, stripped_len, 176da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski outfile, name); 1776f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski } else if (hdr->e_ident[EI_CLASS] == ELFCLASS32) { 178da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski go32(raw_addr, raw_len, stripped_addr, stripped_len, 179da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski outfile, name); 1806f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski } else { 181011561837dad082a92c0537db2d134e66419c6adAndy Lutomirski fail("unknown ELF class\n"); 1826f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski } 1836f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski} 1846f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 185da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirskistatic void map_input(const char *name, void **addr, size_t *len, int prot) 186da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski{ 187da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski off_t tmp_len; 188da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski 189da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski int fd = open(name, O_RDONLY); 190da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski if (fd == -1) 191da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski err(1, "%s", name); 192da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski 193da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski tmp_len = lseek(fd, 0, SEEK_END); 194da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski if (tmp_len == (off_t)-1) 195da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski err(1, "lseek"); 196da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski *len = (size_t)tmp_len; 197da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski 198da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski *addr = mmap(NULL, tmp_len, prot, MAP_PRIVATE, fd, 0); 199da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski if (*addr == MAP_FAILED) 200da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski err(1, "mmap"); 201da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski 202da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski close(fd); 203da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski} 204da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski 2056f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirskiint main(int argc, char **argv) 2066f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski{ 207da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski size_t raw_len, stripped_len; 208da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski void *raw_addr, *stripped_addr; 2096f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski FILE *outfile; 2106f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski char *name, *tmp; 2116f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski int namelen; 2126f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 213da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski if (argc != 4) { 214da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski printf("Usage: vdso2c RAW_INPUT STRIPPED_INPUT OUTPUT\n"); 2156f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski return 1; 2166f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski } 2176f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 2186f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski /* 2196f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski * Figure out the struct name. If we're writing to a .so file, 2206f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski * generate raw output insted. 2216f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski */ 222da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski name = strdup(argv[3]); 2236f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski namelen = strlen(name); 2246f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski if (namelen >= 3 && !strcmp(name + namelen - 3, ".so")) { 2256f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski name = NULL; 2266f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski } else { 2276f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski tmp = strrchr(name, '/'); 2286f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski if (tmp) 2296f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski name = tmp + 1; 2306f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski tmp = strchr(name, '.'); 2316f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski if (tmp) 2326f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski *tmp = '\0'; 2336f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski for (tmp = name; *tmp; tmp++) 2346f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski if (*tmp == '-') 2356f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski *tmp = '_'; 2366f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski } 2376f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 238da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski map_input(argv[1], &raw_addr, &raw_len, PROT_READ); 239da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski map_input(argv[2], &stripped_addr, &stripped_len, PROT_READ); 2406f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 241da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski outfilename = argv[3]; 242011561837dad082a92c0537db2d134e66419c6adAndy Lutomirski outfile = fopen(outfilename, "w"); 2436f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski if (!outfile) 2446f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski err(1, "%s", argv[2]); 2456f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 246da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski go(raw_addr, raw_len, stripped_addr, stripped_len, outfile, name); 2476f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 248da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski munmap(raw_addr, raw_len); 249da861e18ecccb5c126b9eb95ff720ce082a46286Andy Lutomirski munmap(stripped_addr, stripped_len); 2506f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski fclose(outfile); 2516f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski 252011561837dad082a92c0537db2d134e66419c6adAndy Lutomirski return 0; 2536f121e548f83674ab4920a4e60afb58d4f61b829Andy Lutomirski} 254