-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect offsets in PCC-relative address calculations when compiling C for CHERIoT #106
Comments
With the -S flag, this is the output:
|
That's interesting. I thought we expanded that in the back end, rather than emitting it. |
As far as I can tell, the CHERIoT 11-bit immediate for AUIPCC wasn't implemented in LLD (except when applying a I assume the reason this was overlooked was because the toolchain users and developers were always using relaxations and all of those
It's expanded in the MC layer but not for textual assembly. |
Yes, that sounds about right. I don't think I've ever seen an auipcc with a non-zero offset that wasn't coupled with a relocation. I'm not really sure why your code is not being emitted with a relaxation. LLD doesn't need to know about the shift except when applying relocations. We shouldn't have any relocations except |
The reproducer is being compiled with
It has a |
I switched off the relaxations only because the linker was failing to achieve convergence and I needed to get past that. The problem was seen before that, though, albeit not as such an obvious fault. With relaxations permitted I still see a failure at the point of trying to follow an implicit compiler-generated library call to |
Toolchain issue with
auipcc
instructions in compiled C.Commit: 6d22636
(also observed with earlier versions)
The offsets used in the calculation of PCC-relative targets are observed to be incorrect. The offsets appear not to have been adjusted for the fact that the AUIPCC instruction employs an 11-bit shifted constant rather than the RV-standard 12-bit offset. This has been observed to occur when the ensuing instruction is 'clc' (as in the pseudo-op 'cllc'), cincaddrimm or cjalr, as in this demonstration of a simple function call.
In every case that's been studied, the correct target address may be obtained by adding the literal constant from the 'auipcc <>' into the calculated address a second time, i.e. calculating as if that constant were still 12-bit shifted as per the RV standard.
Note: the file
cheriot_toolchain.cmake
shows the compilation switches being used; since this is our first use of C and CHERI on a large codebase, please do check the options used.Update: the significant variable in this specific failure is the disabling of linker relaxations, but with more extensive source trees, the same faults occurs even with linker relaxations enabled.
This simple reproduction consists of a simple C/C++ file (test_case.c and test_case.cc; the code is the same) and a contrived assembler file - test_space.S - that ensures the target address is sufficiently far from the call site that auipcc must have a non-zero offset.
Build instructions:
Output:
Relevant disassembly from 'test_c':
The above disassembly shows the error in
test_c
but you may also simulate it using the included Verilator build of Sunburst chip:Output from simulation of test_c (C compilation)
Compilation with linker relaxations enabled
The corresponding output from the build, where the auipcc/cjalr is replaced with a simple cjal instruction, is fine:
./Vtop_chip_verilator -E build/test_cc | more
Output from simulation of test_c/cc
Source files for reproducing this issue: source.zip
Simulator binary (x64 Linux): simulator.zip
The text was updated successfully, but these errors were encountered: