kernel: Binary code patches on x86.
This will be used to support SMAP. Sponsored-by: https://liberapay.com/korli
This commit is contained in:
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018, Jérôme Duval, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef _KERNEL_ARCH_x86_ALTCODEPATCH_H
|
||||||
|
#define _KERNEL_ARCH_x86_ALTCODEPATCH_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <arch/x86/arch_kernel.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define ASM_NOP1 .byte 0x90
|
||||||
|
#define ASM_NOP2 .byte 0x66, 0x90
|
||||||
|
#define ASM_NOP3 .byte 0x0f, 0x1f, 0x00
|
||||||
|
#define ASM_NOP4 .byte 0x0f, 0x1f, 0x40, 0x00
|
||||||
|
#define ASM_NOP5 .byte 0x0f, 0x1f, 0x44, 0x00, 0x00
|
||||||
|
#define ASM_NOP6 .byte 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00
|
||||||
|
#define ASM_NOP7 .byte 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00
|
||||||
|
#define ASM_NOP8 .byte 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
#define ASM_NOP9 .byte 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _ASSEMBLER
|
||||||
|
|
||||||
|
#define CODEPATCH_START 990:
|
||||||
|
#define CODEPATCH_END(tag) 991: \
|
||||||
|
.pushsection .altcodepatch, "a" ; \
|
||||||
|
.long (990b - KERNEL_LOAD_BASE) ; \
|
||||||
|
.short (991b - 990b) ; \
|
||||||
|
.short tag ; \
|
||||||
|
.popsection
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define _STRINGIFY(x...) #x
|
||||||
|
#define STRINGIFY(x...) _STRINGIFY(x)
|
||||||
|
|
||||||
|
#define CODEPATCH_START "990: \n"
|
||||||
|
#define CODEPATCH_END(tag) "991: \n" \
|
||||||
|
".pushsection .altcodepatch, \"a\" \n" \
|
||||||
|
".long (990b - " STRINGIFY(KERNEL_LOAD_BASE) ") \n" \
|
||||||
|
".short (991b - 990b) \n" \
|
||||||
|
".short " STRINGIFY(tag) " \n" \
|
||||||
|
".popsection"
|
||||||
|
|
||||||
|
void arch_altcodepatch_replace(uint16 tag, void* newcodepatch, size_t length);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _KERNEL_ARCH_x86_ALTCODEPATCH_H */
|
||||||
@@ -72,6 +72,7 @@ if $(TARGET_ARCH) = x86_64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
local archGenericSources =
|
local archGenericSources =
|
||||||
|
arch_altcodepatch.cpp
|
||||||
arch_cpu.cpp
|
arch_cpu.cpp
|
||||||
arch_commpage.cpp
|
arch_commpage.cpp
|
||||||
arch_debug.cpp
|
arch_debug.cpp
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018, Jérôme Duval, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "arch/x86/arch_altcodepatch.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
#include <kernel.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct altcodepatch {
|
||||||
|
uint32 kernel_offset;
|
||||||
|
uint16 length;
|
||||||
|
uint16 tag;
|
||||||
|
} altcodepatch;
|
||||||
|
|
||||||
|
|
||||||
|
extern altcodepatch altcodepatch_begin;
|
||||||
|
extern altcodepatch altcodepatch_end;
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
arch_altcodepatch_replace(uint16 tag, void* newcodepatch, size_t length)
|
||||||
|
{
|
||||||
|
uint32 count = 0;
|
||||||
|
|
||||||
|
for (altcodepatch *patch = &altcodepatch_begin; patch < &altcodepatch_end;
|
||||||
|
patch++) {
|
||||||
|
if (patch->tag != tag)
|
||||||
|
continue;
|
||||||
|
addr_t address = KERNEL_LOAD_BASE + patch->kernel_offset;
|
||||||
|
if (patch->length < length)
|
||||||
|
panic("can't copy patch: new code is too long\n");
|
||||||
|
memcpy((void*)address, newcodepatch, length);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
dprintf("arch_altcodepatch_replace found %d altcodepatches\n", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -39,6 +39,11 @@ SECTIONS
|
|||||||
|
|
||||||
.rodata : { *(.rodata) }
|
.rodata : { *(.rodata) }
|
||||||
|
|
||||||
|
. = ALIGN(0x4);
|
||||||
|
altcodepatch_begin = .;
|
||||||
|
.altcodepatch : { *(.altcodepatch) }
|
||||||
|
altcodepatch_end = .;
|
||||||
|
|
||||||
/* writable data */
|
/* writable data */
|
||||||
. = ALIGN(0x1000);
|
. = ALIGN(0x1000);
|
||||||
__data_start = .;
|
__data_start = .;
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ SECTIONS
|
|||||||
|
|
||||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||||
|
|
||||||
|
. = ALIGN(0x8);
|
||||||
|
altcodepatch_begin = .;
|
||||||
|
.altcodepatch : { *(.altcodepatch) }
|
||||||
|
altcodepatch_end = .;
|
||||||
|
|
||||||
/* writable data */
|
/* writable data */
|
||||||
. = ALIGN (0x1000);
|
. = ALIGN (0x1000);
|
||||||
__data_start = .;
|
__data_start = .;
|
||||||
|
|||||||
Reference in New Issue
Block a user