From junkoi2004  Wed Oct  4 18:28:20 2006
From: junkoi2004 (Jun Koi)
Date: Thu, 5 Oct 2006 03:28:20 +0900
Subject: [Dwarf-discuss] Question about variable location in Dwarf
In-Reply-To: <fdaac4d50610041126q6651d105h64fc2af79504f94@mail.gmail.com>
References: <mailman.285.1159954930.6015.dwarf-discuss@lists.freestandards.org>
	<fdaac4d50610041126q6651d105h64fc2af79504f94@mail.gmail.com>
Message-ID: <fdaac4d50610041128k10346537ted39ed5af3caa72b@mail.gmail.com>

Hello,

I am having some problem interpreting Dwarf format. I am trying to get
the address of a local variable in my C program by analyzing the Dwarf
format. Here is my simple code:

....
int main()
{
        static char buffer[512];
        struct old_utsname old;
...
}

I use dwarfdump on the debugged binary of my code, and get the below data:

...
<1><  578>      DW_TAG_subprogram
                DW_AT_sibling               <655>
                DW_AT_external              yes(1)
                DW_AT_name                  main
                DW_AT_decl_file             1 /home/jun/projects/olduname.c
                DW_AT_decl_line             24
                DW_AT_type                  <208>
                DW_AT_low_pc                0x8048433
                DW_AT_high_pc               0x804854e
                DW_AT_frame_base            DW_OP_reg5
<2><  605>      DW_TAG_variable
                DW_AT_name                  buffer
                DW_AT_decl_file             1 /home/bun/projects/olduname.c
                DW_AT_decl_line             25
                DW_AT_type                  <655>
                DW_AT_location              DW_OP_addr 0x80497c0
<2><  625>      DW_TAG_variable
                DW_AT_name                  old
                DW_AT_decl_file             1 /home/bun/projects/olduname.c
                DW_AT_decl_line             26
                DW_AT_type                  <291>
                DW_AT_location              DW_OP_breg5-329

.....

So I understand that the (run-time) virtual address of the variable
"buffer" is at 0x80497c0. But how can I get the virtual address of the
variable "old"? It seems that I must get it by computing "DW_OP_breg5
- 329"? But how can I get the value of DW_OP_breg5 in this case?

I understand that DW_OP_breg5 is the value of a register, right? But
what is that register? (ebp? I am on Intel x86)

Thank you a lot,
Jun




From john.e.bishop  Wed Oct  4 20:21:21 2006
From: john.e.bishop (Bishop, John E)
Date: Wed, 4 Oct 2006 16:21:21 -0400
Subject: [Dwarf-discuss] Dwarf-discuss Digest, Vol 23, Issue 1
Message-ID: <DFE30915550166479787C27231F7E5107161FC@hdsmsx412.amr.corp.intel.com>


> I understand that DW_OP_breg5 is the value of a register, right? But
> what is that register? (ebp? I am on Intel x86)

This is one of those things that each compiler gets to
decide, if I understand correctly.  DWARF just says how
to name a register, the compiler guys decide how to map
those names to actual registers, and the debugger must
follow suit.

I believe the Intel mapping is as follows, based on one
experiment with IDB internals:

 Register number 0 is eax
 Register number 1 is ecx
 Register number 2 is edx
 Register number 3 is ebx
 Register number 4 is esp
 Register number 5 is ebp
 Register number 6 is esi
 Register number 7 is edi
 Register number 8 is eip
 Register number 9 is eflags
 Register number 10 is cs
 Register number 11 is ss
 Register number 12 is ds
 Register number 13 is es
 Register number 14 is fs
 Register number 15 is gs
 Register number 16 is orig_eax
 Register number 17 is fctrl
 Register number 18 is fstat
 Register number 19 is ftag
 Register number 20 is fiseg
 Register number 21 is fioff
 Register number 22 is foseg
 Register number 23 is fooff
 Register number 24 is fop
 Register number 25 is f0
 Register number 26 is f1
 Register number 27 is f2
 Register number 28 is f3
 Register number 29 is f4
 Register number 30 is f5
 Register number 31 is f6
 Register number 32 is f7
 Register number 33 is xmm0
 Register number 34 is xmm1
 Register number 35 is xmm2
 Register number 36 is xmm3
 Register number 37 is xmm4
 Register number 38 is xmm5
 Register number 39 is xmm6
 Register number 40 is xmm7
 Register number 41 is mxcsr
 Register number 42 is vfp

Note that these don't exactly reflect any of
the structs the system returns to PTRACE calls
or the like.  And they may be IDB-internal rather
than the actual BREG mapping.  I'll try to 
chase that down and post another reply.

	-John




From ramana.radhakrishnan  Wed Oct  4 20:25:50 2006
From: ramana.radhakrishnan (Ramana Radhakrishnan)
Date: Thu, 05 Oct 2006 01:55:50 +0530
Subject: [Dwarf-discuss] Dwarf-discuss Digest, Vol 23, Issue 1
In-Reply-To: <DFE30915550166479787C27231F7E5107161FC@hdsmsx412.amr.corp.intel.com>
References: <DFE30915550166479787C27231F7E5107161FC@hdsmsx412.amr.corp.intel.com>
Message-ID: <1159993550.5796.23.camel@localhost.localdomain>

I thought this was decided by a paragraph some place in the ABI which
dealt with DWARF register numbers so that all vendors would agree on
it. 


-Ramana

On Wed, 2006-10-04 at 16:21 -0400, Bishop, John E wrote:
> > I understand that DW_OP_breg5 is the value of a register, right? But
> > what is that register? (ebp? I am on Intel x86)
> 
> This is one of those things that each compiler gets to
> decide, if I understand correctly.  DWARF just says how
> to name a register, the compiler guys decide how to map
> those names to actual registers, and the debugger must
> follow suit.
> 
> I believe the Intel mapping is as follows, based on one
> experiment with IDB internals:
> 
>  Register number 0 is eax
>  Register number 1 is ecx
>  Register number 2 is edx
>  Register number 3 is ebx
>  Register number 4 is esp
>  Register number 5 is ebp
>  Register number 6 is esi
>  Register number 7 is edi
>  Register number 8 is eip
>  Register number 9 is eflags
>  Register number 10 is cs
>  Register number 11 is ss
>  Register number 12 is ds
>  Register number 13 is es
>  Register number 14 is fs
>  Register number 15 is gs
>  Register number 16 is orig_eax
>  Register number 17 is fctrl
>  Register number 18 is fstat
>  Register number 19 is ftag
>  Register number 20 is fiseg
>  Register number 21 is fioff
>  Register number 22 is foseg
>  Register number 23 is fooff
>  Register number 24 is fop
>  Register number 25 is f0
>  Register number 26 is f1
>  Register number 27 is f2
>  Register number 28 is f3
>  Register number 29 is f4
>  Register number 30 is f5
>  Register number 31 is f6
>  Register number 32 is f7
>  Register number 33 is xmm0
>  Register number 34 is xmm1
>  Register number 35 is xmm2
>  Register number 36 is xmm3
>  Register number 37 is xmm4
>  Register number 38 is xmm5
>  Register number 39 is xmm6
>  Register number 40 is xmm7
>  Register number 41 is mxcsr
>  Register number 42 is vfp
> 
> Note that these don't exactly reflect any of
> the structs the system returns to PTRACE calls
> or the like.  And they may be IDB-internal rather
> than the actual BREG mapping.  I'll try to 
> chase that down and post another reply.
> 
> 	-John
> 
> _______________________________________________
> Dwarf-discuss mailing list
> Dwarf-discuss at lists.freestandards.org
> http://lists.freestandards.org/mailman/listinfo/dwarf-discuss
-- 
Ramana Radhakrishnan <ramana.radhakrishnan at codito.com>
Codito Technologies Pvt. Ltd.




From drow  Wed Oct  4 20:28:31 2006
From: drow (Daniel Jacobowitz)
Date: Wed, 4 Oct 2006 16:28:31 -0400
Subject: [Dwarf-discuss] Dwarf-discuss Digest, Vol 23, Issue 1
In-Reply-To: <1159993550.5796.23.camel@localhost.localdomain>
References: <DFE30915550166479787C27231F7E5107161FC@hdsmsx412.amr.corp.intel.com>
	<1159993550.5796.23.camel@localhost.localdomain>
Message-ID: <20061004202831.GA6506@nevyn.them.org>

On Thu, Oct 05, 2006 at 01:55:50AM +0530, Ramana Radhakrishnan wrote:
> I thought this was decided by a paragraph some place in the ABI which
> dealt with DWARF register numbers so that all vendors would agree on
> it. 

Yes.  But some platform ABIs have it, and others don't.  For instance,
ARM publishes their numbering; but I think the correct numbering for
x86 is a matter of folklore.

-- 
Daniel Jacobowitz
CodeSourcery




From brian.nettleton  Wed Oct  4 20:29:27 2006
From: brian.nettleton (Nettleton, Brian)
Date: Wed, 4 Oct 2006 13:29:27 -0700
Subject: [Dwarf-discuss] Question about variable location in Dwarf
Message-ID: <205D614FB7B84C468726248150BC46AE0121B11D@ala-mail04.corp.ad.wrs.com>

Yes, I believe that DW_OP_breg5 is ebp for x86.  

Not sure what exactly you're trying to do, but one (obvious??)
recommendation would be to use a debugger to get the address of the
variable, they are already built to read the DWARF data and figure out
all the details.  Of course if you're trying to write your own debugger
(or similar?) then this doesn't really help you.

-Brian Nettleton



> -----Original Message-----
> From: dwarf-discuss-bounces at lists.freestandards.org 
> [mailto:dwarf-discuss-bounces at lists.freestandards.org] On 
> Behalf Of Jun Koi
> Sent: Wednesday, October 04, 2006 11:28 AM
> To: dwarf-discuss at lists.freestandards.org
> Subject: [Dwarf-discuss] Question about variable location in Dwarf
> 
> Hello,
> 
> I am having some problem interpreting Dwarf format. I am trying to get
> the address of a local variable in my C program by analyzing the Dwarf
> format. Here is my simple code:
> 
> ....
> int main()
> {
>         static char buffer[512];
>         struct old_utsname old;
> ...
> }
> 
> I use dwarfdump on the debugged binary of my code, and get 
> the below data:
> 
> ...
> <1><  578>      DW_TAG_subprogram
>                 DW_AT_sibling               <655>
>                 DW_AT_external              yes(1)
>                 DW_AT_name                  main
>                 DW_AT_decl_file             1 
> /home/jun/projects/olduname.c
>                 DW_AT_decl_line             24
>                 DW_AT_type                  <208>
>                 DW_AT_low_pc                0x8048433
>                 DW_AT_high_pc               0x804854e
>                 DW_AT_frame_base            DW_OP_reg5
> <2><  605>      DW_TAG_variable
>                 DW_AT_name                  buffer
>                 DW_AT_decl_file             1 
> /home/bun/projects/olduname.c
>                 DW_AT_decl_line             25
>                 DW_AT_type                  <655>
>                 DW_AT_location              DW_OP_addr 0x80497c0
> <2><  625>      DW_TAG_variable
>                 DW_AT_name                  old
>                 DW_AT_decl_file             1 
> /home/bun/projects/olduname.c
>                 DW_AT_decl_line             26
>                 DW_AT_type                  <291>
>                 DW_AT_location              DW_OP_breg5-329
> 
> .....
> 
> So I understand that the (run-time) virtual address of the variable
> "buffer" is at 0x80497c0. But how can I get the virtual address of the
> variable "old"? It seems that I must get it by computing "DW_OP_breg5
> - 329"? But how can I get the value of DW_OP_breg5 in this case?
> 
> I understand that DW_OP_breg5 is the value of a register, right? But
> what is that register? (ebp? I am on Intel x86)
> 
> Thank you a lot,
> Jun
> 
> _______________________________________________
> Dwarf-discuss mailing list
> Dwarf-discuss at lists.freestandards.org
> http://lists.freestandards.org/mailman/listinfo/dwarf-discuss
> 




From syk  Wed Oct  4 20:37:39 2006
From: syk (Sebastian Krawczuk)
Date: Wed, 04 Oct 2006 16:37:39 -0400
Subject: [Dwarf-discuss] Question about variable location in Dwarf
In-Reply-To: <fdaac4d50610041128k10346537ted39ed5af3caa72b@mail.gmail.com>
References: <mailman.285.1159954930.6015.dwarf-discuss@lists.freestandards.org>	<fdaac4d50610041126q6651d105h64fc2af79504f94@mail.gmail.com>
	<fdaac4d50610041128k10346537ted39ed5af3caa72b@mail.gmail.com>
Message-ID: <45241B93.9090201@ocsystems.com>

Jun,

You can almost blindly assume that this has to be (but not necessarily) 
a frame pointer register.  Unfortunately mapping between DWARF register 
IDs and H/W registers is compiler-centric.  For gcc (and some other 
compilers too) Reg #5 happens to be EBP ;)

Good luck!
Sebastian.

Jun Koi wrote:
> Hello,
>
> I am having some problem interpreting Dwarf format. I am trying to get
> the address of a local variable in my C program by analyzing the Dwarf
> format. Here is my simple code:
>
> .....
> int main()
> {
>         static char buffer[512];
>         struct old_utsname old;
> ....
> }
>
> I use dwarfdump on the debugged binary of my code, and get the below data:
>
> ....
> <1><  578>      DW_TAG_subprogram
>                 DW_AT_sibling               <655>
>                 DW_AT_external              yes(1)
>                 DW_AT_name                  main
>                 DW_AT_decl_file             1 /home/jun/projects/olduname.c
>                 DW_AT_decl_line             24
>                 DW_AT_type                  <208>
>                 DW_AT_low_pc                0x8048433
>                 DW_AT_high_pc               0x804854e
>                 DW_AT_frame_base            DW_OP_reg5
> <2><  605>      DW_TAG_variable
>                 DW_AT_name                  buffer
>                 DW_AT_decl_file             1 /home/bun/projects/olduname.c
>                 DW_AT_decl_line             25
>                 DW_AT_type                  <655>
>                 DW_AT_location              DW_OP_addr 0x80497c0
> <2><  625>      DW_TAG_variable
>                 DW_AT_name                  old
>                 DW_AT_decl_file             1 /home/bun/projects/olduname.c
>                 DW_AT_decl_line             26
>                 DW_AT_type                  <291>
>                 DW_AT_location              DW_OP_breg5-329
>
> ......
>
> So I understand that the (run-time) virtual address of the variable
> "buffer" is at 0x80497c0. But how can I get the virtual address of the
> variable "old"? It seems that I must get it by computing "DW_OP_breg5
> - 329"? But how can I get the value of DW_OP_breg5 in this case?
>
> I understand that DW_OP_breg5 is the value of a register, right? But
> what is that register? (ebp? I am on Intel x86)
>
> Thank you a lot,
> Jun
>
> _______________________________________________
> Dwarf-discuss mailing list
> Dwarf-discuss at lists.freestandards.org
> http://lists.freestandards.org/mailman/listinfo/dwarf-discuss
>   

-- 
Sebastian Krawczuk
OC Systems, Inc.
Office: 703-279-2770
Cell:   703-855-2323
Email:  syk at ocsystems.com

# make sense
make: 1254-002 Cannot find a rule to create target sense from dependencies.
Stop.




From junkoi2004  Thu Oct  5 10:11:47 2006
From: junkoi2004 (Jun Koi)
Date: Thu, 5 Oct 2006 19:11:47 +0900
Subject: [Dwarf-discuss] Question on loclist
Message-ID: <fdaac4d50610050311j3aff52fbkb5014129eee14203@mail.gmail.com>

Hi,

Thank you all for great replies on my last question. I am quite new to
the Dwarf spec, so have quite a few newbie questions :-)

I am working on Linux, and trying to investigate kernel at run-time.
Like everybody else, I use gcc to compile Linux kernel. I have another
question regarding loclist, and appreciate your kind helps.

In kernel 2.6.16.29, file fs/namei.c, we have the code like this:

