Verified Commit 7fd60c8d authored by jD91mZM2's avatar jD91mZM2

Fix segfault by adding the remaining registers

I think missing fs_base was the culprit...
parent e482de42
/target
**/*.rs.bk
a.out
*.out
*.o
......@@ -9,4 +9,4 @@ Linux somewhat works.
Current status:
![Screenshot of debugging with GDB](https://i.imgur.com/LVCdO1S.png)
![Screenshot of debugging with GDB](https://i.imgur.com/Xuke1du.png)
......@@ -2,10 +2,15 @@
let
gdb-init = pkgs.writers.writeBashBin "gdb" ''
${pkgs.gdb}/bin/gdb "$@" \
${pkgs.gdb}/bin/gdb \
-ex "set tdesc filename ${./target-desc.xml}" \
-ex "set debug remote 1"
"$@"
'';
gdb-test = pkgs.writers.writeBashBin "gdb-test" ''
${gdb-init}/bin/gdb \
-ex "target remote :64126" \
"$@"
'';
in pkgs.mkShell {
nativeBuildInputs = [ gdb-init ];
nativeBuildInputs = [ gdb-init gdb-test ];
}
......@@ -191,9 +191,8 @@ impl super::Target for Os {
registers.fs = Some(int.fs as _);
registers.gs = Some(int.gs as _);
registers.fcw = Some(float.cwd as _);
registers.fctrl = Some(float.cwd as _);
registers.fop = Some(float.fop as _);
registers.mxcsr = Some(float.mxcsr);
registers.st0 = Some(float.st_space[0] as _);
registers.st1 = Some(float.st_space[1] as _);
......@@ -221,6 +220,11 @@ impl super::Target for Os {
registers.xmm14 = Some(float.xmm_space[14] as _);
registers.xmm15 = Some(float.xmm_space[15] as _);
registers.mxcsr = Some(float.mxcsr);
registers.fs_base = Some(int.fs_base as _);
registers.gs_base = Some(int.gs_base as _);
registers.orig_rax = Some(int.orig_rax as _);
Ok(registers)
}
......@@ -253,9 +257,8 @@ impl super::Target for Os {
int.fs = registers.fs.map(|r| r as _).unwrap_or(int.fs);
int.gs = registers.gs.map(|r| r as _).unwrap_or(int.gs);
float.cwd = registers.fcw.map(|r| r as _).unwrap_or(float.cwd);
float.cwd = registers.fctrl.map(|r| r as _).unwrap_or(float.cwd);
float.fop = registers.fop.map(|r| r as _).unwrap_or(float.fop);
float.mxcsr = registers.mxcsr.unwrap_or(float.mxcsr);
float.st_space[0] = registers.st0.map(|r| r as _).unwrap_or(float.st_space[0]);
float.st_space[1] = registers.st1.map(|r| r as _).unwrap_or(float.st_space[1]);
......@@ -301,6 +304,11 @@ impl super::Target for Os {
.map(|r| r as _)
.unwrap_or(float.xmm_space[15]);
float.mxcsr = registers.mxcsr.unwrap_or(float.mxcsr);
int.fs_base = registers.fs_base.map(|r| r as _).unwrap_or(int.fs_base);
int.gs_base = registers.gs_base.map(|r| r as _).unwrap_or(int.gs_base);
int.orig_rax = registers.orig_rax.map(|r| r as _).unwrap_or(int.orig_rax);
unsafe {
ce!(libc::ptrace(libc::PTRACE_SETREGS, self.pid, 0, &int));
ce!(libc::ptrace(libc::PTRACE_SETFPREGS, self.pid, 0, &float));
......
......@@ -4,6 +4,7 @@ use std::io::prelude::*;
#[derive(Default)]
pub struct Registers {
// Gotten from gnu-binutils/gdb/regformats/i386/amd64-linux.dat
pub rax: Option<u64>,
pub rbx: Option<u64>,
pub rcx: Option<u64>,
......@@ -36,13 +37,13 @@ pub struct Registers {
pub st5: Option<u128>,
pub st6: Option<u128>,
pub st7: Option<u128>,
pub fcw: Option<u32>,
pub fctrl: Option<u32>,
pub fstat: Option<u32>,
pub ftag: Option<u32>,
pub fiseg: Option<u32>,
pub fiofs: Option<u32>,
pub fioff: Option<u32>,
pub foseg: Option<u32>,
pub foofs: Option<u32>,
pub fooff: Option<u32>,
pub fop: Option<u32>,
pub xmm0: Option<u128>,
pub xmm1: Option<u128>,
......@@ -61,6 +62,9 @@ pub struct Registers {
pub xmm14: Option<u128>,
pub xmm15: Option<u128>,
pub mxcsr: Option<u32>,
pub orig_rax: Option<u64>,
pub fs_base: Option<u64>,
pub gs_base: Option<u64>,
}
impl Registers {
// The following sadly assume the endianness in order to only read
......@@ -106,13 +110,13 @@ impl Registers {
st5: Some(u128::from_le_bytes([byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, 0, 0, 0, 0, 0, 0])),
st6: Some(u128::from_le_bytes([byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, 0, 0, 0, 0, 0, 0])),
st7: Some(u128::from_le_bytes([byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, 0, 0, 0, 0, 0, 0])),
fcw: Some(u32::from_le_bytes([byte()?, byte()?, byte()?, byte()?])),
fctrl: Some(u32::from_le_bytes([byte()?, byte()?, byte()?, byte()?])),
fstat: Some(u32::from_le_bytes([byte()?, byte()?, byte()?, byte()?])),
ftag: Some(u32::from_le_bytes([byte()?, byte()?, byte()?, byte()?])),
fiseg: Some(u32::from_le_bytes([byte()?, byte()?, byte()?, byte()?])),
fiofs: Some(u32::from_le_bytes([byte()?, byte()?, byte()?, byte()?])),
fioff: Some(u32::from_le_bytes([byte()?, byte()?, byte()?, byte()?])),
foseg: Some(u32::from_le_bytes([byte()?, byte()?, byte()?, byte()?])),
foofs: Some(u32::from_le_bytes([byte()?, byte()?, byte()?, byte()?])),
fooff: Some(u32::from_le_bytes([byte()?, byte()?, byte()?, byte()?])),
fop: Some(u32::from_le_bytes([byte()?, byte()?, byte()?, byte()?])),
xmm0: Some(u128::from_le_bytes([byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?])),
xmm1: Some(u128::from_le_bytes([byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?])),
......@@ -131,6 +135,9 @@ impl Registers {
xmm14: Some(u128::from_le_bytes([byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?])),
xmm15: Some(u128::from_le_bytes([byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?])),
mxcsr: Some(u32::from_le_bytes([byte()?, byte()?, byte()?, byte()?])),
orig_rax: Some(u64::from_le_bytes([byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?])),
fs_base: Some(u64::from_le_bytes([byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?])),
gs_base: Some(u64::from_le_bytes([byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?, byte()?])),
})
}
#[rustfmt::skip] // formatting can only make this horrible code look worse
......@@ -182,13 +189,13 @@ impl Registers {
write(self.st5.map(u128::to_le_bytes).as_ref().map(|s| &s[..10]), 10);
write(self.st6.map(u128::to_le_bytes).as_ref().map(|s| &s[..10]), 10);
write(self.st7.map(u128::to_le_bytes).as_ref().map(|s| &s[..10]), 10);
write(self.fcw.map(u32::to_le_bytes).as_ref().map(|s| &s[..]), 4);
write(self.fctrl.map(u32::to_le_bytes).as_ref().map(|s| &s[..]), 4);
write(self.fstat.map(u32::to_le_bytes).as_ref().map(|s| &s[..]), 4);
write(self.ftag.map(u32::to_le_bytes).as_ref().map(|s| &s[..]), 4);
write(self.fiseg.map(u32::to_le_bytes).as_ref().map(|s| &s[..]), 4);
write(self.fiofs.map(u32::to_le_bytes).as_ref().map(|s| &s[..]), 4);
write(self.fioff.map(u32::to_le_bytes).as_ref().map(|s| &s[..]), 4);
write(self.foseg.map(u32::to_le_bytes).as_ref().map(|s| &s[..]), 4);
write(self.foofs.map(u32::to_le_bytes).as_ref().map(|s| &s[..]), 4);
write(self.fooff.map(u32::to_le_bytes).as_ref().map(|s| &s[..]), 4);
write(self.fop.map(u32::to_le_bytes).as_ref().map(|s| &s[..]), 4);
write(self.xmm0.map(u128::to_le_bytes).as_ref().map(|s| &s[..]), 16);
write(self.xmm1.map(u128::to_le_bytes).as_ref().map(|s| &s[..]), 16);
......@@ -207,6 +214,9 @@ impl Registers {
write(self.xmm14.map(u128::to_le_bytes).as_ref().map(|s| &s[..]), 16);
write(self.xmm15.map(u128::to_le_bytes).as_ref().map(|s| &s[..]), 16);
write(self.mxcsr.map(u32::to_le_bytes).as_ref().map(|s| &s[..]), 4);
write(self.orig_rax.map(u64::to_le_bytes).as_ref().map(|s| &s[..]), 8);
write(self.fs_base.map(u64::to_le_bytes).as_ref().map(|s| &s[..]), 8);
write(self.gs_base.map(u64::to_le_bytes).as_ref().map(|s| &s[..]), 8);
Ok(())
}
}
......@@ -2,7 +2,9 @@
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<target version="1.0">
<architecture>i386:x86-64</architecture>
<!-- Gotten from gnu-binutils/gdb/regformats/i386/amd64-linux.dat -->
<reg name="rax" bitsize="64" save-restore="no" type="int" group="general" />
<reg name="rax" bitsize="64" save-restore="yes" type="int" group="general" />
<reg name="rbx" bitsize="64" save-restore="yes" type="int" group="general" />
<reg name="rcx" bitsize="64" save-restore="yes" type="int" group="general" />
<reg name="rdx" bitsize="64" save-restore="yes" type="int" group="general" />
......@@ -26,21 +28,21 @@
<reg name="es" bitsize="32" save-restore="yes" type="int" group="general" />
<reg name="fs" bitsize="32" save-restore="yes" type="int" group="general" />
<reg name="gs" bitsize="32" save-restore="yes" type="int" group="general" />
<reg name="st0" bitsize="128" save-restore="yes" type="int" group="general" />
<reg name="st1" bitsize="128" save-restore="yes" type="int" group="general" />
<reg name="st2" bitsize="128" save-restore="yes" type="int" group="general" />
<reg name="st3" bitsize="128" save-restore="yes" type="int" group="general" />
<reg name="st4" bitsize="128" save-restore="yes" type="int" group="general" />
<reg name="st5" bitsize="128" save-restore="yes" type="int" group="general" />
<reg name="st6" bitsize="128" save-restore="yes" type="int" group="general" />
<reg name="st7" bitsize="128" save-restore="yes" type="int" group="general" />
<reg name="fcw" bitsize="32" save-restore="yes" type="float" group="general" />
<reg name="st0" bitsize="80" save-restore="yes" type="float" group="general" />
<reg name="st1" bitsize="80" save-restore="yes" type="float" group="general" />
<reg name="st2" bitsize="80" save-restore="yes" type="float" group="general" />
<reg name="st3" bitsize="80" save-restore="yes" type="float" group="general" />
<reg name="st4" bitsize="80" save-restore="yes" type="float" group="general" />
<reg name="st5" bitsize="80" save-restore="yes" type="float" group="general" />
<reg name="st6" bitsize="80" save-restore="yes" type="float" group="general" />
<reg name="st7" bitsize="80" save-restore="yes" type="float" group="general" />
<reg name="fctrl" bitsize="32" save-restore="yes" type="float" group="general" />
<reg name="fstat" bitsize="32" save-restore="yes" type="float" group="general" />
<reg name="ftag" bitsize="32" save-restore="yes" type="float" group="general" />
<reg name="fiseg" bitsize="32" save-restore="yes" type="float" group="general" />
<reg name="fiofs" bitsize="32" save-restore="yes" type="float" group="general" />
<reg name="fioff" bitsize="32" save-restore="yes" type="float" group="general" />
<reg name="foseg" bitsize="32" save-restore="yes" type="float" group="general" />
<reg name="foofs" bitsize="32" save-restore="yes" type="float" group="general" />
<reg name="fooff" bitsize="32" save-restore="yes" type="float" group="general" />
<reg name="fop" bitsize="32" save-restore="yes" type="float" group="general" />
<reg name="xmm0" bitsize="128" save-restore="yes" type="float" group="general" />
<reg name="xmm1" bitsize="128" save-restore="yes" type="float" group="general" />
......@@ -58,5 +60,8 @@
<reg name="xmm13" bitsize="128" save-restore="yes" type="float" group="general" />
<reg name="xmm14" bitsize="128" save-restore="yes" type="float" group="general" />
<reg name="xmm15" bitsize="128" save-restore="yes" type="float" group="general" />
<reg name="mxcsr" bitsize="128" save-restore="yes" type="float" group="general" />
<reg name="mxcsr" bitsize="32" save-restore="yes" type="float" group="general" />
<reg name="orig_rax" bitsize="64" save-restore="yes" type="int" group="general" />
<reg name="fs_base" bitsize="64" save-restore="yes" type="int" group="general" />
<reg name="gs_base" bitsize="64" save-restore="yes" type="int" group="general" />
</target>
;; Compile with:
;; nasm -f elf64 test.asm -g && ld test.o && ./a.out
global _start
section .data
str: db "Hello, world!", 0xA
len: equ $-str
section .text
_start:
mov rax, 1
mov rdi, 1
mov rsi, str
mov rdx, len
syscall
mov rax, 60
xor rdi, rdi
syscall
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment