Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disassembled gcc output appears to do a "call 0" instead of "call function-offset", but works correctly

I had just a look at a very simple SPARC assembly output that I got from this C programm:

int addition_func(int a, int b)
{
  return(a+b);
}

void main()
{

int a = 20;
int b = 19;
int res;    

res = addition_func(a, b);
}

Disassembly of section .text:

00000000 <addition_func>:
 0: 81 c3 e0 08     retl 
 4: 90 02 00 09     add  %o0, %o1, %o0

00000008 <main>:
 8: 90 10 20 14     mov  0x14, %o0
 c: 92 10 20 13     mov  0x13, %o1
10: 82 13 c0 00     mov  %o7, %g1
14: 40 00 00 00     call  14 <main+0xc>
18: 9e 10 40 00     mov  %g1, %o7
1c: 01 00 00 00     nop 

I do not understand why the "call" instruction says:

  call  14 <main+0xc>

Why is it not:

  call  0 <addition_func+0x0>

The program works fine, however, this output does not make too much sense to me. Any suggestions why it is handled this way?

Thanks

like image 203
Markus Avatar asked Jul 21 '10 15:07

Markus


2 Answers

I'll assume you're using GCC, but other compilers/assemblers should have equivalent options.

That's not the assembly output; it's the disassembly. If you want the input to the assembler, use gcc -S.

The notable number is not 14 — the instruction is a call to a relative address of 0:

14: 40 00 00 00     call  14 <main+0xc>

If you're disassembling an object file compiled with -ffunction-sections, then the instruction is simply a placeholder to be fixed up by the linker. The linker will fill it in with the actual offset to addition_func; you might see this if you dump the relocation tables.

like image 75
tc. Avatar answered Nov 03 '22 01:11

tc.


Long story short, it's an unfilled-in relative call in an object file waiting to be filled in with the appropriate offset by the linker to the actual symbol. Until that time the relative offset is 0, like x86, meaning it's relatively calling itself (which happens to be absolute address 0x14 within the code segment, which is an offset of 0xc from main). SPARC relative call appears to be relative to the start of the current instruction and not the end like x86.

like image 31
Lewis Kelsey Avatar answered Nov 03 '22 00:11

Lewis Kelsey