È possibile creare un programma in C che si colleghi a una libreria e che sia in grado di chiamare le funzioni di tale libreria. Se quella biblioteca chiama una funzione dal programma principale si pone un errore:Libreria collegata dinamica Android non in grado di risolvere i simboli del programma principale
[email protected]:/data/local/tmp # ./helloworld
link_image[1966]: 637 could not load needed library 'libhello.so' for './helloworld' (reloc_library[1315]: 637 cannot locate 'crossfunction'...) CANNOT LINK EXECUTABLE
Il codice è in due file C, e mi comprendono anche il Makefile. ciao.c è la libreria che contiene la funzione ciao, che è chiamata da main.c (il programma principale). La funzione ciao prova ad invocare la funzione crossfunction e ciò non funziona in Android (in Linux funziona perfettamente). Sospetto dal linker Android, ma non ho prove fino ad ora (vedi https://android.googlesource.com/platform/bionic/+/froyo-release/linker/README.TXT).
Un altro suggerimento utile potrebbe essere l'assegnazione NOTYPE nell'output readelf per la funzione cross nel file libhello.so. Vedi sotto.
5: 00000000 0 NOTYPE GLOBAL DEFAULT UND crossfunction
Eventuali suggerimenti forse nei flag del compilatore o nei flag del linker?
::::::::::::::
main.c
::::::::::::::
#include <stdio.h>
extern void hello(const char* name);
int main(void) {
hello("World!");
}
void crossfunction(void) {
printf("This is called from the library\n");
}
::::::::::::::
hello.c
::::::::::::::
#include <stdio.h>
extern void crossfunction(void);
static char *s;
void hello(const char* name) {
s = "my second name";
printf("Hello %s %s!\n", s, name);
crossfunction();
}
Per compilare Io uso l'involucro AGCC con l'Android NDK https://github.com/nitomartinez/agcc
Ecco il Makefile:
OBJECTS=main.o
LIB=libhello.so
LIBOBJ=hello.o
TARGET=helloworld
TARGETDIR=/data/local/tmp
CC=agcc
.PHONY: all install run clean distclean
all: $(TARGET) $(LIB)
hello.o: hello.c Makefile
$(CC) $(CFLAGS) -c -o hello.o hello.c
$(TARGET): $(OBJECTS) $(LIB) Makefile
$(CC) -Wl,-rpath=$(TARGETDIR) -lhello -L . -o $(TARGET) $(OBJECTS)
$(LIB): $(LIBOBJ) Makefile
$(CC) -shared -o $(LIB) $(LIBOBJ)
install: $(TARGET)
adb push $(TARGET) $(TARGETDIR)/$(TARGET)
adb push $(LIB) $(TARGETDIR)/$(LIB)
run: install
adb shell "export LD_LIBRARY_PATH=$(TARGETDIR); $(TARGETDIR)/$(TARGET) "
ho avuto uno sguardo ai bit readelf, ma ho trovato differenze sostanziali nelle sezioni .dynsym, .rel.plt e .symtab.
Per helloworld
Relocation section '.rel.plt' at offset 0x33c contains 3 entries:
Offset Info Type Sym.Value Sym. Name
0000954c 00000416 R_ARM_JUMP_SLOT 00008368 hello
00009550 00000516 R_ARM_JUMP_SLOT 00008374 puts
00009554 00000816 R_ARM_JUMP_SLOT 00008380 __libc_init
Symbol table '.dynsym' contains 16 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 000083b0 32 FUNC GLOBAL DEFAULT 7 crossfunction
2: 00008450 0 NOTYPE GLOBAL DEFAULT ABS __exidx_end
3: 00009558 0 NOTYPE GLOBAL DEFAULT ABS _bss_end__
4: 00008368 0 FUNC GLOBAL DEFAULT UND hello
5: 00008374 0 FUNC GLOBAL DEFAULT UND puts
...
Symbol table '.symtab' contains 62 entries:
Num: Value Size Type Bind Vis Ndx Name
...
41: 000083b0 32 FUNC GLOBAL DEFAULT 7 crossfunction
42: 00008450 0 NOTYPE GLOBAL DEFAULT ABS __exidx_end
43: 00009558 0 NOTYPE GLOBAL DEFAULT ABS _bss_end__
44: 00008368 0 FUNC GLOBAL DEFAULT UND hello
45: 00008374 0 FUNC GLOBAL DEFAULT UND puts
...
55: 00008390 32 FUNC GLOBAL DEFAULT 7 main
...
E per libhello.so
Relocation section '.rel.plt' at offset 0xae8 contains 7 entries:
Offset Info Type Sym.Value Sym. Name
000032cc 00000516 R_ARM_JUMP_SLOT 00000000 crossfunction
000032d0 00000616 R_ARM_JUMP_SLOT 00000000 printf
000032d4 00000f16 R_ARM_JUMP_SLOT 00000000 __cxa_begin_cleanup
000032d8 00001516 R_ARM_JUMP_SLOT 00000000 memcpy
000032dc 00001f16 R_ARM_JUMP_SLOT 00000000 abort
...
Symbol table '.dynsym' contains 64 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
...
5: 00000000 0 NOTYPE GLOBAL DEFAULT UND crossfunction
6: 00000000 0 FUNC GLOBAL DEFAULT UND printf
...
19: 00000b88 100 FUNC GLOBAL DEFAULT 7 hello
21: 00000000 0 FUNC GLOBAL DEFAULT UND memcpy
...
Symbol table '.symtab' contains 138 entries:
Num: Value Size Type Bind Vis Ndx Name
25: 00000000 0 FILE LOCAL DEFAULT ABS hello.c
79: 00000000 0 NOTYPE GLOBAL DEFAULT UND crossfunction
80: 00000000 0 FUNC GLOBAL DEFAULT UND printf
Grazie per averlo confermato, l'ho sospettato in qualche modo. Grazie per aver segnalato anche la discussione. – Nito