Newbie asm: where is the call code?

paulAl picture paulAl · Mar 18, 2012 · Viewed 9.6k times · Source

I wrote this simple kernel module:

#include <linux/module.h>        // for printk() 

int init( void ) 
{ 
    printk( "n  Kello, everybody! nn" ); 

    return    0; 
} 

void exit( void ) 
{ 
    printk( "n  Goodbye now... nn" ); 
} 

MODULE_LICENSE("GPL"); 
module_init(init); 
module_exit(exit); 

and I'm trying to understand how the code gets translated to asm, so I objdumped it:

root@ubuntu:/home/alex/Desktop/KModule# objdump -D kmodule.ko 

kmodule.ko:    file format elf64-x86-64 


Disassembly of section .note.gnu.build-id: 

0000000000000000 <.note.gnu.build-id>: 
  0:    04 00                    add    $0x0,%al 
  2:    00 00                    add    %al,(%rax) 
  4:    14 00                    adc    $0x0,%al 
  6:    00 00                    add    %al,(%rax) 
  8:    03 00                    add    (%rax),%eax 
  a:    00 00                    add    %al,(%rax) 
  c:    47                      rex.RXB 
  d:    4e 55                    rex.WRX push %rbp 
  f:    00 5e ef                add    %bl,-0x11(%rsi) 
  12:    7d 73                    jge    87 <__mod_vermagic5+0x4f> 
  14:    83 47 e9 4d              addl  $0x4d,-0x17(%rdi) 
  18:    98                      cwtl  
  19:    eb b8                    jmp    ffffffffffffffd3 <__mod_vermagic5+0xffffffffffffff9b> 
  1b:    eb 18                    jmp    35 <__module_depends+0x6> 
  1d:    fb                      sti    
  1e:    84 28                    test  %ch,(%rax) 
  20:    73 db                    jae    fffffffffffffffd <__mod_vermagic5+0xffffffffffffffc5> 
  22:    51                      push  %rcx 
  23:    e4                      .byte 0xe4 

Disassembly of section .text: 

0000000000000000 <init>: 
  0:    55                      push  %rbp 
  1:    48 89 e5                mov    %rsp,%rbp 
  4:    e8 00 00 00 00          callq  9 <init+0x9> 
  9:    48 c7 c7 00 00 00 00     mov    $0x0,%rdi 
  10:    31 c0                    xor    %eax,%eax 
  12:    e8 00 00 00 00          callq  17 <init+0x17> 
  17:    31 c0                    xor    %eax,%eax 
  19:    5d                      pop    %rbp 
  1a:    c3                      retq  
  1b:    0f 1f 44 00 00          nopl  0x0(%rax,%rax,1) 

0000000000000020 <cleanup_module>: 
  20:    55                      push  %rbp 
  21:    48 89 e5                mov    %rsp,%rbp 
  24:    e8 00 00 00 00          callq  29 <cleanup_module+0x9> 
  29:    48 c7 c7 00 00 00 00     mov    $0x0,%rdi 
  30:    31 c0                    xor    %eax,%eax 
  32:    e8 00 00 00 00          callq  37 <cleanup_module+0x17> 
  37:    5d                      pop    %rbp 
  38:    c3                      retq  
  39:    00 00                    add    %al,(%rax) 
    ... 

Disassembly of section .rodata.str1.1: 

0000000000000000 <.rodata.str1.1>: 
  0:    0a 20                    or    (%rax),%ah 
  2:    20 20                    and    %ah,(%rax) 
  4:    4b                      rex.WXB 
  5:    65                      gs 
  6:    6c                      insb  (%dx),%es:(%rdi) 
  7:    6c                      insb  (%dx),%es:(%rdi) 
  8:    6f                      outsl  %ds:(%rsi),(%dx) 
  9:    2c 20                    sub    $0x20,%al 
  b:    65                      gs 
  c:    76 65                    jbe    73 <__mod_vermagic5+0x3b> 
  e:    72 79                    jb    89 <__mod_vermagic5+0x51> 
  10:    62                      (bad)  
  11:    6f                      outsl  %ds:(%rsi),(%dx) 
  12:    64                      fs 
  13:    79 21                    jns    36 <__module_depends+0x7> 
  15:    20 0a                    and    %cl,(%rdx) 
  17:    0a 00                    or    (%rax),%al 
  19:    0a 20                    or    (%rax),%ah 
  1b:    20 20                    and    %ah,(%rax) 
  1d:    47 6f                    rex.RXB outsl %ds:(%rsi),(%dx) 
  1f:    6f                      outsl  %ds:(%rsi),(%dx) 
  20:    64                      fs 
  21:    62                      (bad)  
  22:    79 65                    jns    89 <__mod_vermagic5+0x51> 
  24:    20 6e 6f                and    %ch,0x6f(%rsi) 
  27:    77 2e                    ja    57 <__mod_vermagic5+0x1f> 
  29:    2e 2e 20 0a              cs and %cl,%cs:(%rdx) 
  2d:    0a 00                    or    (%rax),%al 

