Bug 1807308
| Summary: | objcopy can not embed data to shared library, and --set-section-flags donot work with "share" flag. | ||
|---|---|---|---|
| Product: | Red Hat Enterprise Linux 8 | Reporter: | Kirby Zhou <kirbyzhou> |
| Component: | binutils | Assignee: | Nick Clifton <nickc> |
| binutils sub component: | system-version | QA Contact: | Miloš Prchlík <mprchlik> |
| Status: | CLOSED ERRATA | Docs Contact: | |
| Severity: | unspecified | ||
| Priority: | unspecified | CC: | fweimer, law, mcermak, mprchlik, ohudlick, sipoyare, tschelle |
| Version: | 8.1 | Keywords: | Bugfix, Reopened, Triaged |
| Target Milestone: | rc | Flags: | pm-rhel:
mirror+
|
| Target Release: | 8.0 | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
| Whiteboard: | |||
| Fixed In Version: | binutils-2.30-74.el8 | Doc Type: | No Doc Update |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2020-11-04 01:41:45 UTC | Type: | Bug |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
Maybe there is some bug in ld or ld-linux.so or gcc?
I write a asm file to simulate the objcopy, but still failed.
]$ cat dicmap.asm
.section .rodata
.global _binary_dicmap_bin_start
.type _binary_dicmap_bin_start, @object
.align 8
_binary_dicmap_bin_start:
#.incbin "dicmap.bin"
.string "helloworld"
.global _binary_dicmap_bin_end
.type _binary_dicmap_bin_end, @object
_binary_dicmap_bin_end:
.global _binary_dicmap_bin_size
.type _binary_dicmap_bin_size, @object
.align 8
.offset _binary_dicmap_bin_end - _binary_dicmap_bin_start
_binary_dicmap_bin_size:
Actual (dynamic link)
]$ as -k --64 dicmap.asm -o dicmap.o && gcc -shared -o libxxx.so dicmap.o && g++ -L. -lxxx test_dicmap.cpp && ./a.out
start=0x60103c, end=0x60103c
end-start=0, size=6295612
data[0..8]=00 00 00 00 00 00 00 00
a.out: test_dicmap.cpp:27: int main(): Assertion `_binary_dicmap_bin_end - _binary_dicmap_bin_start == data_size' failed.
Aborted
Expected (use static link to simulate)
]$ as -k --64 dicmap.asm -o dicmap.o && g++ dicmap.o test_dicmap.cpp && ./a.out
start=0x400730, end=0x40073b
end-start=11, size=11
data[0..8]=68 65 6c 6c 6f 77 6f 72
More information: If you take gdb to watch the symbol, It will give a different value than the program sees. ]$ gdb test_dicmap GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-115.el7 (gdb) b main Breakpoint 1 at 0x400690: file test_dicmap.cpp, line 15. (gdb) r Breakpoint 1, main () at test_dicmap.cpp:15 (gdb) p _binary_dicmap_bin_start $1 = 0x7ffff7bd96d8 "helloworld" (gdb) p _binary_dicmap_bin_end $2 = 0x7ffff7bd96e3 "" (gdb) p _binary_dicmap_bin_end-_binary_dicmap_bin_start $3 = 11 (gdb) c Continuing. start=0x60103c, end=0x60103c end-start=0, size=6295612 data[0..8]=00 00 00 00 00 00 00 00 lt-test_dicmap: test_dicmap.cpp:27: int main(): Assertion `_binary_dicmap_bin_end - _binary_dicmap_bin_start == data_size' failed. Workaround: Compile test_dicmap.cpp with "-fPIC", which is an uncommon usage for compiling main programs. ]$ as -k --64 dicmap.asm -o dicmap.o && gcc -shared -o libxxx.so dicmap.o && g++ -fPIC -L. -lxxx test_dicmap.cpp && ./a.out start=0x7ff3fd9826b8, end=0x7ff3fd9826c3 end-start=11, size=11 data[0..8]=68 65 6c 6c 6f 77 6f 72 Hi Kirby, It is intentional that you cannot use objcopy to convert a static binary into a shared binary. It needs a lot more work, than just changing a flag in a section header. The entire binary needs to be recompiled with the correct command line options if you want to make it a shared binary. The workaround you mention is just this - compiling for a shared executable instead of a static one. Reopening after further discussions with the reporter. There are three issues here. The first is that the "share" section flag cannot be used to make a shared ELF section. The second is that the objcopy program should not allow the user to try this, and the documentation should inform the user that this is not allowed. The third is that the BFD library should not call abort() when the situation does arise, but instead issue an error message and return a failure result. A patch has been committed upstream to fix the second and third problems: https://www.sourceware.org/ml/binutils/2020-03/msg00143.html Fixed in inutils-2.30-74.el8 Verified with binutils-2.30-77.el8. After Nick's comment #4 and comment #5, this is the final result: $ objcopy -B i386 -I binary -O elf64-x86-64 dicmap.bin dicmap.o --set-section-flags .data=share objcopy: dicmap.o[.data]: Note - dropping 'share' flag as output format is not COFF Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory (Low: binutils security update), and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHSA-2020:4465 |
Description of problem: objcopy can not embed data to shared library. and --set-section-flags donot work with "share" flag. Version-Release number of selected component (if applicable): binutils-2.30-58.el8.0.1.x86_64 gcc-8.3.1-4.5.el8.x86_64 How reproducible: 100% Steps to Reproduce: 1. ]# cat > test_dicmap.cpp <<__EOF #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=%p\nend-start=%zd, size=%zd\n", _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 %02x\n", _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]); } __EOF ]# echo helloworld > dicmap.bin 2. ]# 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 3. ]# LD_LIBRARY_PATH=. ./a.out 4. try to add "share" flags to .data section ]# objcopy -B i386 -I binary -O elf64-x86-64 dicmap.bin dicmap.o --set-section-flags .data=share objcopy: BFD version 2.30-58.el8.0.1 internal error, aborting at elf.c:8878 in _bfd_elf_set_section_contents objcopy: Please report this bug. Actual results: /usr/bin/ld: warning: type and size of dynamic symbol `_binary_dicmap_bin_end' are not defined /usr/bin/ld: warning: type and size of dynamic symbol `_binary_dicmap_bin_size' are not defined /usr/bin/ld: warning: type and size of dynamic symbol `_binary_dicmap_bin_start' are not defined start=0x601024, end=0x601024 end-start=0, size=6295588 data[0..8]=00 00 00 00 00 00 00 00 Expected results: end-start=11, size=11 data[0..8]=68 65 6c 6c 6f 77 6f 72 Additional info: Directly embed data into a.out is OK: ]# objcopy -B i386 -I binary -O elf64-x86-64 dicmap.bin dicmap.o && g++ -o libxxx.so dicmap.o -shared && g++ test_dicmap.cpp dicmap.o ]# ./a.out objcopy --set-section-flags .data=share crash objcopy: BFD version 2.30-58.el8.0.1 internal error, aborting at elf.c:8878 in _bfd_elf_set_section_contents objcopy: Please report this bug. binutils-2.27-41.base.el7_7.1.x86_64 of RHEL7 have the same problem.