forked from msysgit/msysgit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgdb.info-4
4214 lines (3840 loc) · 249 KB
/
gdb.info-4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
This is gdb.info, produced by makeinfo version 4.8 from
../.././gdb/doc/gdb.texinfo.
INFO-DIR-SECTION Software development
START-INFO-DIR-ENTRY
* Gdb: (gdb). The GNU debugger.
END-INFO-DIR-ENTRY
This file documents the GNU debugger GDB.
This is the Ninth Edition, of `Debugging with GDB: the GNU
Source-Level Debugger' for GDB Version 6.8.
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with the
Invariant Sections being "Free Software" and "Free Software Needs Free
Documentation", with the Front-Cover Texts being "A GNU Manual," and
with the Back-Cover Texts as in (a) below.
(a) The FSF's Back-Cover Text is: "You are free to copy and modify
this GNU Manual. Buying copies from GNU Press supports the FSF in
developing GNU and promoting software freedom."
File: gdb.info, Node: Bytecode Descriptions, Next: Using Agent Expressions, Prev: General Bytecode Design, Up: Agent Expressions
E.2 Bytecode Descriptions
=========================
Each bytecode description has the following form:
`add' (0x02): A B => A+B
Pop the top two stack items, A and B, as integers; push their sum,
as an integer.
In this example, `add' is the name of the bytecode, and `(0x02)' is
the one-byte value used to encode the bytecode, in hexadecimal. The
phrase "A B => A+B" shows the stack before and after the bytecode
executes. Beforehand, the stack must contain at least two values, A
and B; since the top of the stack is to the right, B is on the top of
the stack, and A is underneath it. After execution, the bytecode will
have popped A and B from the stack, and replaced them with a single
value, A+B. There may be other values on the stack below those shown,
but the bytecode affects only those shown.
Here is another example:
`const8' (0x22) N: => N
Push the 8-bit integer constant N on the stack, without sign
extension.
In this example, the bytecode `const8' takes an operand N directly
from the bytecode stream; the operand follows the `const8' bytecode
itself. We write any such operands immediately after the name of the
bytecode, before the colon, and describe the exact encoding of the
operand in the bytecode stream in the body of the bytecode description.
For the `const8' bytecode, there are no stack items given before the
=>; this simply means that the bytecode consumes no values from the
stack. If a bytecode consumes no values, or produces no values, the
list on either side of the => may be empty.
If a value is written as A, B, or N, then the bytecode treats it as
an integer. If a value is written is ADDR, then the bytecode treats it
as an address.
We do not fully describe the floating point operations here; although
this design can be extended in a clean way to handle floating point
values, they are not of immediate interest to the customer, so we avoid
describing them, to save time.
`float' (0x01): =>
Prefix for floating-point bytecodes. Not implemented yet.
`add' (0x02): A B => A+B
Pop two integers from the stack, and push their sum, as an integer.
`sub' (0x03): A B => A-B
Pop two integers from the stack, subtract the top value from the
next-to-top value, and push the difference.
`mul' (0x04): A B => A*B
Pop two integers from the stack, multiply them, and push the
product on the stack. Note that, when one multiplies two N-bit
numbers yielding another N-bit number, it is irrelevant whether the
numbers are signed or not; the results are the same.
`div_signed' (0x05): A B => A/B
Pop two signed integers from the stack; divide the next-to-top
value by the top value, and push the quotient. If the divisor is
zero, terminate with an error.
`div_unsigned' (0x06): A B => A/B
Pop two unsigned integers from the stack; divide the next-to-top
value by the top value, and push the quotient. If the divisor is
zero, terminate with an error.
`rem_signed' (0x07): A B => A MODULO B
Pop two signed integers from the stack; divide the next-to-top
value by the top value, and push the remainder. If the divisor is
zero, terminate with an error.
`rem_unsigned' (0x08): A B => A MODULO B
Pop two unsigned integers from the stack; divide the next-to-top
value by the top value, and push the remainder. If the divisor is
zero, terminate with an error.
`lsh' (0x09): A B => A<<B
Pop two integers from the stack; let A be the next-to-top value,
and B be the top value. Shift A left by B bits, and push the
result.
`rsh_signed' (0x0a): A B => `(signed)'A>>B
Pop two integers from the stack; let A be the next-to-top value,
and B be the top value. Shift A right by B bits, inserting copies
of the top bit at the high end, and push the result.
`rsh_unsigned' (0x0b): A B => A>>B
Pop two integers from the stack; let A be the next-to-top value,
and B be the top value. Shift A right by B bits, inserting zero
bits at the high end, and push the result.
`log_not' (0x0e): A => !A
Pop an integer from the stack; if it is zero, push the value one;
otherwise, push the value zero.
`bit_and' (0x0f): A B => A&B
Pop two integers from the stack, and push their bitwise `and'.
`bit_or' (0x10): A B => A|B
Pop two integers from the stack, and push their bitwise `or'.
`bit_xor' (0x11): A B => A^B
Pop two integers from the stack, and push their bitwise
exclusive-`or'.
`bit_not' (0x12): A => ~A
Pop an integer from the stack, and push its bitwise complement.
`equal' (0x13): A B => A=B
Pop two integers from the stack; if they are equal, push the value
one; otherwise, push the value zero.
`less_signed' (0x14): A B => A<B
Pop two signed integers from the stack; if the next-to-top value
is less than the top value, push the value one; otherwise, push
the value zero.
`less_unsigned' (0x15): A B => A<B
Pop two unsigned integers from the stack; if the next-to-top value
is less than the top value, push the value one; otherwise, push
the value zero.
`ext' (0x16) N: A => A, sign-extended from N bits
Pop an unsigned value from the stack; treating it as an N-bit
twos-complement value, extend it to full length. This means that
all bits to the left of bit N-1 (where the least significant bit
is bit 0) are set to the value of bit N-1. Note that N may be
larger than or equal to the width of the stack elements of the
bytecode engine; in this case, the bytecode should have no effect.
The number of source bits to preserve, N, is encoded as a single
byte unsigned integer following the `ext' bytecode.
`zero_ext' (0x2a) N: A => A, zero-extended from N bits
Pop an unsigned value from the stack; zero all but the bottom N
bits. This means that all bits to the left of bit N-1 (where the
least significant bit is bit 0) are set to the value of bit N-1.
The number of source bits to preserve, N, is encoded as a single
byte unsigned integer following the `zero_ext' bytecode.
`ref8' (0x17): ADDR => A
`ref16' (0x18): ADDR => A
`ref32' (0x19): ADDR => A
`ref64' (0x1a): ADDR => A
Pop an address ADDR from the stack. For bytecode `ref'N, fetch an
N-bit value from ADDR, using the natural target endianness. Push
the fetched value as an unsigned integer.
Note that ADDR may not be aligned in any particular way; the
`refN' bytecodes should operate correctly for any address.
If attempting to access memory at ADDR would cause a processor
exception of some sort, terminate with an error.
`ref_float' (0x1b): ADDR => D
`ref_double' (0x1c): ADDR => D
`ref_long_double' (0x1d): ADDR => D
`l_to_d' (0x1e): A => D
`d_to_l' (0x1f): D => A
Not implemented yet.
`dup' (0x28): A => A A
Push another copy of the stack's top element.
`swap' (0x2b): A B => B A
Exchange the top two items on the stack.
`pop' (0x29): A =>
Discard the top value on the stack.
`if_goto' (0x20) OFFSET: A =>
Pop an integer off the stack; if it is non-zero, branch to the
given offset in the bytecode string. Otherwise, continue to the
next instruction in the bytecode stream. In other words, if A is
non-zero, set the `pc' register to `start' + OFFSET. Thus, an
offset of zero denotes the beginning of the expression.
The OFFSET is stored as a sixteen-bit unsigned value, stored
immediately following the `if_goto' bytecode. It is always stored
most significant byte first, regardless of the target's normal
endianness. The offset is not guaranteed to fall at any particular
alignment within the bytecode stream; thus, on machines where
fetching a 16-bit on an unaligned address raises an exception, you
should fetch the offset one byte at a time.
`goto' (0x21) OFFSET: =>
Branch unconditionally to OFFSET; in other words, set the `pc'
register to `start' + OFFSET.
The offset is stored in the same way as for the `if_goto' bytecode.
`const8' (0x22) N: => N
`const16' (0x23) N: => N
`const32' (0x24) N: => N
`const64' (0x25) N: => N
Push the integer constant N on the stack, without sign extension.
To produce a small negative value, push a small twos-complement
value, and then sign-extend it using the `ext' bytecode.
The constant N is stored in the appropriate number of bytes
following the `const'B bytecode. The constant N is always stored
most significant byte first, regardless of the target's normal
endianness. The constant is not guaranteed to fall at any
particular alignment within the bytecode stream; thus, on machines
where fetching a 16-bit on an unaligned address raises an
exception, you should fetch N one byte at a time.
`reg' (0x26) N: => A
Push the value of register number N, without sign extension. The
registers are numbered following GDB's conventions.
The register number N is encoded as a 16-bit unsigned integer
immediately following the `reg' bytecode. It is always stored most
significant byte first, regardless of the target's normal
endianness. The register number is not guaranteed to fall at any
particular alignment within the bytecode stream; thus, on machines
where fetching a 16-bit on an unaligned address raises an
exception, you should fetch the register number one byte at a time.
`trace' (0x0c): ADDR SIZE =>
Record the contents of the SIZE bytes at ADDR in a trace buffer,
for later retrieval by GDB.
`trace_quick' (0x0d) SIZE: ADDR => ADDR
Record the contents of the SIZE bytes at ADDR in a trace buffer,
for later retrieval by GDB. SIZE is a single byte unsigned
integer following the `trace' opcode.
This bytecode is equivalent to the sequence `dup const8 SIZE
trace', but we provide it anyway to save space in bytecode strings.
`trace16' (0x30) SIZE: ADDR => ADDR
Identical to trace_quick, except that SIZE is a 16-bit big-endian
unsigned integer, not a single byte. This should probably have
been named `trace_quick16', for consistency.
`end' (0x27): =>
Stop executing bytecode; the result should be the top element of
the stack. If the purpose of the expression was to compute an
lvalue or a range of memory, then the next-to-top of the stack is
the lvalue's address, and the top of the stack is the lvalue's
size, in bytes.
File: gdb.info, Node: Using Agent Expressions, Next: Varying Target Capabilities, Prev: Bytecode Descriptions, Up: Agent Expressions
E.3 Using Agent Expressions
===========================
Here is a sketch of a full non-stop debugging cycle, showing how agent
expressions fit into the process.
* The user selects trace points in the program's code at which GDB
should collect data.
* The user specifies expressions to evaluate at each trace point.
These expressions may denote objects in memory, in which case
those objects' contents are recorded as the program runs, or
computed values, in which case the values themselves are recorded.
* GDB transmits the tracepoints and their associated expressions to
the GDB agent, running on the debugging target.
* The agent arranges to be notified when a trace point is hit. Note
that, on some systems, the target operating system is completely
responsible for collecting the data; see *Note Tracing on
Symmetrix::.
* When execution on the target reaches a trace point, the agent
evaluates the expressions associated with that trace point, and
records the resulting values and memory ranges.
* Later, when the user selects a given trace event and inspects the
objects and expression values recorded, GDB talks to the agent to
retrieve recorded data as necessary to meet the user's requests.
If the user asks to see an object whose contents have not been
recorded, GDB reports an error.
File: gdb.info, Node: Varying Target Capabilities, Next: Tracing on Symmetrix, Prev: Using Agent Expressions, Up: Agent Expressions
E.4 Varying Target Capabilities
===============================
Some targets don't support floating-point, and some would rather not
have to deal with `long long' operations. Also, different targets will
have different stack sizes, and different bytecode buffer lengths.
Thus, GDB needs a way to ask the target about itself. We haven't
worked out the details yet, but in general, GDB should be able to send
the target a packet asking it to describe itself. The reply should be a
packet whose length is explicit, so we can add new information to the
packet in future revisions of the agent, without confusing old versions
of GDB, and it should contain a version number. It should contain at
least the following information:
* whether floating point is supported
* whether `long long' is supported
* maximum acceptable size of bytecode stack
* maximum acceptable length of bytecode expressions
* which registers are actually available for collection
* whether the target supports disabled tracepoints
File: gdb.info, Node: Tracing on Symmetrix, Next: Rationale, Prev: Varying Target Capabilities, Up: Agent Expressions
E.5 Tracing on Symmetrix
========================
This section documents the API used by the GDB agent to collect data on
Symmetrix systems.
Cygnus originally implemented these tracing features to help EMC
Corporation debug their Symmetrix high-availability disk drives. The
Symmetrix application code already includes substantial tracing
facilities; the GDB agent for the Symmetrix system uses those facilities
for its own data collection, via the API described here.
-- Function: DTC_RESPONSE adbg_find_memory_in_frame (FRAME_DEF *FRAME,
char *ADDRESS, char **BUFFER, unsigned int *SIZE)
Search the trace frame FRAME for memory saved from ADDRESS. If
the memory is available, provide the address of the buffer holding
it; otherwise, provide the address of the next saved area.
* If the memory at ADDRESS was saved in FRAME, set `*BUFFER' to
point to the buffer in which that memory was saved, set
`*SIZE' to the number of bytes from ADDRESS that are saved at
`*BUFFER', and return `OK_TARGET_RESPONSE'. (Clearly, in
this case, the function will always set `*SIZE' to a value
greater than zero.)
* If FRAME does not record any memory at ADDRESS, set `*SIZE'
to the distance from ADDRESS to the start of the saved region
with the lowest address higher than ADDRESS. If there is no
memory saved from any higher address, set `*SIZE' to zero.
Return `NOT_FOUND_TARGET_RESPONSE'.
These two possibilities allow the caller to either retrieve the
data, or walk the address space to the next saved area.
This function allows the GDB agent to map the regions of memory
saved in a particular frame, and retrieve their contents efficiently.
This function also provides a clean interface between the GDB agent
and the Symmetrix tracing structures, making it easier to adapt the GDB
agent to future versions of the Symmetrix system, and vice versa. This
function searches all data saved in FRAME, whether the data is there at
the request of a bytecode expression, or because it falls in one of the
format's memory ranges, or because it was saved from the top of the
stack. EMC can arbitrarily change and enhance the tracing mechanism,
but as long as this function works properly, all collected memory is
visible to GDB.
The function itself is straightforward to implement. A single pass
over the trace frame's stack area, memory ranges, and expression blocks
can yield the address of the buffer (if the requested address was
saved), and also note the address of the next higher range of memory,
to be returned when the search fails.
As an example, suppose the trace frame `f' has saved sixteen bytes
from address `0x8000' in a buffer at `0x1000', and thirty-two bytes
from address `0xc000' in a buffer at `0x1010'. Here are some sample
calls, and the effect each would have:
`adbg_find_memory_in_frame (f, (char*) 0x8000, &buffer, &size)'
This would set `buffer' to `0x1000', set `size' to sixteen, and
return `OK_TARGET_RESPONSE', since `f' saves sixteen bytes from
`0x8000' at `0x1000'.
`adbg_find_memory_in_frame (f, (char *) 0x8004, &buffer, &size)'
This would set `buffer' to `0x1004', set `size' to twelve, and
return `OK_TARGET_RESPONSE', since `f' saves the twelve bytes from
`0x8004' starting four bytes into the buffer at `0x1000'. This
shows that request addresses may fall in the middle of saved
areas; the function should return the address and size of the
remainder of the buffer.
`adbg_find_memory_in_frame (f, (char *) 0x8100, &buffer, &size)'
This would set `size' to `0x3f00' and return
`NOT_FOUND_TARGET_RESPONSE', since there is no memory saved in `f'
from the address `0x8100', and the next memory available is at
`0x8100 + 0x3f00', or `0xc000'. This shows that request addresses
may fall outside of all saved memory ranges; the function should
indicate the next saved area, if any.
`adbg_find_memory_in_frame (f, (char *) 0x7000, &buffer, &size)'
This would set `size' to `0x1000' and return
`NOT_FOUND_TARGET_RESPONSE', since the next saved memory is at
`0x7000 + 0x1000', or `0x8000'.
`adbg_find_memory_in_frame (f, (char *) 0xf000, &buffer, &size)'
This would set `size' to zero, and return
`NOT_FOUND_TARGET_RESPONSE'. This shows how the function tells the
caller that no further memory ranges have been saved.
As another example, here is a function which will print out the
addresses of all memory saved in the trace frame `frame' on the
Symmetrix INLINES console:
void
print_frame_addresses (FRAME_DEF *frame)
{
char *addr;
char *buffer;
unsigned long size;
addr = 0;
for (;;)
{
/* Either find out how much memory we have here, or discover
where the next saved region is. */
if (adbg_find_memory_in_frame (frame, addr, &buffer, &size)
== OK_TARGET_RESPONSE)
printp ("saved %x to %x\n", addr, addr + size);
if (size == 0)
break;
addr += size;
}
}
Note that there is not necessarily any connection between the order
in which the data is saved in the trace frame, and the order in which
`adbg_find_memory_in_frame' will return those memory ranges. The code
above will always print the saved memory regions in order of increasing
address, while the underlying frame structure might store the data in a
random order.
[[This section should cover the rest of the Symmetrix functions the
stub relies upon, too.]]
File: gdb.info, Node: Rationale, Prev: Tracing on Symmetrix, Up: Agent Expressions
E.6 Rationale
=============
Some of the design decisions apparent above are arguable.
What about stack overflow/underflow?
GDB should be able to query the target to discover its stack size.
Given that information, GDB can determine at translation time
whether a given expression will overflow the stack. But this spec
isn't about what kinds of error-checking GDB ought to do.
Why are you doing everything in LONGEST?
Speed isn't important, but agent code size is; using LONGEST
brings in a bunch of support code to do things like division, etc.
So this is a serious concern.
First, note that you don't need different bytecodes for different
operand sizes. You can generate code without _knowing_ how big the
stack elements actually are on the target. If the target only
supports 32-bit ints, and you don't send any 64-bit bytecodes,
everything just works. The observation here is that the MIPS and
the Alpha have only fixed-size registers, and you can still get
C's semantics even though most instructions only operate on
full-sized words. You just need to make sure everything is
properly sign-extended at the right times. So there is no need
for 32- and 64-bit variants of the bytecodes. Just implement
everything using the largest size you support.
GDB should certainly check to see what sizes the target supports,
so the user can get an error earlier, rather than later. But this
information is not necessary for correctness.
Why don't you have `>' or `<=' operators?
I want to keep the interpreter small, and we don't need them. We
can combine the `less_' opcodes with `log_not', and swap the order
of the operands, yielding all four asymmetrical comparison
operators. For example, `(x <= y)' is `! (x > y)', which is `! (y
< x)'.
Why do you have `log_not'?
Why do you have `ext'?
Why do you have `zero_ext'?
These are all easily synthesized from other instructions, but I
expect them to be used frequently, and they're simple, so I
include them to keep bytecode strings short.
`log_not' is equivalent to `const8 0 equal'; it's used in half the
relational operators.
`ext N' is equivalent to `const8 S-N lsh const8 S-N rsh_signed',
where S is the size of the stack elements; it follows `refM' and
REG bytecodes when the value should be signed. See the next
bulleted item.
`zero_ext N' is equivalent to `constM MASK log_and'; it's used
whenever we push the value of a register, because we can't assume
the upper bits of the register aren't garbage.
Why not have sign-extending variants of the `ref' operators?
Because that would double the number of `ref' operators, and we
need the `ext' bytecode anyway for accessing bitfields.
Why not have constant-address variants of the `ref' operators?
Because that would double the number of `ref' operators again, and
`const32 ADDRESS ref32' is only one byte longer.
Why do the `refN' operators have to support unaligned fetches?
GDB will generate bytecode that fetches multi-byte values at
unaligned addresses whenever the executable's debugging
information tells it to. Furthermore, GDB does not know the value
the pointer will have when GDB generates the bytecode, so it
cannot determine whether a particular fetch will be aligned or not.
In particular, structure bitfields may be several bytes long, but
follow no alignment rules; members of packed structures are not
necessarily aligned either.
In general, there are many cases where unaligned references occur
in correct C code, either at the programmer's explicit request, or
at the compiler's discretion. Thus, it is simpler to make the GDB
agent bytecodes work correctly in all circumstances than to make
GDB guess in each case whether the compiler did the usual thing.
Why are there no side-effecting operators?
Because our current client doesn't want them? That's a cheap
answer. I think the real answer is that I'm afraid of
implementing function calls. We should re-visit this issue after
the present contract is delivered.
Why aren't the `goto' ops PC-relative?
The interpreter has the base address around anyway for PC bounds
checking, and it seemed simpler.
Why is there only one offset size for the `goto' ops?
Offsets are currently sixteen bits. I'm not happy with this
situation either:
Suppose we have multiple branch ops with different offset sizes.
As I generate code left-to-right, all my jumps are forward jumps
(there are no loops in expressions), so I never know the target
when I emit the jump opcode. Thus, I have to either always assume
the largest offset size, or do jump relaxation on the code after I
generate it, which seems like a big waste of time.
I can imagine a reasonable expression being longer than 256 bytes.
I can't imagine one being longer than 64k. Thus, we need 16-bit
offsets. This kind of reasoning is so bogus, but relaxation is
pathetic.
The other approach would be to generate code right-to-left. Then
I'd always know my offset size. That might be fun.
Where is the function call bytecode?
When we add side-effects, we should add this.
Why does the `reg' bytecode take a 16-bit register number?
Intel's IA-64 architecture has 128 general-purpose registers, and
128 floating-point registers, and I'm sure it has some random
control registers.
Why do we need `trace' and `trace_quick'?
Because GDB needs to record all the memory contents and registers
an expression touches. If the user wants to evaluate an expression
`x->y->z', the agent must record the values of `x' and `x->y' as
well as the value of `x->y->z'.
Don't the `trace' bytecodes make the interpreter less general?
They do mean that the interpreter contains special-purpose code,
but that doesn't mean the interpreter can only be used for that
purpose. If an expression doesn't use the `trace' bytecodes, they
don't get in its way.
Why doesn't `trace_quick' consume its arguments the way everything else does?
In general, you do want your operators to consume their arguments;
it's consistent, and generally reduces the amount of stack
rearrangement necessary. However, `trace_quick' is a kludge to
save space; it only exists so we needn't write `dup const8 SIZE
trace' before every memory reference. Therefore, it's okay for it
not to consume its arguments; it's meant for a specific context in
which we know exactly what it should do with the stack. If we're
going to have a kludge, it should be an effective kludge.
Why does `trace16' exist?
That opcode was added by the customer that contracted Cygnus for
the data tracing work. I personally think it is unnecessary;
objects that large will be quite rare, so it is okay to use `dup
const16 SIZE trace' in those cases.
Whatever we decide to do with `trace16', we should at least leave
opcode 0x30 reserved, to remain compatible with the customer who
added it.
File: gdb.info, Node: Target Descriptions, Next: Copying, Prev: Agent Expressions, Up: Top
Appendix F Target Descriptions
******************************
*Warning:* target descriptions are still under active development, and
the contents and format may change between GDB releases. The format is
expected to stabilize in the future.
One of the challenges of using GDB to debug embedded systems is that
there are so many minor variants of each processor architecture in use.
It is common practice for vendors to start with a standard processor
core -- ARM, PowerPC, or MIPS, for example -- and then make changes to
adapt it to a particular market niche. Some architectures have
hundreds of variants, available from dozens of vendors. This leads to
a number of problems:
* With so many different customized processors, it is difficult for
the GDB maintainers to keep up with the changes.
* Since individual variants may have short lifetimes or limited
audiences, it may not be worthwhile to carry information about
every variant in the GDB source tree.
* When GDB does support the architecture of the embedded system at
hand, the task of finding the correct architecture name to give the
`set architecture' command can be error-prone.
To address these problems, the GDB remote protocol allows a target
system to not only identify itself to GDB, but to actually describe its
own features. This lets GDB support processor variants it has never
seen before -- to the extent that the descriptions are accurate, and
that GDB understands them.
GDB must be linked with the Expat library to support XML target
descriptions. *Note Expat::.
* Menu:
* Retrieving Descriptions:: How descriptions are fetched from a target.
* Target Description Format:: The contents of a target description.
* Predefined Target Types:: Standard types available for target
descriptions.
* Standard Target Features:: Features GDB knows about.
File: gdb.info, Node: Retrieving Descriptions, Next: Target Description Format, Up: Target Descriptions
F.1 Retrieving Descriptions
===========================
Target descriptions can be read from the target automatically, or
specified by the user manually. The default behavior is to read the
description from the target. GDB retrieves it via the remote protocol
using `qXfer' requests (*note qXfer: General Query Packets.). The
ANNEX in the `qXfer' packet will be `target.xml'. The contents of the
`target.xml' annex are an XML document, of the form described in *Note
Target Description Format::.
Alternatively, you can specify a file to read for the target
description. If a file is set, the target will not be queried. The
commands to specify a file are:
`set tdesc filename PATH'
Read the target description from PATH.
`unset tdesc filename'
Do not read the XML target description from a file. GDB will use
the description supplied by the current target.
`show tdesc filename'
Show the filename to read for a target description, if any.
File: gdb.info, Node: Target Description Format, Next: Predefined Target Types, Prev: Retrieving Descriptions, Up: Target Descriptions
F.2 Target Description Format
=============================
A target description annex is an XML (http://www.w3.org/XML/) document
which complies with the Document Type Definition provided in the GDB
sources in `gdb/features/gdb-target.dtd'. This means you can use
generally available tools like `xmllint' to check that your feature
descriptions are well-formed and valid. However, to help people
unfamiliar with XML write descriptions for their targets, we also
describe the grammar here.
Target descriptions can identify the architecture of the remote
target and (for some architectures) provide information about custom
register sets. GDB can use this information to autoconfigure for your
target, or to warn you if you connect to an unsupported target.
Here is a simple target description:
<target version="1.0">
<architecture>i386:x86-64</architecture>
</target>
This minimal description only says that the target uses the x86-64
architecture.
A target description has the following overall form, with [ ] marking
optional elements and ... marking repeatable elements. The elements
are explained further below.
<?xml version="1.0"?>
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<target version="1.0">
[ARCHITECTURE]
[FEATURE...]
</target>
The description is generally insensitive to whitespace and line breaks,
under the usual common-sense rules. The XML version declaration and
document type declaration can generally be omitted (GDB does not
require them), but specifying them may be useful for XML validation
tools. The `version' attribute for `<target>' may also be omitted, but
we recommend including it; if future versions of GDB use an incompatible
revision of `gdb-target.dtd', they will detect and report the version
mismatch.
F.2.1 Inclusion
---------------
It can sometimes be valuable to split a target description up into
several different annexes, either for organizational purposes, or to
share files between different possible target descriptions. You can
divide a description into multiple files by replacing any element of
the target description with an inclusion directive of the form:
<xi:include href="DOCUMENT"/>
When GDB encounters an element of this form, it will retrieve the named
XML DOCUMENT, and replace the inclusion directive with the contents of
that document. If the current description was read using `qXfer', then
so will be the included document; DOCUMENT will be interpreted as the
name of an annex. If the current description was read from a file, GDB
will look for DOCUMENT as a file in the same directory where it found
the original description.
F.2.2 Architecture
------------------
An `<architecture>' element has this form:
<architecture>ARCH</architecture>
ARCH is an architecture name from the same selection accepted by
`set architecture' (*note Specifying a Debugging Target: Targets.).
F.2.3 Features
--------------
Each `<feature>' describes some logical portion of the target system.
Features are currently used to describe available CPU registers and the
types of their contents. A `<feature>' element has this form:
<feature name="NAME">
[TYPE...]
REG...
</feature>
Each feature's name should be unique within the description. The name
of a feature does not matter unless GDB has some special knowledge of
the contents of that feature; if it does, the feature should have its
standard name. *Note Standard Target Features::.
F.2.4 Types
-----------
Any register's value is a collection of bits which GDB must interpret.
The default interpretation is a two's complement integer, but other
types can be requested by name in the register description. Some
predefined types are provided by GDB (*note Predefined Target Types::),
and the description can define additional composite types.
Each type element must have an `id' attribute, which gives a unique
(within the containing `<feature>') name to the type. Types must be
defined before they are used.
Some targets offer vector registers, which can be treated as arrays
of scalar elements. These types are written as `<vector>' elements,
specifying the array element type, TYPE, and the number of elements,
COUNT:
<vector id="ID" type="TYPE" count="COUNT"/>
If a register's value is usefully viewed in multiple ways, define it
with a union type containing the useful representations. The `<union>'
element contains one or more `<field>' elements, each of which has a
NAME and a TYPE:
<union id="ID">
<field name="NAME" type="TYPE"/>
...
</union>
F.2.5 Registers
---------------
Each register is represented as an element with this form:
<reg name="NAME"
bitsize="SIZE"
[regnum="NUM"]
[save-restore="SAVE-RESTORE"]
[type="TYPE"]
[group="GROUP"]/>
The components are as follows:
NAME
The register's name; it must be unique within the target
description.
BITSIZE
The register's size, in bits.
REGNUM
The register's number. If omitted, a register's number is one
greater than that of the previous register (either in the current
feature or in a preceeding feature); the first register in the
target description defaults to zero. This register number is used
to read or write the register; e.g. it is used in the remote `p'
and `P' packets, and registers appear in the `g' and `G' packets
in order of increasing register number.
SAVE-RESTORE
Whether the register should be preserved across inferior function
calls; this must be either `yes' or `no'. The default is `yes',
which is appropriate for most registers except for some system
control registers; this is not related to the target's ABI.
TYPE
The type of the register. TYPE may be a predefined type, a type
defined in the current feature, or one of the special types `int'
and `float'. `int' is an integer type of the correct size for
BITSIZE, and `float' is a floating point type (in the
architecture's normal floating point format) of the correct size
for BITSIZE. The default is `int'.
GROUP
The register group to which this register belongs. GROUP must be
either `general', `float', or `vector'. If no GROUP is specified,
GDB will not display the register in `info registers'.
File: gdb.info, Node: Predefined Target Types, Next: Standard Target Features, Prev: Target Description Format, Up: Target Descriptions
F.3 Predefined Target Types
===========================
Type definitions in the self-description can build up composite types
from basic building blocks, but can not define fundamental types.
Instead, standard identifiers are provided by GDB for the fundamental
types. The currently supported types are:
`int8'
`int16'
`int32'
`int64'
`int128'
Signed integer types holding the specified number of bits.
`uint8'
`uint16'
`uint32'
`uint64'
`uint128'
Unsigned integer types holding the specified number of bits.
`code_ptr'
`data_ptr'
Pointers to unspecified code and data. The program counter and
any dedicated return address register may be marked as code
pointers; printing a code pointer converts it into a symbolic
address. The stack pointer and any dedicated address registers
may be marked as data pointers.
`ieee_single'
Single precision IEEE floating point.
`ieee_double'
Double precision IEEE floating point.
`arm_fpa_ext'
The 12-byte extended precision format used by ARM FPA registers.
File: gdb.info, Node: Standard Target Features, Prev: Predefined Target Types, Up: Target Descriptions
F.4 Standard Target Features
============================
A target description must contain either no registers or all the
target's registers. If the description contains no registers, then GDB
will assume a default register layout, selected based on the
architecture. If the description contains any registers, the default
layout will not be used; the standard registers must be described in
the target description, in such a way that GDB can recognize them.
This is accomplished by giving specific names to feature elements
which contain standard registers. GDB will look for features with
those names and verify that they contain the expected registers; if any
known feature is missing required registers, or if any required feature
is missing, GDB will reject the target description. You can add
additional registers to any of the standard features -- GDB will
display them just as if they were added to an unrecognized feature.
This section lists the known features and their expected contents.
Sample XML documents for these features are included in the GDB source
tree, in the directory `gdb/features'.
Names recognized by GDB should include the name of the company or
organization which selected the name, and the overall architecture to
which the feature applies; so e.g. the feature containing ARM core
registers is named `org.gnu.gdb.arm.core'.
The names of registers are not case sensitive for the purpose of
recognizing standard features, but GDB will only display registers
using the capitalization used in the description.
* Menu:
* ARM Features::
* MIPS Features::
* M68K Features::
* PowerPC Features::
File: gdb.info, Node: ARM Features, Next: MIPS Features, Up: Standard Target Features
F.4.1 ARM Features
------------------
The `org.gnu.gdb.arm.core' feature is required for ARM targets. It
should contain registers `r0' through `r13', `sp', `lr', `pc', and
`cpsr'.
The `org.gnu.gdb.arm.fpa' feature is optional. If present, it
should contain registers `f0' through `f7' and `fps'.
The `org.gnu.gdb.xscale.iwmmxt' feature is optional. If present, it
should contain at least registers `wR0' through `wR15' and `wCGR0'
through `wCGR3'. The `wCID', `wCon', `wCSSF', and `wCASF' registers
are optional.
File: gdb.info, Node: MIPS Features, Next: M68K Features, Prev: ARM Features, Up: Standard Target Features
F.4.2 MIPS Features
-------------------
The `org.gnu.gdb.mips.cpu' feature is required for MIPS targets. It
should contain registers `r0' through `r31', `lo', `hi', and `pc'.
They may be 32-bit or 64-bit depending on the target.
The `org.gnu.gdb.mips.cp0' feature is also required. It should
contain at least the `status', `badvaddr', and `cause' registers. They
may be 32-bit or 64-bit depending on the target.
The `org.gnu.gdb.mips.fpu' feature is currently required, though it
may be optional in a future version of GDB. It should contain