Disassembly of section .modinfo: 

0000000000000000 <__mod_license27>: 
  0:    6c                      insb  (%dx),%es:(%rdi) 
  1:    69 63 65 6e 73 65 3d     imul  $0x3d65736e,0x65(%rbx),%esp 
  8:    47 50                    rex.RXB push %r8 
  a:    4c 00 73 72              rex.WR add %r14b,0x72(%rbx) 

000000000000000c <__mod_srcversion31>: 
  c:    73 72                    jae    80 <__mod_vermagic5+0x48> 
  e:    63 76 65                movslq 0x65(%rsi),%esi 
  11:    72 73                    jb    86 <__mod_vermagic5+0x4e> 
  13:    69 6f 6e 3d 45 33 46     imul  $0x4633453d,0x6e(%rdi),%ebp 
  1a:    38 45 32                cmp    %al,0x32(%rbp) 
  1d:    30 39                    xor    %bh,(%rcx) 
  1f:    34 37                    xor    $0x37,%al 
  21:    44 32 31                xor    (%rcx),%r14b 
  24:    33 30                    xor    (%rax),%esi 
  26:    32 35 44 36 39 34        xor    0x34393644(%rip),%dh        # 34393670 <__mod_vermagic5+0x34393638> 
  2c:    34 45                    xor    $0x45,%al 
    ... 

000000000000002f <__module_depends>: 
  2f:    64                      fs 
  30:    65                      gs 
  31:    70 65                    jo    98 <__mod_vermagic5+0x60> 
  33:    6e                      outsb  %ds:(%rsi),(%dx) 
  34:    64                      fs 
  35:    73 3d                    jae    74 <__mod_vermagic5+0x3c> 
    ... 

0000000000000038 <__mod_vermagic5>: 
  38:    76 65                    jbe    9f <__mod_vermagic5+0x67> 
  3a:    72 6d                    jb    a9 <__mod_vermagic5+0x71> 
  3c:    61                      (bad)  
  3d:    67 69 63 3d 33 2e 30     imul  $0x2e302e33,0x3d(%ebx),%esp 
  44:    2e 
  45:    30 2d 31 36 2d 67        xor    %ch,0x672d3631(%rip)        # 672d367c <__mod_vermagic5+0x672d3644> 
  4b:    65 6e                    outsb  %gs:(%rsi),(%dx) 
  4d:    65                      gs 
  4e:    72 69                    jb    b9 <__mod_vermagic5+0x81> 
  50:    63 20                    movslq (%rax),%esp 
  52:    53                      push  %rbx 
  53:    4d 50                    rex.WRB push %r8 
  55:    20 6d 6f                and    %ch,0x6f(%rbp) 
  58:    64                      fs 
  59:    5f                      pop    %rdi 
  5a:    75 6e                    jne    ca <__mod_vermagic5+0x92> 
  5c:    6c                      insb  (%dx),%es:(%rdi) 
  5d:    6f                      outsl  %ds:(%rsi),(%dx) 
  5e:    61                      (bad)  
  5f:    64 20 6d 6f              and    %ch,%fs:0x6f(%rbp) 
  63:    64                      fs 
  64:    76 65                    jbe    cb <__mod_vermagic5+0x93> 
  66:    72 73                    jb    db <__mod_vermagic5+0xa3> 
  68:    69                      .byte 0x69 
  69:    6f                      outsl  %ds:(%rsi),(%dx) 
  6a:    6e                      outsb  %ds:(%rsi),(%dx) 
  6b:    73 20                    jae    8d <__mod_vermagic5+0x55> 
    ... 

Disassembly of section __mcount_loc: 

0000000000000000 <__mcount_loc>: 
    ... 

Disassembly of section __versions: 

