#pmOS - microkernel OS for RISC-V, x86, and LoongArch

1 messages · Page 6 of 1

toxic torrent
#

trolled

carmine nacelle
#

It's an IPC call

#

Which can always error out

toxic torrent
#

fair point

carmine nacelle
#

(because of bad design)

toxic torrent
#

but ipc call to what?

#

from libc to posix server?

carmine nacelle
#

The same way that my pthread_mutex_unlock can also ENOMEM

carmine nacelle
toxic torrent
#

ahh

carmine nacelle
#

Tbh I probably need to move the processes to kernel

#

memes

#

And maybe signals

toxic torrent
#

i have processes and threads in kernel, but posix layer in user

carmine nacelle
#

Though idk I don't even have signals fully implemented

toxic torrent
#

signals are :(

carmine nacelle
#

And for signals I have userspace thread per process

#

But idk

#

I'll see

#

"rustc has very good error messages"

#

thonk nvm, I'm dumb

toxic torrent
#

i have a microkernel question

#

how does one start a posix server without the posix system

#

like

#

wouldn't you need a lot of ipc calls to itself?

#

because i noticed you're not compiling with -ffreestanding

carmine nacelle
#

all my ipc is async

#

and the library thread is what makes the calls

#

lib/libc/src/generic/worker_thread/worker_main.c

#

Idk if it's a good design...

toxic torrent
#

i mean, how are you able to use a hosted environment for e.g. bootstrapd

carmine nacelle
#

It doesn't use POSIX API

#

And everything is done lazilly

#

I mean it does

#

Nvm

#

It calls malloc and friends

toxic torrent
#

same thing with managarm

carmine nacelle
#

It doesn't use the things provided by posix server

toxic torrent
#

i don't see how i'm supposed to bootstrap e.g. the posix server without a vfs

#

if that needs an interpreter

#

lol

agile patrol
#

Come on, why you do that

toxic torrent
#

?

carmine nacelle
agile patrol
carmine nacelle
#

Also, I don't have exec* functions yet

#

Because I have no filesystems

#

(For which I'm porting Rust)

mellow sleet
#

I would just not use posix functions in the posix server

toxic torrent
#

maybe im misunderstanding things

#

because e.g. posix-subsystem on managarm has a PT_INTERP entry

carmine nacelle
agile patrol
#

I just dont know what I would typing

carmine nacelle
hexed acorn
toxic torrent
#

ah

#

that explains it

hexed acorn
#

for the vfs it serves stuff from the initrd and whatever you upload at runtime

mellow sleet
#

fake microkernel

hexed acorn
#

it's called being pragmatic

mellow sleet
#

boooooring you need to be IDEALISTIC

#

smh

toxic torrent
#

i kinda want to keep the posix server self contained

agile patrol
#

I am offering $12

carmine nacelle
#

I also have a very small ELF loader in kernel to load bootstrapd

toxic torrent
#

same

carmine nacelle
#

You can also just use a flat binary

mellow sleet
#

you should do scheduling in userspace or yotrure not a real microkernel

carmine nacelle
#

I'm planning to do that trl

#

Idr why

#

But I've been thinking about it a lot and it made sense

vernal bay
#

I think Tanenbaum put the line at the VFS

toxic torrent
#

performance is cringe anyways

carmine nacelle
#

My kernel has no knowledge of vfs

carmine nacelle
#

I remembered why

#

Linux added userspace schedulers in 6.12

carmine nacelle
agile patrol
#

Where is everyone,,, now is morning

carmine nacelle
hexed acorn
#

technically we could get rid of it

#

by having a second set of mlibc sysdeps or not using mlibc at all

toxic torrent
#

@agile patrol can you stop posting random things to derail the discussion

hexed acorn
carmine nacelle
#

I also use C++

carmine nacelle
#

everywhere

agile patrol
hexed acorn
#

not just freestanding stuff

carmine nacelle
toxic torrent
#

banger

carmine nacelle
#

the only freestanding program is kernel, everything else is fully hosted

hexed acorn
#

yeah and for that you need at least a skeleton of a libc

agile patrol
hexed acorn
#

and for managarm instead of having a separate libc or whatever we just have the minimum needed to run mlibc programs in the kernel instead

carmine nacelle
hexed acorn
#

although it's still all done via ipc, the programs just talk over ipc to the kernel

toxic torrent
#

how dumb would it be to just have the posix system be a freestanding binary meme

carmine nacelle
#

I just wrote my own freestanding containers and stuff for the kernel

mellow sleet
#

the only real syscall imple,mented should be write()

hexed acorn
mellow sleet
#

you make fd 3 the syscall fd

#

and you write all syscalls into that fd

hexed acorn
carmine nacelle
#

I think I need to look at managram

#

I'm lost

hexed acorn
carmine nacelle
#

My stdin/stdout/stderr just waits for the log server to appear (the first time they are used), and libc also only talks to vfs when you call open() or whatnot

#

It's done without vfs

hexed acorn
#

well we need the vfs since posix-subsystem et al are dynamically linked

#

and we use dynamic libraries for more than just libc

carmine nacelle
#

You can just statically link it (?)

#

Yeah

carmine nacelle
hexed acorn
#

i mean we could, but mlibc static linking support came after all this was in place

carmine nacelle
#

I don't have dynamic linking yet

mellow sleet
#

or is it ipc

hexed acorn
#

just to an ipc stream where the other lane is listened to by the kernel instead of posix-subsystem

carmine nacelle
#

my bootstrap server can (could in the past, it's probably broken now) also act as a filesystem

carmine nacelle
#

so tmpfs driver could just open() the module passed by the bootloader

hexed acorn
#

it is a small impurity in the microkernelness but it's self-contained in a 700 line file (+ associated header file)

#

the other code just does runService(name, controlHandle, myNewThread); and that spins up the coroutine that does the request handling

hexed acorn
vernal bay
#

I'd gladly take it

toxic torrent
#

free

inland temple
agile patrol
vernal bay
#

.!naenae @agile patrol no soliciting in DMs!

long grailBOT
#
Dd-Aing JUST GOT NAENAED

GET FRICKED KIDDO

hexed acorn
vernal bay
#

.!naenae @Dd-Aing no soliciting in other project's threads

long grailBOT
#
Command executed by lukflug
Command Error
Type

SyntaxError

Details

Expected type: user for argument: target but got: "@Dd-Aing no soliciting in other project's threads" (string) instead
NOTE: Attempted implicit cast from: string ->user failed (not found)

vernal bay
#

.!naenae 450856877472088066 no soliciting in other project's threads

long grailBOT
#
Confirmation

@agile patrol is already banned. Do you want to update the ban reason/author?

long grailBOT
# long grail
Dd-Aing JUST GOT HACKNAENAED

GET FRICKED KIDDO

carmine nacelle
#

thonk what if I just implement arc4random?

#

Seems like a nice API

carmine nacelle
#

bruh wsl crashed

left dew
#

lol wtf did u do

eager rose
#

maybe it got OOM'd

carmine nacelle
#

my laptop has 32gb of ram

#

Anyway, the only things missing are this rust dumbness (or more likely my skill issue), ioctl and a couple of broken things

carmine nacelle
#

I think this is the only thing that I need to add to my libc/Rust?

inland temple
#

if you would use mlibc you could just autogenerate the bindings for the libc crate meme

#

we have a script that uses libclang to parse mlibc headers and output rust libc bindings that you just copy+paste into the crate

#

and then you need a 2-line patch to the crade to pub mod managarm; or equivalent

pearl narwhal
#

if no i think that should be a thing

carmine nacelle
#

too late

#

I did it manually

#

(though I might switch to mlibc later once I stabilize my API)

pearl narwhal
inland temple
#

like

#

linux-mlibc has no relation to managarm

pearl narwhal
#

i meant the managarm project

#

not os lol

inland temple
#

yeah still what does that refer to

pearl narwhal
#

e.g. for gcc there's a fork i can use

#

but if there's no such thing for rust I'll have to do it myself (either using the rust binding generator in nixpkgs or uploading the fork somewhere

inland temple
#

so for providing the (patched) libc crate, we pull the libc crate source, copy/paste our autogenerated bindings, and apply a small patch for it to include our bindings

pearl narwhal
#

ah so there's no downstream fork for it or anything and is just patched by the build system?

inland temple
#

I'm not sure how relevant that would be on linux with mlibc tho

carmine nacelle
#

Someone can also just upstream mlibc to rust meme

inland temple
#

I was working on that

#

I lost track tho

#

ah right I need to ping LLVM people

pearl narwhal
inland temple
#

generally we do not maintain forked repos of anything except gcc and binutils

#

we always just ship patch files that we apply on top of the source

toxic torrent
#

wait do i understand it correctly, if mlibc was upstream, would that enable it for all projects using it?

carmine nacelle
#

bruhI have Rust??

carmine nacelle
#

You still have to add OS-specific stuff?

toxic torrent
#

isn't that then handled by libc?

left dew
#

is rust std entirely implemented in terms of libc calls?

toxic torrent
#

would be omega based

left dew
#

would be kinda cringe

#

but also understandable

toxic torrent
#

duality of man

left dew
#

nah i fully stand behind implementing std in terms of syscalls

#

linking against libc in non-C code is cringe

#

after all it's the C library...

#

not the Rust library

toxic torrent
#

for a big os, maybe

#

but its tedious if you have to do it on your own

#

libc my beloved

dense carbon
#

OSes and languages always went together historically

inland temple
#

it needs to be per-os

#

obv as the ABI and options selection changes

#

what I will attempt to do is to upstream the (auto-generated) managarm bindings

pearl narwhal
#

it needs to be per-os yes but quite a lot can be libc calls i believe

pearl narwhal
carmine nacelle
#

I'll test now

#

It probably won't link

#

How do I give cargo sysroot?

#

Do I just use normal lld?

hexed acorn
#

are you rewriting pmos in rust?

carmine nacelle
#

I'm trying to write stuff in Rust in userspace

#

I'm gonna keep C and C++

hexed acorn
#

ah

carmine nacelle
#

Like I normally link C/C++ with clang --target=x86_64-pmos --sysroot=/home/misha/pmos/i8042/../sysroot ./ports.o ./main.o ./timers.o -o i8042.elf or whatever

#

Is there no way to see why it's failing?

#

I'm too dumb for this...

hexed acorn
#

no such file or directory: crt0.o?

carmine nacelle
#

bruh

#

I didn't see that

#

I'm blind

#

Do I even need crt0? thonk

#

If I'm linking with libc anyway

pearl narwhal
#

probably?

#

-nodefaultlibs so you need it yes

#

also test it with rust-lld too when you have crt0

carmine nacelle
#

Though I should have it

carmine nacelle
#

Does it not search in usr/lib?

carmine nacelle
#

(time to recompile the compiler)

#

(I wonder how long my laptop will survive compiling rustc on battery)

carmine nacelle
#

Ok, I suppose I only need compiler_rt?

#

Bruh it also wants this for some reason

#

Which I don't have

#

And compiler rt?

#

bruh my libc was compiled for i686 for some reason??

#

(like this stuff builds fine on i686 and riscv)

#

Idk how, but I compiled it

#

nevermind

#

it just casually failed

carmine nacelle
carmine nacelle
#

What the fuck

#

Why the fuck is it building jit libraries?

carmine nacelle
#

(and how it just magically works on i686)

#

I think copying random things from chatgpt solved it...

#

(totally perfectly working build system)

#

wtf wdym

#

The functions are for Real Time Solaris (Real Time means guaranteed response in a time boundary), which has since been integrated into mainline Solaris and is part of libc. Librt is present only for historical, backward compatibility reasons and you do not need to reference it.

carmine nacelle
#

(It's not including libunwind for some reason?)

twilit talon
carmine nacelle
#

Tbh it's crashing all the time lately

#

Windows 11 is getting worse every day

twilit talon
#

had my first time in like 5 years today

carmine nacelle
#

This is like an extreme jank

#

(it didn't work)

carmine nacelle
#

bruh

#

it not work

carmine nacelle
#

Missing functions to hello world

#

(I guess I can just stub them)

#

(except writev)

#

(it should be easy)

#

(famous last words)

#

trl export RUSTFLAGS="-C link-arg=--sysroot=$HOME/pmos/sysroot/ -C linker=clang++ -C link-arg=--target=x86_64-unknown-pmos -C link-arg=-lunwind -C link-arg=-static"

inland temple
#

you will get absolutely shafted by libc ngl

carmine nacelle
#

?

carmine nacelle
#

Ok, I have no idea how to implement poll

#

Since everything is IPC...

#

ok, I think I have an idea

#

(though my libc is kinda casually becoming a huge mess)

carmine nacelle
#

Time to test

#

Ok, Rust really wants poll

#

(But it is working I'd imagine)

#

(enough for libc to printf the error)

carmine nacelle
pearl narwhal
#

OMG

#

when drivers in rust

carmine nacelle
#

Idk, now

#

(I need to unstub poll though)

#

(and a couple of other places)

#

(but it works for println)

#

I wonder if panic works

pearl narwhal
#

imagine if it fails to fail

carmine nacelle
#

I don't have a mechanism to pass env variables

pearl narwhal
#

does unwind work??

carmine nacelle
#

It should

#

C++ exceptions do work

pearl narwhal
#

ah it probably does

carmine nacelle
#

Where does it get variables?

pearl narwhal
#

std?

#

std::os::env or whatever

carmine nacelle
#

It's broken

#

It's probably trying to open /proc/self or whatever, which I don't have

#

but still

carmine nacelle
inland temple
#

surprising

inland temple
carmine nacelle
#

idk

inland temple
#

it it is that should be guarded behind a OS == Linux check

carmine nacelle
#

I don't really care I guess

#

Go needed to open that to print backtraces

#

bruh I'm having a skill issue with git

hexed knot
#

i guess the shitty go compiler might though

#

although

#

its not a thing on macos, or the BSDs

#

so

carmine nacelle
#

idk

#

but rust doesn't need weird assembly shenanigans for userspace threads

#

?

hexed knot
#

no

carmine nacelle
#

So I'm just gonna use it

hexed knot
#

go green threading asm is like

#

not hard

#

lol

#

also if you are cool with a mildly scuffed version of go there's also tinygo

pearl narwhal
#

in std

hexed knot
pearl narwhal
hexed knot
#

yeah rust also takes the "let's have a stupid% performance degradation in pathological cases" approach

#

instead of "let's realloc() the thread stack when it gets too full"

carmine nacelle
#

idk

#

I just need to figure out how to implement my kernel's interface in Rust now...

carmine nacelle
#

I guess I'll just delete the local repo and clone it again galaxybrain

carmine nacelle
#

thonk I think I need to finally add handles to IPC

#

The interface gets clunkier every time...

#

(I'm currently writing mbus-inspired mechanism for device discovery)

hexed knot
#

cool!

carmine nacelle
#

Like they could both be useful to distinguish various async IPC message replies, create permission memes, and also have some system to track the servers programs dying and not replying to IPC

#

The only issue is that I need to have some mechanism for handles to be shared between several threads

#

(for which I could use task groups which I already have, now that I think of it)

#

The only thing I'm worried about is performance, since it would be allocating more stuff for every IPC message...

carmine nacelle
hexed knot
carmine nacelle
carmine nacelle
hexed knot
#

ah

#

would still be cool to have async support

carmine nacelle
#

My C++ stuff is async

hexed knot
#

at least for parity

carmine nacelle
#

In Rust

hexed knot
#

there is a "Future" trait

#

which has one function named poll

#

which takes a context and returns a future status

#

the context contains a waker

#

when you want to do io, you return a future which, when polled, tries to read/write/whatever

#

and if it blocks, it arranges for the waker to be woken up when it is ready

#

so yeah like c++ but dumber

pearl narwhal
hexed knot
#

yes it is tbh

#

the C++ approach produces faster code

#

because their wakeup logic wakes up a coroutine instead of queuing a coroutine to be scheduled

carmine nacelle
#

wait, who schedules coroutines?

#

wtf

hexed knot
#

in rust, you need a scheduler

#

yeah

#

like the original top-level waker is provided by the scheduler

carmine nacelle
hexed knot
#

yes.

carmine nacelle
#

I need to look into that

#

My C++ coroutines code is with event loops

hexed knot
#

"the" scheduler = the userspace future scheduler that is

#

yeah C++ coros are a lot easier to work with

#

the main disadvantage is that they allocate implicitly

carmine nacelle
#

Like I have an event loops, which block on reading from IPC queues

hexed knot
#

and aiui they allocate one allocation more

carmine nacelle
#

Or create new coroutines

#

(idk what's the term for awaking)

hexed knot
#

so a message arriving would unblock a future

#

and then you run the unblocked futures until all of them are blocked

#

(yes this is stupid)

carmine nacelle
#

So the future would have just 1 coroutine in its queue?

#

Ok I will not use coroutines for now then

#

(Also, I need to implement handles first anyway)

hexed knot
carmine nacelle
#

this sounds weird

hexed knot
#

except its implemented differently

#

since in rust futures only run when the future scheduler decides they should

#

and not immediatly when work completes

pearl narwhal
hexed knot
#

C++ doesnt need it

pearl narwhal
#

libstdcxx provides a thread runtime tho right?

hexed knot
#

no

pearl narwhal
#

std doesn't

#

ah

hexed knot
#

libstd provides the same amount of thread stuff as libc++ and libstdc++

pearl narwhal
#

tbh I'm not well versed into this so i can't really say anything

#

but my experience with rust async (including implementing a simple thread runtime) was nice

#

the biggest issue is that the ecosystem is split between async and sync

#

sans-io ftw

carmine nacelle
#

C++ allows you to do wtf you want with coroutines

hexed knot
#

which makes impl significantly easier

#

its also faster in certain semi-pathological cases

toxic torrent
hexed knot
#

it makes code quite a bit uglier

toxic torrent
hexed knot
#

C++ has implicit alloc which is more convinient

#

but may be slower

toxic torrent
#

it's negligible imo

hexed knot
#

probably

#

the important factors are that rust wakes up the root coroutine

#

and not the leaf coroutine

#

which is not negligible

carmine nacelle
#

Bruh my Rust abstractions to kernel API just work..?

#

(I think I'll write more tomorrow, if I have time)

inland temple
#

based

carmine nacelle
#

Now I just need to implement the parsing of the stuff that I send over IPC...

#

(It will be C, C++ and Rust programs talking together)

#

(also I maybe really need to look at using xbstrap or something, since Makefiles are really rough for building 2 compilers and 12 executables...)

hexed knot
#

also damn you have std, very nice

carmine nacelle
hexed knot
#

handles for ipc?

carmine nacelle
#

Like for IPC ports/chanels/whatever

hexed knot
#

like, sending IPC handles?

#

or

carmine nacelle
#

Yes

hexed knot
#

ah

carmine nacelle
#

Like I send a message and give provide a handle to reply

#

(that's what I want to do)

hexed knot
#

ahhh

carmine nacelle
#

And then I can distinguish where messages come from

hexed knot
#

btw mach has a neat concept here

#

they have a concept of a "send once" port right

carmine nacelle
hexed knot
#

which allows the sender to, well, send exactly one message in return

carmine nacelle
#

Idk

#

I don't have a mechanism to block waiting for more than 1 port

#

And I don't think I need to

carmine nacelle
hexed knot
#

when you do an ipc call, you send (call arguments, send once port right)

carmine nacelle
#

But it's obnoxious and not universal

hexed knot
#

and then when they return, they send a message to that send once port right

carmine nacelle
#

(at the moment)

#

But I want it to send a handle, along with message

#

Which would resolve to a port

#

But the sender would know the id of the handle which was assigned when a message was sent

#

So even though the messages would all still come back to the same 1 port

#

(which I can read from in an event loop)

#

I can universally have sync IPC-lookalike behaviour

#

To know which coroutine to unblock/schedule/resume/whatever by the handle

#

Idk

#

(I think I'm repeating myself)

carmine nacelle
#

Which in reality are handles for memory objects

#

It shouldn't be too difficult

#

And since my ports are bound to threads, a lot of the stuff could be CPU-local

#

And I have RCU in kernel...

#

So like I'm hoping the performance shouldn't be bad

carmine nacelle
eager rose
carmine nacelle
#

Like take a disk driver, it pops a bunch of requests from the message queue, sends commands to disk, blocks for however long the operation takes, and replies

#

There needs to be some mechanism to explicitly reply to a message

eager rose
#

yup

carmine nacelle
#

Another thing I've though about it holding onto messages

eager rose
#

it responds by writing to the send-once port included with the message it is replying to

carmine nacelle
eager rose
#

"everything is SCM_RIGHTS" kernel KEKW

eager rose
# carmine nacelle But then this is problematic

not really. a possible solution: the send-once handle is a 'thin wrapper' around a 'real' port handle, that simply sends a message to the real port along with the auxiliary dara attached to the send-once port

carmine nacelle
eager rose
#

and multiple send-once handles can point to the same port

eager rose
carmine nacelle
#

(maybe the name is bad)

carmine nacelle
#

But I really need to think about it

#

Since I want to have a mechanism to send multiple handles at a time

carmine nacelle
eager rose
#

send-once port is bad too. because they might not actually be send-once, e.g. if you decide to expand the functionality to be able to reply more than once. it might be worth designing it such that a process can instantiate a special kind of handle to a port that associates auxiliary data with all messages sent to it, and then making the 'send-once' part a usage detail

carmine nacelle
eager rose
#

yup

#

was about to say

carmine nacelle
#

And also ports requiring handles by default, but some ports could be public

eager rose
#

like a general facility for creating these, and it can specify a usage limit

carmine nacelle
#

I can move my ports discovery mechanism to userspace, and just have that server hand out handles

eager rose
#

by 'ports being public'

#

do you have like a VFS for ports?

carmine nacelle
#

No

#

I mean kinda

#

yes

eager rose
#

as in open_port("/path/to/port")

#

you can make ports implicitly private by not giving them a name

carmine nacelle
#

At the moment, all ports are given a unique u64

#

which are assigned sequentially

hexed knot
carmine nacelle
hexed knot
#

and a "send many" port right

eager rose
carmine nacelle
#

So like there's no protection

eager rose
#

yeah, that feels like a fundamental flaw to me

carmine nacelle
#

And then I have a global namespace kind of thing, which allows to get port id by its name, if the port owner decides to publish it

#

That's how I discover things atm

carmine nacelle
carmine nacelle
#

Another problem is that the kernel doesn't know about processes

#

So the issue is in making a handle available to different threads which form part of the same process

eager rose
#

'handles' are not part of this global port namespace, i.e. a malicious or faulty process cannot guess and write to a 'handle'?

carmine nacelle
#

I don't have them at the moment

carmine nacelle
#

Although potentially not

eager rose
carmine nacelle
#

The issue is not with fork

#

The only thing that's common in a process inside the kernel is a page table/address space

#

So there is nothing to latch to

#

Idk how to explain it

#

Like a filesystem would give a handle for a file

#

But then, how do I share that with threads inside a process

eager rose
carmine nacelle
eager rose
#

a task doesn't have a private handle namespace. rather, it is shared among tasks.

eager rose
carmine nacelle
#

task groups (I'm bad at naming things) ultrameme

#

But there can be many

#

So I will have to pass task_group + handle to ipc_send

#

Which will be 2 uint64_t's

#

Which don't fit into i686 registers for syscalls

eager rose
carmine nacelle
#

Yes, but any given task can be part of as many task groups as it likes

eager rose
#

the pointer to the handle table is not kept in a 'task group', rather, it is refcounted and pointed to by each individual task that makes up the task group

carmine nacelle
#

I could make handles global, and check that the task is part of task group that the handle is attached to

eager rose
eager rose
carmine nacelle
#

Like a filesystem consumer opens a file, and gives a task group. That task (thread) group can represent a single thread, a process, a set of tasks (threads), maybe two processes

#

(task is thread)

#

(I need to work on naming)

carmine nacelle
eager rose
carmine nacelle
#

No

eager rose
#

well then

carmine nacelle
#

I just create a task group for the process and use that everywhere

#

But it seems like a nice abstraction

#

Instead of doing that for the whole process, it could be done for select threads

eager rose
#

does the kernel know about task groups?

carmine nacelle
#

It's provided by kernel

#

and it has a mechanism to notify userspace when there are no threads left in a group

#

So if the process dies, the files are closed in servers, and so on

#

(and it's also used for permission checking)

eager rose
carmine nacelle
#

idk

eager rose
#

yup, but then you lose out on some of the benefits of a 'local' handle table

carmine nacelle
#

Or I can just pass two u64s

#

tbh it's not that big of a problem

lunar island
eager rose
carmine nacelle
#

thonk for signals

eager rose
lunar island
#

have an handle namespace per-process

carmine nacelle
#

I don't have processes

hexed knot
lunar island
#

group

#

whatever

lunar island
#

which makes it send-once

hexed knot
#

uh, no?

#

you simply cant copy it

eager rose
#

@carmine nacelle it feels like you are overcomplicating object management by, like, a lot.

hexed knot
#

but its refcount can be nonzero

#

(e.g. you can have a different send-once right to the same port)

lunar island
#

"Send-once rights always have a user reference count of one. Tasks may hold multiple user references for dead names. Each send-once right generated guarantees the receipt of a single message, either a message sent to that send-once right or, if the send-once right is in any way destroyed, a send-once notification."

carmine nacelle
lunar island
#

I am talking about the right

#

not the port

eager rose
#

yup. and iiuc, the (or rather, a) problem is how do we make sure that the sender has the right to respond to the message? and a proposed answer is local handles

carmine nacelle
carmine nacelle
carmine nacelle
#

idk

eager rose
lunar island
#

u just pass an handle along with your message

eager rose
#

but actually

#

sender of the response

#

as in, sender to a send-once handle

carmine nacelle
eager rose
#

but like

#

my kernel doesn't do much either (hardly anything)

#

and LoC is a bad measurement unit anyways

lunar island
#

im currently microkerneling so the kernel isnt doing that much either

carmine nacelle
#

It's a measure of project's maintainability

#

The kernel is about 20k I think

eager rose
#

I should finish writing my in-kernel debugging tools (unwind and symbol lookup), and then implement the page cache so my files can actually have contents lol

carmine nacelle
#

I had libunwind and libcxxrt with C++ exceptions in kernel, but I've removed that

#

Now I just kinda keep my fingers crossed that the kernel doesn't crash since it only writes to COM0 on panic

#

When running it on laptops and whatnot

carmine nacelle
#

bruh

By default, HashMap uses a hashing algorithm selected to provide resistance against HashDoS attacks. The algorithm is randomly seeded, and a reasonable best-effort is made to generate this seed from a high quality, secure source of randomness provided by the host without blocking the program. Because of this, the randomness of the seed depends on the output quality of the system’s random number coroutine when the seed is created. In particular, seeds generated when the system’s entropy pool is abnormally low such as during system boot may be of a lower quality.

carmine nacelle
#

Good and bad news bruh

wide spruce
#

🪨

carmine nacelle
#

backtraces have decided to work

#

but wtf is failed printing to stdout

modest nest
#

Also second panic while unwinding was in progress

carmine nacelle
#

I know it's because of syscall that's not implemented by kernel

wide spruce
#

Imagine syscalls

carmine nacelle
#

Which function does write call?

carmine nacelle
#

(ok, I think I'll just not print long strings then and pretend it's working trl)

carmine nacelle
#

This is unfun

left dew
#

you said you'd implement it

carmine nacelle
#

I'm just gonna use BTreeMap for the time being trl

carmine nacelle
carmine nacelle
#

Nice Rust code

#

But it looks like Rust and C++ are talking successfully

left dew
#

Box<str> pains me for some reason

carmine nacelle
#

What am I supposed to use instead ?

left dew
#

i mean, i guess it ends up being functionally equivalent because of Deref<Target=str> (or smth, idk rust lol) but String is a nicer, owned string type

#

but as i said, Box<str> works as well

carmine nacelle
#

I've read that it stores 2 usizes instead of 3

#

Although does Rust do SSO?

#

SSO has been intentionally left out, because it adds trade-offs (like extra checks on each data access) and you can use a library to implement your own flavor of SSO (there are many crates for this with various levels of compactness and unsafety).

toxic torrent
restive junco
#

cause serialization and deserialization hurt to do in higher level languages

#

speaking from experience

#

it's much much easier to do it in C

restive junco
pearl narwhal
#

i wonder how hard it is to port tokio

#

considering it basically reimplements std

#

something simpler might be prefferred

toxic torrent
pearl narwhal
#

did u do it?

toxic torrent
#

no but i looked at tokio internals

pearl narwhal
#

i wonder if async-std is simpler

#

or one of the lower level stuff (that don't reimplement std)

toxic torrent
#

pmos all servers in rust when

pearl narwhal
#

my opinion is that userspace drivers would be fun in rust

#

but I won't do them for stuff that needs to be optimised for binary size

toxic torrent
#

sure

pearl narwhal
#

e.g. i don't need huge rust binaries for a uart driver

#

ns16550 and friends would be so simple to implement, doing them in C or C++ wouldn't make you lose anything really

carmine nacelle
#

(yet)

#

Also I need to implement a bunch of stuff

#

Namely finish pmbus, fix AHCI, write ext4 driver, implement IPC handled/whatever

#

At which point I might actually finally implement a slab allocator in kernel

hexed knot
#

may i recommend a name that is more creative than pmbus?

#

:^)

carmine nacelle
#

Yes

#

Tbh pmOS is also not a very good name

pearl narwhal
#

name it premarketOS

carmine nacelle
#

(though what if... thonk)

carmine nacelle
#

What the hell

#

How is only 4 bytes are guaranteed on x86

kindred venture
#

in rust, x86 means i*86

#

and with i*86 the only way to do anything on more than 4 bytes is cmpxchg8b

toxic torrent
kindred venture
#

i386 and i486 don't have cmpxchg8b and thus it is impossible to do atomic ops on 64-bit values

#

well you can use libatomic but that's implemented with spinlocks

carmine nacelle
#

ok, that's reasonable then

kindred venture
#

also note that that's only saying that atomic loads on 8 bytes are only guaranteed to work on rw memory, not that it's not supported

#

i suspect an atomic load of 8 bytes gets lowered into cmpxchg8b(ptr, x, x)

carmine nacelle
#

or xmm

#

?

kindred venture
#

xmm isn't guaranteed to be available on 32 bit

#

but if it is yeah that's an option

carmine nacelle
#

but if I target i686

#

clang emits it quite happily and doesn't care

kindred venture
#

i686 is a subset of 32 bit x86 that is guaranteed to support sse (like x86_64)

#

specifically i686 = everything the pentium pro (P6 microarch) supports

carmine nacelle
#

cmpxchgw8b is also i586+

#

(And I think that also supports xmm?)

kindred venture
#

i586 def doesn't support xmm, it doesn't even guarantee mmx

#

but yeah so on i386 and i486 it'd get lowered into libatomic, i586 to cmpxchg8b, i686 to sse (probably)

carmine nacelle
#

Also maybe floating point instructions?

kindred venture
#

how does x87 help with atomics

carmine nacelle
#

is it not atomic as well?

kindred venture
#

ah you mean like loading something as a double and copying to a cpu reg

#

idk what the atomicity guarantees were like on pre-i586

#

on i586+ it'd work probably but then you have cmpxchg8b so why would you

carmine nacelle
#

isn't cmpxchg8b slow?

#

like if you just want to read something with relaxed ordering

kindred venture
#

depends on implementation and whether it's successful

#

relaxed ordering isn't a thing on x86, everything is acq rel

#

or well there's some newer simd instructions that might have relaxed ordering idk but in general everything's acq rel

carmine nacelle
#

but I mean if you just want to read a value from memory, not exchange it

kindred venture
#

lock cmpxchg8b is def much more expensive than a normal mov yeah

#

but idk how it compares to fp load + copy to int reg

#

clang on i586 uses fp ops so i guess that's more performant than cmpxchg8b

carmine nacelle
#

Bruh, recieving objects with Rust is easy, now the question comes, how do I serialize them...

#

Since with C/C++ I just sent structs or vectors directly, but it doesn't seem to be easy with Rust idk

left dew
#

write your own serializer :^)

#

(or use serde)

carmine nacelle
#

I've talked to ChatGPT and it just said to use std::borrow::Cow

#

My data is represented as C structs

left dew
#

im afraid that asking chatgpt might not be the best thing you could have done (lol) but oh well, let's see what you come up with

#

maybe i misunderstood what you're trying to do :^)

carmine nacelle
#

bytemuck Pod?

left dew
#

okay, sure

#

if you just want to bytemush the whole thing over ipc then that would work i guess

#

strings aren't repr(C) though lol

left dew
#

neither are more complicated objects

#

VLAs, fun

carmine nacelle
#

Hence Cow

#

Which is a universal representation of both without writing my own enum for either &[u8] or vec

left dew
#

yeah i understand, might work

carmine nacelle
#

bruh there's bindgen

#

but do I want to use it?

left dew
#

native rust bindings > generated rust bindings

#

though if you want you can write rust wrappers around generated bindings

carmine nacelle
#

I'll just write that stuff myself

#

Is there a way to implement some sort of universal thing on everything that's bytemuck Pod?

#

So it translates it to Cow

#

There's no function overloading in Rust??

#

Ok, I'm gonna try something...

carmine nacelle
#

Is it a bad idea to use #![feature(default_field_values)]?

#

What the fuck

error[E0726]: implicit elided lifetime not allowed here
  --> /home/misha/pmos/rust/pmos/src/ipc_msgs.rs:29:18
   |
29 | impl Default for IPCBusPublishObject {
   |                  ^^^^^^^^^^^^^^^^^^^ expected lifetime parameter
   |
help: indicate the anonymous lifetime
   |
29 | impl Default for IPCBusPublishObject<'_> {
   |                                     ++++
#

I'm extremely dumb

carmine nacelle
#

How am I supposed to do this?

pub const IPC_BUS_PUBLISH_OBJECT_REPLY_NUM: u32 = 0x1b0;
#[repr(C)]
#[derive(Debug, Copy, Clone, Zeroable, Pod)]
pub struct IPCBusPublishObjectReply {
    msg_type: u32,
    pub flags: u32,
    pub result: i32,
    reserved: u32,
    pub sequence_number: u64,
}

impl IPCBusPublishObjectReply {
    pub fn new() -> IPCBusPublishObjectReply {
        IPCBusPublishObjectReply {
            msg_type: IPC_BUS_PUBLISH_OBJECT_REPLY_NUM,
            flags: 0,
            result: 0,
            reserved: 0,
            sequence_number: 0,
        }
    }
}
#

Like so that msg_type and reserved are private, but always set

#

Without writing new for everything

#
  • mut memes
pearl narwhal
#

but your approach should also work

carmine nacelle
#

efficiently and generically
I don't understand how anything could be more efficient than just casting structs to pointers

carmine nacelle
#

And I'm not using json or other stuff for IPC

carmine nacelle
#

And works across 3 languages

pearl narwhal
#

you can implement Default

#

if that's what you want

#

or you can pass arguments to new

carmine nacelle
#

It complained that default fields are private

pearl narwhal
#

the default trait complained?

#

e.g. impl Default for Foo or #[derive(Default)]

carmine nacelle
pearl narwhal
#

..Default::default()

#

there's a spread operator

#

and I would just pass arguments to new

carmine nacelle
#

Doing ```rust
let msg = IPCBusPublishObjectReply {
flags: 0,
result: whatever,
sequence_number: bruh,
..Default::default()
}

#

(I've tried it and rustc refused to compile it)

pearl narwhal
#

yea the issue isn't default

#

the issue is that you can't construct a struct with private fields this way

#

also don't put a semicolon there, put a comma

carmine nacelle
#

I want msg_type to be constant, but it needs to be there

pearl narwhal
carmine nacelle
#

And I don't want to have to copy the struct every time I send a message

pearl narwhal
carmine nacelle
pearl narwhal
#

new isn't special

#

it's just an associated function (aka static method)

#

it can take arguments

carmine nacelle
#

But I don't like it

pearl narwhal
#

yea then keep it in the struct

carmine nacelle
#

So the struct is just normal rust struct, and the data sent between stuff is different

pearl narwhal
#
impl IPCBusPublishObjectReply {
    pub fn new(flags: u32, result: u32, sequence_number: u64) -> IPCBusPublishObjectReply {
        IPCBusPublishObjectReply {
            msg_type: IPC_BUS_PUBLISH_OBJECT_REPLY_NUM,
            flags,
            result,
            reserved: 0,
            sequence_number,
        }
    }
}
#

also please make FLAGS an enum unless it really needs to be bitflags

#

and if it really needs to be bitflags, use bitflags or whatever the crate was named

#

only make it an integer if you don't want to depend on that crate

#

rn you could be passed an invalid flags and would have to check it manually

#

if you had a IPCBusPublishObjectReplyFlags type where only the valid flags can be constructed, you don't have to check that

carmine nacelle
#

Flags is basically a reserved field atm

#

(it doesn't matter for now)

#

I want to see this working, I will add this stuff later

#

(later as in before I push the commit)

carmine nacelle
#

How do I pass int into bitflags! memes?

#

(bruh, vscode is as lost with Rust as it is with C++)

#

(idk which is worse)

#

Creative variable naming (result.result)

#

What the fuck

#

Why does it suddenly want linux?

kindred venture
#

it's being used by your main.rs directly

#

possibly something lsp did based on your host system?

carmine nacelle
#

I think vscode is trolling me

#

Something added use std::os::linux::raw::stat;

kindred venture
#

yeah it autoimported based on your host system

carmine nacelle
#

Fun, I think it's working

#

(better screenshot)

#

The top 4 lines are printed by Rust, the bottom one is printed by AHCId/C++

#

(Now there is too much stuff to do)

#

That is (not including all my previous plans):

  1. Implement requests for stuff from pmbus
  2. Publish ACPI and PCI devices in pmbus (which needs to be done in C trl)
  3. Write an init server, which matches devices in pmbus and starts servers this way as they appear
  4. Implement handles to radically decrease the obnoxiousness of IPC API (among other things) and provide a good interface for coroutines
  5. Change blockd to discover disks with pmbus, discover filesystems using it (talking to init server, see step 3), publish partitions onto it and do disk mounting (etc.)
  6. Finish (though it's almost not even started) the ext4 driver trl (this implies improving VFS, which I wrote when I was experimenting with ChatGPT in 2023, so the code is very bad)
  7. Do what @ infy wanted, that is discover PS/2 controllers with ACPI (now if I do 2, everything can be discovered like that...)
  8. ... improve the build system (it's so bad I'm having to call cargo build and then make (several times) and then qemu manually to run pmOS)
#

nooo I'm going to sleep, this is too much

#

(though I guess I can just call cargo with make ultrameme)

hoary moat
carmine nacelle
hoary moat
#

no one say "when you write an article for it"

#

I will do it soon™️ trust

carmine nacelle
#

I'm dumb

toxic torrent
#

that warning message is useless

#

they could've just said "you probably meant to do *obj"

carmine nacelle
carmine nacelle
#

(I think it's stack overflow? bruh)

#

How does this even GPF?

#

Wtf, how does this get to shit in %rcx?

carmine nacelle
carmine nacelle
#

Ok, I don't know what to do

#

So I guess I'll finally look at xbstrap

#

Or something

#

(improve my build system that is)

plain jungle
#

good choice halfmemeleft

#

feel free to ask if anything is unclear

carmine nacelle
#

I don't understand anything

toxic torrent
#

real

hoary moat
#

use obos-strap

#

(do not)

#

((it is dogshit))

toxic torrent
#

xbstrap my beloved

pearl narwhal
#

nixstrap my beloved 😍

carmine nacelle
#

Idk, I need something which can build (in this order) llvm, my C libraries with CMake, rustc, libc++ and company, kernel with CMake and a bunch of userspace (about 10 servers, with more planned trl) with Make and Cargo (basically C, C++ and Rust), and create the root image

#

Like maybe I'm dumb, but I haven't figured out how to make cargo produce output binary in the same location

#

That's not in target/{arch}/bin/whatever (idr the exact path)

#

Since I'm targeting 3 architectures, with more to come

pearl narwhal
#

I think you can make it "install" to some destination dir

#

but nix will do it :3 (nixstrap shilling

carmine nacelle
#

So I can just call cargo install with Make? trl

pearl narwhal
#

I doubt the gentoo cargo eclass or whatever is complicated

#

well it also vendors in crates so it likely is but you don't need to do that

#

but for maximum reproducibility you want to read the cargo.lock file and vendor in the needed crates

#

then pass --frozen or whatever to cargo so it doesn't fetch from the internet

carmine nacelle
#

I don't really care about reproducibility, but the way I'm passing files/programs to be loaded is as modules in Limine/Hyper

#

Like I don't have a proper filesystem

pearl narwhal
#

but if you don't care about reproducibility, wrapping cargo is fine

carmine nacelle
carmine nacelle
#

Idk my build system is a mess

#

Maybe I should finally have an init ramdisk or something like that

#

So I can just dump a bunch of files into a directory and it be dynamic

#

Without having to change the bootloader configs

pearl narwhal
#

yea I don't have that problem because I do like '${pkgs.whatever}/bin/whatever'

#

and the nix recipe will install to the store so where cargo puts it doesn't matter

carmine nacelle
#

But then I don't want everything in ram (eventually)

#

Idk I need to think

#

Maybe I'll consider it

pearl narwhal
#

you know you could do like string substitution to get the path to the binary in target/

#

then copy it to your ESP or wherever

#

for now

pearl narwhal
carmine nacelle
#

Yeah

#

But I still need to play with Make

carmine nacelle
#

Ok I've just managed to do what I want with makefiles

#

The build system migration effort is on halt until I get S3 sleep working trl

pearl narwhal
#

obos but microkernel

hoary moat
#

I need to implement some cool feature for obos

#

to get it known for something other than suspend

#

and crashing all the time

carmine nacelle
#

bruh I'm having a skill issue with a relative far jump

pearl narwhal
#

™️

hoary moat
#

no

pearl narwhal
#

roleplay making an OS in the 90s

hoary moat
#

you mean the implementation that crashes after 5 minutes of a real network?

#

lol

hexed acorn
pearl narwhal
#

and be like ¡¡ THIS IS THE INTERNET IT IS THE FUTURE !!

pearl narwhal
#

also 5 minutes is gokd

#

good

#

I could never let my stuff run for 5 minutes, not because it wouldn't work but because I couldn't wait that long

carmine nacelle
#

thonk llvm optimizes my memcpy memes to nopl (%rax)

carmine nacelle
#

Could it be llvm miscompilation? trl

#

I know what's happening...

#

Fun, my pmm decided that SMP/ACPI bootup vector will be at 0x9E000

#

(also, maybe hyper port will get smp now that I'm implementing it anyway...)

carmine nacelle
#

I've been copying char * to void **, which llvm was assuming to be aligned to 8

#

Which was emitting broken assembly

hexed knot
#

hmm actually

#

is it

carmine nacelle
#

(Which was the end of a section in assembly)

twilit talon
#

i dont think memcpy of anything to anything is ub

carmine nacelle
#

I declared the variable as char and it worked

#

Tbh I'm memcpying code to some random place in memory

hexed knot
twilit talon
#

well ok

hexed knot
#

or if there is a data race

twilit talon
#

actually no

#

i think overlap is just unspecified result

hexed knot
#

no its UB i think

twilit talon
#

only nullptr is ub

#

iirc

kindred venture
#

the parameters are restrict, passing overlapping pointers is UB

hexed knot
#

no its clear ub

carmine nacelle
twilit talon
#

ah yeah restrict

#

right

carmine nacelle
#

It was an issue with alignment

twilit talon
#

memcpy doesnt really care i think?

hexed knot
twilit talon
#

with restrict it makes sense

carmine nacelle
#

It's C++23 trl

hexed knot
#

still UB

#

but i dont know where the standard is so cbf

kindred venture
#

the alignment UB here isn't in the memcpy, that's just where it manifests itself

#

it's UB to have a misaligned pointer

hexed knot
#

yeah id say so

hexed knot
twilit talon
#

yeah clang's intrinsic rightly assumes that your pointer to a void* is aligned to a void*

kindred venture
# hexed knot actually no

A pointer to an object type may be converted to a pointer to a different object type. If the resulting
pointer is not correctly aligned59) for the referenced type, the behavior is undefined

#

n3220 6.3.2.4

kindred venture
#

it's UB to produce a pointer that is unaligned therefore it is UB to have one

hexed knot
kindred venture
#

6.3.2.3 sorry

hexed knot
kindred venture
#

was looking at the bottom of the page

hexed knot
#

ah okay

kindred venture
hexed knot
#

but yeah ^^

#

i dont think its necessarily ub though

carmine nacelle
#

(which wasn't a variable)

hexed knot
kindred venture
hexed knot
#

because llvm can see the alignment

kindred venture
#

oh wait declaring it in asm?

plain jungle
#

Having an unaligned ptr is not UB in C++

#

Just accessing it

carmine nacelle
hexed knot
#

spec paragraph?

carmine nacelle
#
    .equ CODE_SEGMENT, 0x08
    .equ DATA_SEGMENT, 0x10

    .data
init_vec_stuff:
    .code16

    .globl acpi_trampoline_begin
acpi_trampoline_begin:
    .globl acpi_cpu_startup
acpi_cpu_startup:
    cli

    movw %cs, %bx

    xorl %ecx, %ecx
    movw %bx, %cx
    addl $(acpi_trampoline_gdt - acpi_cpu_startup), %ecx
    movl %ecx, %cs:(acpi_tampoline_gdtr_addr - acpi_cpu_startup)

    lgdt %cs:(acpi_trampoline_gdtr - acpi_cpu_startup)
    movl %cs:(acpi_trampoline_startup_cr3 - acpi_cpu_startup), %eax

    movl $0x01, %eax # Protected mode
    movl %eax, %cr0

    jmp 1f
1:
    .code32
    movl %eax, %cr3 # cr3 (Page table)

    movl %cr4, %eax # PAE 
    orl $(1 << 5), %eax
    movl %eax, %cr4

    movl $(1 << 10), %eax # LME BIT
    xorl %edx, %edx
    movl $0xC0000080, %ecx # IA32_EFER
    wrmsr 

    # Enable paging
    movl $(1 << 0) | (1 << 31), %eax
    movl %eax, %cr0

    movw $DATA_SEGMENT, %ax
    movw %ax, %ds
    movw %ax, %ss
    movw %ax, %es
    movw %ax, %fs
    movw %ax, %gs
    shr $16, %ebx
    leal (acpi_trampoline_kernel_entry - acpi_cpu_startup)(, %ebx, 1), %esp
    leal (_64bitst - acpi_cpu_startup)(, %ebx, 1), %eax
    pushl %eax
    lretl $CODE_SEGMENT
_64bitst:
    .code64
    jmp *acpi_trampoline_kernel_entry(%rip)

    .p2align 4, 0xCC

acpi_trampoline_gdtr:
    .space 2 # alignment 
acpi_trampoline_gdtr_limit:
    .word 23 # 3 entries - 1
acpi_tampoline_gdtr_addr:
    .long 0

acpi_trampoline_gdt:
    .quad 0
    .quad 0x00af9b000000ffff
    .quad 0x00af93000000ffff
    .globl acpi_trampoline_startup_cr3
acpi_trampoline_startup_cr3:
    .space 4
    .globl acpi_trampoline_kernel_entry
acpi_trampoline_kernel_entry:
    .space 8
scratch_stack:
    .space 8

    .globl acpi_trampoline_startup_end
acpi_trampoline_startup_end:
kindred venture
carmine nacelle
#

I memcpy from init_vec_stuff to acpi_trampoline_startup_end

kindred venture
carmine nacelle
#

And the acpi_trampoline_startup_end was not aligned to 8 even though I declared it as extern void * in C++

hexed knot
carmine nacelle
#

Since clang didn't let me declare it as void

#

Memecpy compiled to ```x86asm
ffffffff80013c4d: 31 d2 xorl %edx, %edx
ffffffff80013c4f: 90 nop
; *((char *)dest++) = *((char *)src++);
ffffffff80013c50: 0f b6 34 02 movzbl (%rdx,%rax), %esi
ffffffff80013c54: 41 88 34 16 movb %sil, (%r14,%rdx)
ffffffff80013c58: 0f b6 74 02 01 movzbl 0x1(%rdx,%rax), %esi
ffffffff80013c5d: 41 88 74 16 01 movb %sil, 0x1(%r14,%rdx)
ffffffff80013c62: 0f b6 74 02 02 movzbl 0x2(%rdx,%rax), %esi
ffffffff80013c67: 41 88 74 16 02 movb %sil, 0x2(%r14,%rdx)
ffffffff80013c6c: 0f b6 74 02 03 movzbl 0x3(%rdx,%rax), %esi
ffffffff80013c71: 41 88 74 16 03 movb %sil, 0x3(%r14,%rdx)
ffffffff80013c76: 0f b6 74 02 04 movzbl 0x4(%rdx,%rax), %esi
ffffffff80013c7b: 41 88 74 16 04 movb %sil, 0x4(%r14,%rdx)
ffffffff80013c80: 0f b6 74 02 05 movzbl 0x5(%rdx,%rax), %esi
ffffffff80013c85: 41 88 74 16 05 movb %sil, 0x5(%r14,%rdx)
ffffffff80013c8a: 0f b6 74 02 06 movzbl 0x6(%rdx,%rax), %esi
ffffffff80013c8f: 41 88 74 16 06 movb %sil, 0x6(%r14,%rdx)
ffffffff80013c94: 0f b6 74 02 07 movzbl 0x7(%rdx,%rax), %esi
ffffffff80013c99: 41 88 74 16 07 movb %sil, 0x7(%r14,%rdx)
; while (n--) {
ffffffff80013c9e: 48 83 c2 08 addq $0x8, %rdx
ffffffff80013ca2: 48 39 d1 cmpq %rdx, %rcx
ffffffff80013ca5: 75 a9 jne 0xffffffff80013c50 <limine_main+0x29e0>

#

Even though the size was 0xb4

hexed knot
#

what is mozbl wtf

kindred venture
hexed knot
#

ah load

left dew
carmine nacelle
#

idk clang memes (I need a better memcpy)

kindred venture
hexed knot
#

(T*)((size_t)foo + 1) is not necessarily UB

#

it's ID

kindred venture
#

ah fair enough

left dew
#

i did not notice that

#

for some reaosn

hexed knot
#

lol

#

yeah

carmine nacelle
#

btw why does clang unroll memcpy to copies of byte width?

hexed knot
#

it shoulkdn't

left dew
#

unaligned memory?

carmine nacelle
#

Like without mgeneral-regs-only it unrolls to 4 xmm loads then 4 stores

plain jungle
#

the wording in the C++ standard is:

Attempting to create an object ([intro.object]) in storage that does not meet the alignment requirements of the object's type is undefined behavior.

hexed knot
left dew
#

fair enough

carmine nacelle