Skip to content

Commit c0076e2

Browse files
committed
[CHERIoT] Use the CompressedCap tables to compute cap alignment in LLD.
1 parent 4da66a8 commit c0076e2

File tree

4 files changed

+19
-10
lines changed

4 files changed

+19
-10
lines changed

lld/ELF/Arch/RISCV.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "Symbols.h"
1414
#include "SyntheticSections.h"
1515
#include "Target.h"
16+
#include "llvm/CHERI/CompressedCapability.h"
1617
#include "llvm/Support/ELFAttributes.h"
1718
#include "llvm/Support/LEB128.h"
1819
#include "llvm/Support/RISCVAttributeParser.h"
@@ -760,16 +761,14 @@ static void tlsdescToLe(uint8_t *loc, const Relocation &rel, uint64_t val) {
760761
}
761762

762763
uint64_t RISCV::cheriRequiredAlignment(uint64_t size) const {
763-
// FIXME: Non-CherIoT targets will have different calculations here
764-
uint64_t mantissaWidth = 9;
765-
auto mantissaWidthMinusOneMask = (uint64_t(1) << (mantissaWidth - 1)) - 1;
766-
uint64_t msbIdxPlusOne = 64 - llvm::countl_zero(size);
767-
uint64_t e = std::max<int64_t>(int64_t(msbIdxPlusOne) - mantissaWidth, 0);
768-
// If we are very close to the top, then we need to round up one more
769-
if (((size >> (e + 1)) & mantissaWidthMinusOneMask) ==
770-
mantissaWidthMinusOneMask)
771-
++e;
772-
return uint64_t(1) << e;
764+
auto CapFormat = llvm::CompressedCapability::Cheri128;
765+
if (ctx.arg.isCheriot)
766+
CapFormat = llvm::CompressedCapability::Cheriot64;
767+
else if (!ctx.arg.is64)
768+
CapFormat = llvm::CompressedCapability::Cheri64;
769+
770+
return llvm::CompressedCapability::GetRequiredAlignment(size, CapFormat)
771+
.value();
773772
}
774773

775774
void RISCV::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {

lld/ELF/Config.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,9 @@ struct Config {
549549
// True if we are creating a pure-capability CheriABI output.
550550
bool isCheriAbi = false;
551551

552+
// True if we are creating a CHERIoT output.
553+
bool isCheriot = false;
554+
552555
// Mode of MTE to write to the ELF note. Should be one of NT_MEMTAG_ASYNC (for
553556
// async), NT_MEMTAG_SYNC (for sync), or NT_MEMTAG_LEVEL_NONE (for none). If
554557
// async or sync is enabled, write the ELF note specifying the default MTE

lld/ELF/Driver.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3496,6 +3496,9 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
34963496

34973497
ctx.arg.eflags = ctx.target->calcEFlags();
34983498
ctx.arg.isCheriAbi = ctx.target->calcIsCheriAbi();
3499+
if (ctx.arg.isCheriAbi)
3500+
ctx.arg.isCheriot = ctx.arg.eflags & EF_RISCV_CHERIOT;
3501+
34993502
// maxPageSize (sometimes called abi page size) is the maximum page size that
35003503
// the output can be run on. For example if the OS can use 4k or 64k page
35013504
// sizes then maxPageSize must be 64k for the output to be useable on both.

llvm/include/llvm/CHERI/CompressedCapability.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@
99
#ifndef LLVM_COMPRESSED_CAPABILITY_H
1010
#define LLVM_COMPRESSED_CAPABILITY_H
1111

12+
#include "llvm/MC/MCTargetOptions.h"
13+
#include "llvm/Support/Alignment.h"
14+
1215
#include <algorithm>
1316
#include <cstdint>
1417

1518
namespace llvm {
19+
1620
namespace CompressedCapability {
1721

1822
enum class CapabilityFormat {

0 commit comments

Comments
 (0)