For example, I want to embed dicmap.bin to a shared library libxxx.so
.
I write a program to verify it.
test_dicmap.cpp
#include <stdio.h> #include <stdint.h> extern "C" { extern const uint8_t _binary_dicmap_bin_start[]; extern const uint8_t _binary_dicmap_bin_end[]; extern const void* _binary_dicmap_bin_size; } int main() { size_t size = (size_t)&_binary_dicmap_bin_size; printf("start=%p, end=%pnend-start=%zd, size=%zdn", _binary_dicmap_bin_start, _binary_dicmap_bin_end, _binary_dicmap_bin_end - _binary_dicmap_bin_start, size); printf("data[0..8]=%02x %02x %02x %02x %02x %02x %02x %02xn", _binary_dicmap_bin_start[0], _binary_dicmap_bin_start[1], _binary_dicmap_bin_start[2], _binary_dicmap_bin_start[3], _binary_dicmap_bin_start[4], _binary_dicmap_bin_start[5], _binary_dicmap_bin_start[6], _binary_dicmap_bin_start[7]); }
But its _start
, _end
and _size
is invalid.
]$ ls dicmap.bin -l -rw-rw-r-- 1 kirbyzhou kirbyzhou 198600798 Feb 26 10:58 dicmap.bin ]# objcopy -B i386 -I binary -O elf64-x86-64 dicmap.bin dicmap.o && g++ -o libxxx.so dicmap.o -shared && g++ -L. -lxxx test_dicmap.cpp /opt/rh/devtoolset-8/root/usr/libexec/gcc/x86_64-redhat-linux/8/ld: warning: type and size of dynamic symbol `_binary_dicmap_bin_size' are not defined /opt/rh/devtoolset-8/root/usr/libexec/gcc/x86_64-redhat-linux/8/ld: warning: type and size of dynamic symbol `_binary_dicmap_bin_start' are not defined /opt/rh/devtoolset-8/root/usr/libexec/gcc/x86_64-redhat-linux/8/ld: warning: type and size of dynamic symbol `_binary_dicmap_bin_end' are not defined ]# ./a.out start=0x601034, end=0x601034 end-start=0, size=6295604 data[0..8]=00 00 00 00 00 00 00 00
end-start and size should be sizeof dicmap.bin
(198600798).
My objcopy
is binutils-2.30-54.el7
of rhel7 with devtoolset-8
.
I try to add share flags to the .o
file, but a error happens:
objcopy -B i386 -I binary -O elf64-x86-64 dicmap.bin dicmap.o --set-section-flag .data=share objcopy: BFD version 2.30-54.el7 internal error, aborting at elf.c:8869 in _bfd_elf_set_section_contents objcopy: Please report this bug.
binutils-2.27-41.base.el7_7.1.x86_64
of rhel7 also have the same problem.
Is there any method to help me?
Advertisement
Answer
There 2 methods works for me now.
Method 1: Use objcopy to convert data to “.o”, then link to “.so”. Then link the “.so” and main code with “-fPIC”.
objcopy -B i386 -I binary -O elf64-x86-64 dicmap.bin dicmap.o g++ -shared -fPIC dicmap.o -o libdicmap1.so # -fPIC is very import in the following line, # But it is very unusual when you compile and link main code. g++ -fPIC test_dicmap.cpp libdicmap1.so -o test_dicmap1-PIC
Method 2: Use assmbler to wrap the data, and store the size in a different way of objcopy.
g++ -shared -fPIC dicmap3.s -o libdicmap3.so g++ test_dicmap3.cpp libdicmap3.so -o test-dicmap3
Codes:
test_dicmap.cpp:
#include <stdio.h> #include <stdint.h> #include <assert.h> extern "C" { extern const uint8_t _binary_dicmap_bin_start[]; extern const uint8_t _binary_dicmap_bin_end[]; extern const void* _binary_dicmap_bin_size; } int main() { size_t data_size = (size_t)&_binary_dicmap_bin_size; printf("start=%p, end=%pnend-start=%zd, size=%zdn", _binary_dicmap_bin_start, _binary_dicmap_bin_end, _binary_dicmap_bin_end - _binary_dicmap_bin_start, data_size); printf("data[0..8]=%02x %02x %02x %02x %02x %02x %02x %02xn", _binary_dicmap_bin_start[0], _binary_dicmap_bin_start[1], _binary_dicmap_bin_start[2], _binary_dicmap_bin_start[3], _binary_dicmap_bin_start[4], _binary_dicmap_bin_start[5], _binary_dicmap_bin_start[6], _binary_dicmap_bin_start[7]); assert(_binary_dicmap_bin_end - _binary_dicmap_bin_start == data_size); }
test_dicmap3.cpp:
#include <stdio.h> #include <stdint.h> #include <assert.h> extern "C" { extern const uint8_t _binary_dicmap_bin_start[]; extern const uint8_t _binary_dicmap_bin_end[]; extern const size_t _binary_dicmap_bin_size; } int main() { size_t data_size = _binary_dicmap_bin_size; printf("start=%p, end=%pnend-start=%zd, size=%zdn", _binary_dicmap_bin_start, _binary_dicmap_bin_end, _binary_dicmap_bin_end - _binary_dicmap_bin_start, data_size); printf("data[0..8]=%02x %02x %02x %02x %02x %02x %02x %02xn", _binary_dicmap_bin_start[0], _binary_dicmap_bin_start[1], _binary_dicmap_bin_start[2], _binary_dicmap_bin_start[3], _binary_dicmap_bin_start[4], _binary_dicmap_bin_start[5], _binary_dicmap_bin_start[6], _binary_dicmap_bin_start[7]); // _binary_dicmap_bin_end is invalid //assert(_binary_dicmap_bin_end - _binary_dicmap_bin_start == data_size); }
dicmap3.s:
.globl _binary_dicmap_bin_start .globl _binary_dicmap_bin_end .globl _binary_dicmap_bin_size .section .rodata .type _binary_dicmap_bin_start, @object .align 8 _binary_dicmap_bin_start: .incbin "dicmap.bin" .align 1 .size _binary_dicmap_bin_end, 1 _binary_dicmap_bin_end: .byte 0 .size _binary_dicmap_bin_start, _binary_dicmap_bin_end - _binary_dicmap_bin_start .type _binary_dicmap_bin_size, @object .size _binary_dicmap_bin_size, 8 .align 8 _binary_dicmap_bin_size: .quad _binary_dicmap_bin_end - _binary_dicmap_bin_start
dicmap.bin:
helloworld