...
static long do_rmdir(int dfd, const char __user *pathname)
{
        int error = 0;
        char * name;
        struct dentry *dentry;
        struct nameidata nd;

        name = getname(pathname);
        if(IS_ERR(name))
                return PTR_ERR(name);

        error = do_path_lookup(dfd, name, LOOKUP_PARENT, &nd);
        if (error)
                goto exit;
....

I compiled kernel with debug info option, and use dwarfdump to extract
information out. Then I got something corresponding to the above code:

...
                DW_AT_name                  do_rmdir
                DW_AT_decl_file             1 fs/namei.c
                DW_AT_decl_line             1988
                DW_AT_prototyped            yes(1)
                DW_AT_type                  <193>
                DW_AT_low_pc                0xc01617a0
                DW_AT_high_pc               0xc0161873
                DW_AT_frame_base            DW_OP_reg5
<2><41023>      DW_TAG_formal_parameter
                DW_AT_name                  dfd
                DW_AT_decl_file             1 fs/namei.c
                DW_AT_decl_line             1987
                DW_AT_type                  <49>
                DW_AT_location              <loclist with 3 entries follows>
                        [ 0]<lowpc=0x2e00><highpc=0x2e19>DW_OP_reg0
                        [ 1]<lowpc=0x2e19><highpc=0x2e3f>DW_OP_reg3
                        [ 2]<lowpc=0x2ec4><highpc=0x2ec7>DW_OP_reg3
<2><41039>      DW_TAG_formal_parameter
                DW_AT_name                  pathname
                DW_AT_decl_file             1 fs/namei.c
                DW_AT_decl_line             1987
                DW_AT_type                  <64>
                DW_AT_location              <loclist with 1 entries follows>
                        [ 0]<lowpc=0x2e00><highpc=0x2e19>DW_OP_reg2
<2><41055>      DW_TAG_variable
                DW_AT_name                  error
                DW_AT_decl_file             1 fs/namei.c
                DW_AT_decl_line             1989
                DW_AT_type                  <49>
                DW_AT_location              <loclist with 3 entries follows>
                        [ 0]<lowpc=0x2e3b><highpc=0x2e3d>DW_OP_reg0
                        [ 1]<lowpc=0x2e3f><highpc=0x2e53>DW_OP_reg3
                        [ 2]<lowpc=0x2e7a><highpc=0x2ec7>DW_OP_reg3
<2><41071>      DW_TAG_variable
                DW_AT_name                  name
                DW_AT_decl_file             1 fs/namei.c
                DW_AT_decl_line             1990
                DW_AT_type                  <82>
                DW_AT_location              <loclist with 2 entries follows>
                        [ 0]<lowpc=0x2e1b><highpc=0x2eca>DW_OP_reg6
                        [ 1]<lowpc=0x2ecf><highpc=0x2ed3>DW_OP_reg6
.....


I have few questions:

1) Why the location of variable "name" is not made with plain location
expression (like DW_OP_breg5...), but loclist?

2) Why location of "name" consists of 2 entries?The 2nd entry
"[1]<lowpc=0x2ecf><highpc=0x2ed3>DW_OP_reg6" makes more sense to me,
as the range is exactly 4bytes, and name is in fact a pointer of 4
bytes.
But how about the 1st entry? What is its meaning?

3) Most important question to my project: in the case like above, how
to determine the run-time address of "name"? (Suppose that I can have
value of all the registers - I am on x86)
I read through the Dwarf2 spec many times, but still very confused here :-(


Thank you a lot,
Jun




From dberlin  Thu Oct  5 13:51:57 2006
From: dberlin (Daniel Berlin)
Date: Thu, 5 Oct 2006 09:51:57 -0400
Subject: [Dwarf-discuss] Question on loclist
In-Reply-To: <fdaac4d50610050311j3aff52fbkb5014129eee14203@mail.gmail.com>
References: <fdaac4d50610050311j3aff52fbkb5014129eee14203@mail.gmail.com>
Message-ID: <4aca3dc20610050651q5bb22548j2b758dece4a935f4@mail.gmail.com>

> I compiled kernel with debug info option, and use dwarfdump to extract
> information out. Then I got something corresponding to the above code:
>
> ...
>                 DW_AT_name                  do_rmdir
>                 DW_AT_decl_file             1 fs/namei.c
>                 DW_AT_decl_line             1988
>                 DW_AT_prototyped            yes(1)
>                 DW_AT_type                  <193>
>                 DW_AT_low_pc                0xc01617a0
>                 DW_AT_high_pc               0xc0161873
>                 DW_AT_frame_base            DW_OP_reg5
> <2><41023>      DW_TAG_formal_parameter
>                 DW_AT_name                  dfd
>                 DW_AT_decl_file             1 fs/namei.c
>                 DW_AT_decl_line             1987
>                 DW_AT_type                  <49>
>                 DW_AT_location              <loclist with 3 entries follows>
>                         [ 0]<lowpc=0x2e00><highpc=0x2e19>DW_OP_reg0
>                         [ 1]<lowpc=0x2e19><highpc=0x2e3f>DW_OP_reg3
>                         [ 2]<lowpc=0x2ec4><highpc=0x2ec7>DW_OP_reg3
> <2><41039>      DW_TAG_formal_parameter
>                 DW_AT_name                  pathname
>                 DW_AT_decl_file             1 fs/namei.c
>                 DW_AT_decl_line             1987
>                 DW_AT_type                  <64>
>                 DW_AT_location              <loclist with 1 entries follows>
>                         [ 0]<lowpc=0x2e00><highpc=0x2e19>DW_OP_reg2
> <2><41055>      DW_TAG_variable
>                 DW_AT_name                  error
>                 DW_AT_decl_file             1 fs/namei.c
>                 DW_AT_decl_line             1989
>                 DW_AT_type                  <49>
>                 DW_AT_location              <loclist with 3 entries follows>
>                         [ 0]<lowpc=0x2e3b><highpc=0x2e3d>DW_OP_reg0
>                         [ 1]<lowpc=0x2e3f><highpc=0x2e53>DW_OP_reg3
>                         [ 2]<lowpc=0x2e7a><highpc=0x2ec7>DW_OP_reg3
> <2><41071>      DW_TAG_variable
>                 DW_AT_name                  name
>                 DW_AT_decl_file             1 fs/namei.c
>                 DW_AT_decl_line             1990
>                 DW_AT_type                  <82>
>                 DW_AT_location              <loclist with 2 entries follows>
>                         [ 0]<lowpc=0x2e1b><highpc=0x2eca>DW_OP_reg6
>                         [ 1]<lowpc=0x2ecf><highpc=0x2ed3>DW_OP_reg6
> .....
>
>
> I have few questions:
>
> 1) Why the location of variable "name" is not made with plain location
> expression (like DW_OP_breg5...), but loclist?

Because GCC decided to use a location list, and it turned out later it
only had one entry.  For various internal reasons, we don't convert it
back to a location expression.
>
> 2) Why location of "name" consists of 2 entries?
Because the ranges appear disjoint, it could not merge them, since
there appears to be a point during the routine where there is no way
to validly get the value of name.


> "[1]<lowpc=0x2ecf><highpc=0x2ed3>DW_OP_reg6" makes more sense to me,
> as the range is exactly 4bytes, and name is in fact a pointer of 4
> bytes.

The lowpc and highpc are the range of program counters over which the
expression is valid, *not* the place in memory where the variable
lives.


> But how about the 1st entry? What is its meaning?

It means that during program execution, when the program counter is
between 0x2e1b and 0x2eca, that the variable is in register 6.

>
> 3) Most important question to my project: in the case like above, how
> to determine the run-time address of "name"? (Suppose that I can have
> value of all the registers - I am on x86)

It depends.
The absolute simplest way is to store all the location ranges and
expression, for the variable in an array:

When you want to know the value of the variable
1. get the value of the current PC.
2. Look through the array to see if the PC falls within any of the
location ranges.
    a. If it does, evaluate the location expression to get the
location of the variable
    b. If it does not, the value is optimized out
3. Use the location of the variable to read it's value




