cassemblygccnasmelf

How to add debug information for NASM functions? From C header file?


I have function foo which is used by inclusion of header and linking with the implementation staticaly: main.c:

#include <stdio.h>
#include "foo.h"
int main(void) {
    printf("%f\n", foo(123, 456));
}

foo.h:

int foo(int, int);

build:

$ gcc -m32 -o -g main main.c foo.o

And two different implementations: one in C, and one in Assembly language. foo.c:

#include "foo.h"
int foo(int a, int b) {
    return a + b;
}

foo.asm:

global foo
section .text
foo:
        mov eax, dword [esp+4]
        add eax, dword [esp+8]
        ret

I want to debug my function using gdb, to do so I need to add the debugging information while compiling:

gcc -m32 -o foo.o -c foo.c -g
nasm -felf32 -o foo.o foo.asm -g

When I am in gdb I can view the implementation of the function foo, but when I use the C implementation gdb hints me the prototype of the function foo and can I call it like this:

call foo(1, 2)

But with Assembly language implementation I should call it like this:

call (int (*)(int, int))foo(1, 2)

How can I use the header foo.h to generate the debugging information about the prototype of the foo function, and how to add such an information to the elf file?

I have tried to compile the header file as a C file and see if it will contain any debugging information.

$ cp foo.h foo_debug.c
$ gcc -m32 -o foo_debug.o -c foo_debug.c -g

But the resulting foo_debug.o do not contain anything related to the function foo.


Solution

  • How can I use the header foo.h to generate the debugging information about the prototype of the foo function

    I don't think you can.

    Your best option might be to provide a C wrapper for the asm routine:

    #include "foo.h"
    int foo_wrapper(int a, int b) { return foo(a, b); }
    

    Build this file with -g flag, and call foo_wrapper from GDB instead of calling foo itself.

    Alternatively, you can create a pointer to foo with a known type:

    #include "foo.h"
    int (*pfoo)(int, int) = &foo;
    int main(void) { ...
    

    Then in GDB use pfoo instead of foo:

    (gdb) p pfoo
    $1 = (int (*)(int, int)) 0x55555555513e <foo>
    (gdb) p pfoo(2, 3)
    $2 = 5