0

I have read a number of SO posts on this but they do not answer the question of why an "undefined reference to ..." error can persist after marking a function as weak. I have a header file:

#ifndef SCHEDULER_H_
#define SCHEDULER_H_
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

#include <arch/cpu/exceptions.h>
#include "lib/kprintf.h"

// here are structs and enums that are used but not relevant.

extern void __attribute__((weak)) syscall_exit (void);



int scheduler_thread_create(void (* func) (void *),
                            const void *arg,
                            unsigned int arg_size,
                            unsigned int flags);

The function definition of scheduler_thread_create is in a binary file that I do not have access to. It uses the function syscall_exit which is compiled separately from this file hence the linker error "undefined reference to syscall_exit" and my problem is that this linker error persists even after marking the function as weak as I did. I also tried [[gnu::weak]]. Can anyone tell me how to resolve this?

Edit: this is the error message, and thanks to all of you!

arm-none-eabi-ld: .//libe3.a(scheduler.o): in function `scheduler_thread_create':
(.text+0x548): undefined reference to `syscall_exit'
arm-none-eabi-ld: (.text+0x54c): undefined reference to `syscall_exit'
make: *** [Makefile:215: build/kernel_only.elf] Error 1
17
  • 1
    If the call to syscall_exit is in a separate binary, then you don't need to declare it at all. Commented Jan 6 at 18:33
  • 2
    Why do you think you can get away without a definition of syscall_exit? Do you think the other object module will never actually use the symbol; your program will never execute in such a way that syscall_exit is called? If so, then a workaround is simply to provide your own definition of syscall_exit. Commented Jan 6 at 19:13
  • 5
    You seem to have the wrong idea about weak symbols. Declaring a symbol weak in a given translation unit says that the definition provided by that TU should not be used if a strong one is provided by a different TU contributing to the same program. It's not meaningful to do this in a TU that does not provide a definition of the symbol, and declaring a symbol weak does not mean that references to that symbol do not need to be resolved. Commented Jan 6 at 19:24
  • 3
    I doubt you solved your problem. It either does not exist, or you just hid it breaking the functionality of your program. Commented Jan 6 at 19:29
  • 3
    Note well that "my program compiled successfully" is not necessarily the same thing as "problem solved". Providing a do-nothing definition of syscall_exit(), even a weak one, is a problem waiting to happen if the program, including all libraries and implementation-specific startup and shutdown code, ever actually calls syscall_exit(). And if it doesn't, then why does it contain a reference to that function? Commented Jan 6 at 19:33

0

Your Answer

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