From junkoi2004  Thu Oct  5 14:40:55 2006
From: junkoi2004 (Jun Koi)
Date: Thu, 5 Oct 2006 23:40:55 +0900
Subject: [Dwarf-discuss] Question on loclist
In-Reply-To: <4aca3dc20610050651q5bb22548j2b758dece4a935f4@mail.gmail.com>
References: <fdaac4d50610050311j3aff52fbkb5014129eee14203@mail.gmail.com>
	<4aca3dc20610050651q5bb22548j2b758dece4a935f4@mail.gmail.com>
Message-ID: <fdaac4d50610050740i7bf6c51cy36023d52e5767b42@mail.gmail.com>

On 10/5/06, Daniel Berlin <dberlin at dberlin.org> wrote:
> > I compiled kernel with debug info option, and use dwarfdump to extract
> > information out. Then I got something corresponding to the above code:
> >
> > ...
> >                 DW_AT_name                  do_rmdir
> >                 DW_AT_decl_file             1 fs/namei.c
> >                 DW_AT_decl_line             1988
> >                 DW_AT_prototyped            yes(1)
> >                 DW_AT_type                  <193>
> >                 DW_AT_low_pc                0xc01617a0
> >                 DW_AT_high_pc               0xc0161873
> >                 DW_AT_frame_base            DW_OP_reg5
> > <2><41023>      DW_TAG_formal_parameter
> >                 DW_AT_name                  dfd
> >                 DW_AT_decl_file             1 fs/namei.c
> >                 DW_AT_decl_line             1987
> >                 DW_AT_type                  <49>
> >                 DW_AT_location              <loclist with 3 entries follows>
> >                         [ 0]<lowpc=0x2e00><highpc=0x2e19>DW_OP_reg0
> >                         [ 1]<lowpc=0x2e19><highpc=0x2e3f>DW_OP_reg3
> >                         [ 2]<lowpc=0x2ec4><highpc=0x2ec7>DW_OP_reg3
> > <2><41039>      DW_TAG_formal_parameter
> >                 DW_AT_name                  pathname
> >                 DW_AT_decl_file             1 fs/namei.c
> >                 DW_AT_decl_line             1987
> >                 DW_AT_type                  <64>
> >                 DW_AT_location              <loclist with 1 entries follows>
> >                         [ 0]<lowpc=0x2e00><highpc=0x2e19>DW_OP_reg2
> > <2><41055>      DW_TAG_variable
> >                 DW_AT_name                  error
> >                 DW_AT_decl_file             1 fs/namei.c
> >                 DW_AT_decl_line             1989
> >                 DW_AT_type                  <49>
> >                 DW_AT_location              <loclist with 3 entries follows>
> >                         [ 0]<lowpc=0x2e3b><highpc=0x2e3d>DW_OP_reg0
> >                         [ 1]<lowpc=0x2e3f><highpc=0x2e53>DW_OP_reg3
> >                         [ 2]<lowpc=0x2e7a><highpc=0x2ec7>DW_OP_reg3
> > <2><41071>      DW_TAG_variable
> >                 DW_AT_name                  name
> >                 DW_AT_decl_file             1 fs/namei.c
> >                 DW_AT_decl_line             1990
> >                 DW_AT_type                  <82>
> >                 DW_AT_location              <loclist with 2 entries follows>
> >                         [ 0]<lowpc=0x2e1b><highpc=0x2eca>DW_OP_reg6
> >                         [ 1]<lowpc=0x2ecf><highpc=0x2ed3>DW_OP_reg6
> > .....
> >
> >
> > I have few questions:
> >
> > 1) Why the location of variable "name" is not made with plain location
> > expression (like DW_OP_breg5...), but loclist?
>
> Because GCC decided to use a location list, and it turned out later it
> only had one entry.  For various internal reasons, we don't convert it
> back to a location expression.
> >
> > 2) Why location of "name" consists of 2 entries?
> Because the ranges appear disjoint, it could not merge them, since
> there appears to be a point during the routine where there is no way
> to validly get the value of name.
>
>
> > "[1]<lowpc=0x2ecf><highpc=0x2ed3>DW_OP_reg6" makes more sense to me,
> > as the range is exactly 4bytes, and name is in fact a pointer of 4
> > bytes.
>
> The lowpc and highpc are the range of program counters over which the
> expression is valid, *not* the place in memory where the variable
> lives.
>
>
> > But how about the 1st entry? What is its meaning?
>
> It means that during program execution, when the program counter is
> between 0x2e1b and 0x2eca, that the variable is in register 6.
>
> >
> > 3) Most important question to my project: in the case like above, how
> > to determine the run-time address of "name"? (Suppose that I can have
> > value of all the registers - I am on x86)
>
> It depends.
> The absolute simplest way is to store all the location ranges and
> expression, for the variable in an array:
>
> When you want to know the value of the variable
> 1. get the value of the current PC.
> 2. Look through the array to see if the PC falls within any of the
> location ranges.
>     a. If it does, evaluate the location expression to get the
> location of the variable
>     b. If it does not, the value is optimized out
> 3. Use the location of the variable to read it's value
>

Daniel, you are excellent!

Now I will go through this example again. So in this case, we have:

                 DW_AT_name                  name
                 DW_AT_decl_file             1 fs/namei.c
                 DW_AT_decl_line             1990
                 DW_AT_type                  <82>
                 DW_AT_location              <loclist with 2 entries follows>
==>                         [ 0]<lowpc=0x2e1b><highpc=0x2eca>DW_OP_reg6
==>                         [ 1]<lowpc=0x2ecf><highpc=0x2ed3>DW_OP_reg6


Because "name" variable belongs to fs/namei.c, the "lowpc" and
"highpc" mentioned in its loclist are relative to the *base* of the
*CU*. The CU means the object file, right? So we must look for the CU
of fs/namei.c. According to dwarfdump output, we have:

COMPILE_UNIT<header overall offset = 4000707>:
<0><   11>      DW_TAG_compile_unit
                DW_AT_stmt_list             280885
                DW_AT_high_pc               0xc0162b62
==>         DW_AT_low_pc                0xc015e9a0
                DW_AT_producer              GNU C 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
                DW_AT_language              DW_LANG_C89
                DW_AT_name                  fs/namei.c
                DW_AT_comp_dir              /home/jun/linux-2.6.16.29

I believe the base of the CU is the DW_AT_low_pc. So We must compute
the range of location for "name", which is 2 ranges:

(1) { DW_AT_low_pc of CU } + [range 1 of "name" location]
= 0xC015E9A0 + [<lowpc=0x2e1b> <highpc=0x2eca>]

(2) { DW_AT_low_pc of CU } + [range2 of "name" location]
= 0xC015E9A0 + [<lowpc=0x2ecf> <highpc=0x2ed3>]

Then we check the PC value (ie. EIP) to see if it falls into 1 of the
above 2 ranges.
Is that all correct so far?

Then the final step is to get the location from reg6 (ie.ESI on x86).
Am I correct in everything?




OK, if I am right, the final concern is: I am really shocked to see
these things. Before, I always suppose that the local variable like
"name" in this example can always be located via stack (ie. EBP). I
never think that they can be accessed in a different way. But it seems
it is much more complicated in reality. So why we cannot simplify
things by using EBP for stuffs on stack?


Thank you all for great helps.
Jun




From eager  Thu Oct  5 15:02:57 2006
From: eager (Michael Eager)
Date: Thu, 05 Oct 2006 08:02:57 -0700
Subject: [Dwarf-discuss] Question on loclist
In-Reply-To: <fdaac4d50610050740i7bf6c51cy36023d52e5767b42@mail.gmail.com>
References: <fdaac4d50610050311j3aff52fbkb5014129eee14203@mail.gmail.com>	<4aca3dc20610050651q5bb22548j2b758dece4a935f4@mail.gmail.com>
	<fdaac4d50610050740i7bf6c51cy36023d52e5767b42@mail.gmail.com>
Message-ID: <45251EA1.1030905@eagercon.com>

