Bug 203950 - clang mis-assembles immediate operands
Summary: clang mis-assembles immediate operands
Status: Closed Overcome By Events
Alias: None
Product: Base System
Classification: Unclassified
Component: arm (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: Bugmeister
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-10-22 11:22 UTC by Peter Jeremy
Modified: 2023-12-31 16:44 UTC (History)
2 users (show)

See Also:


Attachments
ARM AES code generated by OpenSSL perl script. (22.58 KB, text/plain)
2015-10-22 11:22 UTC, Peter Jeremy
no flags Details
perl script to generate ARM immediate constants (1.23 KB, application/x-perl)
2015-10-22 19:27 UTC, Peter Jeremy
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Jeremy freebsd_committer freebsd_triage 2015-10-22 11:22:58 UTC
Created attachment 162344 [details]
ARM AES code generated by OpenSSL perl script.

Whilst experimenting with the OpenSSL ARM assembler code, I discovered that clang is incorrectly handling immediate operands.

This is using:
% cc -c aes_arm.s
% objdump -d aes_arm.o | less
% cc -v
FreeBSD clang version 3.6.1 (tags/RELEASE_361/final 237755) 20150525
Target: armv6--freebsd11.0-gnueabihf
Thread model: posix

The source code (attached) includes:
AES_encrypt:
        sub     r3,pc,#8                @ AES_encrypt
        stmdb   sp!,{r1,r4-r12,lr}
        mov     r12,r0          @ inp
        mov     r11,r2
        sub     r10,r3,#AES_encrypt-AES_Te      @ Te

#AES_encrypt-AES_Te is 1344 or 0x540.  clang compiles this subtraction to 0xe243a540 - which decompiles to:
e243a540        sub     sl, r3, #268435456      ; 0x10000000
because the 12-bit immediate field is not a direct binary number but is a 4-bit rotation followed by a 8-bit binary value.  A correct value for this field would be (eg) 0xe54.  Note that as(1) gets compiles the instruction to:
e243ad15        sub     sl, r3, #1344   ; 0x540
Comment 1 Peter Jeremy freebsd_committer freebsd_triage 2015-10-22 19:27:55 UTC
Created attachment 162367 [details]
perl script to generate ARM immediate constants

Some experimenting with the attached script shows that the C compiler correctly handles constants in the C to object and C to asm cases but not the asm to object case.
Comment 2 Mark Linimon freebsd_committer freebsd_triage 2023-12-31 03:09:11 UTC
^Triage: close as OBE.

I'm sorry that this PR never got looked at, but by now, any OS from 2005 is long out of support.
Comment 3 Marcin Cieślak 2023-12-31 09:51:40 UTC
I have tried to compile this code on

FreeBSD clang version 14.0.5 (https://github.com/llvm/llvm-project.git llvmorg-14.0.5-0-gc12386ae247c)
Target: aarch64-unknown-freebsd13.2

and indeed it produces:

00000540 <AES_encrypt>:
     540: 08 30 4f e2   sub     r3, pc, #8
     544: f2 5f 2d e9   push    {r1, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}
     548: 00 c0 a0 e1   mov     r12, r0
     54c: 02 b0 a0 e1   mov     r11, r2
     550: 15 ad 43 e2   sub     r10, r3, #1344

same with the cross-compilation on amd64 on FreeBSD 15:

$ cc -target armv6--freebsd11.0-gnueabihf  -v          
FreeBSD clang version 17.0.6 (https://github.com/llvm/llvm-project.git llvmorg-17.0.6-0-g6009708b4367)
Target: armv6-unknown-freebsd11.0-gnueabihf

So this has been fixed in the meantime with clang.
Comment 4 Mark Linimon freebsd_committer freebsd_triage 2023-12-31 16:44:29 UTC
^Triage: confirmed fixed.