Академический Документы
Профессиональный Документы
Культура Документы
func+0 sp cfa[0]
func+22 sp cfa[0]
Some things to note here:
• Each row describes the state of affairs before executing the
instruction at the given address. Thus, the row for func+0
describes the state before we execute the first instruction, which
allocates the stack frame. In the next row, the formula for
computing the CFA has changed, reflecting the allocation.
• The other entries are written in terms of the CFA; this allows them
to remain unchanged as the stack pointer gets bumped around.
For example, to find the caller's value for r0 at func+2, we would
first compute the CFA by adding 16 to the sp, and then subtract
four from that to find the address at which r0 was saved.
• Although the example doesn't show this, most calling conventions
designate "callee-saves" and "caller-saves" registers. The callee
must restore the values of "callee-saves" registers before
returning (if it uses them at all), whereas the callee is free to use
"caller-saves" registers without restoring their values. A function
that uses caller-saves registers typically does not save their
original values at all; in this case, the CFI marks such registers'
values as "unrecoverable".
• Exactly where the CFA points in the frame --- at the return
address? below it? At some fixed point within the frame? --- is a
question of definition that depends on the architecture and ABI in
use. But by definition, the CFA remains constant throughout the
lifetime of the frame. It's up to architecture- specific code to know
what significance to assign the CFA, if any.
To save space, the most common type of CFI record only mentions the
table entries at which changes take place. So for the above, the CFI
data would only actually mention the non-blank entries here:
insn cfa r0 r1 ... ra
func+0 sp cfa[0]
func+1 sp+16
func+2 cfa[-4]
func+11 sp+20
func+21 r0
func+22 sp
A STACK CFI INIT record indicates that, at the machine instruction
at address, belonging to some function, the value that registern had in
that function's caller can be recovered by evaluating expressionn. The
values of any callee-saves registers not mentioned are assumed to be
unchanged. (STACK CFI records never mention caller-saves registers.)
These rules apply starting at address and continue up to, but not
including, the address given in the next STACK CFI record.
The size field is the total number of bytes of machine code covered by
this record and any subsequent STACK CFI records (until the
next STACK CFI INIT record). The address field is relative to the
module's load address.
A STACK CFI record (no INIT) is the same, except that it mentions
only those registers whose recovery rules have changed from the
previous CFI record. There must be a prior STACK CFI
INIT or STACK CFI record in the symbol file. The address field of this
record must be greater than that of the previous record, and it must not
be at or beyond the end of the range given by the most recent STACK
CFI INIT record. The address is relative to the module's load address.
Each expression is a breakpad-style postfix expression. Expressions
may contain spaces, but their tokens may not end with colons. When an
expression mentions a register, it refers to the value of that register in
the callee, even if a prior name/expression pair gives that register's
value in the caller. The exception is .cfa, which refers to the canonical
frame address computed by the .cfa rule in force at the current
instruction.
The special expression .undef indicates that the given register's value
cannot be recovered.
The register names preceding the expressions are always followed by
colons. The expressions themselves never contain tokens ending with
colons.
There are two special register names:
• .cfa ("Canonical Frame Address") is the base address of the
stack frame. Other registers' rules may refer to this. If no rule is
provided for the stack pointer, the value of .cfa is the caller's
stack pointer.
• .ra is the return address. This is the value of the restored
program counter. We use .ra instead of the architecture-specific
name for the program counter.
The Breakpad stack walker requires that there be rules in force
for .cfa and .ra at every code address from which it unwinds. If those
rules are not present, the stack walker will ignore the STACK CFI data,
and try to use a different strategy.
So the CFI for the example function above would be as follows,
if func were at address 0x1000 (relative to the module's load address):
STACK CFI INIT 1000 .cfa: $sp .ra: .cfa ^
STACK CFI 1001 .cfa: $sp 16 +
STACK CFI 1002 $r0: .cfa 4 - ^
STACK CFI 100b .cfa: $sp 20 +
STACK CFI 1015 $r0: $r0
STACK CFI 1016 .cfa: $sp
Tell the linker to put this into the executable's .text section:
.text
Another external symbol, this one for the main function's Frame
Description Entry (still part of the exception handling information):
.globl _main.eh
_main.eh:
Examining memory
You can use the command x (for "examine") to examine memory in any of
several formats, independently of your program's data types.
x/nfu addr
x addr
x
Use the x command to examine memory.
n, f, and u are all optional parameters that specify how much memory to
display and how to format it; addr is an expression giving the address where
you want to start displaying memory. If you use defaults for nfu, you need
not type the slash `/'. Several commands set convenient defaults for addr.
n, the repeat count
The repeat count is a decimal integer; the default is 1.
It specifies how much memory (counting by units u) to
display.
f, the display format
The display format is one of the formats used
by print, `s' (null-terminated string), or `i' (machine
instruction). The default is `x' (hexadecimal) initially.
The default changes each time you use either x or print.
u, the unit size
The unit size is any of
b
Bytes.
h
Halfwords (two bytes).
w
Words (four bytes). This is the initial default.
g
Giant words (eight bytes).
Each time you specify a unit size with x, that size becomes the default
unit the next time you use x. (For the `s' and `i' formats, the unit
size is ignored and is normally not written.)
addr, starting display address
addr is the address where you want GDB to begin
displaying memory. The expression need not have a
pointer value (though it may); it is always interpreted
as an integer address of a byte of memory. See
section Expressions, for more information on
expressions. The default for addr is usually just after
the last address examined--but several other
commands also set the default address: info
breakpoints (to the address of the last breakpoint
listed), info line (to the starting address of a line),
and print (if you use it to display a value from memory).
For example, `x/3uh 0x54320' is a request to display three halfwords
(h) of memory, formatted as unsigned decimal integers (`u'), starting at
address 0x54320. `x/4xw $sp' prints the four words (`w') of memory
above the stack pointer (here, `$sp'; see section Registers) in hexadecimal
(`x').
Since the letters indicating unit sizes are all distinct from the letters
specifying output formats, you do not have to remember whether unit size or
format comes first; either order works. The output
specifications `4xw' and `4wx' mean exactly the same thing. (However,
the count n must come first; `wx4' does not work.)
Even though the unit size u is ignored for the formats `s' and `i', you
might still want to use a count n; for example, `3i' specifies that you want
to see three machine instructions, including any operands. The
command disassemble gives an alternative way of inspecting machine
instructions; see Source and machine code.
All the defaults for the arguments to x are designed to make it easy to
continue scanning memory with minimal specifications each time you use x.
For example, after you have inspected three machine instructions
with `x/3i addr', you can inspect the next seven with just `x/7'. If
you use RET to repeat the x command, the repeat count n is used again; the
other arguments default as for successive uses of x.
The addresses and contents printed by the x command are not saved in the
value history because there is often too much of them and they would get in
the way. Instead, GDB makes these values available for subsequent use in
expressions as values of the convenience variables $_ and $__. After
an x command, the last address examined is available for use in expressions
in the convenience variable $_. The contents of that address, as examined,
are available in the convenience variable $__.
If the x command has a repeat count, the address and contents saved are
from the last memory unit printed; this is not the same as the last address
printed if several units were printed on the last line of output.