Jun Koi wrote:
> On 10/5/06, Daniel Berlin <dberlin at dberlin.org> wrote:
>>> I compiled kernel with debug info option, and use dwarfdump to extract
>>> information out. Then I got something corresponding to the above code:
>>>
>>> ...
>>>                 DW_AT_name                  do_rmdir
>>>                 DW_AT_decl_file             1 fs/namei.c
>>>                 DW_AT_decl_line             1988
>>>                 DW_AT_prototyped            yes(1)
>>>                 DW_AT_type                  <193>
>>>                 DW_AT_low_pc                0xc01617a0
>>>                 DW_AT_high_pc               0xc0161873
>>>                 DW_AT_frame_base            DW_OP_reg5
>>> <2><41023>      DW_TAG_formal_parameter
>>>                 DW_AT_name                  dfd
>>>                 DW_AT_decl_file             1 fs/namei.c
>>>                 DW_AT_decl_line             1987
>>>                 DW_AT_type                  <49>
>>>                 DW_AT_location              <loclist with 3 entries follows>
>>>                         [ 0]<lowpc=0x2e00><highpc=0x2e19>DW_OP_reg0
>>>                         [ 1]<lowpc=0x2e19><highpc=0x2e3f>DW_OP_reg3
>>>                         [ 2]<lowpc=0x2ec4><highpc=0x2ec7>DW_OP_reg3
>>> <2><41039>      DW_TAG_formal_parameter
>>>                 DW_AT_name                  pathname
>>>                 DW_AT_decl_file             1 fs/namei.c
>>>                 DW_AT_decl_line             1987
>>>                 DW_AT_type                  <64>
>>>                 DW_AT_location              <loclist with 1 entries follows>
>>>                         [ 0]<lowpc=0x2e00><highpc=0x2e19>DW_OP_reg2
>>> <2><41055>      DW_TAG_variable
>>>                 DW_AT_name                  error
>>>                 DW_AT_decl_file             1 fs/namei.c
>>>                 DW_AT_decl_line             1989
>>>                 DW_AT_type                  <49>
>>>                 DW_AT_location              <loclist with 3 entries follows>
>>>                         [ 0]<lowpc=0x2e3b><highpc=0x2e3d>DW_OP_reg0
>>>                         [ 1]<lowpc=0x2e3f><highpc=0x2e53>DW_OP_reg3
>>>                         [ 2]<lowpc=0x2e7a><highpc=0x2ec7>DW_OP_reg3
>>> <2><41071>      DW_TAG_variable
>>>                 DW_AT_name                  name
>>>                 DW_AT_decl_file             1 fs/namei.c
>>>                 DW_AT_decl_line             1990
>>>                 DW_AT_type                  <82>
>>>                 DW_AT_location              <loclist with 2 entries follows>
>>>                         [ 0]<lowpc=0x2e1b><highpc=0x2eca>DW_OP_reg6
>>>                         [ 1]<lowpc=0x2ecf><highpc=0x2ed3>DW_OP_reg6
>>> .....
>>>
>>>
>>> I have few questions:
>>>
>>> 1) Why the location of variable "name" is not made with plain location
>>> expression (like DW_OP_breg5...), but loclist?
>> Because GCC decided to use a location list, and it turned out later it
>> only had one entry.  For various internal reasons, we don't convert it
>> back to a location expression.
>>> 2) Why location of "name" consists of 2 entries?
>> Because the ranges appear disjoint, it could not merge them, since
>> there appears to be a point during the routine where there is no way
>> to validly get the value of name.
>>
>>
>>> "[1]<lowpc=0x2ecf><highpc=0x2ed3>DW_OP_reg6" makes more sense to me,
>>> as the range is exactly 4bytes, and name is in fact a pointer of 4
>>> bytes.
>> The lowpc and highpc are the range of program counters over which the
>> expression is valid, *not* the place in memory where the variable
>> lives.
>>
>>
>>> But how about the 1st entry? What is its meaning?
>> It means that during program execution, when the program counter is
>> between 0x2e1b and 0x2eca, that the variable is in register 6.
>>
>>> 3) Most important question to my project: in the case like above, how
>>> to determine the run-time address of "name"? (Suppose that I can have
>>> value of all the registers - I am on x86)
>> It depends.
>> The absolute simplest way is to store all the location ranges and
>> expression, for the variable in an array:
>>
>> When you want to know the value of the variable
>> 1. get the value of the current PC.
>> 2. Look through the array to see if the PC falls within any of the
>> location ranges.
>>     a. If it does, evaluate the location expression to get the
>> location of the variable
>>     b. If it does not, the value is optimized out
>> 3. Use the location of the variable to read it's value
>>
> 
> Daniel, you are excellent!
> 
> Now I will go through this example again. So in this case, we have:
> 
>                  DW_AT_name                  name
>                  DW_AT_decl_file             1 fs/namei.c
>                  DW_AT_decl_line             1990
>                  DW_AT_type                  <82>
>                  DW_AT_location              <loclist with 2 entries follows>
> ==>                         [ 0]<lowpc=0x2e1b><highpc=0x2eca>DW_OP_reg6
> ==>                         [ 1]<lowpc=0x2ecf><highpc=0x2ed3>DW_OP_reg6
> 
> 
> Because "name" variable belongs to fs/namei.c, the "lowpc" and
> "highpc" mentioned in its loclist are relative to the *base* of the
> *CU*. The CU means the object file, right? So we must look for the CU
> of fs/namei.c. According to dwarfdump output, we have:
> 
> COMPILE_UNIT<header overall offset = 4000707>:
> <0><   11>      DW_TAG_compile_unit
>                 DW_AT_stmt_list             280885
>                 DW_AT_high_pc               0xc0162b62
> ==>         DW_AT_low_pc                0xc015e9a0
>                 DW_AT_producer              GNU C 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
>                 DW_AT_language              DW_LANG_C89
>                 DW_AT_name                  fs/namei.c
>                 DW_AT_comp_dir              /home/jun/linux-2.6.16.29
> 
> I believe the base of the CU is the DW_AT_low_pc. So We must compute
> the range of location for "name", which is 2 ranges:
> 
> (1) { DW_AT_low_pc of CU } + [range 1 of "name" location]
> = 0xC015E9A0 + [<lowpc=0x2e1b> <highpc=0x2eca>]
> 
> (2) { DW_AT_low_pc of CU } + [range2 of "name" location]
> = 0xC015E9A0 + [<lowpc=0x2ecf> <highpc=0x2ed3>]
> 
> Then we check the PC value (ie. EIP) to see if it falls into 1 of the
> above 2 ranges.
> Is that all correct so far?
> 
> Then the final step is to get the location from reg6 (ie.ESI on x86).
> Am I correct in everything?
> 
> 
> 
> 
> OK, if I am right, the final concern is: I am really shocked to see
> these things. Before, I always suppose that the local variable like
> "name" in this example can always be located via stack (ie. EBP). I
> never think that they can be accessed in a different way. But it seems
> it is much more complicated in reality. So why we cannot simplify
> things by using EBP for stuffs on stack?

Gcc will frequently allocate local variables to registers.  There
may not be a stack location reserved for 'name'.  All you know is
that within the specified pc range, the value of name can be found
in reg6.

-- 
Michael Eager	 eager at eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077




From junkoi2004  Fri Oct  6 18:23:24 2006
From: junkoi2004 (Jun Koi)
Date: Sat, 7 Oct 2006 03:23:24 +0900
Subject: [Dwarf-discuss] asmlinkage directive with debug_line ?
Message-ID: <fdaac4d50610061123m1242779ai581d475f3ea1d56b@mail.gmail.com>

Hi,

Anybody please tell me why asmlinkage directive in Linux kernel code
makes its content disappear from debug_line section?

I compiled Linux kernel, and found that in a file with several
asmlinkage directives (like sys_read() in fs/read_write.c), many lines
are not listed in debug_line at all. Why that happened? And in that
case, how can a debugger solve the problem of reasoning to the source
code in a syscall?

Thank you,
Jun




From eager  Fri Oct  6 18:28:56 2006
From: eager (Michael Eager)
Date: Fri, 06 Oct 2006 11:28:56 -0700
Subject: [Dwarf-discuss] asmlinkage directive with debug_line ?
In-Reply-To: <fdaac4d50610061123m1242779ai581d475f3ea1d56b@mail.gmail.com>
References: <fdaac4d50610061123m1242779ai581d475f3ea1d56b@mail.gmail.com>
Message-ID: <4526A068.1020602@eagercon.com>

