View Issue Details

IDProjectCategoryView StatusLast Update
0038353FPCCompilerpublic2021-04-24 00:08
ReporterPierre Muller Assigned ToPierre Muller  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.3.1 
Summary0038353: Internal x86_64 assembler generates wrong code with -Cg option
DescriptionCurrent trunk compiler using internal and external assembler generate different relocation code with -O2 option.

For x86_64-openbsd target, -Cg option is default (generate_pic_code),
which leads to
https://www.freepascal.org/testsuite/cgi-bin/new-testsuite2.cgi?run1id=550120&run2id=550150&previousrunid=549871&noskipped=1&failedonly=1&action=Show%2FCompare
 
 Example code below is extracted from tvectorcall1.pp test,
I do not know the exact difference between R_X86_64_REX_GOTPCRELX and R_X86_64_GOTPCREL,
but the main issue it the offset for this relocation is wrong in the internal assembler
17c17
< 16: R_X86_64_GOTPCREL U_$P$PROGRAM_$$_P-0x8
---
> 16: R_X86_64_GOTPCREL U_$P$PROGRAM_$$_P-0x4
leading to the loading of a GOT entry in-between two real entries.

  This error exists at least for x86_64-linux and x86_64-openbsd
(the later does not require the -Cg option, as it is default)
Steps To ReproduceCompile test-got.pp (in between >>>> lines)
>>>>>>>>>>>
var
  p : pointer;
  is_aligned : boolean;
begin
  p:=@p;
  if (PtrUInt(@p) and $F) <> 0 then
    is_aligned:=false
  else
    is_aligned:=true;
end.
>>>>>>>>>
ppcx64 -O2 -Cg test-got
objdump -dr test-got.o > test-got-trunk-O2-Cg.log
ppcx64 -O2 -Cg -al test-got
objdump -dr test-got.o > test-got-trunk-O2-Cg-al.log
diff test-got-trunk-O2-Cg-al.log test-got-trunk-O2-Cg.log

gives the following output:
muller@gcc10:~/pas/check$ diff test-got-trunk-O2-Cg-al.log test-got-trunk-O2-Cg.log
12c12
< 9: R_X86_64_REX_GOTPCRELX U_$P$PROGRAM_$$_P-0x4
---
> 9: R_X86_64_GOTPCREL U_$P$PROGRAM_$$_P-0x4
17c17
< 16: R_X86_64_GOTPCREL U_$P$PROGRAM_$$_P-0x8
---
> 16: R_X86_64_GOTPCREL U_$P$PROGRAM_$$_P-0x4
20c20
< 23: R_X86_64_REX_GOTPCRELX U_$P$PROGRAM_$$_IS_ALIGNED-0x4
---
> 23: R_X86_64_GOTPCREL U_$P$PROGRAM_$$_IS_ALIGNED-0x4
25c25
< 33: R_X86_64_REX_GOTPCRELX U_$P$PROGRAM_$$_IS_ALIGNED-0x4
---
> 33: R_X86_64_GOTPCREL U_$P$PROGRAM_$$_IS_ALIGNED-0x4
27c27
< 3a: e8 00 00 00 00 callq 3f <U_$P$PROGRAM_$$_IS_ALIGNED+0x37>
---
> 3a: e8 00 00 00 00 callq 3f <main+0x3f>
28a29
> ...

TagsNo tags attached.
Fixed in Revision49252
FPCOldBugId
FPCTarget-
Attached Files

Activities

Florian

2021-01-14 21:55

administrator   ~0128326

Can you please also attach the logs you use?

Pierre Muller

2021-01-15 00:05

developer   ~0128333

I suppose you mean the full output of objdump -dr

muller@gcc10:~/pas/check$ fpc -iVDWSOSPTOTP
3.3.1 2021/01/14 3.3.1-r20:48150M linux x86_64 linux x86_64
(Note that this does not contain the last commit 48156)

muller@gcc10:~/pas/check$ cat test-got-331-O2-Cg.log

test-got.o: file format elf64-x86-64


Disassembly of section .text.n_main:

0000000000000000 <main>:
   0: 50 push %rax
   1: e8 00 00 00 00 callq 6 <main+0x6>
                        2: R_X86_64_PLT32 fpc_initializeunits-0x4
   6: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # d <main+0xd>
                        9: R_X86_64_GOTPCREL U_$P$PROGRAM_$$_P-0x4
   d: 48 89 c2 mov %rax,%rdx
  10: 48 89 02 mov %rax,(%rdx)
  13: 48 f7 05 00 00 00 00 testq $0xf,0x0(%rip) # 1e <main+0x1e>
  1a: 0f 00 00 00
                        16: R_X86_64_GOTPCREL U_$P$PROGRAM_$$_P-0x4
  1e: 74 10 je 30 <main+0x30>
  20: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 27 <main+0x27>
                        23: R_X86_64_GOTPCREL U_$P$PROGRAM_$$_IS_ALIGNED-0x4
  27: c6 00 00 movb $0x0,(%rax)
  2a: eb 0e jmp 3a <main+0x3a>
  2c: 0f 1f 40 00 nopl 0x0(%rax)
  30: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 37 <main+0x37>
                        33: R_X86_64_GOTPCREL U_$P$PROGRAM_$$_IS_ALIGNED-0x4
  37: c6 00 01 movb $0x1,(%rax)
  3a: e8 00 00 00 00 callq 3f <main+0x3f>
                        3b: R_X86_64_PLT32 fpc_do_exit-0x4
        ...
muller@gcc10:~/pas/check$ cat test-got-331-O2-Cg-al.log

test-got.o: file format elf64-x86-64


Disassembly of section .text.n_main:

0000000000000000 <main>:
   0: 50 push %rax
   1: e8 00 00 00 00 callq 6 <main+0x6>
                        2: R_X86_64_PLT32 fpc_initializeunits-0x4
   6: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # d <main+0xd>
                        9: R_X86_64_REX_GOTPCRELX U_$P$PROGRAM_$$_P-0x4
   d: 48 89 c2 mov %rax,%rdx
  10: 48 89 02 mov %rax,(%rdx)
  13: 48 f7 05 00 00 00 00 testq $0xf,0x0(%rip) # 1e <main+0x1e>
  1a: 0f 00 00 00
                        16: R_X86_64_GOTPCREL U_$P$PROGRAM_$$_P-0x8
  1e: 74 10 je 30 <main+0x30>
  20: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 27 <main+0x27>
                        23: R_X86_64_REX_GOTPCRELX U_$P$PROGRAM_$$_IS_ALIGNED-0x4
  27: c6 00 00 movb $0x0,(%rax)
  2a: eb 0e jmp 3a <main+0x3a>
  2c: 0f 1f 40 00 nopl 0x0(%rax)
  30: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 37 <main+0x37>
                        33: R_X86_64_REX_GOTPCRELX U_$P$PROGRAM_$$_IS_ALIGNED-0x4
  37: c6 00 01 movb $0x1,(%rax)
  3a: e8 00 00 00 00 callq 3f <U_$P$PROGRAM_$$_IS_ALIGNED+0x37>
                        3b: R_X86_64_PLT32 fpc_do_exit-0x4

Pierre Muller

2021-01-15 00:06

developer   ~0128334

