https://sourceware.org/bugzilla/show_bug.cgi?id=20832
Bug ID: 20832 Summary: String merging elf32-i386 object files with elf64-x86-64 ld causes incorrect results Product: binutils Version: 2.25 Status: UNCONFIRMED Severity: normal Priority: P2 Component: ld Assignee: unassigned at sourceware dot org Reporter: Jonathon.Reinhart at gmail dot com Target Milestone: --- Summary: Attempting to use ld in "native" mode on x86-64 (elf_x86_64) to link 32-bit (elf32-i386) object files causes incorrect results. A working proof-of-concept is available at https://github.com/JonathonReinhart/ld-bug-merge-strings-corrupt First, we have two C files that have a few string literals. One of the string literals in a.c exactly matches b.c. We compile these two files using `gcc -Os -c -m32` to produce elf32-i386 object files. The generated assembly looks correct. Next, we link these using a very basic linker script, using ld in native mode on an x86-64 system (elf_x86_64), which necessitates passing -no-warn-mismatch. (In the full-scale project, other 64-bit object files are included.) The result is a broken build. Here's the file b.c: void func_b(void) { use("b_before"); use("A long string that will be merged"); use("b_after"); } Here's the critical part of the output: Hex dump of section '.rodata': 0x00000048 615f6265 666f7265 0041206c 6f6e6720 a_before.A long 0x00000058 73747269 6e672074 68617420 77696c6c string that will 0x00000068 20626520 6d657267 65640061 5f616674 be merged.a_aft 0x00000078 65720062 5f626566 6f726500 41206c6f er.b_before.A lo 0x00000088 6e672073 ng s 0000000000000029 <func_b>: 29: 55 push rbp 2a: b8 7b 00 00 00 mov eax,0x7b 2f: 89 e5 mov ebp,esp 31: e8 ee ff ff ff call 24 <func_a+0x1f> 36: b8 84 00 00 00 mov eax,0x84 3b: e8 e4 ff ff ff call 24 <func_a+0x1f> 40: 5d pop rbp 41: b8 a6 00 00 00 mov eax,0xa6 46: eb dc jmp 24 <func_a+0x1f> You can see two thing here: 1) The output .rodata section appears to be truncated. The amount it is truncated by appears to be equal to the amount of string data that should have been removed due to merging. In the dump above, the string "b_after" is missing, but exactly that many bytes of "A long s"... were included instead. 2) The offsets passed to use() are as if no string data was merged. Namely 0x84 points to the correct string, but truncated, and 0xA6 points past the end of the section. -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils