• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::prelude::*;
2 use crate::arch::lldb::Encoding;
3 use crate::arch::lldb::Format;
4 use crate::arch::lldb::Generic;
5 use crate::arch::lldb::Register;
6 use crate::arch::lldb::RegisterInfo as LLDBRegisterInfo;
7 use crate::arch::Arch;
8 use crate::protocol::commands::ext::LldbRegisterInfo;
9 
10 impl<T: Target, C: Connection> GdbStubImpl<T, C> {
handle_lldb_register_info( &mut self, res: &mut ResponseWriter<'_, C>, target: &mut T, command: LldbRegisterInfo, ) -> Result<HandlerStatus, Error<T::Error, C::Error>>11     pub(crate) fn handle_lldb_register_info(
12         &mut self,
13         res: &mut ResponseWriter<'_, C>,
14         target: &mut T,
15         command: LldbRegisterInfo,
16     ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {
17         if !target.use_lldb_register_info() {
18             return Ok(HandlerStatus::Handled);
19         }
20 
21         let handler_status = match command {
22             LldbRegisterInfo::qRegisterInfo(cmd) => {
23                 let mut err = Ok(());
24                 let cb = &mut |reg: Option<Register<'_>>| {
25                     let res = match reg {
26                         // TODO: replace this with a try block (once stabilized)
27                         Some(reg) => (|| {
28                             res.write_str("name:")?;
29                             res.write_str(reg.name)?;
30                             if let Some(alt_name) = reg.alt_name {
31                                 res.write_str(";alt-name:")?;
32                                 res.write_str(alt_name)?;
33                             }
34                             res.write_str(";bitsize:")?;
35                             res.write_dec(reg.bitsize)?;
36                             res.write_str(";offset:")?;
37                             res.write_dec(reg.offset)?;
38                             res.write_str(";encoding:")?;
39                             res.write_str(match reg.encoding {
40                                 Encoding::Uint => "uint",
41                                 Encoding::Sint => "sint",
42                                 Encoding::IEEE754 => "ieee754",
43                                 Encoding::Vector => "vector",
44                             })?;
45                             res.write_str(";format:")?;
46                             res.write_str(match reg.format {
47                                 Format::Binary => "binary",
48                                 Format::Decimal => "decimal",
49                                 Format::Hex => "hex",
50                                 Format::Float => "float",
51                                 Format::VectorSInt8 => "vector-sint8",
52                                 Format::VectorUInt8 => "vector-uint8",
53                                 Format::VectorSInt16 => "vector-sint16",
54                                 Format::VectorUInt16 => "vector-uint16",
55                                 Format::VectorSInt32 => "vector-sint32",
56                                 Format::VectorUInt32 => "vector-uint32",
57                                 Format::VectorFloat32 => "vector-float32",
58                                 Format::VectorUInt128 => "vector-uint128",
59                             })?;
60                             res.write_str(";set:")?;
61                             res.write_str(reg.set)?;
62                             if let Some(gcc) = reg.gcc {
63                                 res.write_str(";gcc:")?;
64                                 res.write_dec(gcc)?;
65                             }
66                             if let Some(dwarf) = reg.dwarf {
67                                 res.write_str(";dwarf:")?;
68                                 res.write_dec(dwarf)?;
69                             }
70                             if let Some(generic) = reg.generic {
71                                 res.write_str(";generic:")?;
72                                 res.write_str(match generic {
73                                     Generic::Pc => "pc",
74                                     Generic::Sp => "sp",
75                                     Generic::Fp => "fp",
76                                     Generic::Ra => "ra",
77                                     Generic::Flags => "flags",
78                                     Generic::Arg1 => "arg1",
79                                     Generic::Arg2 => "arg2",
80                                     Generic::Arg3 => "arg3",
81                                     Generic::Arg4 => "arg4",
82                                     Generic::Arg5 => "arg5",
83                                     Generic::Arg6 => "arg6",
84                                     Generic::Arg7 => "arg7",
85                                     Generic::Arg8 => "arg8",
86                                 })?;
87                             }
88                             if let Some(c_regs) = reg.container_regs {
89                                 res.write_str(";container-regs:")?;
90                                 res.write_num(c_regs[0])?;
91                                 for reg in c_regs.iter().skip(1) {
92                                     res.write_str(",")?;
93                                     res.write_num(*reg)?;
94                                 }
95                             }
96                             if let Some(i_regs) = reg.invalidate_regs {
97                                 res.write_str(";invalidate-regs:")?;
98                                 res.write_num(i_regs[0])?;
99                                 for reg in i_regs.iter().skip(1) {
100                                     res.write_str(",")?;
101                                     res.write_num(*reg)?;
102                                 }
103                             }
104                             res.write_str(";")
105                         })(),
106                         // In fact, this doesn't has to be E45! It could equally well be any
107                         // other error code or even an eOk, eAck or eNack! It turns out that
108                         // 0x45 == 69, so presumably the LLDB people were just having some fun
109                         // here. For a little discussion on this and LLDB source code pointers,
110                         // see https://github.com/daniel5151/gdbstub/pull/103#discussion_r888590197
111                         _ => res.write_str("E45"),
112                     };
113                     if let Err(e) = res {
114                         err = Err(e);
115                     }
116                 };
117                 if let Some(ops) = target.support_lldb_register_info_override() {
118                     use crate::target::ext::lldb_register_info_override::Callback;
119                     use crate::target::ext::lldb_register_info_override::CallbackToken;
120 
121                     ops.lldb_register_info(
122                         cmd.reg_id,
123                         Callback {
124                             cb,
125                             token: CallbackToken(core::marker::PhantomData),
126                         },
127                     )
128                     .map_err(Error::TargetError)?;
129                     err?;
130                 } else if let Some(reg) = T::Arch::lldb_register_info(cmd.reg_id) {
131                     match reg {
132                         LLDBRegisterInfo::Register(reg) => cb(Some(reg)),
133                         LLDBRegisterInfo::Done => cb(None),
134                     };
135                 }
136                 HandlerStatus::Handled
137             }
138         };
139 
140         Ok(handler_status)
141     }
142 }
143