I forgot this:
muller@gcc10:~/pas/check$ as --version
GNU assembler (GNU Binutils for Debian) 2.28
Copyright (C) 2017 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `x86_64-linux-gnu'.

Pierre Muller

2021-01-15 00:18

developer   ~0128335

I just recompiled binutils 2.35 on gcc10,
the output is the same as with binutils 2.28
for that source code.

Pierre Muller

2021-04-20 00:22

developer   ~0130460

I simplified the source code:
with latest trunk compiler, I still get the same relocation error:

bash-5.0 ~/pas/check$ cat test-addr.pp
{ %CPU=x86_64 }
program vectorcall_hva_test1;

{$IFNDEF CPUX86_64}
  {$FATAL This test program can only be compiled on Windows or Linux 64-bit with an Intel processor }
{$ENDIF}

{$ASMMODE Intel}
{$PUSH}
{$CODEALIGN RECORDMIN=16}
{$PACKRECORDS C}
type
  TM128 = record
    case Byte of
      0: (M128_F32: array[0..3] of Single);
      1: (M128_F64: array[0..1] of Double);
  end;
{$POP}

var
  HVA: TM128;

begin
{$ifdef verbose}
  writeln('@HVA=',hexstr(ptruint(@HVA),2*sizeof(ptruint)));
{$endif verbose}
  if (PtrUInt(@HVA) and $F) <> 0 then
  begin
{$ifdef verbose}
    WriteLn('FAIL: HVA is not correctly aligned.');
{$endif verbose}
    Halt(1);
  end;
end.
bash-5.0 ~/pas/check$ fpc -O2 test-addr -al -vx
Free Pascal Compiler version 3.3.1-r20:49231 [2021/04/19] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Note: Switching assembler to default source writing assembler
Target OS: OpenBSD for x86-64
Compiling test-addr.pp
Assembling vectorcall_hva_test1
Executing "/usr/bin/as" with command line "--64 -o test-addr.o test-addr.s"
Linking test-addr
Executing "/usr/bin/ld.bfd -dynamic-linker=/usr/libexec/ld.so -s -L. -o test-addr link57420.res" with fpSystem call
/home/muller/pas/fpc-3.3.1/lib/fpc/3.3.1/units/x86_64-openbsd/rtl/system.o: In function `STRCOPY':
../inc/cgenstr.inc:35: warning: strcpy() is almost always misused, please use strlcpy()
34 lines compiled, 0.2 sec
1 note(s) issued
bash-5.0 ~/pas/check$ ./test-addr ; echo "res=$?"
res=0
bash-5.0 ~/pas/check$ objdump -dr ./test-addr.o > test-addr-al.o.dis
bash-5.0 ~/pas/check$ fpc -O2 test-addr -vx
Free Pascal Compiler version 3.3.1-r20:49231 [2021/04/19] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: OpenBSD for x86-64
Compiling test-addr.pp
Linking test-addr
Executing "/usr/bin/ld.bfd -dynamic-linker=/usr/libexec/ld.so -s -L. -o test-addr link83059.res" with fpSystem call
/home/muller/pas/fpc-3.3.1/lib/fpc/3.3.1/units/x86_64-openbsd/rtl/system.o: In function `STRCOPY':
../inc/cgenstr.inc:35: warning: strcpy() is almost always misused, please use strlcpy()
34 lines compiled, 0.1 sec
bash-5.0 ~/pas/check$ ./test-addr ; echo "res=$?"
res=1
bash-5.0 ~/pas/check$ objdump -dr ./test-addr.o > test-addr.o.dis
bash-5.0 ~/pas/check$ diff test-addr-al.o.dis test-addr.o.dis
12c12
< 9: R_X86_64_GOTPCREL U_$P$VECTORCALL_HVA_TEST1_$$_HVA+0xfffffffffffffff8
---
> 9: R_X86_64_GOTPCREL U_$P$VECTORCALL_HVA_TEST1_$$_HVA+0xfffffffffffffffc
17c17
< 1d: e8 00 00 00 00 callq 22 <U_$P$VECTORCALL_HVA_TEST1_$$_HVA+0x22>
---
> 1d: e8 00 00 00 00 callq 22 <PASCALMAIN+0x22>
18a19
> ...

Pierre Muller

2021-04-20 00:29

developer   ~0130461

This code was compiled on x86_646openbsd, for which -Cg is default.
  You can get the same difference in output of disassembly by adding -Cg option on x86_64-linux target.

Pierre Muller

2021-04-20 01:22

developer   ~0130462

I tried the following, but it crashed on ppc2 during cycle:

bash-5.0 ~/pas/trunk/fpcsrc/compiler$ cat wrong-fix-for-bug-report-38353.patch
Index: ogelf.pas
===================================================================
--- ogelf.pas (revision 49237)
+++ ogelf.pas (working copy)
@@ -672,7 +672,12 @@
         if assigned(objreloc) then
           begin
             objreloc.size:=len;
- if reltype in [RELOC_RELATIVE{$ifdef x86},RELOC_PLT32{$endif}{$ifdef x86_64},RELOC_TLSGD,RELOC_GOTPCREL{$endif}] then
+ {$ifdef x86_64}
+ if reltype = RELOC_GOTPCREL then
+ dec(data,sizeof(aint))
+ else
+ {$endif x86_64}
+ if reltype in [RELOC_RELATIVE{$ifdef x86},RELOC_PLT32{$endif}{$ifdef x86_64},RELOC_TLSGD{$endif}] then
               dec(data,len);
             if ElfTarget.relocs_use_addend then
               begin

  Hopefully someone can look into this issue and solve it correctly!

Pierre Muller

2021-04-24 00:08

developer   ~0130555

  Hopefully completely solved by commit #49252.

Issue History

Date Modified Username Field Change
2021-01-13 23:19 Pierre Muller New Issue
2021-01-14 21:55 Florian Note Added: 0128326
2021-01-15 00:05 Pierre Muller Note Added: 0128333
2021-01-15 00:06 Pierre Muller Note Added: 0128334
2021-01-15 00:18 Pierre Muller Note Added: 0128335
2021-04-20 00:22 Pierre Muller Note Added: 0130460
2021-04-20 00:29 Pierre Muller Note Added: 0130461
2021-04-20 01:22 Pierre Muller Note Added: 0130462
2021-04-24 00:08 Pierre Muller Assigned To => Pierre Muller
2021-04-24 00:08 Pierre Muller Status new => resolved
2021-04-24 00:08 Pierre Muller Resolution open => fixed
2021-04-24 00:08 Pierre Muller Fixed in Revision => 49252
2021-04-24 00:08 Pierre Muller FPCTarget => -
2021-04-24 00:08 Pierre Muller Note Added: 0130555