Notes |
|
(0000976)
|
wangp
|
2018-03-13 14:23
|
|
The previous configuration (gcc 5.4.0, asm_fast.gc, x86) passes bootcheck if the Mercury libraries are statically linked, i.e. ./configure --disable-dynamic-link |
|
|
(0000988)
|
wangp
|
2018-03-15 12:57
|
|
I can reproduce a crash more simply with a call to string.count_codepoints/2. I've copied that predicate to a separate module for ease of debugging, and generated the assembly with mmake string2.pic_s. Then we can edit the assembly and create libmer_std.so with: as -g string2.pic_s -o string2.pic_o && mmake libmer_std.so
This is the start of string2.count_codepoints:
.globl _entry_mercury__string2__count_codepoints_2_0
.type _entry_mercury__string2__count_codepoints_2_0,@function
_entry_mercury__string2__count_codepoints_2_0:
call 0f
0:
popl %ebx
addl $_GLOBAL_OFFSET_TABLE_+[.-0b],%ebx
# 0 "" 2
.LDL1:
#NO_APP
.L4:
movl -12(%ebp), %ebx
leal .L5@GOTOFF(%ebx), %eax
.LBB2:
.loc 1 281 0
movl MR_engine_base@GOT(%ebx), %eax
movl 8(%eax), %ecx
...
The four lines beginning with "call 0f" are due to MR_INLINE_ASM_FIXUP_REGS, to (as I understand it) load the position of the code into ebx. Right afterwards, gcc has added an instruction to copy something off the stack into ebx (presumably it would have stashed the correct value on the stack, but we've jumped into the middle of a C function).
Inserting an instruction "movl %ebx, -12(%ebp)" to cancel out that instruction makes this particular predicate work, so I think this is on the right track. |
|
|
(0000989)
|
wangp
|
2018-03-15 14:59
|
|
On the other hand... x86 usage is only decreasing, linking with Mercury shared libraries is not very important, and inter-function jumps were never officially supported by gcc anyway. Maybe it is time to drop support for the combination? |
|
|
|
If you disable optimization in GCC (e.g. -O0) does the problem still occur? |
|
|
(0000991)
|
wangp
|
2018-03-15 16:26
|
|
It works at -O0, but not -O1, and not at -O1 with -f* options I could find disabled (everything listed by "gcc -O1 -Q --help=optimizers"). |
|
|
(0000992)
|
wangp
|
2018-03-15 16:40
|
|
|
|
(0000993)
|
wangp
|
2018-03-15 17:04
|
|
(convince GCC not to restore the GOT address from the stack, not only directly after the MR_INLINE_ASM_FIXUP_REGS sequence) |
|
|
|
You could try starting at -O0 and adding optimizations. (Past experience of this
kind of thing indicates that GCC is not entirely truthful about which optimizations it applies at which optimization level.) |
|
|
(0000995)
|
wangp
|
2018-03-16 15:15
|
|
Ok, bootcheck still passes with these options (which are what gcc reports as being enabled by -O1):
-fbranch-count-reg
-fcombine-stack-adjustments
-fcompare-elim
-fcprop-registers
-fforward-propagate
-fguess-branch-probability
-fif-conversion
-fif-conversion2
-finline-functions-called-once
-fipa-profile
-fipa-pure-const
-fipa-reference
-freorder-blocks
-fshrink-wrap
-fsplit-wide-types
-fssa-phiopt
-ftree-bit-ccp
-ftree-builtin-call-dce
-ftree-ccp
-ftree-ch
-ftree-coalesce-vars
-ftree-copy-prop
-ftree-dce
-ftree-dse
-ftree-fre
-ftree-pta
-ftree-sink
-ftree-slsr
-ftree-sra
-ftree-ter
Regardless, gcc 5 and up do not use a fixed PIC register on x86. Jumping into the middle of a function and putting the GOT address into EBX is not going to work if the rest of the function is not expecting it there. |
|