简体   繁体   中英

EXPORT_SYMBOL causes undefined reference in one direction, but not the other (relocation truncated)

I'm working on the 4.9 Linux kernel on a aarch64 machine, specifically mm/memory.c and a custom platform device driver. My goal is to have my device driver communicate some information to hardware that originates in functions in memory.c .

At first, I tried the same approach I always use for communicating across (platform) device drivers:

  • EXPORT_SYMBOL for the respective function in driver A
  • Defining the symbol as extern in driver B and accessing

Usually works like a charm, but this time I came across the following error when linking, with the platform driver EXPORT ing and memory.c using extern :

mm/memory.c:164:(.text+0x2a874): relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 against undefined symbol `my_func'

However, if I do the opposite, that is:

  • Define and EXPORT_SYMBOL a function pointer in memory.c
  • Assign a pointer to the platform driver function to the exported symbol

... it works!

Specifically...

Platform Driver:

void my_func(args){ ... };
EXPORT_SYMBOL(my_func);

memory.c:

extern void my_func(args);

... causes the linker error described above.

But ...

Platform Driver:

extern void (*funcptr)(args);

driver_probe() {
...
funcptr = &my_func;
....
}

memory.c:

void (*funcptr)(args) = NULL;
EXPORT_SYMBOL(funcptr);

... works !

A quick google search hinted that the linker error is concerned with the gcc options PIC/PIE, but I couldn't find a definitive answer.

It works now ... but WHY? :-)

I think the given picture will clarify whats the mistake here. Symbols exported by modules can not be used by the kernel. On the first place kernel won't build giving linker error as you are facing.

内核符号导出知识

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM