Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 28 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,29 +96,31 @@ Here's a list of supported arch/ABI combinations accepted via `--arch` (values
are case-insensitive). This information is also available running
`systrack --arch help`.

| Value | Aliases | Arch | Kernel | Syscall ABI | Build based on | Notes |
|:----------------|:-------------------|:--------|:-------|:---------------|:------------------------------|:--------|
| `arm` | `arm-eabi`, `eabi` | ARM | 32-bit | 32-bit EABI | `multi_v7_defconfig` | *[2]* |
| `arm-oabi` | `oabi` | ARM | 32-bit | 32-bit OABI | `multi_v7_defconfig` | *[2,4]* |
| `arm64` | `aarch64` | ARM | 64-bit | 64-bit AArch64 | `defconfig` | |
| `arm64-aarch32` | `aarch32` | ARM | 64-bit | 32-bit AArch32 | `defconfig` | *[1]* |
| `mips` | `mips32`, `o32` | MIPS | 32-bit | 32-bit O32 | `defconfig` | |
| `mips64` | `n64` | MIPS | 64-bit | 64-bit N64 | `ip27_defconfig` | *[1]* |
| `mips64-n32` | `n32` | MIPS | 64-bit | 64-bit N32 | `ip27_defconfig` | *[1]* |
| `mips64-o32` | `o32-64` | MIPS | 64-bit | 32-bit O32 | `ip27_defconfig` | *[1]* |
| `powerpc` | `ppc`, `ppc32` | PowerPC | 32-bit | 32-bit PPC32 | `ppc64_defconfig` | |
| `powerpc64` | `ppc64` | PowerPC | 64-bit | 64-bit PPC64 | `ppc64_defconfig` | *[1]* |
| `powerpc64-32` | `ppc64-32` | PowerPC | 64-bit | 32-bit PPC32 | `ppc64_defconfig` | *[1]* |
| `powerpc64-spu` | `ppc64-spu`, `spu` | PowerPC | 64-bit | 64-bit "SPU" | `ppc64_defconfig` | *[1,5]* |
| `riscv` | `riscv32`, `rv32` | RISC-V | 32-bit | 32-bit "RV32" | `defconfig` + `32-bit.config` | *[3,6]* |
| `riscv64` | `rv64` | RISC-V | 64-bit | 64-bit "RV64" | `defconfig` | *[1,6]* |
| `riscv64-32` | `rv64-32` | RISC-V | 64-bit | 32-bit "RV32" | `defconfig` | *[1,6]* |
| `s390x` | | IBM Z | 64-bit | 64-bit s390x | `defconfig` | *[1]* |
| `s390` | | IBM Z | 64-bit | 32-bit s390 | `defconfig` | *[1]* |
| `x86` | `i386`, `ia32` | x86 | 32-bit | 32-bit IA32 | `i386_defconfig` | |
| `x86-64` | `x64` | x86 | 64-bit | 64-bit x86-64 | `x86_64_defconfig` | *[1]* |
| `x86-64-x32` | `x32` | x86 | 64-bit | 64-bit x32 | `x86_64_defconfig` | *[1]* |
| `x86-64-ia32` | `ia32-64` | x86 | 64-bit | 32-bit IA32 | `x86_64_defconfig` | *[1]* |
| Value | Aliases | Arch | Kernel | Syscall ABI | Build based on | Notes |
|:----------------|:-------------------|:----------|:-------|:---------------|:------------------------------|:--------|
| `arm` | `arm-eabi`, `eabi` | ARM | 32-bit | 32-bit EABI | `multi_v7_defconfig` | *[2]* |
| `arm-oabi` | `oabi` | ARM | 32-bit | 32-bit OABI | `multi_v7_defconfig` | *[2,4]* |
| `arm64` | `aarch64` | ARM | 64-bit | 64-bit AArch64 | `defconfig` | |
| `arm64-aarch32` | `aarch32` | ARM | 64-bit | 32-bit AArch32 | `defconfig` | *[1]* |
| `loongarch32` | `la32` | LoongArch | 32-bit | 32-bit "LA32" | `loongson32_defconfig` | *[7,8]* |
| `loongarch64` | `la64` | LoongArch | 64-bit | 64-bit "LA64" | `loongson64_defconfig` | *[7,8]* |
| `mips` | `mips32`, `o32` | MIPS | 32-bit | 32-bit O32 | `defconfig` | |
| `mips64` | `n64` | MIPS | 64-bit | 64-bit N64 | `ip27_defconfig` | *[1]* |
| `mips64-n32` | `n32` | MIPS | 64-bit | 64-bit N32 | `ip27_defconfig` | *[1]* |
| `mips64-o32` | `o32-64` | MIPS | 64-bit | 32-bit O32 | `ip27_defconfig` | *[1]* |
| `powerpc` | `ppc`, `ppc32` | PowerPC | 32-bit | 32-bit PPC32 | `ppc64_defconfig` | |
| `powerpc64` | `ppc64` | PowerPC | 64-bit | 64-bit PPC64 | `ppc64_defconfig` | *[1]* |
| `powerpc64-32` | `ppc64-32` | PowerPC | 64-bit | 32-bit PPC32 | `ppc64_defconfig` | *[1]* |
| `powerpc64-spu` | `ppc64-spu`, `spu` | PowerPC | 64-bit | 64-bit "SPU" | `ppc64_defconfig` | *[1,5]* |
| `riscv` | `riscv32`, `rv32` | RISC-V | 32-bit | 32-bit "RV32" | `defconfig` + `32-bit.config` | *[3,6]* |
| `riscv64` | `rv64` | RISC-V | 64-bit | 64-bit "RV64" | `defconfig` | *[1,6]* |
| `riscv64-32` | `rv64-32` | RISC-V | 64-bit | 32-bit "RV32" | `defconfig` | *[1,6]* |
| `s390x` | | IBM Z | 64-bit | 64-bit s390x | `defconfig` | *[1]* |
| `s390` | | IBM Z | 64-bit | 32-bit s390 | `defconfig` | *[1]* |
| `x86` | `i386`, `ia32` | x86 | 32-bit | 32-bit IA32 | `i386_defconfig` | |
| `x86-64` | `x64` | x86 | 64-bit | 64-bit x86-64 | `x86_64_defconfig` | *[1]* |
| `x86-64-x32` | `x32` | x86 | 64-bit | 64-bit x32 | `x86_64_defconfig` | *[1]* |
| `x86-64-ia32` | `ia32-64` | x86 | 64-bit | 32-bit IA32 | `x86_64_defconfig` | *[1]* |

