[llvm-bugs] [Bug 46364] New: .init section incorrectly filled (padded) with int3 instructions
via llvm-bugs
llvm-bugs at lists.llvm.org
Wed Jun 17 08:25:54 PDT 2020
https://bugs.llvm.org/show_bug.cgi?id=46364
Bug ID: 46364
Summary: .init section incorrectly filled (padded) with int3
instructions
Product: lld
Version: unspecified
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: ELF
Assignee: unassignedbugs at nondot.org
Reporter: tad.coburn at sonos.com
CC: llvm-bugs at lists.llvm.org, smithp352 at googlemail.com
Created attachment 23622
--> https://bugs.llvm.org/attachment.cgi?id=23622&action=edit
.tar.gz file with two source files, a Makefile, and the .o and executable files
I produced locally
Environment:
Ubuntu 18.04 LTS
gcc 7.5.0
gnu make 4.1
lld-9
I am trying to use lld as a drop-in replacement for ld to speed up our builds.
The code is compiled using gcc 7.5.0. When linked using lld, the resulting
executables abort on startup with a SIGTRAP; the same exact code linked with ld
runs fine.
Repro steps:
untar attached tar file into the current directory (3 files; one is .s with
code in the .init segment)
# tar xzvf ld-vs-lld-init-section-crash.tar.gz
# make clean all
# ./myprog-ld
OPENSSL_ia32cap_P = 0x422
# ./myprog-ldd
Trace/breakpoint trap (core dumped)
Expected Result:
OPENSSL_ia32cap_P = 0x422
Actual Result:
Trace/breakpoint trap (core dumped)
More Info:
It appears the problem has to do with fill bytes in the middle of the .init
section. I link my test program once with ld (myprog-ld) and again using lld
(myprog-lld).
The attached .tar.gz file contains the .o and executable files I generated
locally so you can inspect them yourself with objdump.
Here is what I found:
# objdump -d --section=".init" myprog-ld
00000380 <_init>:
380: 53 push %ebx
381: 83 ec 08 sub $0x8,%esp
384: e8 b7 00 00 00 call 440 <__x86.get_pc_thunk.bx>
389: 81 c3 4f 1c 00 00 add $0x1c4f,%ebx
38f: 8b 83 1c 00 00 00 mov 0x1c(%ebx),%eax
395: 85 c0 test %eax,%eax
397: 74 05 je 39e <_init+0x1e>
399: e8 5a 00 00 00 call 3f8 <__gmon_start__ at plt>
39e: 66 90 xchg %ax,%ax <=== ld fills with an
executable instruction
3a0: e8 98 01 00 00 call 53d <OPENSSL_cpuid_setup>
3a5: eb 09 jmp 3b0 <_init+0x30>
3a7: 89 f6 mov %esi,%esi
3a9: 8d bc 27 00 00 00 00 lea 0x0(%edi,%eiz,1),%edi
3b0: 83 c4 08 add $0x8,%esp
3b3: 5b pop %ebx
3b4: c3 ret
# objdump -d --section=".init" myprog-lld
00001220 <_init>:
1220: 53 push %ebx
1221: 83 ec 08 sub $0x8,%esp
1224: e8 04 ff ff ff call 112d <__x86.get_pc_thunk.bx>
1229: 81 c3 cb 0e 00 00 add $0xecb,%ebx
122f: 8b 83 f0 ff ff ff mov -0x10(%ebx),%eax
1235: 85 c0 test %eax,%eax
1237: 74 05 je 123e <_init+0x1e>
1239: e8 52 00 00 00 call 1290 <__gmon_start__ at plt>
123e: cc int3 <==== lld fills with int3
123f: cc int3
1240: e8 ec fe ff ff call 1131 <OPENSSL_cpuid_setup>
1245: eb 09 jmp 1250 <_init+0x30>
1247: 89 f6 mov %esi,%esi
1249: 8d bc 27 00 00 00 00 lea 0x0(%edi,%eiz,1),%edi
1250: 83 c4 08 add $0x8,%esp
1253: 5b pop %ebx
1254: c3 ret
I see that a change was made in lld-6.0 (or earlier?) to change the default
fill from 0x00 to 0xcc. I think that is fine in general, but is incorrect for
fill bytes _in the middle_ of an .init section (and probably a .fini section as
well).
The real-world context for this is that I have a number of executables that
statically link with libcrypto.a (OpenSSL v0.9.8); that is where the assembly
code for the .init section comes from. The OpenSSL team recommends linking
with -Bsymbolic but that has no effect when linking statically.
I was able to work around the problem by completely replacing the linker script
with a new one that with the .init section fillexp explicitly set to
0x90909090, but IMHO that should not be necessary to produce a working
executable.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200617/3e91c39c/attachment.html>
More information about the llvm-bugs
mailing list