"Peter Cheung" <
mche...@gmail.com> wrote in message
news:5b04a939-5f9a-40e6...@googlegroups.com...
>James Harris? 2015?5?31???? UTC+8??1?46?16???:
You mean you want to find the parameters passed to your code by the boot
loader you are using? I'll assume that below.
> so far these are the possible ways:
>
>1) subtract the esp by 8 blindly
Doesn't sound good. When your code starts it seems that ESP is expected
to point to a return address. If it was called with a normal x86 call
instruction the first parameter passed to your code would start at ESP +
4.
>2) read out the CFA,
Are you trying to read and parse Dwarf structures in your OS so you can
find the parameters? If so it may be better to just work with the
interface defined by the boot loader that calls your OS and forget about
Dwarf, IMO.
Or are you interested in Dwarf because you want to run your OS under a
debugger? If so I can understand your questions.
> but I got two problems
> a) DW_CFA_def_cfa already told you how to find the stack frame, it
> has register and offset. Why need DW_CFA_def_cfa_register and
> DW_CFA_def_cfa_offset.
Updates to the CFA definition are needed because the it may change as
execution progresses. I have been reading up on this and my
understanding may not be correct but ISTM that Dwarf provides
instructions to change the register and offset individually just because
that is more convenient. AFAICT it always knows which register and which
offset are needed but it allows just one to be changed at a time.
It seems that one has to start with the CIE (Common Information Entry)
and then work through each entry in an FDE (Frame Description Entry). In
your case the initial CFA is defined as (ESP + 4) and ESP points at the
return EIP.
> b) I am jumping from multiboot to my kernel, the first function in
> dwarf doesn't have DW_CFA_def_cfa, is that mean if the function
> doesn't have DW_CFA_def_cfa, then use the one in CIE?
Yes, start with the CIE. Each FDE refers back to a CIE and that CIE,
AIUI, can define the initial conditions before the FDE instructions are
looked at. So for each FDE one can start with the associated CIE.
>00000000 00000014 00000000 CIE
> Version: 1
> Augmentation: "zR"
> Code alignment factor: 1
> Data alignment factor: -4
> Return address column: 8
> Augmentation data: 1b
>
> DW_CFA_def_cfa: r4 (esp) ofs 4
This seems to say that the CFA is at ESP + 4. (AFAICT offsets are
positive so this means ESP + 4, not ESP - 4.)
> DW_CFA_offset: r8 (eip) at cfa-4
Meaning that EIP is stored at CFA - 4 (aka ESP + 0 at this point).
> DW_CFA_nop
> DW_CFA_nop
>
>00000018 00000018 0000001c FDE cie=00000000 pc=01600000..01600737
> DW_CFA_advance_loc: 1 to 01600001
Advance by 1 needed because the instruction at 1600000 is a 1-byte push
instruction and has changed ESP.
> DW_CFA_def_cfa_offset: 8
CFA (which was at offset 4) is now at offset 8. In this case, CFA is at
ESP + 8. Its definition had to be changed because ESP changed.
> DW_CFA_offset: r5 (ebp) at cfa-8 <------ we don't have
> DW_CFA_def_cfa here
I think this only means that EBP is now stored at CFA - 8.
> DW_CFA_advance_loc: 2 to 01600003
> DW_CFA_def_cfa_register: r5 (ebp)
The CFA register is now EBP so the CFA is now at EBP + 8. Presumably you
have the following instruction.
mov ebp, esp
EBP is now used as the frame pointer so Dwarf has changed to use it as
the basis for calculating the CFA address. The offset of CFA has not
changed.
This is a different issue which I haven't looked at - and maybe you
don't need now? :-)
James