bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/20832] New: String merging elf32-i386 object files with elf64-x8


From: Jonathon.Reinhart at gmail dot com
Subject: [Bug ld/20832] New: String merging elf32-i386 object files with elf64-x86-64 ld causes incorrect results
Date: Thu, 17 Nov 2016 02:08:37 +0000

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.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]