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

2

9

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

Spiro answered 21/7, 2010 at 15:4 Comment(0)
C
9

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.

Cyb answered 21/7, 2010 at 15:11 Comment(5)
Alright, so the linker fixes this address problem. I will have a further look into this issue, it not completely clear why it looks as it looksSpiro
It's not a problem; it's by design.Cyb
Use objdump -drwC - the -r includes symbol relocation info so you can see what it's actually calling (i.e. what symbol the linker will fill in when you link this .o). That's not specific to -ffunction-sections, it always happens (at least on x86) for target functions that aren't in the current file.Canonicals
@PeterCordes Thanks a lot! This -r option for objdump should be in one of the answers IMHO. I had a similar problem where I got utterly confused by the disassembly, and suddenly with -r it all makes sense.Randallrandan
@ElmarZander: It's in an answer to objdump and resolving linkage of local function calls?, and my answers on How to disassemble a binary executable in Linux to get the assembly code? and Why does the assembly encoding of objdump vary?. But yeah, every answer recommending objdump should recommend -r, IDK why people would want to disassemble without it.Canonicals
B
3

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.

Bach answered 26/2, 2021 at 3:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.