I am trying to call a function from closed-source library. Original toolchain is not available, library headers not available.
$ file libvendor.so
libvendor.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=ff, stripped
$ nm -CD libvendor.so | grep Start
0001ec3a T nm::vendor::className::Start(int, char const**, std::__1::function<void ()>)
Recreated header file:
#include <functional>
namespace nm {
namespace vendor {
class className {
public:
static className* Get();
void Start(int, char const**, std::function<void ()>);
}
}
}
main.cpp:
#include "header.h"
using namespace nm::vendor;
using namespace std;
std::function<void ()> startFunc;
void Start() {}
int main(void)
{
className* c = className::Get();
char const *str = "c style string";
const char** str_ptr = &str;
startFunc = Start;
c->Start(1, str_ptr, startFunc);
}
Compiling, I am using crosstool-ng:
$ ~/x-tools/arm-linux-gnueabihf/bin/arm-linux-gnueabihf-c++ --version
arm-linux-gnueabihf-c++ (crosstool-NG 1.25.0) 11.2.0
$ ~/x-tools/arm-linux-gnueabihf/bin/arm-linux-gnueabihf-c++ \
-std=c++11 \
-Wl,-v \
-Wl,-rpath,. \
-ldl \
-mthumb-interwork \
libvendor.so \
-o main \
main.cpp
collect2 version 11.2.0
~/x-tools/arm-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/11.2.0/../../../../arm-linux-gnueabihf/bin/ld -plugin ~/x-tools/arm-linux-gnueabihf/libexec/gcc/arm-linux-gnueabihf/11.2.0/liblto_plugin.so -plugin-opt=~/x-tools/arm-linux-gnueabihf/libexec/gcc/arm-linux-gnueabihf/11.2.0/lto-wrapper -plugin-opt=-fresolution=/tmp/cc35fC2k.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --sysroot=~/x-tools/arm-linux-gnueabihf/arm-linux-gnueabihf/sysroot --eh-frame-hdr -dynamic-linker /lib/ld-linux-armhf.so.3 -X -m armelf_linux_eabi -o main ~/x-tools/arm-linux-gnueabihf/arm-linux-gnueabihf/sysroot/usr/lib/crt1.o ~/x-tools/arm-linux-gnueabihf/arm-linux-gnueabihf/sysroot/usr/lib/crti.o ~/x-tools/arm-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/11.2.0/crtbegin.o -L~/x-tools/arm-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/11.2.0 -L~/x-tools/arm-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/11.2.0/../../../../arm-linux-gnueabihf/lib -L~/x-tools/arm-linux-gnueabihf/arm-linux-gnueabihf/sysroot/lib -L~/x-tools/arm-linux-gnueabihf/arm-linux-gnueabihf/sysroot/usr/lib -v -rpath . -rpath /system/vendor/sony/lib -rpath ~/nw-a50/myfirmware/bootimg/initrd_unpacked/lib/ -ldl libvendor.so /tmp/ccKaDp0K.o -lstdc++ -lm -lc -lgcc_s -lgcc -lc -lgcc_s -lgcc ~/x-tools/arm-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/11.2.0/crtend.o ~/x-tools/arm-linux-gnueabihf/arm-linux-gnueabihf/sysroot/usr/lib/crtn.o
GNU ld (crosstool-NG 1.25.0) 2.26.1
/tmp/ccSbQv2E.o: In function `main':
main.cpp:(.text+0x70): undefined reference to `nm::vendor::className::Start(int, char const**, std::function<void ()>)'
collect2: error: ld returned 1 exit status
__1
is a inline namespace; compilation fails if specified in header function declaration:
In file included from main.cpp:2:0:
header.h:84:57: error: 'std::__1' has not been declared
void Start(int, char const**, std::__1::function<void ()>);
Other functions (such as Get()
) are correctly resolved by linker and callable.
Is there a way to satisfy linker?
Answer: downgrade llvm to 7.