RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Bug 2216906 - Clang crashes with "load address" s390x assembly instruction
Summary: Clang crashes with "load address" s390x assembly instruction
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 9
Classification: Red Hat
Component: llvm
Version: 9.3
Hardware: s390x
OS: Linux
low
low
Target Milestone: rc
: 9.3
Assignee: Tulio Magno Quites Machado Filho
QA Contact: Jesus Checa
URL:
Whiteboard:
Depends On:
Blocks: 2173885
TreeView+ depends on / blocked
 
Reported: 2023-06-23 07:05 UTC by Thomas Huth
Modified: 2023-11-07 09:12 UTC (History)
9 users (show)

Fixed In Version: llvm-16.0.6-1.el9
Doc Type: No Doc Update
Doc Text:
Clone Of:
Environment:
Last Closed: 2023-11-07 08:25:58 UTC
Type: Bug
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
IBM Linux Technology Center 202876 0 None None None 2023-06-29 05:46:23 UTC
Red Hat Issue Tracker RHELPLAN-160534 0 None None None 2023-06-23 07:06:07 UTC
Red Hat Product Errata RHBA-2023:6360 0 None None None 2023-11-07 08:26:17 UTC

Description Thomas Huth 2023-06-23 07:05:29 UTC
Description of problem:
If trying to assemble an instruction like "la %r2,_end-start(%r2)" with Clang, the compiler crashes with a segmentation fault.

Version-Release number of selected component (if applicable):
clang-16.0.1-3.el9.s390x

How reproducible:
100%

Steps to Reproduce:
1. echo "start: la %r2,_end-start(%r2)" > /tmp/test.S
2. clang -c -o /tmp/test.o /tmp/test.S

Actual results:
clang-16: error: unable to execute command: Segmentation fault (core dumped)
clang-16: error: clang integrated assembler command failed due to signal (use -v to see invocation)

Expected results:
It works with GCC, so I think Clang should ideally be able to compile that line fine, too. At least there should be a proper error message, and not a segmentation fault.

Additional info:
GCC is able to compile the test.S file just fine.

Comment 1 Tulio Magno Quites Machado Filho 2023-06-27 19:46:29 UTC
@thuth , Would you have a link on how this code is being used in the wild, please? Including compiler flags.

Comment 2 Tulio Magno Quites Machado Filho 2023-06-27 19:49:14 UTC
While investigating this issue, I found out that LLVM_UNREACHABLE_OPTIMIZE is enabled (default behavior).
That explains why clang is crashing without providing a better error message.

