diff --git a/examples/armv4t/gdb/mod.rs b/examples/armv4t/gdb/mod.rs
index 0831566..97f7b2d 100644
--- a/examples/armv4t/gdb/mod.rs
+++ b/examples/armv4t/gdb/mod.rs
@@ -314,6 +314,7 @@ impl target::ext::base::single_register_access::SingleRegisterAccess<()> for Emu
);
Ok(buf.len())
}
+ custom_arch::ArmCoreRegIdCustom::Unavailable => Ok(0),
}
}
@@ -341,7 +342,8 @@ impl target::ext::base::single_register_access::SingleRegisterAccess<()> for Emu
Ok(())
}
// ignore writes
- custom_arch::ArmCoreRegIdCustom::Time => Ok(()),
+ custom_arch::ArmCoreRegIdCustom::Unavailable
+ | custom_arch::ArmCoreRegIdCustom::Time => Ok(()),
}
}
}
@@ -460,6 +462,8 @@ mod custom_arch {
// not sent as part of `struct ArmCoreRegsCustom`, and only accessible via the single
// register read/write functions
Time,
+ /// This pseudo-register is valid but never available
+ Unavailable,
}
impl RegId for ArmCoreRegIdCustom {
@@ -467,6 +471,7 @@ mod custom_arch {
let reg = match id {
26 => Self::Custom,
27 => Self::Time,
+ 28 => Self::Unavailable,
_ => {
let (reg, size) = ArmCoreRegId::from_raw_id(id)?;
return Some((Self::Core(reg), size));
@@ -530,6 +535,7 @@ mod custom_arch {
ArmCoreRegIdCustom::Core(ArmCoreRegId::Fps) => "padding",
ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr) => "cpsr",
ArmCoreRegIdCustom::Custom => "custom",
+ ArmCoreRegIdCustom::Unavailable => "Unavailable",
_ => "unknown",
};
let encoding = match r {
@@ -537,6 +543,7 @@ mod custom_arch {
ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp)
| ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc)
| ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr)
+ | ArmCoreRegIdCustom::Unavailable
| ArmCoreRegIdCustom::Custom => Encoding::Uint,
_ => Encoding::Vector,
};
@@ -545,6 +552,7 @@ mod custom_arch {
ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp)
| ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc)
| ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr)
+ | ArmCoreRegIdCustom::Unavailable
| ArmCoreRegIdCustom::Custom => Format::Hex,
_ => Format::VectorUInt8,
};
@@ -555,6 +563,7 @@ mod custom_arch {
ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp)
| ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc)
| ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr)
+ | ArmCoreRegIdCustom::Unavailable
| ArmCoreRegIdCustom::Custom => "General Purpose Registers",
_ => "Floating Point Registers",
};
diff --git a/examples/armv4t/gdb/target_description_xml_override.rs b/examples/armv4t/gdb/target_description_xml_override.rs
index 294b513..2c5348c 100644
--- a/examples/armv4t/gdb/target_description_xml_override.rs
+++ b/examples/armv4t/gdb/target_description_xml_override.rs
@@ -96,5 +96,13 @@ const EXTRA_XML: &str = r#"
this register via the 'p' and 'P' packets respectively
-->
+
+
+
"#;
diff --git a/src/stub/core_impl/single_register_access.rs b/src/stub/core_impl/single_register_access.rs
index fd61c58..cace9d6 100644
--- a/src/stub/core_impl/single_register_access.rs
+++ b/src/stub/core_impl/single_register_access.rs
@@ -33,14 +33,22 @@ impl GdbStubImpl {
let len = ops.read_register(id, reg_id, buf).handle_error()?;
- if let Some(size) = reg_size {
- if size.get() != len {
+ if len == 0 {
+ if let Some(size) = reg_size {
+ res.write_x(size.get())?;
+ } else {
return Err(Error::TargetMismatch);
}
} else {
- buf = buf.get_mut(..len).ok_or(Error::PacketBufferOverflow)?;
+ if let Some(size) = reg_size {
+ if size.get() != len {
+ return Err(Error::TargetMismatch);
+ }
+ } else {
+ buf = buf.get_mut(..len).ok_or(Error::PacketBufferOverflow)?;
+ }
+ res.write_hex_buf(buf)?;
}
- res.write_hex_buf(buf)?;
HandlerStatus::Handled
}
SingleRegisterAccess::P(p) => {
diff --git a/src/target/ext/base/single_register_access.rs b/src/target/ext/base/single_register_access.rs
index f7a9b16..2887fef 100644
--- a/src/target/ext/base/single_register_access.rs
+++ b/src/target/ext/base/single_register_access.rs
@@ -29,7 +29,8 @@ where
/// Implementations should write the value of the register using target's
/// native byte order in the buffer `buf`.
///
- /// Return the number of bytes written into `buf`.
+ /// Return the number of bytes written into `buf` or `0` if the register is
+ /// valid but unavailable.
///
/// If the requested register could not be accessed, an appropriate
/// non-fatal error should be returned.