|
@@ -27,7 +27,7 @@
|
27
|
27
|
#include <stddef.h>
|
28
|
28
|
#include <stdio.h>
|
29
|
29
|
#include <ctype.h>
|
30
|
|
-#include <assert.h>
|
|
30
|
+#include <byteswap.h>
|
31
|
31
|
#include <gpxe/process.h>
|
32
|
32
|
#include <gpxe/serial.h>
|
33
|
33
|
#include "gdbmach.h"
|
|
@@ -67,20 +67,60 @@ static uint8_t gdbstub_to_hex_digit ( uint8_t b ) {
|
67
|
67
|
return ( b < 0xa ? '0' : 'a' - 0xa ) + b;
|
68
|
68
|
}
|
69
|
69
|
|
70
|
|
-static void gdbstub_from_hex_buf ( char *dst, char *src, int len ) {
|
71
|
|
- while ( len-- > 0 ) {
|
72
|
|
- *dst = gdbstub_from_hex_digit ( *src++ );
|
73
|
|
- if ( len-- > 0 ) {
|
74
|
|
- *dst = (*dst << 4) | gdbstub_from_hex_digit ( *src++ );
|
|
70
|
+/*
|
|
71
|
+ * To make reading/writing device memory atomic, we check for
|
|
72
|
+ * 2- or 4-byte aligned operations and handle them specially.
|
|
73
|
+ */
|
|
74
|
+
|
|
75
|
+static void gdbstub_from_hex_buf ( char *dst, char *src, int lenbytes ) {
|
|
76
|
+ if ( lenbytes == 2 && ( ( unsigned long ) dst & 0x1 ) == 0 ) {
|
|
77
|
+ uint16_t i = gdbstub_from_hex_digit ( src [ 2 ] ) << 12 |
|
|
78
|
+ gdbstub_from_hex_digit ( src [ 3 ] ) << 8 |
|
|
79
|
+ gdbstub_from_hex_digit ( src [ 0 ] ) << 4 |
|
|
80
|
+ gdbstub_from_hex_digit ( src [ 1 ] );
|
|
81
|
+ * ( uint16_t * ) dst = cpu_to_le16 ( i );
|
|
82
|
+ } else if ( lenbytes == 4 && ( ( unsigned long ) dst & 0x3 ) == 0 ) {
|
|
83
|
+ uint32_t i = gdbstub_from_hex_digit ( src [ 6 ] ) << 28 |
|
|
84
|
+ gdbstub_from_hex_digit ( src [ 7 ] ) << 24 |
|
|
85
|
+ gdbstub_from_hex_digit ( src [ 4 ] ) << 20 |
|
|
86
|
+ gdbstub_from_hex_digit ( src [ 5 ] ) << 16 |
|
|
87
|
+ gdbstub_from_hex_digit ( src [ 2 ] ) << 12 |
|
|
88
|
+ gdbstub_from_hex_digit ( src [ 3 ] ) << 8 |
|
|
89
|
+ gdbstub_from_hex_digit ( src [ 0 ] ) << 4 |
|
|
90
|
+ gdbstub_from_hex_digit ( src [ 1 ] );
|
|
91
|
+ * ( uint32_t * ) dst = cpu_to_le32 ( i );
|
|
92
|
+ } else {
|
|
93
|
+ while ( lenbytes-- > 0 ) {
|
|
94
|
+ *dst++ = gdbstub_from_hex_digit ( src [ 0 ] ) << 4 |
|
|
95
|
+ gdbstub_from_hex_digit ( src [ 1 ] );
|
|
96
|
+ src += 2;
|
75
|
97
|
}
|
76
|
|
- dst++;
|
77
|
98
|
}
|
78
|
99
|
}
|
79
|
100
|
|
80
|
|
-static void gdbstub_to_hex_buf ( char *dst, char *src, int len ) {
|
81
|
|
- while ( len-- > 0 ) {
|
82
|
|
- *dst++ = gdbstub_to_hex_digit ( *src >> 4 );
|
83
|
|
- *dst++ = gdbstub_to_hex_digit ( *src++ );
|
|
101
|
+static void gdbstub_to_hex_buf ( char *dst, char *src, int lenbytes ) {
|
|
102
|
+ if ( lenbytes == 2 && ( ( unsigned long ) src & 0x1 ) == 0 ) {
|
|
103
|
+ uint16_t i = cpu_to_le16 ( * ( uint16_t * ) src );
|
|
104
|
+ dst [ 0 ] = gdbstub_to_hex_digit ( i >> 4 );
|
|
105
|
+ dst [ 1 ] = gdbstub_to_hex_digit ( i );
|
|
106
|
+ dst [ 2 ] = gdbstub_to_hex_digit ( i >> 12 );
|
|
107
|
+ dst [ 3 ] = gdbstub_to_hex_digit ( i >> 8 );
|
|
108
|
+ } else if ( lenbytes == 4 && ( ( unsigned long ) src & 0x3 ) == 0 ) {
|
|
109
|
+ uint32_t i = cpu_to_le32 ( * ( uint32_t * ) src );
|
|
110
|
+ dst [ 0 ] = gdbstub_to_hex_digit ( i >> 4 );
|
|
111
|
+ dst [ 1 ] = gdbstub_to_hex_digit ( i );
|
|
112
|
+ dst [ 2 ] = gdbstub_to_hex_digit ( i >> 12 );
|
|
113
|
+ dst [ 3 ] = gdbstub_to_hex_digit ( i >> 8 );
|
|
114
|
+ dst [ 4 ] = gdbstub_to_hex_digit ( i >> 20 );
|
|
115
|
+ dst [ 5 ] = gdbstub_to_hex_digit ( i >> 16);
|
|
116
|
+ dst [ 6 ] = gdbstub_to_hex_digit ( i >> 28 );
|
|
117
|
+ dst [ 7 ] = gdbstub_to_hex_digit ( i >> 24 );
|
|
118
|
+ } else {
|
|
119
|
+ while ( lenbytes-- > 0 ) {
|
|
120
|
+ *dst++ = gdbstub_to_hex_digit ( *src >> 4 );
|
|
121
|
+ *dst++ = gdbstub_to_hex_digit ( *src );
|
|
122
|
+ src++;
|
|
123
|
+ }
|
84
|
124
|
}
|
85
|
125
|
}
|
86
|
126
|
|
|
@@ -179,7 +219,7 @@ static void gdbstub_write_regs ( struct gdbstub *stub ) {
|
179
|
219
|
gdbstub_send_errno ( stub, POSIX_EINVAL );
|
180
|
220
|
return;
|
181
|
221
|
}
|
182
|
|
- gdbstub_from_hex_buf ( ( char * ) stub->regs, &stub->payload [ 1 ], stub->len );
|
|
222
|
+ gdbstub_from_hex_buf ( ( char * ) stub->regs, &stub->payload [ 1 ], GDBMACH_SIZEOF_REGS );
|
183
|
223
|
gdbstub_send_ok ( stub );
|
184
|
224
|
}
|
185
|
225
|
|
|
@@ -204,7 +244,7 @@ static void gdbstub_write_mem ( struct gdbstub *stub ) {
|
204
|
244
|
gdbstub_send_errno ( stub, POSIX_EINVAL );
|
205
|
245
|
return;
|
206
|
246
|
}
|
207
|
|
- gdbstub_from_hex_buf ( ( char * ) args [ 0 ], &stub->payload [ colon + 1 ], stub->len - colon - 1 );
|
|
247
|
+ gdbstub_from_hex_buf ( ( char * ) args [ 0 ], &stub->payload [ colon + 1 ], ( stub->len - colon - 1 ) / 2 );
|
208
|
248
|
gdbstub_send_ok ( stub );
|
209
|
249
|
}
|
210
|
250
|
|