Skip to content

Commit

Permalink
Also parse __CheriBSD_version when building natively
Browse files Browse the repository at this point in the history
This ensures the correct flags are passed to select the appropriate
variadic calling convention.
  • Loading branch information
arichardson committed Mar 22, 2024
1 parent d98bdd5 commit 5984f75
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 26 deletions.
27 changes: 4 additions & 23 deletions pycheribuild/config/compilation_targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
DefaultInstallDir,
MipsFloatAbi,
TargetInfo,
cheribsd_morello_version_dependent_flags,
sys_param_h_cheribsd_version,
)
from ..processutils import extract_version, get_compiler_info, get_version_output
from ..projects.simple_project import SimpleProject
Expand Down Expand Up @@ -689,16 +691,7 @@ def _get_rootfs_class(self, xtarget: "CrossCompileTarget") -> "type[SimpleProjec
return SimpleProject.get_class_for_target_name("cheribsd", xtarget)

def cheribsd_version(self) -> "Optional[int]":
pattern = re.compile(r"#define\s+__CheriBSD_version\s+([0-9]+)")
try:
with open(self.sysroot_dir / "usr/include/sys/param.h", encoding="utf-8") as f:
for line in f:
match = pattern.match(line)
if match:
return int(match.groups()[0])
except FileNotFoundError:
return None
return 0
return sys_param_h_cheribsd_version(self.sysroot_dir)


class CheriBSDMorelloTargetInfo(CheriBSDTargetInfo):
Expand Down Expand Up @@ -729,19 +722,7 @@ def get_non_rootfs_sysroot_dir(self) -> Path:
def essential_compiler_and_linker_flags_impl(cls, instance: "CheriBSDTargetInfo", *args, xtarget, **kwargs):
result = super().essential_compiler_and_linker_flags_impl(instance, *args, xtarget=xtarget, **kwargs)
version = instance.cheribsd_version()
# NB: If version is None, no CheriBSD tree exists, so we assume the new
# ABI will be used when CheriBSD is eventually built. This ensures the
# LLVM config files for the SDK utilities get the right flags in the
# common case as otherwise there is a circular dependency.
if version is None or version >= 20220511:
# Use new var-args ABI
result.extend(["-Xclang", "-morello-vararg=new"])
if version is None or version >= 20230804:
# Use new function call ABI
result.extend(["-Xclang", "-morello-bounded-memargs=caller-only"])
if xtarget.is_cheri_purecap([CPUArchitecture.AARCH64]) and version is not None and version < 20220511:
# Use emulated TLS on older purecap
result.append("-femulated-tls")
result.extend(cheribsd_morello_version_dependent_flags(version, xtarget.is_cheri_purecap()))
return result


Expand Down
48 changes: 45 additions & 3 deletions pycheribuild/config/target_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#
import functools
import platform
import re
import typing
from abc import ABC, abstractmethod
from enum import Enum
Expand All @@ -52,6 +53,8 @@
"MipsFloatAbi",
"NativeTargetInfo",
"TargetInfo",
"sys_param_h_cheribsd_version",
"cheribsd_morello_version_dependent_flags",
]


Expand Down Expand Up @@ -742,11 +745,18 @@ def essential_compiler_and_linker_flags_impl(
instance.project.fatal(
"Requested automatic variable initialization, but don't know how to for", compiler
)
if xtarget.is_cheri_hybrid():
if cls.is_cheribsd():
if xtarget.is_aarch64(include_purecap=True):
result.append("-mabi=aapcs")
cheribsd_version = sys_param_h_cheribsd_version(Path("/"))
result.extend(cheribsd_morello_version_dependent_flags(cheribsd_version, xtarget.is_cheri_purecap()))
if xtarget.is_cheri_purecap():
result.append("-mabi=purecap")
else:
assert xtarget.is_cheri_hybrid(), "non-cheri not supported"
result.append("-mabi=aapcs") # in case cc defaults to -mabi=purecap
result.append("-mcpu=rainier")
else:
instance.project.fatal("-native-hybrid not supported yet for non-Morello targets")
instance.project.fatal("Native CheriBSD compilation currently only supported for Morello targets")
return result # default host compiler should not need any extra flags


Expand Down Expand Up @@ -1111,6 +1121,38 @@ def _is_native_purecap():
return OSInfo.is_cheribsd() and platform.processor() in ("aarch64c", "riscv64c")


@functools.lru_cache(maxsize=3)
def sys_param_h_cheribsd_version(sysroot: Path) -> "Optional[int]":
pattern = re.compile(r"#define\s+__CheriBSD_version\s+([0-9]+)")
try:
with open(sysroot / "usr/include/sys/param.h", encoding="utf-8") as f:
for line in f:
match = pattern.match(line)
if match:
return int(match.groups()[0])
except FileNotFoundError:
return None
return 0


def cheribsd_morello_version_dependent_flags(cheribsd_version: "Optional[int]", is_purecap) -> "list[str]":
result = []
# NB: If version is None, no CheriBSD tree exists, so we assume the new
# ABI will be used when CheriBSD is eventually built. This ensures the
# LLVM config files for the SDK utilities get the right flags in the
# common case as otherwise there is a circular dependency.
if cheribsd_version is None or cheribsd_version >= 20220511:
# Use new var-args ABI
result.extend(["-Xclang", "-morello-vararg=new"])
if cheribsd_version is None or cheribsd_version >= 20230804:
# Use new function call ABI
result.extend(["-Xclang", "-morello-bounded-memargs=caller-only"])
if is_purecap and cheribsd_version is not None and cheribsd_version < 20220511:
# Use emulated TLS on older purecap
result.append("-femulated-tls")
return result


# This is a separate class to avoid cyclic dependencies.
# The real list is in CompilationTargets in compilation_targets.py
class BasicCompilationTargets:
Expand Down

0 comments on commit 5984f75

Please sign in to comment.