Jun Koi wrote:
> Hi,
> 
> Anybody please tell me why asmlinkage directive in Linux kernel code
> makes its content disappear from debug_line section?
> 
> I compiled Linux kernel, and found that in a file with several
> asmlinkage directives (like sys_read() in fs/read_write.c), many lines
> are not listed in debug_line at all. Why that happened? And in that
> case, how can a debugger solve the problem of reasoning to the source
> code in a syscall?

The DWARF mailing list is for discussions about the DWARF
Debugging Standard, not about details of how a particular compiler
or debugger implement the standard.

Possibly someone on the GCC mailing list can offer
some answer to your question.

One first suggestion I would have is that you compile
the source in question and take a look at the assembly
code which the compiler generates.

-- 
Michael Eager	 eager at eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077




From junkoi2004  Fri Oct  6 18:32:54 2006
From: junkoi2004 (Jun Koi)
Date: Sat, 7 Oct 2006 03:32:54 +0900
Subject: [Dwarf-discuss] DW_OP_bregx access?
Message-ID: <fdaac4d50610061132k2a0f258eh9e85326c781a4e24@mail.gmail.com>

Hi,

I am having problem with accessing DW_OP_breg5 on Linux kernel. The
problem is with the vfs_read() function in fs/read_write.c


ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
{
....
}


According to debug_info, we have information about the "buf" param in
the above function like below:


      <2><29552>      DW_TAG_formal_parameter
          DW_AT_name                  buf
          DW_AT_decl_file             1 fs/read_write.c
          DW_AT_decl_line             247
          DW_AT_type                  <555>
          DW_AT_location              DW_OP_breg5+12


So it seems that we can access to "buf" by accessing the memory at the
address (EBP+12) (because breg5 == EBP in gcc)

Then I tried to copy the data from "buf" to other area, ie. something like this

memcpy(myarray, (char *)(EBP+12), number);

But to my surprise, everytime I did this, I got the same data in
"myarray". In fact the data must be different, because each time I
feeded the read syscall (ie. feed vfs_read()) different data.

I am stuck here. Probably I interpreted the way to use breg5+12 in a wrong way?


Thank you lots.
Jun




From eager  Fri Oct  6 19:47:46 2006
From: eager (Michael Eager)
Date: Fri, 06 Oct 2006 12:47:46 -0700
Subject: [Dwarf-discuss] DW_OP_bregx access?
In-Reply-To: <fdaac4d50610061132k2a0f258eh9e85326c781a4e24@mail.gmail.com>
References: <fdaac4d50610061132k2a0f258eh9e85326c781a4e24@mail.gmail.com>
Message-ID: <4526B2E2.5060806@eagercon.com>

Jun Koi wrote:

> Then I tried to copy the data from "buf" to other area, ie. something like this
> 
> memcpy(myarray, (char *)(EBP+12), number);
> 
> But to my surprise, everytime I did this, I got the same data in
> "myarray". In fact the data must be different, because each time I
> feeded the read syscall (ie. feed vfs_read()) different data.
> 
> I am stuck here. Probably I interpreted the way to use breg5+12 in a wrong way?

Your interpretation of DWARF looks correct.

There's far too little information here about what you are
doing to be able to offer any help.  There are any number of
reasons why you would get the same data in myarray, most of
which would seem to be bugs in your code.

Is the value you compute for of EBP correct?  Are you evaluating
it each time you enter the routine?  What does printk in the
routine say the value of buf is?  Does printk of the data match
the data you copy?

-- 
Michael Eager	 eager at eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077




From junkoi2004  Sat Oct  7 06:24:20 2006
From: junkoi2004 (Jun Koi)
Date: Sat, 7 Oct 2006 15:24:20 +0900
Subject: [Dwarf-discuss] asmlinkage directive with debug_line ?
In-Reply-To: <4526A068.1020602@eagercon.com>
References: <fdaac4d50610061123m1242779ai581d475f3ea1d56b@mail.gmail.com>
	<4526A068.1020602@eagercon.com>
Message-ID: <fdaac4d50610062324y30edb017r15a891a2bbe8e103@mail.gmail.com>

Hi Micheal,


On 10/7/06, Michael Eager <eager at eagercon.com> wrote:
> Jun Koi wrote:
> > Hi,
> >
> > Anybody please tell me why asmlinkage directive in Linux kernel code
> > makes its content disappear from debug_line section?
> >
> > I compiled Linux kernel, and found that in a file with several
> > asmlinkage directives (like sys_read() in fs/read_write.c), many lines
> > are not listed in debug_line at all. Why that happened? And in that
> > case, how can a debugger solve the problem of reasoning to the source
> > code in a syscall?
>
> The DWARF mailing list is for discussions about the DWARF
> Debugging Standard, not about details of how a particular compiler
> or debugger implement the standard.
>
> Possibly someone on the GCC mailing list can offer
> some answer to your question.

I have found the reason: some lines that are missing from debug_line
are macro codes. There is nothing to do with the asmlinkage directive
at all.

>
> One first suggestion I would have is that you compile
> the source in question and take a look at the assembly
> code which the compiler generates.

Great idea, indeed. Thank you for this suggestion.


Best,
Jun




From junkoi2004  Sat Oct  7 06:26:15 2006
From: junkoi2004 (Jun Koi)
Date: Sat, 7 Oct 2006 15:26:15 +0900
Subject: [Dwarf-discuss] DW_OP_bregx access?
In-Reply-To: <4526B2E2.5060806@eagercon.com>
References: <fdaac4d50610061132k2a0f258eh9e85326c781a4e24@mail.gmail.com>
	<4526B2E2.5060806@eagercon.com>
Message-ID: <fdaac4d50610062326t15c0ba48v3c68e10e2b5550cd@mail.gmail.com>

On 10/7/06, Michael Eager <eager at eagercon.com> wrote:
> Jun Koi wrote:
>
> > Then I tried to copy the data from "buf" to other area, ie. something like this
> >
> > memcpy(myarray, (char *)(EBP+12), number);
> >
> > But to my surprise, everytime I did this, I got the same data in
> > "myarray". In fact the data must be different, because each time I
> > feeded the read syscall (ie. feed vfs_read()) different data.
> >
> > I am stuck here. Probably I interpreted the way to use breg5+12 in a wrong way?
>
> Your interpretation of DWARF looks correct.
>

Great to hear that :-)

> There's far too little information here about what you are
> doing to be able to offer any help.  There are any number of
> reasons why you would get the same data in myarray, most of
> which would seem to be bugs in your code.
>
> Is the value you compute for of EBP correct?  Are you evaluating
> it each time you enter the routine?  What does printk in the
> routine say the value of buf is?  Does printk of the data match
> the data you copy?

Yes, I did, but it seems nothing wrong to me. I will try to
investigate again, and post what I found for further discussions.

Many thanks, Micheal.
Jun




From junkoi2004  Sat Oct  7 06:27:52 2006
From: junkoi2004 (Jun Koi)
Date: Sat, 7 Oct 2006 15:27:52 +0900
Subject: [Dwarf-discuss] multiple entries for one line of code in
	.debug_line ?
Message-ID: <fdaac4d50610062327m770ef7cbk99fd24a7c1d9324a@mail.gmail.com>

Hello,

I used dwarfdump to get information on source codes, and saw something
strange: one line of code may make up to 4 entries in debug_line?

For example, please see the below code (from Linux kernel):


asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf,
size_t count)
{
    struct file *file;
    ssize_t ret = -EBADF;
    int fput_needed;

    file = fget_light(fd, &fput_needed);
    if (file) {
        loff_t pos = file_pos_read(file);
        ret = vfs_write(file, buf, count, &pos);       <==== ? (line 369)
        file_pos_write(file, pos);
        fput_light(file, fput_needed);
    }

    return ret;
}



The line "ret = vfs_write(...)" at line 369 got 4 entries like below
(vfs_write() is a normal function, not a macro):


/home/jun/projects/linux-2.6.16.29/fs/read_write.c:       [369,-1]
   0xc01526c4      // new statement
