Month: April 2015

I finally understand why “DW_OP_fbreg: 0” is possible

In the following function kmalloc2, take a look the first parameter, the memory location of that parameter is stated by dwarf “DW_AT_location : 2 byte block: 91 0 (DW_OP_fbreg: 0)”, where “DW_OP_fbreg: 0” means stack+0. I was thinking why it is possible. Because when cpu executed call instruction, it already pushed 4 bytes into the stack. So the offset of the first parameter should be ESP+4, not ESP+0.

 <1><502c>: Abbrev Number: 34 (DW_TAG_subprogram)
    <502d>   DW_AT_external    : 1      
    <502d>   DW_AT_name        : (indirect string, offset: 0x18cd): kmalloc2    
    <5031>   DW_AT_decl_file   : 1      
    <5032>   DW_AT_decl_line   : 725    
    <5034>   DW_AT_prototyped  : 1      
    <5034>   DW_AT_type        : <0x482e>       
    <5038>   DW_AT_low_pc      : 0x1607b50      
    <503c>   DW_AT_high_pc     : 0x82   
    <5040>   DW_AT_frame_base  : 1 byte block: 9c       (DW_OP_call_frame_cfa)
    <5042>   DW_AT_GNU_all_call_sites: 1        
    <5042>   DW_AT_sibling     : <0x50d4>       
 <2><5046>: Abbrev Number: 39 (DW_TAG_formal_parameter)
    <5047>   DW_AT_name        : (indirect string, offset: 0x17aa): virtualAddress      
    <504b>   DW_AT_decl_file   : 1      
    <504c>   DW_AT_decl_line   : 725    
    <504e>   DW_AT_type        : <0x47da>       
    <5052>   DW_AT_location    : 2 byte block: 91 0     (DW_OP_fbreg: 0)

I searched around in google and has no answer, finally i found this chinese blog http://tsecer.blog.163.com/blog/static/150181720118395251117/. And I finally know even i don’t have .debug_frames, but I have .eh_frame section. After I dump it out that section, it should be the formula of DW_OP_call_frame_cfa is “r4 (esp) ofs 4”, which mean esp plus four.

read count : 407

objdump has bug

objdump command has bug, i tried to use this command “objdump -dS kernel” to display mixed assembly and c code. But objdump has bug, it dump the same piece of c source code in two different memory locations. I double checked the dwarf data, nothing wrong. On more prove the dwarf is correct, my GKD debugger can dump the source correctly.

objdump has bug
objdump has bug

gkd is better than objdump

below is the code:

void *kmalloc2(unsigned int virtualAddress, unsigned int physicalAddress,
                unsigned size) {
        unsigned int PDselector = virtualAddress >> 22;
        unsigned int PTselector = (virtualAddress >> 12) & 0x3ff;

        // All the kernel's Page Directory is already linked to corresponding page table, so we don't need to create page directory, we just ended to fill in the free physical address into the page tables
        unsigned int freeContinuousPhysicalAddress = physicalAddress;

        //Page_Directory *pageDirectories=(Page_Directory *)0x1100000;
        unsigned int numberOfPage = (size % 4096 == 0) ? size / 4096 : size / 4096
                        + 1;
        struct Page_Table *pageTablesBase = (struct Page_Table *) 0x1101000
                        + PTselector + PDselector * 1024;
        unsigned int pageNo;
        for (pageNo = 0; pageNo < numberOfPage; pageNo++) {
                pageTablesBase->pageTableBase = (freeContinuousPhysicalAddress
                                + (pageNo * 4096)) >> 12;
                pageTablesBase++;
        }
        return (void *) virtualAddress;
}

I compile it by:

system.o : system.c
        $(CC) -I$(NEWLIB_DIR)/include -c -g $? -ffreestanding -Wall -Wno-long-long -O2 -fno-exceptions -fno-builtin -o $@

read count : 353

I finally understand why same parameter even has multiple locations

I finally understand why same parameter even has multiple locations. My pass concept is parameter stay in the stack. But after hacking the dwarf, it show me same parameter have multiple location during execution. Take a look below image, I wrote a function call kmalloc2 (blue arrow), the third parameter “size” has three locations (yellow arrow) during executing that function. The reason is that compile will move the parameter value from stack (rd arrow) to register ecx (green arrow), so during the execution this parameter has multiple locations. Dwarf is able to point you out where it is.

parameter has multiple locations
parameter has multiple locations

read count : 303