Comment 3 Thomas Huth 2023-06-28 07:38:01 UTC
(In reply to Tulio Magno Quites Machado Filho from comment #1)
> @thuth , Would you have a link on how this code is being used in
> the wild, please? Including compiler flags.

I'm not aware of any real occurrences in the wild - I just came around this crash while I tried to find a solution for the problem that we hit in https://bugzilla.redhat.com/show_bug.cgi?id=2216662

Comment 4 Tulio Magno Quites Machado Filho 2023-06-28 15:27:25 UTC
tl;dr; I believe there are 3 independent bugs in this bug report:

1. I believe this asm construction is invalid in s390x, but it's exposing the following 2 issues.
2. GNU AS is trying to workaround limitations in ELF by computing offsets of defined symbols, but this may lead to errors later.
3. Clang assembler is trying to workaround the same limitations by computing PC-relative offsets, which isn't available for this kind of asm construction on s390x. It crashes instead of printing an error message.

Rationale
---------

AFAIU, ELF is not able to compute a relocation of the type: SymbolA - SymbolB + ConstantC. However, it can do SymbolA - ConstantK.
If both symbols were defined in the same object file, this wouldn't be an issue because their offsets are known at compilation time.
But one of the symbols is undefined.

GNU AS appears to work around this limitation by doing the following transformation:

   ConstantK = OffsetB + ConstantC

While this works on some scenarios, it isn't correct for all the cases.

The Clang assembler tries to work around the same limitation by using PC-relative relocation. AFAIU, this is guaranteed to work, but it isn't available for the kind of asm construction used here.

One way to fix this for non-pic code is to load the addresses separately using PC-relative loads, i.e. https://godbolt.org/z/hr758PK1j

Let me ask IBM to review this comment. They will be able to correct me.

I will drive changes to clang in order to provide a proper error output.

Comment 5 IBM Bug Proxy 2023-06-29 06:30:41 UTC
------- Comment From Andreas.Krebbel.com 2023-06-29 02:21 EDT-------
I think the difference you observed for your example between GCC and LLVM comes from the section anchors optimization in GCC we have enabled a while back for s390x. With section anchors GCC tries to address all local symbols using a section anchor to make better use of memory operands which we have in many instructions. You can turn that optimization off with -fno-section-anchors. Then both GCC and LLVM generate exactly the same code for your example.

To me both variants look ok though. If the extern symbol b comes from another .o file it is in fact local in the final link step and addressing it with larl is ok. If it comes from a shared library a copy relocation will be generated what also makes it addressable from the main binary with larl. If you build with -fPIC both compilers fetch the symbol addresses from the GOT and subtract it.

Comment 6 IBM Bug Proxy 2023-06-29 07:20:40 UTC
------- Comment From Andreas.Krebbel.com 2023-06-29 03:19 EDT-------
wrt "la %r2,_end-start(%r2)"

this is only legal if both symbols are defined in the same .s file so that the computation can be done by the assembler. Otherwise there would be no way to express this in a .o file. I'm not aware of any workaround gas is applying in that case. I would expect it just responses with "can't resolve". Not sure why this doesn't happen in that case though.

Comment 7 IBM Bug Proxy 2023-06-29 08:00:19 UTC
------- Comment From Andreas.Krebbel.com 2023-06-29 03:59 EDT-------
Tulio, please ignore my last two comments. I went into an utterly wrong direction. I should have read more carefully first.

You are right that GNU as appears to apply some questionable magic here instead of responding with "can't resolve" as it does for other cases I've tested.

For:

start:
.quad 4
la %r2,end-start(%r2)

gas tries to insert the address of end with an addend of 8 (which apparently is determined by the ".quad 4") as a 12 bit reloc

Relocation section '.rela.text' at offset 0xf0 contains 1 entry:
Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
000000000000000a  0000000500000002 R_390_12               0000000000000000 end + 8

gas only does that if start is defined in the code section. I need to have a closer look what's going on and whether it can be made to work in some cases but issuing an error instead is probably the right thing.

Thanks for looking into it and sorry for the confusion.

Comment 8 IBM Bug Proxy 2023-06-29 11:10:28 UTC
------- Comment From Ulrich.Weigand.com 2023-06-29 07:00 EDT-------
(In reply to comment #8)
> For:
>
> start:
>         .quad 4
>         la %r2,end-start(%r2)
>
> gas tries to insert the address of end with an addend of 8 (which apparently
> is determined by the ".quad 4") as a 12 bit reloc

I believe what's going on here is that GAS recognized that "start" is in the .text section and can therefore expressed relative to the PC:  start = PC - 8.

It then correctly transforms "end-start" into "end+8 - PC", which *could* be expressed as a PC-relative relocation --- if we *had* a 12-bit PC-relative reloc (something like "R_390_PC12").

Since we don't actually have this reloc, we cannot do this transformation here.  Both GAS and LLVM don't handle this correctly, but the details of the bug are different: GAS seems to simply ignore the PC-relative requirement and just uses the absolute relocation instead, while LLVM simply crashes because the relocation is not available ...

Comment 9 IBM Bug Proxy 2023-06-30 14:10:36 UTC
------- Comment From Ulrich.Weigand.com 2023-06-30 10:07 EDT-------
So it turned out LLVM already checked for these scenarios, but it would simply throw an assertion (llvm_unreachable).  Seems like in the RPM release builds, those assert messages don't even show up, so it just looks like a crash ...

In any case, as this can be triggered by invalid user input, it should never result in an assertion, but rather a regular compiler error message.

I've now fixes this, checked in as commit efbaf8bc61f4c0e29a3eaafb11ac0ddda8bd3dff.

In the test case, this now results in:

test.s:5:9: error: Unsupported PC-relative address
la %r2,end-start(%r2)
^

Comment 10 Tulio Magno Quites Machado Filho 2023-06-30 16:19:54 UTC
Thank you!
Let me backport this.

Comment 11 IBM Bug Proxy 2023-07-03 18:20:34 UTC
------- Comment From Andreas.Krebbel.com 2023-07-03 14:14 EDT-------
I've committed a Binutils fix to address this:
https://sourceware.org/pipermail/binutils/2023-July/128252.html

Comment 12 Tulio Magno Quites Machado Filho 2023-07-03 21:08:44 UTC
I created merge requests for the LLVM fixed on c9s: https://gitlab.com/redhat/centos-stream/rpms/llvm/-/merge_requests/45

And on Rawhide: https://src.fedoraproject.org/rpms/llvm/pull-request/174

Comment 14 Jesus Checa 2023-07-20 10:09:18 UTC
Tested with llvm-16.0.6-1.el9. When trying to assemble the code provided in the bug description clang reports the unsupported PC-relative relocation as expected.

++ mktemp -d
+ cd /tmp/tmp.h9xqb2nHNl
+ echo 'start: la %r2,_end-start(%r2)'
+ clang -c -o test.o test.S
+ tee clang.output
/tmp/test-1836fc.s:4:8: error: Unsupported PC-relative address
start: la %r2,_end-start(%r2)
       ^
+ grep -q 'Unsupported PC-relative address' clang.output

Testcase: https://src.fedoraproject.org/tests/llvm/blob/main/f/s390x-asm-unsupported-pc-relative-addr

Comment 19 errata-xmlrpc 2023-11-07 08:25:58 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (python-lit, lldb, lld, libomp, compiler-rt, clang, and llvm update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2023:6360


Note You need to log in before you can comment on or make changes to this bug.