/home/jun/projects/0928/linux-2.6.16.29/fs/read_write.c:
[369,-1]        0xc01526ca      // new statement
/home/jun/projects/0928/linux-2.6.16.29/fs/read_write.c:
[369,-1]        0xc01526d0      // new statement
/home/jun/projects/0928/linux-2.6.16.29/fs/read_write.c:
[369,-1]        0xc01526ea      // new statement


Is there any reason of that? As I observed, normally a line of code
has only 1 debug_line entry.


Many thanks.
Jun




From syk  Sat Oct  7 14:49:36 2006
From: syk (Sebastian Krawczuk)
Date: Sat, 07 Oct 2006 10:49:36 -0400
Subject: [Dwarf-discuss] multiple entries for one line of code
 in	.debug_line ?
In-Reply-To: <fdaac4d50610062327m770ef7cbk99fd24a7c1d9324a@mail.gmail.com>
References: <fdaac4d50610062327m770ef7cbk99fd24a7c1d9324a@mail.gmail.com>
Message-ID: <4527BE80.5090500@ocsystems.com>

Jun,

All is fine.  Anything that your compiler emitted in rage 0xc01526c4 
and  0xc01526ea  is in reference to your 'return' statement at line 
369.  Maybe the compiler broken it into atomic operations and had to 
produce such source line table.  I don't know.  I would not worry too 
much and just aggregate data from such entries and interpret is as one 
line entry and range 0xc01526c4-0xc01526ea.

Good luck!
Sebastian.

PS.  It looks like we do your homework here ;)

Jun Koi wrote:
> Hello,
>
> I used dwarfdump to get information on source codes, and saw something
> strange: one line of code may make up to 4 entries in debug_line?
>
> For example, please see the below code (from Linux kernel):
>
>
> asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf,
> size_t count)
> {
>     struct file *file;
>     ssize_t ret = -EBADF;
>     int fput_needed;
>
>     file = fget_light(fd, &fput_needed);
>     if (file) {
>         loff_t pos = file_pos_read(file);
>         ret = vfs_write(file, buf, count, &pos);       <==== ? (line 369)
>         file_pos_write(file, pos);
>         fput_light(file, fput_needed);
>     }
>
>     return ret;
> }
>
>
>
> The line "ret = vfs_write(...)" at line 369 got 4 entries like below
> (vfs_write() is a normal function, not a macro):
>
>
> /home/jun/projects/linux-2.6.16.29/fs/read_write.c:       [369,-1]
>    0xc01526c4      // new statement
> /home/jun/projects/0928/linux-2.6.16.29/fs/read_write.c:
> [369,-1]        0xc01526ca      // new statement
> /home/jun/projects/0928/linux-2.6.16.29/fs/read_write.c:
> [369,-1]        0xc01526d0      // new statement
> /home/jun/projects/0928/linux-2.6.16.29/fs/read_write.c:
> [369,-1]        0xc01526ea      // new statement
>
>
> Is there any reason of that? As I observed, normally a line of code
> has only 1 debug_line entry.
>
>
> Many thanks.
> Jun
>
> _______________________________________________
> Dwarf-discuss mailing list
> Dwarf-discuss at lists.freestandards.org
> http://lists.freestandards.org/mailman/listinfo/dwarf-discuss
>   




From junkoi2004  Sun Oct  8 00:21:24 2006
From: junkoi2004 (Jun Koi)
Date: Sun, 8 Oct 2006 09:21:24 +0900
Subject: [Dwarf-discuss] multiple entries for one line of code in
	.debug_line ?
In-Reply-To: <4527BE80.5090500@ocsystems.com>
References: <fdaac4d50610062327m770ef7cbk99fd24a7c1d9324a@mail.gmail.com>
	<4527BE80.5090500@ocsystems.com>
Message-ID: <fdaac4d50610071721t6b91f560k4466ad66908900c1@mail.gmail.com>

Hi Sebastian,

On 10/7/06, Sebastian Krawczuk <syk at ocsystems.com> wrote:
> Jun,
>
> All is fine.  Anything that your compiler emitted in rage 0xc01526c4
> and  0xc01526ea  is in reference to your 'return' statement at line
> 369.  Maybe the compiler broken it into atomic operations and had to
> produce such source line table.  I don't know.  I would not worry too
> much and just aggregate data from such entries and interpret is as one
> line entry and range 0xc01526c4-0xc01526ea.
>

What an excellent explanation. Thank you.

> Good luck!
> Sebastian.
>
> PS.  It looks like we do your homework here ;)

It .. is ... not! Because I am not a student!

This is my personal project, for hobby only :-)

Best,
Jun

> > Hello,
> >
> > I used dwarfdump to get information on source codes, and saw something
> > strange: one line of code may make up to 4 entries in debug_line?
> >
> > For example, please see the below code (from Linux kernel):
> >
> >
> > asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf,
> > size_t count)
> > {
> >     struct file *file;
> >     ssize_t ret = -EBADF;
> >     int fput_needed;
> >
> >     file = fget_light(fd, &fput_needed);
> >     if (file) {
> >         loff_t pos = file_pos_read(file);
> >         ret = vfs_write(file, buf, count, &pos);       <==== ? (line 369)
> >         file_pos_write(file, pos);
> >         fput_light(file, fput_needed);
> >     }
> >
> >     return ret;
> > }
> >
> >
> >
> > The line "ret = vfs_write(...)" at line 369 got 4 entries like below
> > (vfs_write() is a normal function, not a macro):
> >
> >
> > /home/jun/projects/linux-2.6.16.29/fs/read_write.c:       [369,-1]
> >    0xc01526c4      // new statement
> > /home/jun/projects/0928/linux-2.6.16.29/fs/read_write.c:
> > [369,-1]        0xc01526ca      // new statement
> > /home/jun/projects/0928/linux-2.6.16.29/fs/read_write.c:
> > [369,-1]        0xc01526d0      // new statement
> > /home/jun/projects/0928/linux-2.6.16.29/fs/read_write.c:
> > [369,-1]        0xc01526ea      // new statement
> >
> >
> > Is there any reason of that? As I observed, normally a line of code
> > has only 1 debug_line entry.
> >
> >
> > Many thanks.
> > Jun
> >
> > _______________________________________________
> > Dwarf-discuss mailing list
> > Dwarf-discuss at lists.freestandards.org
> > http://lists.freestandards.org/mailman/listinfo/dwarf-discuss
> >
>
>




From junkoi2004  Sun Oct  8 00:24:47 2006
From: junkoi2004 (Jun Koi)
Date: Sun, 8 Oct 2006 09:24:47 +0900
Subject: [Dwarf-discuss] multiple entries for one line of code in
	.debug_line ?
In-Reply-To: <fdaac4d50610071721t6b91f560k4466ad66908900c1@mail.gmail.com>
References: <fdaac4d50610062327m770ef7cbk99fd24a7c1d9324a@mail.gmail.com>
	<4527BE80.5090500@ocsystems.com>
	<fdaac4d50610071721t6b91f560k4466ad66908900c1@mail.gmail.com>
Message-ID: <fdaac4d50610071724u7d5a3a4eo341aed19f82d8b66@mail.gmail.com>

On 10/8/06, Jun Koi <junkoi2004 at gmail.com> wrote:
> Hi Sebastian,
>
> On 10/7/06, Sebastian Krawczuk <syk at ocsystems.com> wrote:
> > Jun,
> >
> > All is fine.  Anything that your compiler emitted in rage 0xc01526c4
> > and  0xc01526ea  is in reference to your 'return' statement at line
> > 369.  Maybe the compiler broken it into atomic operations and had to
> > produce such source line table.  I don't know.  I would not worry too
> > much and just aggregate data from such entries and interpret is as one
> > line entry and range 0xc01526c4-0xc01526ea.
> >

OK, but I think again on this matter: as I understand, each line of
code should have a range of address, which indicate the start and end
address of the code, right?

But as I observed, some lines of code has only one entry, which can be
interpreted as start address. So in these cases, we dont have the end
address of that line of code???

Thank you,
Jun


> >
> > PS.  It looks like we do your homework here ;)
>
> It .. is ... not! Because I am not a student!
>
> This is my personal project, for hobby only :-)
>
> Best,
> Jun
>
> > > Hello,
> > >
> > > I used dwarfdump to get information on source codes, and saw something
> > > strange: one line of code may make up to 4 entries in debug_line?
> > >
> > > For example, please see the below code (from Linux kernel):
> > >
> > >
> > > asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf,
> > > size_t count)
> > > {
> > >     struct file *file;
> > >     ssize_t ret = -EBADF;
> > >     int fput_needed;
> > >
> > >     file = fget_light(fd, &fput_needed);
> > >     if (file) {
> > >         loff_t pos = file_pos_read(file);
> > >         ret = vfs_write(file, buf, count, &pos);       <==== ? (line 369)
> > >         file_pos_write(file, pos);
> > >         fput_light(file, fput_needed);
> > >     }
> > >
> > >     return ret;
> > > }
> > >
> > >
> > >
> > > The line "ret = vfs_write(...)" at line 369 got 4 entries like below
> > > (vfs_write() is a normal function, not a macro):
> > >
> > >
> > > /home/jun/projects/linux-2.6.16.29/fs/read_write.c:       [369,-1]
> > >    0xc01526c4      // new statement
> > > /home/jun/projects/0928/linux-2.6.16.29/fs/read_write.c:
> > > [369,-1]        0xc01526ca      // new statement
> > > /home/jun/projects/0928/linux-2.6.16.29/fs/read_write.c:
> > > [369,-1]        0xc01526d0      // new statement
> > > /home/jun/projects/0928/linux-2.6.16.29/fs/read_write.c:
> > > [369,-1]        0xc01526ea      // new statement
> > >
> > >
> > > Is there any reason of that? As I observed, normally a line of code
> > > has only 1 debug_line entry.
> > >
> > >
> > > Many thanks.
> > > Jun
> > >
> > > _______________________________________________
> > > Dwarf-discuss mailing list
> > > Dwarf-discuss at lists.freestandards.org
> > > http://lists.freestandards.org/mailman/listinfo/dwarf-discuss
> > >
> >
> >
>




From junkoi2004  Sun Oct  8 17:38:28 2006
From: junkoi2004 (Jun Koi)
Date: Mon, 9 Oct 2006 02:38:28 +0900
Subject: [Dwarf-discuss] address of variable out of range of its function?
Message-ID: <fdaac4d50610081038h6d9fcfc3oda090d6820ee8129@mail.gmail.com>

Hi,

I use the latest dwarfdump (0925) and dump out the Linux kernel. Here
is what I cannot understand: I saw a variable but its loclist is out
of range of its function. So in that case, how can we access it? I
banged the below bug for whole day, but about to give up now.

Here is the function:


      static long do_unlinkat(int dfd, const char __user *pathname)
      {
          int error = 0;
          char * name;
          struct dentry *dentry;
          struct nameidata nd;
          struct inode *inode = NULL;

          name = getname(pathname);
          if(IS_ERR(name))
              return PTR_ERR(name);

          error = do_path_lookup(dfd, name, LOOKUP_PARENT, &nd);
          if (error)
              goto exit;
 ........

Dwarfdump gave me something like below:

<1><40747>      DW_TAG_subprogram
                DW_AT_sibling               <40953>
                DW_AT_name                  do_unlinkat
                DW_AT_decl_file             1 fs/namei.c
                DW_AT_decl_line             2070
                DW_AT_prototyped            yes(1)
                DW_AT_type                  <193>
                DW_AT_low_pc                0xc0161640
                DW_AT_high_pc               0xc0161782
                DW_AT_frame_base            DW_OP_reg5
<2><40822>      DW_TAG_variable
                DW_AT_name                  name
                DW_AT_decl_file             1 fs/namei.c
                DW_AT_decl_line             2072
                DW_AT_type                  <82>
                DW_AT_location              <loclist with 1 entries follows>
                        [ 0]<lowpc=0x2ccd><highpc=0x2cd7>DW_OP_reg2

As you see, variable "name" has only 1 loclist entry, and can be
accessed only via reg2.
However, while the function do_unlinkat() ranges in [0xc0161640,
0xc0161782], the variable "name" within the function can only be
accessed if the PC is within [0xc0161640 + 0x2ccd, 0xc0161640 +
0x2cd7] == [0xc0164317, 0xc016430d], which is way out of the range of
the do_unlinkat() function (??). That means there is no way to access
to it from within function (??)


No surprise that I could not access the "name" variable using the reg2
within the function (I tried to get to it with reg2, but got only the
incorrect data).

So what is wrong here? How can I interprete the address of variable
"name" in this case?


Thank you a lot,
Jun




From eager  Sun Oct  8 18:23:02 2006
From: eager (Michael Eager)
Date: Sun, 08 Oct 2006 11:23:02 -0700
Subject: [Dwarf-discuss] multiple entries for one line of code
 in	.debug_line ?
In-Reply-To: <fdaac4d50610071724u7d5a3a4eo341aed19f82d8b66@mail.gmail.com>
References: <fdaac4d50610062327m770ef7cbk99fd24a7c1d9324a@mail.gmail.com>	<4527BE80.5090500@ocsystems.com>	<fdaac4d50610071721t6b91f560k4466ad66908900c1@mail.gmail.com>
	<fdaac4d50610071724u7d5a3a4eo341aed19f82d8b66@mail.gmail.com>
Message-ID: <45294206.9010703@eagercon.com>

Jun Koi wrote:
> On 10/8/06, Jun Koi <junkoi2004 at gmail.com> wrote:
>> Hi Sebastian,
>>
>> On 10/7/06, Sebastian Krawczuk <syk at ocsystems.com> wrote:
>>> Jun,
>>>
>>> All is fine.  Anything that your compiler emitted in rage 0xc01526c4
>>> and  0xc01526ea  is in reference to your 'return' statement at line
>>> 369.  Maybe the compiler broken it into atomic operations and had to
>>> produce such source line table.  I don't know.  I would not worry too
>>> much and just aggregate data from such entries and interpret is as one
>>> line entry and range 0xc01526c4-0xc01526ea.
>>>
> 
> OK, but I think again on this matter: as I understand, each line of
> code should have a range of address, which indicate the start and end
> address of the code, right?

No.

> But as I observed, some lines of code has only one entry, which can be
> interpreted as start address. So in these cases, we dont have the end
> address of that line of code???

Please read the description of the line table again.
It's perhaps a bit complex.

The table is *not* a mapping from line to address.  The
mapping goes in the other direction, from address to line.

-- 
Michael Eager	 eager at eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077




From frederic.riss  Mon Oct  9 07:56:09 2006
From: frederic.riss (Frederic RISS)
Date: Mon, 09 Oct 2006 09:56:09 +0200
Subject: [Dwarf-discuss] address of variable out of range of
	its	function?
In-Reply-To: <fdaac4d50610081038h6d9fcfc3oda090d6820ee8129@mail.gmail.com>
References: <fdaac4d50610081038h6d9fcfc3oda090d6820ee8129@mail.gmail.com>
Message-ID: <1160380569.13420.20.camel@crx549.cro.st.com>

On Mon, 2006-10-09 at 02:38 +0900, Jun Koi wrote:
> 
> <1><40747>      DW_TAG_subprogram
>                 DW_AT_name                  do_unlinkat
>                 DW_AT_low_pc                0xc0161640
> <2><40822>      DW_TAG_variable
>                 DW_AT_name                  name
>                 DW_AT_location              <loclist with 1 entries
> follows>
>                         [ 0]<lowpc=0x2ccd><highpc=0x2cd7>DW_OP_reg2
> 
> As you see, variable "name" has only 1 loclist entry, and can be
> accessed only via reg2.
> However, while the function do_unlinkat() ranges in [0xc0161640,
> 0xc0161782], the variable "name" within the function can only be
> accessed if the PC is within [0xc0161640 + 0x2ccd, 0xc0161640 +
> 0x2cd7] == [0xc0164317, 0xc016430d], which is way out of the range of
> the do_unlinkat() function (??). That means there is no way to access
> to it from within function (??) 

The loclist ranges are relative to the compilation unit low_pc, not to
the function's one IIRC.

Fred.




