mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
convert spaces to tabs
This commit is contained in:
+1099
-1099
File diff suppressed because it is too large
Load Diff
@@ -70,17 +70,17 @@ R_OK :: Mode{.IROTH}
|
|||||||
|
|
||||||
/// The stats you get by calling `stat`
|
/// The stats you get by calling `stat`
|
||||||
STATX_BASIC_STATS :: Statx_Mask {
|
STATX_BASIC_STATS :: Statx_Mask {
|
||||||
.TYPE,
|
.TYPE,
|
||||||
.MODE,
|
.MODE,
|
||||||
.NLINK,
|
.NLINK,
|
||||||
.UID,
|
.UID,
|
||||||
.GID,
|
.GID,
|
||||||
.ATIME,
|
.ATIME,
|
||||||
.MTIME,
|
.MTIME,
|
||||||
.CTIME,
|
.CTIME,
|
||||||
.INO,
|
.INO,
|
||||||
.SIZE,
|
.SIZE,
|
||||||
.BLOCKS,
|
.BLOCKS,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+45
-45
@@ -29,7 +29,7 @@ where
|
|||||||
size_of(p2) <= size_of(uintptr)
|
size_of(p2) <= size_of(uintptr)
|
||||||
{
|
{
|
||||||
return cast(int) intrinsics.syscall(nr,
|
return cast(int) intrinsics.syscall(nr,
|
||||||
cast(uintptr) p1, cast(uintptr) p2)
|
cast(uintptr) p1, cast(uintptr) p2)
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
@@ -40,9 +40,9 @@ where
|
|||||||
size_of(p3) <= size_of(uintptr)
|
size_of(p3) <= size_of(uintptr)
|
||||||
{
|
{
|
||||||
return cast(int) intrinsics.syscall(nr,
|
return cast(int) intrinsics.syscall(nr,
|
||||||
cast(uintptr) p1,
|
cast(uintptr) p1,
|
||||||
cast(uintptr) p2,
|
cast(uintptr) p2,
|
||||||
cast(uintptr) p3)
|
cast(uintptr) p3)
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
@@ -54,10 +54,10 @@ where
|
|||||||
size_of(p4) <= size_of(uintptr)
|
size_of(p4) <= size_of(uintptr)
|
||||||
{
|
{
|
||||||
return cast(int) intrinsics.syscall(nr,
|
return cast(int) intrinsics.syscall(nr,
|
||||||
cast(uintptr) p1,
|
cast(uintptr) p1,
|
||||||
cast(uintptr) p2,
|
cast(uintptr) p2,
|
||||||
cast(uintptr) p3,
|
cast(uintptr) p3,
|
||||||
cast(uintptr) p4)
|
cast(uintptr) p4)
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
@@ -70,11 +70,11 @@ where
|
|||||||
size_of(p5) <= size_of(uintptr)
|
size_of(p5) <= size_of(uintptr)
|
||||||
{
|
{
|
||||||
return cast(int) intrinsics.syscall(nr,
|
return cast(int) intrinsics.syscall(nr,
|
||||||
cast(uintptr) p1,
|
cast(uintptr) p1,
|
||||||
cast(uintptr) p2,
|
cast(uintptr) p2,
|
||||||
cast(uintptr) p3,
|
cast(uintptr) p3,
|
||||||
cast(uintptr) p4,
|
cast(uintptr) p4,
|
||||||
cast(uintptr) p5)
|
cast(uintptr) p5)
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
@@ -88,12 +88,12 @@ where
|
|||||||
size_of(p6) <= size_of(uintptr)
|
size_of(p6) <= size_of(uintptr)
|
||||||
{
|
{
|
||||||
return cast(int) intrinsics.syscall(nr,
|
return cast(int) intrinsics.syscall(nr,
|
||||||
cast(uintptr) p1,
|
cast(uintptr) p1,
|
||||||
cast(uintptr) p2,
|
cast(uintptr) p2,
|
||||||
cast(uintptr) p3,
|
cast(uintptr) p3,
|
||||||
cast(uintptr) p4,
|
cast(uintptr) p4,
|
||||||
cast(uintptr) p5,
|
cast(uintptr) p5,
|
||||||
cast(uintptr) p6)
|
cast(uintptr) p6)
|
||||||
}
|
}
|
||||||
|
|
||||||
syscall :: proc {syscall0, syscall1, syscall2, syscall3, syscall4, syscall5, syscall6}
|
syscall :: proc {syscall0, syscall1, syscall2, syscall3, syscall4, syscall5, syscall6}
|
||||||
@@ -106,24 +106,24 @@ syscall :: proc {syscall0, syscall1, syscall2, syscall3, syscall4, syscall5, sys
|
|||||||
@(private)
|
@(private)
|
||||||
errno_unwrap3 :: #force_inline proc "contextless" (ret: $P, $T: typeid, $U: typeid) -> (T, Errno)
|
errno_unwrap3 :: #force_inline proc "contextless" (ret: $P, $T: typeid, $U: typeid) -> (T, Errno)
|
||||||
where
|
where
|
||||||
intrinsics.type_is_ordered_numeric(P)
|
intrinsics.type_is_ordered_numeric(P)
|
||||||
{
|
{
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
default_value: T
|
default_value: T
|
||||||
return default_value, Errno(-ret)
|
return default_value, Errno(-ret)
|
||||||
} else {
|
} else {
|
||||||
return cast(T) transmute(U) ret, Errno(.NONE)
|
return cast(T) transmute(U) ret, Errno(.NONE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
errno_unwrap2 :: #force_inline proc "contextless" (ret: $P, $T: typeid) -> (T, Errno) {
|
errno_unwrap2 :: #force_inline proc "contextless" (ret: $P, $T: typeid) -> (T, Errno) {
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
default_value: T
|
default_value: T
|
||||||
return default_value, Errno(-ret)
|
return default_value, Errno(-ret)
|
||||||
} else {
|
} else {
|
||||||
return cast(T) ret, Errno(.NONE)
|
return cast(T) ret, Errno(.NONE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
@@ -132,19 +132,19 @@ errno_unwrap :: proc {errno_unwrap2, errno_unwrap3}
|
|||||||
// Note(flysand): 32-bit architectures sometimes take in a 64-bit argument in a
|
// Note(flysand): 32-bit architectures sometimes take in a 64-bit argument in a
|
||||||
// register pair. This function should help me avoid typing the same code a few times..
|
// register pair. This function should help me avoid typing the same code a few times..
|
||||||
when size_of(int) == 4 {
|
when size_of(int) == 4 {
|
||||||
// xxx64 system calls take some parameters as pairs of ulongs rather than a single pointer
|
// xxx64 system calls take some parameters as pairs of ulongs rather than a single pointer
|
||||||
@(private)
|
@(private)
|
||||||
compat64_arg_pair :: #force_inline proc "contextless" (a: i64) -> (hi: uint, lo: uint) {
|
compat64_arg_pair :: #force_inline proc "contextless" (a: i64) -> (hi: uint, lo: uint) {
|
||||||
no_sign := uint(a)
|
no_sign := uint(a)
|
||||||
hi = uint(no_sign >> 32)
|
hi = uint(no_sign >> 32)
|
||||||
lo = uint(no_sign & 0xffff_ffff)
|
lo = uint(no_sign & 0xffff_ffff)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ... and on 64-bit architectures it's just a long
|
// ... and on 64-bit architectures it's just a long
|
||||||
@(private)
|
@(private)
|
||||||
compat64_arg_pair :: #force_inline proc "contextless" (a: i64) -> (uint) {
|
compat64_arg_pair :: #force_inline proc "contextless" (a: i64) -> (uint) {
|
||||||
return uint(a)
|
return uint(a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+654
-654
File diff suppressed because it is too large
Load Diff
+316
-316
@@ -28,14 +28,14 @@ Inode :: distinct u64
|
|||||||
|
|
||||||
/// Represents time with nanosecond precision
|
/// Represents time with nanosecond precision
|
||||||
Time_Spec :: struct {
|
Time_Spec :: struct {
|
||||||
time_sec: uint,
|
time_sec: uint,
|
||||||
time_nsec: uint,
|
time_nsec: uint,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents time with millisecond precision
|
/// Represents time with millisecond precision
|
||||||
Time_Val :: struct {
|
Time_Val :: struct {
|
||||||
seconds: int,
|
seconds: int,
|
||||||
microseconds: int,
|
microseconds: int,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// open.2 flags
|
/// open.2 flags
|
||||||
@@ -54,75 +54,75 @@ FD_Flags :: bit_set[FD_Flags_Bits; i32]
|
|||||||
Mode :: bit_set[Mode_Bits; u32]
|
Mode :: bit_set[Mode_Bits; u32]
|
||||||
|
|
||||||
when ODIN_ARCH == .amd64 {
|
when ODIN_ARCH == .amd64 {
|
||||||
// x86-64 has mode and nlink swapped for some reason
|
// x86-64 has mode and nlink swapped for some reason
|
||||||
_Arch_Stat :: struct {
|
_Arch_Stat :: struct {
|
||||||
dev: Dev,
|
dev: Dev,
|
||||||
ino: Inode,
|
ino: Inode,
|
||||||
nlink: uint,
|
nlink: uint,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
uid: Uid,
|
uid: Uid,
|
||||||
gid: Gid,
|
gid: Gid,
|
||||||
_: u32,
|
_: u32,
|
||||||
rdev: Dev,
|
rdev: Dev,
|
||||||
size: uint,
|
size: uint,
|
||||||
blksize: uint,
|
blksize: uint,
|
||||||
blocks: uint,
|
blocks: uint,
|
||||||
atime: Time_Spec,
|
atime: Time_Spec,
|
||||||
mtime: Time_Spec,
|
mtime: Time_Spec,
|
||||||
ctime: Time_Spec,
|
ctime: Time_Spec,
|
||||||
_: [3]uint,
|
_: [3]uint,
|
||||||
}
|
}
|
||||||
} else when ODIN_ARCH == .arm64 {
|
} else when ODIN_ARCH == .arm64 {
|
||||||
_Arch_Stat :: struct {
|
_Arch_Stat :: struct {
|
||||||
dev: Dev,
|
dev: Dev,
|
||||||
ino: Inode,
|
ino: Inode,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
nlink: u32,
|
nlink: u32,
|
||||||
uid: Uid,
|
uid: Uid,
|
||||||
gid: Gid,
|
gid: Gid,
|
||||||
rdev: Dev,
|
rdev: Dev,
|
||||||
_: u64,
|
_: u64,
|
||||||
size: int,
|
size: int,
|
||||||
blksize: i32,
|
blksize: i32,
|
||||||
_: i32,
|
_: i32,
|
||||||
blocks: int,
|
blocks: int,
|
||||||
atime: Time_Spec,
|
atime: Time_Spec,
|
||||||
mtime: Time_Spec,
|
mtime: Time_Spec,
|
||||||
ctime: Time_Spec,
|
ctime: Time_Spec,
|
||||||
_: [3]uint,
|
_: [3]uint,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_Arch_Stat :: struct {
|
_Arch_Stat :: struct {
|
||||||
dev: Dev,
|
dev: Dev,
|
||||||
_: [4]u8,
|
_: [4]u8,
|
||||||
_ino: uint, // Old 32-bit inode number, don't use
|
_ino: uint, // Old 32-bit inode number, don't use
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
nlink: u32,
|
nlink: u32,
|
||||||
uid: Uid,
|
uid: Uid,
|
||||||
gid: Gid,
|
gid: Gid,
|
||||||
rdev: Dev,
|
rdev: Dev,
|
||||||
size: i64,
|
size: i64,
|
||||||
blksize: uint,
|
blksize: uint,
|
||||||
blocks: u64,
|
blocks: u64,
|
||||||
atim: Time_Spec,
|
atim: Time_Spec,
|
||||||
mtim: Time_Spec,
|
mtim: Time_Spec,
|
||||||
ctim: Time_Spec,
|
ctim: Time_Spec,
|
||||||
ino: Inode,
|
ino: Inode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the file state.
|
/// Represents the file state.
|
||||||
/// Mirrors struct stat in glibc/linux kernel.
|
/// Mirrors struct stat in glibc/linux kernel.
|
||||||
/// If you're on 32-bit platform, consider using Stat64 instead
|
/// If you're on 32-bit platform, consider using Stat64 instead
|
||||||
Stat :: struct {
|
Stat :: struct {
|
||||||
using _impl_stat: _Arch_Stat,
|
using _impl_stat: _Arch_Stat,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Timestamp type used for Statx struct
|
/// Timestamp type used for Statx struct
|
||||||
Statx_Timestamp :: struct {
|
Statx_Timestamp :: struct {
|
||||||
sec: i64,
|
sec: i64,
|
||||||
nsec: u32,
|
nsec: u32,
|
||||||
_: i32,
|
_: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Query params/results for `statx()`
|
/// Query params/results for `statx()`
|
||||||
@@ -135,78 +135,78 @@ Statx_Attr :: bit_set[Statx_Attr_Bits; u64]
|
|||||||
|
|
||||||
/// The extended Stat struct
|
/// The extended Stat struct
|
||||||
Statx :: struct {
|
Statx :: struct {
|
||||||
mask: Statx_Mask,
|
mask: Statx_Mask,
|
||||||
blksize: u32,
|
blksize: u32,
|
||||||
attributes: Statx_Attr,
|
attributes: Statx_Attr,
|
||||||
nlink: u32,
|
nlink: u32,
|
||||||
uid: Uid,
|
uid: Uid,
|
||||||
gid: Gid,
|
gid: Gid,
|
||||||
// Note(flysand): mode is 16-bit on linux + there's
|
// Note(flysand): mode is 16-bit on linux + there's
|
||||||
// 16-bit padding following it. Since our mode is 32-bits,
|
// 16-bit padding following it. Since our mode is 32-bits,
|
||||||
// we're using the padding. This should be fine because
|
// we're using the padding. This should be fine because
|
||||||
// the placement of that padding suggests it was going to
|
// the placement of that padding suggests it was going to
|
||||||
// be used for the Mode bits anyway.
|
// be used for the Mode bits anyway.
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
ino: Inode,
|
ino: Inode,
|
||||||
size: u64,
|
size: u64,
|
||||||
blocks: u64,
|
blocks: u64,
|
||||||
attributes_mask: Statx_Attr,
|
attributes_mask: Statx_Attr,
|
||||||
atime: Statx_Timestamp,
|
atime: Statx_Timestamp,
|
||||||
btime: Statx_Timestamp,
|
btime: Statx_Timestamp,
|
||||||
ctime: Statx_Timestamp,
|
ctime: Statx_Timestamp,
|
||||||
mtime: Statx_Timestamp,
|
mtime: Statx_Timestamp,
|
||||||
rdev_major: u32,
|
rdev_major: u32,
|
||||||
rdev_minor: u32,
|
rdev_minor: u32,
|
||||||
dev_major: u32,
|
dev_major: u32,
|
||||||
dev_minor: u32,
|
dev_minor: u32,
|
||||||
mnt_id: u64,
|
mnt_id: u64,
|
||||||
dio_mem_align: u32,
|
dio_mem_align: u32,
|
||||||
dio_offset_align: u32,
|
dio_offset_align: u32,
|
||||||
_: [12]u64,
|
_: [12]u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mount flags for filesystem
|
/// Mount flags for filesystem
|
||||||
FS_Flags :: bit_set[FS_Flags_Bits; u32]
|
FS_Flags :: bit_set[FS_Flags_Bits; u32]
|
||||||
|
|
||||||
when size_of(int) == 8 {
|
when size_of(int) == 8 {
|
||||||
_Arch_Stat_FS :: struct {
|
_Arch_Stat_FS :: struct {
|
||||||
// Note(flysand): The FS_Magic bits are never above
|
// Note(flysand): The FS_Magic bits are never above
|
||||||
// 32-bits, so it should be fine for now...
|
// 32-bits, so it should be fine for now...
|
||||||
type: FS_Magic,
|
type: FS_Magic,
|
||||||
_: u32,
|
_: u32,
|
||||||
bsize: i64,
|
bsize: i64,
|
||||||
blocks: i64,
|
blocks: i64,
|
||||||
bfree: i64,
|
bfree: i64,
|
||||||
bavail: i64,
|
bavail: i64,
|
||||||
files: i64,
|
files: i64,
|
||||||
ffree: i64,
|
ffree: i64,
|
||||||
fsid : [2]i32,
|
fsid : [2]i32,
|
||||||
namelen: i64,
|
namelen: i64,
|
||||||
frsize: i64,
|
frsize: i64,
|
||||||
// Note(flysand): Same story as type
|
// Note(flysand): Same story as type
|
||||||
flags: FS_Flags,
|
flags: FS_Flags,
|
||||||
_: u32,
|
_: u32,
|
||||||
spare: [4]i64,
|
spare: [4]i64,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_Arch_Stat_FS :: struct {
|
_Arch_Stat_FS :: struct {
|
||||||
type: FS_Magic,
|
type: FS_Magic,
|
||||||
bsize: u32,
|
bsize: u32,
|
||||||
blocks: u64,
|
blocks: u64,
|
||||||
bfree: u64,
|
bfree: u64,
|
||||||
bavail: u64,
|
bavail: u64,
|
||||||
files: u64,
|
files: u64,
|
||||||
ffree: u64,
|
ffree: u64,
|
||||||
fsid: [2]i32,
|
fsid: [2]i32,
|
||||||
namelen: u32,
|
namelen: u32,
|
||||||
frsize: u32,
|
frsize: u32,
|
||||||
flags: FS_Flags,
|
flags: FS_Flags,
|
||||||
spare: [4]u32,
|
spare: [4]u32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stat_FS :: struct {
|
Stat_FS :: struct {
|
||||||
using _impl_stat_fs: _Arch_Stat_FS,
|
using _impl_stat_fs: _Arch_Stat_FS,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flags for close_range.2
|
/// Flags for close_range.2
|
||||||
@@ -219,20 +219,20 @@ Rename_Flags :: bit_set[Rename_Flags_Bits; u32]
|
|||||||
/// Recommended to use this with dirent_iterator()
|
/// Recommended to use this with dirent_iterator()
|
||||||
/// and dirent_name()
|
/// and dirent_name()
|
||||||
Dirent :: struct {
|
Dirent :: struct {
|
||||||
ino: Inode,
|
ino: Inode,
|
||||||
off: i64,
|
off: i64,
|
||||||
reclen: u16,
|
reclen: u16,
|
||||||
type: Dirent_Type,
|
type: Dirent_Type,
|
||||||
name: [0]u8, // See dirent_name
|
name: [0]u8, // See dirent_name
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Lock record for fcntl.2
|
/// Lock record for fcntl.2
|
||||||
FLock :: struct {
|
FLock :: struct {
|
||||||
type: FLock_Type,
|
type: FLock_Type,
|
||||||
whence: Seek_Whence,
|
whence: Seek_Whence,
|
||||||
start: i64,
|
start: i64,
|
||||||
len: i64,
|
len: i64,
|
||||||
pid: Pid,
|
pid: Pid,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flags for fcntl_notify
|
/// Flags for fcntl_notify
|
||||||
@@ -243,8 +243,8 @@ Seal :: bit_set[Seal_Bits; i32]
|
|||||||
|
|
||||||
/// Represents owner that receives events on file updates
|
/// Represents owner that receives events on file updates
|
||||||
F_Owner :: struct {
|
F_Owner :: struct {
|
||||||
type: F_Owner_Type,
|
type: F_Owner_Type,
|
||||||
pid: Pid,
|
pid: Pid,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Events for ppoll
|
/// Events for ppoll
|
||||||
@@ -252,9 +252,9 @@ Fd_Poll_Events :: bit_set[Fd_Poll_Events_Bits; u16]
|
|||||||
|
|
||||||
/// Struct for ppoll
|
/// Struct for ppoll
|
||||||
Poll_Fd :: struct {
|
Poll_Fd :: struct {
|
||||||
fd: Fd,
|
fd: Fd,
|
||||||
events: Fd_Poll_Events,
|
events: Fd_Poll_Events,
|
||||||
revents: Fd_Poll_Events,
|
revents: Fd_Poll_Events,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specifies protection for memory pages
|
/// Specifies protection for memory pages
|
||||||
@@ -292,79 +292,79 @@ Branch_Sample_Type :: bit_set[Branch_Sample_Type_Bits; u64]
|
|||||||
|
|
||||||
/// The struct for perf_event_open
|
/// The struct for perf_event_open
|
||||||
Perf_Event_Attr :: struct #packed {
|
Perf_Event_Attr :: struct #packed {
|
||||||
type: Perf_Event_Type,
|
type: Perf_Event_Type,
|
||||||
size: u32,
|
size: u32,
|
||||||
config: struct #raw_union {
|
config: struct #raw_union {
|
||||||
hw: Perf_Hardware_Id,
|
hw: Perf_Hardware_Id,
|
||||||
sw: Perf_Software_Id,
|
sw: Perf_Software_Id,
|
||||||
cache: u64,
|
cache: u64,
|
||||||
other: u64,
|
other: u64,
|
||||||
},
|
},
|
||||||
sample: struct #raw_union {
|
sample: struct #raw_union {
|
||||||
period: u64,
|
period: u64,
|
||||||
frequency: u64,
|
frequency: u64,
|
||||||
},
|
},
|
||||||
sample_type: Perf_Event_Sample_Type,
|
sample_type: Perf_Event_Sample_Type,
|
||||||
read_format: Perf_Read_Format,
|
read_format: Perf_Read_Format,
|
||||||
flags: Perf_Event_Flags,
|
flags: Perf_Event_Flags,
|
||||||
wakeup: struct #raw_union {
|
wakeup: struct #raw_union {
|
||||||
events: u32,
|
events: u32,
|
||||||
watermark: u32,
|
watermark: u32,
|
||||||
},
|
},
|
||||||
breakpoint_type: Hardware_Breakpoint_Type,
|
breakpoint_type: Hardware_Breakpoint_Type,
|
||||||
using _: struct #raw_union {
|
using _: struct #raw_union {
|
||||||
breakpoint_addr: u64,
|
breakpoint_addr: u64,
|
||||||
kprobe_func: u64,
|
kprobe_func: u64,
|
||||||
uprobe_path: u64,
|
uprobe_path: u64,
|
||||||
config1: u64,
|
config1: u64,
|
||||||
},
|
},
|
||||||
using _: struct #raw_union {
|
using _: struct #raw_union {
|
||||||
breakpoint_len: u64,
|
breakpoint_len: u64,
|
||||||
kprobe_addr: u64,
|
kprobe_addr: u64,
|
||||||
uprobe_offset: u64,
|
uprobe_offset: u64,
|
||||||
config2: u64,
|
config2: u64,
|
||||||
},
|
},
|
||||||
branch_sample_type: Branch_Sample_Type,
|
branch_sample_type: Branch_Sample_Type,
|
||||||
sample_regs_user: u64,
|
sample_regs_user: u64,
|
||||||
sample_stack_user: u32,
|
sample_stack_user: u32,
|
||||||
clock_id: i32, // TODO(flysand): clock_id
|
clock_id: i32, // TODO(flysand): clock_id
|
||||||
sample_regs_intr: u64,
|
sample_regs_intr: u64,
|
||||||
aux_watermark: u32,
|
aux_watermark: u32,
|
||||||
sample_max_stack: u16,
|
sample_max_stack: u16,
|
||||||
_: u16,
|
_: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The ring buffer structure when mmaping Perf_Event_Attr
|
/// The ring buffer structure when mmaping Perf_Event_Attr
|
||||||
Perf_Event_Mmap_Page :: struct #packed {
|
Perf_Event_Mmap_Page :: struct #packed {
|
||||||
version: u32,
|
version: u32,
|
||||||
compat_version: u32,
|
compat_version: u32,
|
||||||
lock: u32,
|
lock: u32,
|
||||||
index: u32,
|
index: u32,
|
||||||
offset: i64,
|
offset: i64,
|
||||||
time_enabled: u64,
|
time_enabled: u64,
|
||||||
time_running: u64,
|
time_running: u64,
|
||||||
cap: struct #raw_union {
|
cap: struct #raw_union {
|
||||||
capabilities: u64,
|
capabilities: u64,
|
||||||
flags: Perf_Cap_Flags,
|
flags: Perf_Cap_Flags,
|
||||||
},
|
},
|
||||||
pmc_width: u16,
|
pmc_width: u16,
|
||||||
time_shift: u16,
|
time_shift: u16,
|
||||||
time_mult: u32,
|
time_mult: u32,
|
||||||
time_offset: u64,
|
time_offset: u64,
|
||||||
time_zero: u64,
|
time_zero: u64,
|
||||||
size: u32,
|
size: u32,
|
||||||
reserved1: u32,
|
reserved1: u32,
|
||||||
time_cycles: u64,
|
time_cycles: u64,
|
||||||
time_mask: u64,
|
time_mask: u64,
|
||||||
reserved2: [116*8]u8,
|
reserved2: [116*8]u8,
|
||||||
data_head: u64,
|
data_head: u64,
|
||||||
data_tail: u64,
|
data_tail: u64,
|
||||||
data_offset: u64,
|
data_offset: u64,
|
||||||
data_size: u64,
|
data_size: u64,
|
||||||
aux_head: u64,
|
aux_head: u64,
|
||||||
aux_tail: u64,
|
aux_tail: u64,
|
||||||
aux_offset: u64,
|
aux_offset: u64,
|
||||||
aux_size: u64,
|
aux_size: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(flysand): Its taking too much effort to bind the other data structures related to perf_event_open
|
// TODO(flysand): Its taking too much effort to bind the other data structures related to perf_event_open
|
||||||
@@ -393,68 +393,68 @@ Sig_Handler_Fn :: #type proc "c" (sig: Signal)
|
|||||||
Sig_Restore_Fn :: #type proc "c" ()
|
Sig_Restore_Fn :: #type proc "c" ()
|
||||||
|
|
||||||
Sig_Info :: struct #packed {
|
Sig_Info :: struct #packed {
|
||||||
signo: Signal,
|
signo: Signal,
|
||||||
errno: Errno,
|
errno: Errno,
|
||||||
code: i32,
|
code: i32,
|
||||||
_pad0: i32,
|
_pad0: i32,
|
||||||
using _union: struct #raw_union {
|
using _union: struct #raw_union {
|
||||||
_pad1: [SI_PAD_SIZE]u8,
|
_pad1: [SI_PAD_SIZE]u8,
|
||||||
using _kill: struct {
|
using _kill: struct {
|
||||||
pid: Pid, /* sender's pid */
|
pid: Pid, /* sender's pid */
|
||||||
uid: Uid, /* sender's uid */
|
uid: Uid, /* sender's uid */
|
||||||
},
|
},
|
||||||
using _timer: struct {
|
using _timer: struct {
|
||||||
timerid: i32, /* timer id */
|
timerid: i32, /* timer id */
|
||||||
overrun: i32, /* overrun count */
|
overrun: i32, /* overrun count */
|
||||||
},
|
},
|
||||||
/* POSIX.1b signals */
|
/* POSIX.1b signals */
|
||||||
using _rt: struct {
|
using _rt: struct {
|
||||||
_pid0: Pid, /* sender's pid */
|
_pid0: Pid, /* sender's pid */
|
||||||
_uid0: Uid, /* sender's uid */
|
_uid0: Uid, /* sender's uid */
|
||||||
},
|
},
|
||||||
/* SIGCHLD */
|
/* SIGCHLD */
|
||||||
using _sigchld: struct {
|
using _sigchld: struct {
|
||||||
_pid1: Pid, /* which child */
|
_pid1: Pid, /* which child */
|
||||||
_uid1: Uid, /* sender's uid */
|
_uid1: Uid, /* sender's uid */
|
||||||
status: i32, /* exit code */
|
status: i32, /* exit code */
|
||||||
utime: uint,
|
utime: uint,
|
||||||
stime: uint, //clock_t
|
stime: uint, //clock_t
|
||||||
},
|
},
|
||||||
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
|
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
|
||||||
using _sigfault: struct {
|
using _sigfault: struct {
|
||||||
addr: rawptr, /* faulting insn/memory ref. */
|
addr: rawptr, /* faulting insn/memory ref. */
|
||||||
addr_lsb: i16, /* LSB of the reported address */
|
addr_lsb: i16, /* LSB of the reported address */
|
||||||
},
|
},
|
||||||
/* SIGPOLL */
|
/* SIGPOLL */
|
||||||
using _sigpoll: struct {
|
using _sigpoll: struct {
|
||||||
band: int, /* POLL_IN, POLL_OUT, POLL_MSG */
|
band: int, /* POLL_IN, POLL_OUT, POLL_MSG */
|
||||||
fd: Fd,
|
fd: Fd,
|
||||||
},
|
},
|
||||||
/* SIGSYS */
|
/* SIGSYS */
|
||||||
using _sigsys: struct {
|
using _sigsys: struct {
|
||||||
call_addr: rawptr, /* calling user insn */
|
call_addr: rawptr, /* calling user insn */
|
||||||
syscall: i32, /* triggering system call number */
|
syscall: i32, /* triggering system call number */
|
||||||
arch: u32, /* AUDIT_ARCH_* of syscall */
|
arch: u32, /* AUDIT_ARCH_* of syscall */
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
Sig_Stack_Flags :: bit_set[Sig_Stack_Flag; i32]
|
Sig_Stack_Flags :: bit_set[Sig_Stack_Flag; i32]
|
||||||
|
|
||||||
Sig_Stack :: struct {
|
Sig_Stack :: struct {
|
||||||
sp: rawptr,
|
sp: rawptr,
|
||||||
flags: Sig_Stack_Flags,
|
flags: Sig_Stack_Flags,
|
||||||
size: uintptr,
|
size: uintptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
Sig_Action :: struct($T: typeid) {
|
Sig_Action :: struct($T: typeid) {
|
||||||
using _u: struct #raw_union {
|
using _u: struct #raw_union {
|
||||||
handler: Sig_Handler_Fn,
|
handler: Sig_Handler_Fn,
|
||||||
sigaction: #type proc "c" (sig: Signal, si: ^Sig_Info, ctx: ^T),
|
sigaction: #type proc "c" (sig: Signal, si: ^Sig_Info, ctx: ^T),
|
||||||
},
|
},
|
||||||
flags: uint,
|
flags: uint,
|
||||||
restorer: Sig_Restore_Fn,
|
restorer: Sig_Restore_Fn,
|
||||||
mask: Sig_Set,
|
mask: Sig_Set,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -472,28 +472,28 @@ Socket_Msg :: bit_set[Socket_Msg_Bits; i32]
|
|||||||
|
|
||||||
/// Struct representing IPv4 socket address
|
/// Struct representing IPv4 socket address
|
||||||
Sock_Addr_In :: struct #packed {
|
Sock_Addr_In :: struct #packed {
|
||||||
sin_family: Address_Family,
|
sin_family: Address_Family,
|
||||||
sin_port: u16be,
|
sin_port: u16be,
|
||||||
sin_addr: [4]u8,
|
sin_addr: [4]u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Struct representing IPv6 socket address
|
/// Struct representing IPv6 socket address
|
||||||
Sock_Addr_In6 :: struct #packed {
|
Sock_Addr_In6 :: struct #packed {
|
||||||
sin6_family: Address_Family,
|
sin6_family: Address_Family,
|
||||||
sin6_port: u16be,
|
sin6_port: u16be,
|
||||||
sin6_flowinfo: u32,
|
sin6_flowinfo: u32,
|
||||||
sin6_addr: [16]u8,
|
sin6_addr: [16]u8,
|
||||||
sin6_scope_id: u32,
|
sin6_scope_id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Struct representing an arbitrary socket address
|
/// Struct representing an arbitrary socket address
|
||||||
Sock_Addr_Any :: struct #raw_union {
|
Sock_Addr_Any :: struct #raw_union {
|
||||||
using _: struct {
|
using _: struct {
|
||||||
family: Address_Family,
|
family: Address_Family,
|
||||||
port: u16be,
|
port: u16be,
|
||||||
},
|
},
|
||||||
using ipv4: Sock_Addr_In,
|
using ipv4: Sock_Addr_In,
|
||||||
using ipv6: Sock_Addr_In6,
|
using ipv6: Sock_Addr_In6,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Just an alias to make futex-values more visible
|
/// Just an alias to make futex-values more visible
|
||||||
@@ -504,63 +504,63 @@ Futex_Flags :: bit_set[Futex_Flags_Bits; u32]
|
|||||||
|
|
||||||
/// Times
|
/// Times
|
||||||
Tms :: struct {
|
Tms :: struct {
|
||||||
tms_utime: int,
|
tms_utime: int,
|
||||||
tms_stime: int,
|
tms_stime: int,
|
||||||
tms_cutime: int,
|
tms_cutime: int,
|
||||||
tms_cstime: int,
|
tms_cstime: int,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "Unix time-sharing system name", allegedly
|
/// "Unix time-sharing system name", allegedly
|
||||||
/// Basically system info
|
/// Basically system info
|
||||||
UTS_Name :: struct {
|
UTS_Name :: struct {
|
||||||
sysname: [65]u8 `fmt:"s,0"`,
|
sysname: [65]u8 `fmt:"s,0"`,
|
||||||
nodename: [65]u8 `fmt:"s,0"`,
|
nodename: [65]u8 `fmt:"s,0"`,
|
||||||
release: [65]u8 `fmt:"s,0"`,
|
release: [65]u8 `fmt:"s,0"`,
|
||||||
version: [65]u8 `fmt:"s,0"`,
|
version: [65]u8 `fmt:"s,0"`,
|
||||||
machine: [65]u8 `fmt:"s,0"`,
|
machine: [65]u8 `fmt:"s,0"`,
|
||||||
domainname: [65]u8 `fmt:"s,0"`,
|
domainname: [65]u8 `fmt:"s,0"`,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return buffer for the sysinfo syscall
|
/// Return buffer for the sysinfo syscall
|
||||||
Sys_Info :: struct {
|
Sys_Info :: struct {
|
||||||
uptime: int,
|
uptime: int,
|
||||||
loads: [3]int,
|
loads: [3]int,
|
||||||
totalram: uint,
|
totalram: uint,
|
||||||
freeram: uint,
|
freeram: uint,
|
||||||
sharedram: uint,
|
sharedram: uint,
|
||||||
bufferram: uint,
|
bufferram: uint,
|
||||||
totalswap: uint,
|
totalswap: uint,
|
||||||
freeswap: uint,
|
freeswap: uint,
|
||||||
procs: u16,
|
procs: u16,
|
||||||
totalhigh: uint,
|
totalhigh: uint,
|
||||||
freehigh: uint,
|
freehigh: uint,
|
||||||
mem_unit: i32,
|
mem_unit: i32,
|
||||||
_padding: [20 - (2 * size_of(int)) - size_of(i32)]u8,
|
_padding: [20 - (2 * size_of(int)) - size_of(i32)]u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resource limit
|
/// Resource limit
|
||||||
RLimit :: struct {
|
RLimit :: struct {
|
||||||
cur: uint,
|
cur: uint,
|
||||||
max: uint,
|
max: uint,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Structure representing how much of each resource
|
/// Structure representing how much of each resource
|
||||||
/// got used.
|
/// got used.
|
||||||
RUsage :: struct {
|
RUsage :: struct {
|
||||||
utime: Time_Val,
|
utime: Time_Val,
|
||||||
stime: Time_Val,
|
stime: Time_Val,
|
||||||
maxrss_word: int,
|
maxrss_word: int,
|
||||||
ixrss_word: int,
|
ixrss_word: int,
|
||||||
idrss_word: int,
|
idrss_word: int,
|
||||||
isrss_word: int,
|
isrss_word: int,
|
||||||
minflt_word: int,
|
minflt_word: int,
|
||||||
majflt_word: int,
|
majflt_word: int,
|
||||||
nswap_word: int,
|
nswap_word: int,
|
||||||
inblock_word: int,
|
inblock_word: int,
|
||||||
oublock_word: int,
|
oublock_word: int,
|
||||||
msgsnd_word: int,
|
msgsnd_word: int,
|
||||||
msgrcv_word: int,
|
msgrcv_word: int,
|
||||||
nsignals_word: int,
|
nsignals_word: int,
|
||||||
nvcsw_word: int,
|
nvcsw_word: int,
|
||||||
nivcsw_word: int,
|
nivcsw_word: int,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,48 +4,48 @@ package linux
|
|||||||
/// Low 8 bits of the exit code
|
/// Low 8 bits of the exit code
|
||||||
/// Only retrieve the exit code if WIFEXITED(s) = true
|
/// Only retrieve the exit code if WIFEXITED(s) = true
|
||||||
WEXITSTATUS :: #force_inline proc "contextless" (s: u32) -> u32 {
|
WEXITSTATUS :: #force_inline proc "contextless" (s: u32) -> u32 {
|
||||||
return (s & 0xff00) >> 8
|
return (s & 0xff00) >> 8
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Termination signal
|
/// Termination signal
|
||||||
/// Only retrieve the code if WIFSIGNALED(s) = true
|
/// Only retrieve the code if WIFSIGNALED(s) = true
|
||||||
WTERMSIG :: #force_inline proc "contextless" (s: u32) -> u32 {
|
WTERMSIG :: #force_inline proc "contextless" (s: u32) -> u32 {
|
||||||
return s & 0x7f
|
return s & 0x7f
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The signal that stopped the child
|
/// The signal that stopped the child
|
||||||
/// Only retrieve if WIFSTOPPED(s) = true
|
/// Only retrieve if WIFSTOPPED(s) = true
|
||||||
WSTOPSIG :: #force_inline proc "contextless" (s: u32) -> u32 {
|
WSTOPSIG :: #force_inline proc "contextless" (s: u32) -> u32 {
|
||||||
return WEXITSTATUS(s)
|
return WEXITSTATUS(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the process terminated normally (via exit.2)
|
/// Check if the process terminated normally (via exit.2)
|
||||||
WIFEXITED :: #force_inline proc "contextless" (s: u32) -> bool {
|
WIFEXITED :: #force_inline proc "contextless" (s: u32) -> bool {
|
||||||
return WTERMSIG(s) == 0
|
return WTERMSIG(s) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the process signaled
|
/// Check if the process signaled
|
||||||
WIFSIGNALED :: #force_inline proc "contextless" (s: u32) -> bool {
|
WIFSIGNALED :: #force_inline proc "contextless" (s: u32) -> bool {
|
||||||
return cast(i8)(((s) & 0x7f) + 1) >> 1 > 0
|
return cast(i8)(((s) & 0x7f) + 1) >> 1 > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the process has stopped
|
/// Check if the process has stopped
|
||||||
WIFSTOPPED :: #force_inline proc "contextless" (s: u32) -> bool {
|
WIFSTOPPED :: #force_inline proc "contextless" (s: u32) -> bool {
|
||||||
return (s & 0xff) == 0x7f
|
return (s & 0xff) == 0x7f
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the process is continued by the tracee
|
/// Check if the process is continued by the tracee
|
||||||
WIFCONTINUED :: #force_inline proc "contextless" (s: u32) -> bool {
|
WIFCONTINUED :: #force_inline proc "contextless" (s: u32) -> bool {
|
||||||
return s == 0xffff
|
return s == 0xffff
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the process dumped core
|
/// Check if the process dumped core
|
||||||
WCOREDUMP :: #force_inline proc "contextless" (s: u32) -> bool {
|
WCOREDUMP :: #force_inline proc "contextless" (s: u32) -> bool {
|
||||||
return s & 0x80 == 0x80
|
return s & 0x80 == 0x80
|
||||||
}
|
}
|
||||||
|
|
||||||
@private _sigmask :: proc "contextless" (sig: Signal) -> (uint) {
|
@private _sigmask :: proc "contextless" (sig: Signal) -> (uint) {
|
||||||
return 1 << ((cast(uint)(sig) - 1) % (8*size_of(uint)))
|
return 1 << ((cast(uint)(sig) - 1) % (8*size_of(uint)))
|
||||||
}
|
}
|
||||||
@private _sigword :: proc "contextless" (sig: Signal) -> (uint) {
|
@private _sigword :: proc "contextless" (sig: Signal) -> (uint) {
|
||||||
return (cast(uint)sig - 1) / (8*size_of(uint))
|
return (cast(uint)sig - 1) / (8*size_of(uint))
|
||||||
@@ -71,51 +71,51 @@ WCOREDUMP :: #force_inline proc "contextless" (s: u32) -> bool {
|
|||||||
/// This function doesn't automatically make a request
|
/// This function doesn't automatically make a request
|
||||||
/// for the buffer to be refilled
|
/// for the buffer to be refilled
|
||||||
dirent_iterate_buf :: proc "contextless" (buf: []u8, offs: ^int) -> (d: ^Dirent, cont: bool) {
|
dirent_iterate_buf :: proc "contextless" (buf: []u8, offs: ^int) -> (d: ^Dirent, cont: bool) {
|
||||||
// Stopped iterating when there's no space left
|
// Stopped iterating when there's no space left
|
||||||
if offs^ >= len(buf) {
|
if offs^ >= len(buf) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
// Retrieve dirent form the current offset
|
// Retrieve dirent form the current offset
|
||||||
dirent := cast(^Dirent) &buf[offs^]
|
dirent := cast(^Dirent) &buf[offs^]
|
||||||
// Add the stride of dirent struct to the current offset
|
// Add the stride of dirent struct to the current offset
|
||||||
offs^ += cast(int) dirent.reclen
|
offs^ += cast(int) dirent.reclen
|
||||||
return dirent, true
|
return dirent, true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Obtain the name of dirent as a string
|
/// Obtain the name of dirent as a string
|
||||||
/// The lifetime of the string is bound to the lifetime of the provided dirent structure
|
/// The lifetime of the string is bound to the lifetime of the provided dirent structure
|
||||||
dirent_name :: proc "contextless" (dirent: ^Dirent) -> string #no_bounds_check {
|
dirent_name :: proc "contextless" (dirent: ^Dirent) -> string #no_bounds_check {
|
||||||
str := transmute([^]u8) &dirent.name
|
str := transmute([^]u8) &dirent.name
|
||||||
// Note(flysand): The string size calculated above applies only to the ideal case
|
// Note(flysand): The string size calculated above applies only to the ideal case
|
||||||
// we subtract 1 byte from the string size, because a null terminator is guaranteed
|
// we subtract 1 byte from the string size, because a null terminator is guaranteed
|
||||||
// to be present. But! That said, the dirents are aligned to 8 bytes and the padding
|
// to be present. But! That said, the dirents are aligned to 8 bytes and the padding
|
||||||
// between the null terminator and the start of the next struct may be not initialized
|
// between the null terminator and the start of the next struct may be not initialized
|
||||||
// which means we also have to scan these garbage bytes.
|
// which means we also have to scan these garbage bytes.
|
||||||
str_size := (cast(int) dirent.reclen) - 1 - cast(int) offset_of(Dirent, name)
|
str_size := (cast(int) dirent.reclen) - 1 - cast(int) offset_of(Dirent, name)
|
||||||
// This skips *only* over the garbage, since if we're not garbage we're at nul terminator,
|
// This skips *only* over the garbage, since if we're not garbage we're at nul terminator,
|
||||||
// which skips this loop
|
// which skips this loop
|
||||||
for str[str_size] != 0 {
|
for str[str_size] != 0 {
|
||||||
str_size -= 1
|
str_size -= 1
|
||||||
}
|
}
|
||||||
for str[str_size-1] == 0 {
|
for str[str_size-1] == 0 {
|
||||||
str_size -= 1
|
str_size -= 1
|
||||||
}
|
}
|
||||||
// Oh yeah btw i could also just `repne scasb` this thing, but honestly I started doing
|
// Oh yeah btw i could also just `repne scasb` this thing, but honestly I started doing
|
||||||
// it the painful way, might as well finish doing it that way
|
// it the painful way, might as well finish doing it that way
|
||||||
return string(str[:str_size])
|
return string(str[:str_size])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructor for the `futex_op` argument of a FUTEX_WAKE_OP call
|
/// Constructor for the `futex_op` argument of a FUTEX_WAKE_OP call
|
||||||
futex_op :: proc "contextless" (arg_op: Futex_Arg_Op, cmp_op: Futex_Cmp_Op, op_arg: u32, cmp_arg: u32) -> u32 {
|
futex_op :: proc "contextless" (arg_op: Futex_Arg_Op, cmp_op: Futex_Cmp_Op, op_arg: u32, cmp_arg: u32) -> u32 {
|
||||||
arg_op := cast(u32) arg_op
|
arg_op := cast(u32) arg_op
|
||||||
cmp_op := cast(u32) cmp_op
|
cmp_op := cast(u32) cmp_op
|
||||||
return (arg_op << 28) | (cmp_op << 24) | ((op_arg & 0xfff) << 12) | (cmp_arg & 0xfff)
|
return (arg_op << 28) | (cmp_op << 24) | ((op_arg & 0xfff) << 12) | (cmp_arg & 0xfff)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function for constructing the config for caches
|
/// Helper function for constructing the config for caches
|
||||||
perf_cache_config :: #force_inline proc "contextless" (id: Perf_Hardware_Cache_Id,
|
perf_cache_config :: #force_inline proc "contextless" (id: Perf_Hardware_Cache_Id,
|
||||||
op: Perf_Hardware_Cache_Op_Id,
|
op: Perf_Hardware_Cache_Op_Id,
|
||||||
res: Perf_Hardware_Cache_Result_Id) -> u64
|
res: Perf_Hardware_Cache_Result_Id) -> u64
|
||||||
{
|
{
|
||||||
return u64(id) | (u64(op) << 8) | (u64(res) << 16)
|
return u64(id) | (u64(op) << 8) | (u64(res) << 16)
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user