0000000000000000 <____versions>: 
  0:    73 24                    jae    26 <____versions+0x26> 
  2:    57                      push  %rdi 
  3:    41 00 00                add    %al,(%r8) 
  6:    00 00                    add    %al,(%rax) 
  8:    6d                      insl  (%dx),%es:(%rdi) 
  9:    6f                      outsl  %ds:(%rsi),(%dx) 
  a:    64                      fs 
  b:    75 6c                    jne    79 <____versions+0x79> 
  d:    65                      gs 
  e:    5f                      pop    %rdi 
  f:    6c                      insb  (%dx),%es:(%rdi) 
  10:    61                      (bad)  
  11:    79 6f                    jns    82 <____versions+0x82> 
  13:    75 74                    jne    89 <____versions+0x89> 
    ... 
  3d:    00 00                    add    %al,(%rax) 
  3f:    00 49 a0                add    %cl,-0x60(%rcx) 
  42:    e1 27                    loope  6b <____versions+0x6b> 
  44:    00 00                    add    %al,(%rax) 
  46:    00 00                    add    %al,(%rax) 
  48:    70 72                    jo    bc <____versions+0xbc> 
  4a:    69 6e 74 6b 00 00 00     imul  $0x6b,0x74(%rsi),%ebp 
    ... 
  7d:    00 00                    add    %al,(%rax) 
  7f:    00 9a 0f 39 b4 00        add    %bl,0xb4390f(%rdx) 
  85:    00 00                    add    %al,(%rax) 
  87:    00 6d 63                add    %ch,0x63(%rbp) 
  8a:    6f                      outsl  %ds:(%rsi),(%dx) 
  8b:    75 6e                    jne    fb <__mod_vermagic5+0xc3> 
  8d:    74 00                    je    8f <____versions+0x8f> 
    ... 

Disassembly of section .gnu.linkonce.this_module: 

0000000000000000 <__this_module>: 
    ... 
  18:    6b 6d 6f 64              imul  $0x64,0x6f(%rbp),%ebp 
  1c:    75 6c                    jne    8a <__this_module+0x8a> 
  1e:    65 00 00                add    %al,%gs:(%rax) 
    ... 

Disassembly of section .comment: 

0000000000000000 <.comment>: 
  0:    00 47 43                add    %al,0x43(%rdi) 
  3:    43 3a 20                rex.XB cmp (%r8),%spl 
  6:    28 55 62                sub    %dl,0x62(%rbp) 
  9:    75 6e                    jne    79 <__mod_vermagic5+0x41> 
  b:    74 75                    je    82 <__mod_vermagic5+0x4a> 
  d:    2f                      (bad)  
  e:    4c 69 6e 61 72 6f 20     imul  $0x34206f72,0x61(%rsi),%r13 
  15:    34 
  16:    2e 36 2e 31 2d 39 75     cs ss xor %ebp,%cs:%ss:0x75627539(%rip)        # 75627558 <__mod_vermagic5+0x75627520> 
  1d:    62 75 
  1f:    6e                      outsb  %ds:(%rsi),(%dx) 
  20:    74 75                    je    97 <__mod_vermagic5+0x5f> 
  22:    33 29                    xor    (%rcx),%ebp 
  24:    20 34 2e                and    %dh,(%rsi,%rbp,1) 
  27:    36 2e 31 00              ss xor %eax,%cs:%ss:(%rax) 
  2b:    00 47 43                add    %al,0x43(%rdi) 
  2e:    43 3a 20                rex.XB cmp (%r8),%spl 
  31:    28 55 62                sub    %dl,0x62(%rbp) 
  34:    75 6e                    jne    a4 <__mod_vermagic5+0x6c> 
  36:    74 75                    je    ad <__mod_vermagic5+0x75> 
  38:    2f                      (bad)  
  39:    4c 69 6e 61 72 6f 20     imul  $0x34206f72,0x61(%rsi),%r13 
  40:    34 
  41:    2e 36 2e 31 2d 39 75     cs ss xor %ebp,%cs:%ss:0x75627539(%rip)        # 75627583 <__mod_vermagic5+0x7562754b> 
  48:    62 75 
  4a:    6e                      outsb  %ds:(%rsi),(%dx) 
  4b:    74 75                    je    c2 <__mod_vermagic5+0x8a> 
  4d:    33 29                    xor    (%rcx),%ebp 
  4f:    20 34 2e                and    %dh,(%rsi,%rbp,1) 
  52:    36 2e 31 00              ss xor %eax,%cs:%ss:(%rax)

but something doesn't quite stack up with the rest...

how are the printk function called?? I can only see "callq 9", and that offset doesn't tell me anything.. it's the next instruction.. so what? The message "Kello" gets printed correctly but I can't find the code where this happens!

Besides.. how can this code access the string "Kello etc.." in section .rodata.str1.1 ? If this is a program segment mapped into ds register, shouldn't be something like "ds:0" to access it?

I'm quite confused..

Answer

interjay picture interjay · Mar 18, 2012

Kernel modules are relocatable, and linked into the kernel when they are loaded. The actual memory addresses are only determined at that time. This is because the address for kernel functions, and the address at which the module will be loaded, are not known at compile-time.

If you look at the bytecode for all the call instructions, you will see that they all have four zero bytes. When the module is loaded, these bytes will be replaced with the actual function address. The same is true for the string address: In the instruction mov $0x0,%rdi, the zero will be replaced with the correct address.

The reason you see instructions like callq 9 and callq 17 is that the call instruction specifies the address as relative to the next instruction. Since the relative address stored in the file is 0, the disassembler will show it as if the call instruction is calling the instruction following it.

Using objdump -r should show you the relocations for the module.