/* * ELF relocation code (not used by xen kernel right now). */ #include "libelf-private.h" /* ------------------------------------------------------------------------ */ static const char *rel_names_i386[] = { "R_386_NONE", "R_386_32", "R_386_PC32", "R_386_GOT32", "R_386_PLT32", "R_386_COPY", "R_386_GLOB_DAT", "R_386_JMP_SLOT", "R_386_RELATIVE", "R_386_GOTOFF", "R_386_GOTPC", "R_386_32PLT", "R_386_TLS_TPOFF", "R_386_TLS_IE", "R_386_TLS_GOTIE", "R_386_TLS_LE", "R_386_TLS_GD", "R_386_TLS_LDM", "R_386_16", "R_386_PC16", "R_386_8", "R_386_PC8", "R_386_TLS_GD_32", "R_386_TLS_GD_PUSH", "R_386_TLS_GD_CALL", "R_386_TLS_GD_POP", "R_386_TLS_LDM_32", "R_386_TLS_LDM_PUSH", "R_386_TLS_LDM_CALL", "R_386_TLS_LDM_POP", "R_386_TLS_LDO_32", "R_386_TLS_IE_32", "R_386_TLS_LE_32", "R_386_TLS_DTPMOD32", "R_386_TLS_DTPOFF32", "R_386_TLS_TPOFF32", }; static int elf_reloc_i386(struct elf_binary *elf, int type, uint64_t addr, uint64_t value) { void *ptr = elf_get_ptr(elf, addr); uint32_t *u32; switch ( type ) { case 1 /* R_386_32 */ : u32 = ptr; *u32 += elf->reloc_offset; break; case 2 /* R_386_PC32 */ : /* nothing */ break; default: return -1; } return 0; } /* ------------------------------------------------------------------------ */ static const char *rel_names_x86_64[] = { "R_X86_64_NONE", "R_X86_64_64", "R_X86_64_PC32", "R_X86_64_GOT32", "R_X86_64_PLT32", "R_X86_64_COPY", "R_X86_64_GLOB_DAT", "R_X86_64_JUMP_SLOT", "R_X86_64_RELATIVE", "R_X86_64_GOTPCREL", "R_X86_64_32", "R_X86_64_32S", "R_X86_64_16", "R_X86_64_PC16", "R_X86_64_8", "R_X86_64_PC8", "R_X86_64_DTPMOD64", "R_X86_64_DTPOFF64", "R_X86_64_TPOFF64", "R_X86_64_TLSGD", "R_X86_64_TLSLD", "R_X86_64_DTPOFF32", "R_X86_64_GOTTPOFF", "R_X86_64_TPOFF32", }; static int elf_reloc_x86_64(struct elf_binary *elf, int type, uint64_t addr, uint64_t value) { void *ptr = elf_get_ptr(elf, addr); uint64_t *u64; uint32_t *u32; int32_t *s32; switch ( type ) { case 1 /* R_X86_64_64 */ : u64 = ptr; value += elf->reloc_offset; *u64 = value; break; case 2 /* R_X86_64_PC32 */ : u32 = ptr; *u32 = value - addr; if ( *u32 != (uint32_t)(value - addr) ) { elf_err(elf, "R_X86_64_PC32 overflow: 0x%" PRIx32 " != 0x%" PRIx32 "\n", *u32, (uint32_t) (value - addr)); return -1; } break; case 10 /* R_X86_64_32 */ : u32 = ptr; value += elf->reloc_offset; *u32 = value; if ( *u32 != value ) { elf_err(elf, "R_X86_64_32 overflow: 0x%" PRIx32 " != 0x%" PRIx64 "\n", *u32, value); return -1; } break; case 11 /* R_X86_64_32S */ : s32 = ptr; value += elf->reloc_offset; *s32 = value; if ( *s32 != (int64_t) value ) { elf_err(elf, "R_X86_64_32S overflow: 0x%" PRIx32 " != 0x%" PRIx64 "\n", *s32, (int64_t) value); return -1; } break; default: return -1; } return 0; } /* ------------------------------------------------------------------------ */ static struct relocs { const char **names; int count; int (*func) (struct elf_binary * elf, int type, uint64_t addr, uint64_t value); } relocs[] = /* *INDENT-OFF* */ { [EM_386] = { .names = rel_names_i386, .count = sizeof(rel_names_i386) / sizeof(rel_names_i386[0]), .func = elf_reloc_i386, }, [EM_X86_64] = { .names = rel_names_x86_64, .count = sizeof(rel_names_x86_64) / sizeof(rel_names_x86_64[0]), .func = elf_reloc_x86_64, } }; /* *INDENT-ON* */ /* ------------------------------------------------------------------------ */ static const char *rela_name(int machine, int type) { if ( machine > sizeof(relocs) / siz
/* Copyright 2017 Joseph Wasson
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef PROCESS_STENO_H
#define PROCESS_STENO_H

#include "quantum.h"

#if defined(STENO_ENABLE) && !defined(VIRTSER_ENABLE)
  #error "must have virtser enabled to use steno"
#endif

typedef enum { STENO_MODE_BOLT, STENO_MODE_GEMINI } steno_mode_t;

bool process_steno(uint16_t keycode, keyrecord_t *record);
void steno_init(void);
void steno_set_mode(steno_mode_t mode);

#endif