Needed by libraries produced by the Go compiler.
With this patch and the golang app the runtime
init crash later because of a vdso issue.
It can be examinated by insertion an abort()
before osv send SIGSEGV to the program.
(gdb) bt
at /usr/lib/golang/src/runtime/mheap.go:503
argc=<error reading variable: Cannot access memory at address 0xffffffffffffffcc>, argv=<optimized out>) at core/app.cc:338
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) frame 9
188 CALL AX
(gdb) lsit
Undefined command: "lsit". Try "help".
(gdb) list
183 RET
184 fallback:
185 LEAQ 0(SP), DI
186 MOVQ $0, SI
187 MOVQ runtime·__vdso_gettimeofday_sym(SB), AX
188 CALL AX
189 MOVQ 0(SP), AX // sec
190 MOVL 8(SP), DX // usec
191 IMULQ $1000, DX
192 // sec is in AX, nsec in DX
(gdb) p $ax
$1 = 0
(gdb)
Signed-off-by: Pekka Enberg <
pen...@scylladb.com>
Signed-off-by: Benoît Canet <
ben...@scylladb.com>
---
Makefile | 1 +
arch/x64/msr.hh | 1 +
arch/x64/prctl.cc | 39 +++++++++++++++++++++++++++++++++++++++
linux.cc | 3 +++
4 files changed, 44 insertions(+)
create mode 100644 arch/x64/prctl.cc
diff --git a/Makefile b/Makefile
index e294a03..4518da8 100644
--- a/Makefile
+++ b/Makefile
@@ -882,6 +882,7 @@ objects += arch/x64/ioapic.o
objects += arch/x64/apic.o
objects += arch/x64/apic-clock.o
objects += arch/x64/entry-xen.o
+objects += arch/x64/prctl.o
objects += arch/x64/xen.o
objects += arch/x64/xen_intr.o
objects += core/sampler.o
diff --git a/arch/x64/msr.hh b/arch/x64/msr.hh
index d77c75c..9aa8314 100644
--- a/arch/x64/msr.hh
+++ b/arch/x64/msr.hh
@@ -62,6 +62,7 @@ enum class msr : uint32_t {
IA32_LSTAR = 0xc0000082,
IA32_FMASK = 0xc0000084,
IA32_FS_BASE = 0xc0000100,
+ IA32_GS_BASE = 0xc0000101,
KVM_WALL_CLOCK = 0x11,
KVM_SYSTEM_TIME = 0x12,
diff --git a/arch/x64/prctl.cc b/arch/x64/prctl.cc
new file mode 100644
index 0000000..73ba7c7
--- /dev/null
+++ b/arch/x64/prctl.cc
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 Cloudius Systems, Ltd.
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include "arch.hh"
+#include "msr.hh"
+#include "libc/libc.hh"
+
+#include <assert.h>
+#include <stdio.h>
+
+enum {
+ ARCH_SET_GS = 0x1001,
+ ARCH_SET_FS = 0x1002,
+ ARCH_GET_FS = 0x1003,
+ ARCH_GET_GS = 0x1004,
+};
+
+long arch_prctl(int code, unsigned long addr)
+{
+ switch (code) {
+ case ARCH_SET_GS:
+ processor::wrmsr(msr::IA32_GS_BASE, addr);
+ asm volatile ("movq %0, %%gs" :: "r"(addr));
+ break;
+ case ARCH_SET_FS:
+ processor::wrmsr(msr::IA32_FS_BASE, addr);
+ asm volatile ("movq %0, %%fs" :: "r"(addr));
+ break;
+ case ARCH_GET_FS:
+ return processor::rdmsr(msr::IA32_FS_BASE);
+ case ARCH_GET_GS:
+ return processor::rdmsr(msr::IA32_GS_BASE);
+ }
+ return libc_error(EINVAL);
+}
diff --git a/linux.cc b/linux.cc
index e78bb0c..03be002 100644
--- a/linux.cc
+++ b/linux.cc
@@ -297,6 +297,8 @@ int rt_sigprocmask(int how, sigset_t * nset, sigset_t * oset, size_t sigsetsize)
return sigprocmask(how, nset, oset);
}
+extern long arch_prctl(int code, unsigned long addr);
+
long syscall(long number, ...)
{
switch (number) {
@@ -319,6 +321,7 @@ long syscall(long number, ...)
SYSCALL2(munmap, void *, size_t);
SYSCALL4(rt_sigaction, int, const struct k_sigaction *, struct k_sigaction *, size_t);
SYSCALL4(rt_sigprocmask, int, sigset_t *, sigset_t *, size_t);
+ SYSCALL2(arch_prctl, int, unsigned long);
}
debug_always("syscall(): unimplemented system call %d\n", number);
--
2.7.4