Notes:

Expand All @@ -134,6 +136,9 @@ Notes:
6. "RV32" and "RV64" are not real ABIs, but rather ISAs. The RISC-V syscall
ABI is the same for 32-bit and 64-bit (only register size differs). These
names are only used for clarity.
7. "LA32" and "LA64" are not real ABIs, but rather ISAs. The LoongArch syscall ABI is the same
for 32-bit and 64-bit (only register size differs). These names are only used for clarity.
8. "Old-world" ABI is not and won't be supported.

Runtime dependencies
--------------------
Expand Down
70 changes: 41 additions & 29 deletions src/systrack/arch/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .arch_base import Arch
from .arm import ArchArm
from .arm64 import ArchArm64
from .loongarch import ArchLoongArch
from .mips import ArchMips
from .powerpc import ArchPowerPC
from .riscv import ArchRiscV
Expand All @@ -16,6 +17,7 @@
ARCH_CLASSES = (
ArchArm,
ArchArm64,
ArchLoongArch,
ArchMips,
ArchPowerPC,
ArchRiscV,
Expand All @@ -34,6 +36,8 @@
'arm-oabi' : lambda v: ArchArm(v, abi='oabi'),
'arm64' : lambda v: ArchArm64(v, abi='aarch64'),
'arm64-aarch32': lambda v: ArchArm64(v, abi='aarch32'),
'loongarch32' : lambda v: ArchLoongArch(v, abi='la32', bits32=True),
'loongarch64' : lambda v: ArchLoongArch(v, abi='la64'),
'mips' : lambda v: ArchMips(v, abi='o32', bits32=True),
'mips64' : lambda v: ArchMips(v, abi='n64'),
'mips64-n32' : lambda v: ArchMips(v, abi='n32'),
Expand Down Expand Up @@ -61,6 +65,8 @@
('arm-oabi' , 'oabi' ),
('arm64' , 'aarch64' ),
('arm64-aarch32', 'aarch32' ),
('loongarch32' , 'la32' ),
('loongarch64' , 'la64' ),
('mips' , 'mips32' ),
('mips' , 'o32' ),
('mips64' , 'n64' ),
Expand All @@ -83,35 +89,38 @@
SUPPORTED_ARCHS_HELP = '''\
Supported architectures and ABIs (values are case-insensitive):

Value Aliases Arch Kernel Syscall ABI Build based on Notes
------------------------------------------------------------------------------------------------
arm arm-eabi, eabi ARM 32-bit 32-bit EABI multi_v7_defconfig [2]
arm-oabi oabi ARM 32-bit 32-bit OABI multi_v7_defconfig [2,4]
------------------------------------------------------------------------------------------------
arm64 aarch64 ARM 64-bit 64-bit AArch64 defconfig
arm64-aarch32 aarch32 ARM 64-bit 32-bit AArch32 defconfig [1]
------------------------------------------------------------------------------------------------
mips mips32, o32 MIPS 32-bit 32-bit O32 defconfig
mips64 n64 MIPS 64-bit 64-bit N64 ip27_defconfig [1]
mips64-n32 n32 MIPS 64-bit 64-bit N32 ip27_defconfig [1]
mips64-o32 o32-64 MIPS 64-bit 32-bit O32 ip27_defconfig [1]
------------------------------------------------------------------------------------------------
powerpc ppc, ppc32 PowerPC 32-bit 32-bit PPC32 ppc64_defconfig
powerpc64 ppc64 PowerPC 64-bit 64-bit PPC64 ppc64_defconfig [1]
powerpc64-32 ppc64-32 PowerPC 64-bit 32-bit PPC32 ppc64_defconfig [1]
powerpc64-spu ppc64-spu, spu PowerPC 64-bit 64-bit "SPU" ppc64_defconfig [1,5]
------------------------------------------------------------------------------------------------
riscv riscv32, rv32 RISC-V 32-bit 32-bit "RV32" defconfig + 32-bit.config [3,6]
riscv64 rv64 RISC-V 64-bit 64-bit "RV64" defconfig [1,6]
riscv64-32 rv64-32 RISC-V 64-bit 32-bit "RV32" defconfig [1,6]
------------------------------------------------------------------------------------------------
s390x IBM Z 64-bit 64-bit s390x defconfig [1]
s390 IBM Z 64-bit 32-bit s390 defconfig [1]
------------------------------------------------------------------------------------------------
x86 i386, ia32 x86 32-bit 32-bit IA32 i386_defconfig
x86-64 x64 x86 64-bit 64-bit x86-64 x86_64_defconfig [1]
x86-64-x32 x32 x86 64-bit 64-bit x32 x86_64_defconfig [1]
x86-64-ia32 ia32-64 x86 64-bit 32-bit IA32 x86_64_defconfig [1]
Value Aliases Arch Kernel Syscall ABI Build based on Notes
-------------------------------------------------------------------------------------------------
arm arm-eabi, eabi ARM 32-bit 32-bit EABI multi_v7_defconfig [2]
arm-oabi oabi ARM 32-bit 32-bit OABI multi_v7_defconfig [2,4]
-------------------------------------------------------------------------------------------------
arm64 aarch64 ARM 64-bit 64-bit AArch64 defconfig
arm64-aarch32 aarch32 ARM 64-bit 32-bit AArch32 defconfig [1]
-------------------------------------------------------------------------------------------------
loongarch32 la32 LoongArch 32-bit 32-bit "LA32" loongson32_defconfig [7,8]
loongarch64 la64 LoongArch 64-bit 64-bit "LA64" loongson64_defconfig [7,8]
-------------------------------------------------------------------------------------------------
mips mips32, o32 MIPS 32-bit 32-bit O32 defconfig
mips64 n64 MIPS 64-bit 64-bit N64 ip27_defconfig [1]
mips64-n32 n32 MIPS 64-bit 64-bit N32 ip27_defconfig [1]
mips64-o32 o32-64 MIPS 64-bit 32-bit O32 ip27_defconfig [1]
-------------------------------------------------------------------------------------------------
powerpc ppc, ppc32 PowerPC 32-bit 32-bit PPC32 ppc64_defconfig
powerpc64 ppc64 PowerPC 64-bit 64-bit PPC64 ppc64_defconfig [1]
powerpc64-32 ppc64-32 PowerPC 64-bit 32-bit PPC32 ppc64_defconfig [1]
powerpc64-spu ppc64-spu, spu PowerPC 64-bit 64-bit "SPU" ppc64_defconfig [1,5]
-------------------------------------------------------------------------------------------------
riscv riscv32, rv32 RISC-V 32-bit 32-bit "RV32" defconfig + 32-bit.config [3,6]
riscv64 rv64 RISC-V 64-bit 64-bit "RV64" defconfig [1,6]
riscv64-32 rv64-32 RISC-V 64-bit 32-bit "RV32" defconfig [1,6]
-------------------------------------------------------------------------------------------------
s390x IBM Z 64-bit 64-bit s390x defconfig [1]
s390 IBM Z 64-bit 32-bit s390 defconfig [1]
-------------------------------------------------------------------------------------------------
x86 i386, ia32 x86 32-bit 32-bit IA32 i386_defconfig
x86-64 x64 x86 64-bit 64-bit x86-64 x86_64_defconfig [1]
x86-64-x32 x32 x86 64-bit 64-bit x32 x86_64_defconfig [1]
x86-64-ia32 ia32-64 x86 64-bit 32-bit IA32 x86_64_defconfig [1]

[1] Building creates a kernel supporting all ABIs for this architecture.
[2] Build based on "defconfig" for Linux <= v3.7.
Expand All @@ -122,6 +131,9 @@
The ABI is really PPC64, but SPUs can only use a subset of syscalls.
[6] "RV32" and "RV64" are not real ABIs, but rather ISAs. The RISC-V syscall ABI is the same
for 32-bit and 64-bit (only register size differs). These names are only used for clarity.
[7] "LA32" and "LA64" are not real ABIs, but rather ISAs. The LoongArch syscall ABI is the same
for 32-bit and 64-bit (only register size differs). These names are only used for clarity.
[8] "Old-world" ABI is not and won't be supported.
'''

def arch_from_name(name: str, kernel_version: KernelVersion) -> Arch:
Expand Down
71 changes: 71 additions & 0 deletions src/systrack/arch/loongarch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from typing import Tuple, List, Optional

from ..elf import ELF, E_MACHINE, E_FLAGS
from ..kconfig_options import VERSION_INF
from ..type_hints import KernelVersion
from ..utils import VersionedDict

from .arch_base import Arch

class ArchLoongArch(Arch):
name = 'loongarch'
syscall_num_reg = 'a7'
syscall_arg_regs = ('a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6')

kconfig = VersionedDict(
(
# kexec_load
((6, 1), VERSION_INF, 'KEXEC=y', ['MMU=y']),
# seccomp
((5, 19), (5, 10), 'SECCOMP=y', []),
# mbind, {migrate.move}_pages, {get,set}_mempolicy
((5, 19), VERSION_INF, 'NUMA=y', ['SMP=y']),
)
)

def __init__(self, kernel_version: KernelVersion, abi: str, bits32: bool = False):
super().__init__(kernel_version, abi, bits32)
assert kernel_version >= (5, 19), (
'Mainline Linux only supports LoongArch from v5.19'
)
assert self.abi in ('la32', 'la64')

if self.abi == 'la32':
self.abi_bits32 = True
assert self.bits32

if self.bits32:
assert kernel_version >= (6, 19), (
'Mainline Linux only supports 32-bit LoongArch from v6.19'
)
self.config_targets = ('loongson32_defconfig',)
else:
if kernel_version >= (6, 19):
self.config_targets = ('loongson64_defconfig',)
else:
self.config_targets = ('loongson3_defconfig',)

# kexec_file_load
self.kconfig.add((6, 18), VERSION_INF, 'KEXEC_FILE=y', ['64BIT=y'])

@staticmethod
def match(vmlinux: ELF) -> Optional[Tuple[bool, List[str]]]:
if vmlinux.e_machine != E_MACHINE.EM_LOONGARCH:
return None

if vmlinux.bits32:
abis = ['la32']
else:
abis = ['la64']

return vmlinux.bits32, abis

def matches(self, vmlinux: ELF) -> bool:
assert not vmlinux.big_endian, 'Big-endian LoongArch kernel? WAT'
assert ((vmlinux.e_flags & E_FLAGS.EF_LOONGARCH_ABI_MASK) >> 6) == 1, (
'Unsupported ABI version'
)
return (
vmlinux.e_machine == E_MACHINE.EM_LOONGARCH
and vmlinux.bits32 == self.bits32
)
23 changes: 13 additions & 10 deletions src/systrack/elf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,21 @@

# Only EM_* macros relevant for vmlinux ELFs
class E_MACHINE(IntEnum):
EM_386 = 3 # x86
EM_MIPS = 8 # MIPS R3000 (32 or 64 bit)
EM_PPC = 20 # PowerPC 32-bit
EM_PPC64 = 21 # PowerPC 64-bit
EM_S390 = 22 # IBM S/390
EM_ARM = 40 # ARM 32-bit
EM_X86_64 = 62 # x86-64
EM_AARCH64 = 183 # ARM 64-bit
EM_RISCV = 243 # RISC-V
EM_386 = 3 # x86
EM_MIPS = 8 # MIPS R3000 (32 or 64 bit)
EM_PPC = 20 # PowerPC 32-bit
EM_PPC64 = 21 # PowerPC 64-bit
EM_S390 = 22 # IBM S/390
EM_ARM = 40 # ARM 32-bit
EM_X86_64 = 62 # x86-64
EM_AARCH64 = 183 # ARM 64-bit
EM_RISCV = 243 # RISC-V
EM_LOONGARCH = 258 # LoongArch

# Only EF_* macros that we actually use
class E_FLAGS(IntEnum):
EF_ARM_EABI_MASK = 0xff000000
EF_LOONGARCH_ABI_MASK = 0x000000c0

Section = namedtuple('Section', ('name', 'vaddr', 'off', 'size'))
_Symbol = namedtuple('_Symbol', ('vaddr', 'real_vaddr', 'size', 'type', 'name'))
Expand Down Expand Up @@ -79,7 +81,8 @@ def __init__(self, path: Union[str,Path]):
assert self.file.seek(0x12) == 0x12
self.e_machine = unpack(unpack_endian + 'H', self.file.read(2))[0]

assert self.file.seek(0x24) == 0x24
e_flags_offset = 0x24 if self.bits32 else 0x30
assert self.file.seek(e_flags_offset) == e_flags_offset
self.e_flags = unpack(unpack_endian + 'L', self.file.read(4))[0]

@property
Expand Down