ReadMemoryCommand.cs
1 //
2 // Copyright (c) 2010-2024 Antmicro
3 //
4 // This file is licensed under the MIT License.
5 // Full license text is available in 'licenses/MIT.txt'.
6 //
7 using System;
8 using System.Text;
9 using Antmicro.Renode.Exceptions;
10 using Endianess = ELFSharp.ELF.Endianess;
11
12 namespace Antmicro.Renode.Utilities.GDB.Commands
13 {
14 internal class ReadMemoryCommand : Command
15 {
ReadMemoryCommand(CommandsManager manager)16 public ReadMemoryCommand(CommandsManager manager) : base(manager)
17 {
18 }
19
20 [Execute("m")]
Execute( [Argument(Separator = B, Encoding = ArgumentAttribute.ArgumentEncoding.HexNumber)]ulong address, [Argument(Encoding = ArgumentAttribute.ArgumentEncoding.HexNumber)]ulong length)21 public PacketData Execute(
22 [Argument(Separator = ',', Encoding = ArgumentAttribute.ArgumentEncoding.HexNumber)]ulong address,
23 [Argument(Encoding = ArgumentAttribute.ArgumentEncoding.HexNumber)]ulong length)
24 {
25 var content = new StringBuilder();
26 var accesses = GetTranslatedAccesses(address, length, write: false);
27
28 if(accesses == null)
29 {
30 return PacketData.ErrorReply(Error.BadAddress);
31 }
32
33 foreach(var access in accesses)
34 {
35 if(manager.Machine.SystemBus.WhatIsAt(access.Address, context: manager.Cpu) == null)
36 {
37 return PacketData.ErrorReply(Error.BadAddress);
38 }
39
40 byte[] data;
41 ulong val;
42 try
43 {
44 switch(access.Length)
45 {
46 case 1:
47 val = manager.Machine.SystemBus.ReadByte(access.Address, context: manager.Cpu);
48 data = BytesFromValue(val, access.Length);
49 break;
50 case 2:
51 val = manager.Machine.SystemBus.ReadWord(access.Address, context: manager.Cpu);
52 data = BytesFromValue(val, access.Length);
53 break;
54 case 4:
55 val = manager.Machine.SystemBus.ReadDoubleWord(access.Address, context: manager.Cpu);
56 data = BytesFromValue(val, access.Length);
57 break;
58 case 8:
59 val = manager.Machine.SystemBus.ReadQuadWord(access.Address, context: manager.Cpu);
60 data = BytesFromValue(val, access.Length);
61 break;
62 default:
63 data = manager.Machine.SystemBus.ReadBytes(access.Address, (int)access.Length, context: manager.Cpu);
64 break;
65 }
66 }
67 catch(RecoverableException)
68 {
69 return PacketData.ErrorReply(Error.BadAddress);
70 }
71
72 foreach(var b in data)
73 {
74 content.AppendFormat("{0:x2}", b);
75 }
76 }
77
78 return new PacketData(content.ToString());
79 }
80
BytesFromValue(ulong val, ulong length)81 private byte [] BytesFromValue(ulong val, ulong length)
82 {
83 return BitHelper.GetBytesFromValue(val, (int)length, manager.Cpu.Endianness == Endianess.LittleEndian);
84 }
85 }
86 }
87