3

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.

2
  • So you want symbol type information. gcc cannot provide it (there is no symbol in header; maybe there is a way to force type info for "undefined" symbol but I kinda doubt it). nasm doesn't provide anything but source file information. Commented Jun 3 at 16:27
  • Does call (int)foo(1, 2) not work for you? Commented Jun 5 at 9:56

1 Answer 1

3

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.