<geist>
gotta say that nano pi r5s is not a half bad little machine. a lot pokey on the ram (2GB) but it *seems* hackable, and more importantly it's cheap and available
thinkpol has quit [Remote host closed the connection]
<geist>
that being said i haven't really looked into precisely getting code on it yet. it has some complicated bootloader scheme that of course ultimately arrives at uboot, but need to figure out where to 'cut in' so to speak
thinkpol has joined #osdev
<geist>
but it has a bunch of standard ethernet blocks (2.5gb realtek) so should be fun to write some networking stuffs on
Likorn has quit [Quit: WeeChat 3.4.1]
<heat>
geist, what did you mean with "the use of PCID changes that calculus somewhat"?
<geist>
well, if you're not using PCID then by definition when you reload the cr3 switching processes, it dumps all the TLB entries for that process (assumung you're using global pages in the usual way)
<heat>
yes
<geist>
but if you're using PCID now other cpus can have TLBs active from aspaces that are not currently active, so the calculation of what is potentially on that cpu is different
<geist>
so it makes the solution more complicated
<geist>
and then there's the AMD solution which basically points you in the direction of ARM, sincei t's fundamentally the same thing
<heat>
how do you solve that?
<heat>
you can't possibly know that you have an ASID present in the TLB that's not active
<geist>
i guess you could keep a list of cpus that the aspace is *ptentially* available on
<geist>
which means more IPIs for more shootdowns
<geist>
or i guess you could set some sort of generation counter that when the aspace becomes active again on that cpu it simply dumps the entire TLB
<geist>
that way you only get the advantage of switching back if the aspace hadn't been touched
<geist>
but now yuo have to track gen counters per cpu per aspace?
<geist>
(we haven't solved it in zircon yet, no PCIDs for x86)
<geist>
my guess is a good solution is also integrated into PCID assignment, which we also haven't solved. currently am just assigning a 16bit id per ASID in ARM per fprocess, which is good up to 64k processes, of course
<geist>
but with 8 or 12 bit you start pushing it. so seems that real oses do some sort of more dynamic assignment where they roll through IDs on the fly
<geist>
so most likely if you can pick some sort of reasonable point where you swizzle ids you can also integrate the recycling of ids to dumpgint eh TLB
<geist>
and thus avoid the stale cpu PCID TLB shootdown problem
<heat>
linux uses gens
<heat>
makes sense
<geist>
yeah i dunno what they do but i'm not surprised. i'm a fan of gen-style algorithms
<heat>
does TLBI's latency increase linearly with the number of CPUs an address space is on?
<geist>
the arm/amd solution? presumably
<geist>
but note that both of them are a two instruction sequence: one where you start the sync and the othe where you wait to complete it
<geist>
so there's some ability to hide the latency by manually filling that gap with other work
<heat>
hmm
<geist>
but i'm guessing it internally uses whatever existing logic is there to deal with cache and atomic coherency, so it's probably not too bad
<heat>
two instructions?
<geist>
yah, two instructions
<heat>
on arm isn't just a TLBI?
<heat>
or is this just for local TLBs
<geist>
it's the same instruction local or global
<geist>
just different option bits
<geist>
and even local, it's a two instruction sequence
psykose has quit [Remote host closed the connection]
<geist>
it doesn';t block waiting for the TLB to sync, it juist starts the operation, you add a DSB instruction to synchronize it
psykose has joined #osdev
<geist>
same as cache flusing instructions on arm. basically aside from DSB and DMB instructions, which are explicit barriers, no general instructions stall on ARM like that, so it's a fairly consistent model
<geist>
even writing to core control registers like SCTLR and whatnot are not considered synchronizing necessarily (theres a bunch of rules about that) so in general you follow one of those up immediately with an ISB, which synchronizes the pipeline with the value you just wrotre to the control register
<heat>
yeah
<heat>
AMD has TLBSYNC for that
<heat>
I had never seen this extension before
<heat>
looks cool
<geist>
yeah, it is almost perfectly a match for the ARM model, so it almost has to have come out of the K12 work
<geist>
like they already had to build the machinery for it, but they finally got it ready for prime time
<geist>
but if not for the lack of needing IPI, you can also locally sync with a range, which is nice
<heat>
this reminds me, I remember vaguely that you mentioned that an AMD extension required you to invalidate something when you changed the page tables
<heat>
any idea of what that was?
CaCode- has joined #osdev
CaCode_ has quit [Ping timeout: 255 seconds]
lainon has joined #osdev
lainon has quit [Client Quit]
lainon has joined #osdev
scaramanga has joined #osdev
simpl_e has joined #osdev
lainon has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
CaCode- has quit [Ping timeout: 246 seconds]
dude12312414 has joined #osdev
pretty_dumm_guy has quit [Quit: WeeChat 3.5]
dude12312414 has quit [Client Quit]
heat has quit [Read error: Connection reset by peer]
heat has joined #osdev
Likorn has joined #osdev
matrice64 has joined #osdev
gog has quit [Ping timeout: 272 seconds]
heat has quit [Remote host closed the connection]
heat has joined #osdev
wand has quit [Ping timeout: 268 seconds]
CaCode- has joined #osdev
toluene has quit [Quit: Ping timeout (120 seconds)]
toluene has joined #osdev
wand has joined #osdev
CaCode- has quit [Ping timeout: 255 seconds]
rorx has joined #osdev
foudfou has quit [Remote host closed the connection]
foudfou has quit [Remote host closed the connection]
Likorn has quit [Quit: WeeChat 3.4.1]
foudfou has joined #osdev
vai has joined #osdev
vai is now known as Jari--
* Jari--
been busy designing his AIML Project
GeDaMo has joined #osdev
heat has quit [Read error: Connection reset by peer]
heat has joined #osdev
toluene has quit [Quit: Ping timeout (120 seconds)]
toluene has joined #osdev
opal has quit [Remote host closed the connection]
opal has joined #osdev
heat_ has joined #osdev
heat has quit [Read error: Connection reset by peer]
srjek has quit [Ping timeout: 272 seconds]
heat_ has quit [Ping timeout: 272 seconds]
the_lanetly_052_ has joined #osdev
jafarlihi has joined #osdev
jafarlihi is now known as l33th4x0r
l33th4x0r is now known as l337h4x0r
<l337h4x0r>
Does anyone know if execveat calls execve internally in Linux? Or where it is defined at?
<l337h4x0r>
I grepped, can't find it
<psykose>
not this again
<geist>
no idea. keep in mind this isn't a linux channel
<geist>
when it comes to things like the GDT or whatnot low level stuff, thats kinda interesting to us, but we're not really here to help folks dig into guts of linux
<geist>
except maybe to learn operating system concepts
<l337h4x0r>
Other channels don't know shit
<geist>
bummer
Jari-- has quit [Quit: leaving]
<geist>
mostly just pointing out that if you just pop in every few days and pepper us with questions about linux for your hack linux project and then dissapear, you'll probably wear out your welcome
Matt|home has quit [Ping timeout: 246 seconds]
<mrvn>
too late
Matt|home has joined #osdev
l337h4x0r has quit [Ping timeout: 255 seconds]
l337h4x0r has joined #osdev
l337h4x0r has quit [Client Quit]
psykose has quit [Remote host closed the connection]
psykose has joined #osdev
Burgundy has joined #osdev
<kazinsal>
anyone know if there are any good books or similar about the PPC MacOS nanokernel/68k rosetta?
l337h4x0r has joined #osdev
<ddevault>
error: attempt to use poisoned "calloc"
<ddevault>
the fuck
<liz_>
"poisoned" is a humorous term
<liz_>
well, in the context of GCC; it's less funny generally
<ddevault>
patched it out of gcc/system.h
<ddevault>
¯\_(ツ)_/¯
<kazinsal>
the real fun part is that in the modern search engine environment, trying to look up an error like that results in just people trying to hack their way around it rather than an understanding of what the root cause is
<liz_>
perhaps that's a symptom of compounding complexity in the tools with those errors
<ddevault>
yeah, why am I even using gcc instead of cproc
mzxtuelkl has joined #osdev
<mrvn>
so what does it mean?
<ddevault>
something about wanting to really undefine an identifier
<mrvn>
forgot nostdinc, nostdlib, nobuiltin?
<ddevault>
I'm building a cross compiler that targets my OS
* Mutabah
does a little dance - EHCI interrupt endpoints working
<Mutabah>
although... I hear that the dropbear dev is looking into makng one
<heat_>
we rewrote it in rust bois
<mrvn>
in rust can I use different allocators for collections or can I only define the global_allocator?
<Mutabah>
You can override the allocator in the data type
<heat_>
Mutabah, that kinda beats the purpose of having a "runs on anything program" program
<heat_>
"Dropbear is particularly useful for "embedded"-type Linux (or other Unix) systems, such as wireless routers." <-- how many routers have LLVM and rust targets?
heat_ is now known as heat
<Mutabah>
heat: Oh, not rewriting dropbear in rust... I think
<heat>
ah, making a new one?
<Mutabah>
probably
<mrvn>
heat: arm has rust, doesn't mips?
<Mutabah>
Or a ssh library
<j`ey>
mips has
<mrvn>
So basically all wireless routers are covered.
<heat>
that's missing the point
<heat>
this runs everywhere
<heat>
every little crap system
<heat>
it even runs on my fucking OS
<mrvn>
I doubt it runs on 6502 or even avr
<mrvn>
heat: no rust for your OS?
<heat>
no
<mrvn>
better start then. :)
<heat>
not yet at least
<heat>
meanwhile, dropbear can run on Tru-fucking-64
<heat>
the power of C and gcc :)
<psykose>
it runs everywhere but it sucks
<psykose>
it's better to run nowhere and not to suck
<heat>
it sucks?
<mrvn>
curl sucks faster, and saver
<heat>
curl needs UNIX sockets so I don't have support for it yet
<clever>
heat: i have seen in the man page, that it supports http over unix
<clever>
which exist outside of the filesystem, in their own realm
<clever>
i forgot about the difference, and had trouble getting curl to connect to my socket when i tried this out
<heat>
abstract unix sockets should've been the only unix sockets, or at least the default ones
<heat>
messing with the filesystem to create a socket is stupid
<clever>
i kind of like being able to use standard tooling like ls and chmod to both find and control permissions
<mrvn>
heat: how does another process access the abstract socket? Do you have to pass the FD or does path work?
<clever>
and symlinks to alias the sockets
<clever>
mrvn: they have names like @foo, and if you know the name, you can connect
<clever>
you just cant see it with ls
<mrvn>
So it's an FS just not visible in the default namespace.
<clever>
exactly
<heat>
no, it's not
<heat>
clever is wrong
<mrvn>
and how do you control permissions?
<heat>
you don't
<clever>
i think abstract sockets also lack directories?
<mrvn>
that seems like 1 step forward and 100 steps back
<heat>
abstract unix sockets are just socket addresses that have a name and start with a \0
<clever>
so its more of a flat name -> socket list
<heat>
you don't need a filesystem to do IPC
<heat>
sorry, that's just a stupid idea
<heat>
sockets are ephemeral
<mrvn>
heat: you don't need a unix socket to doe IPC
<heat>
unix sockets are *the way* to the IPC in unix
<clever>
yeah, i'm kind of bothered by how you need to delete a unix socket before you can listen on it
<clever>
so you need to clean up after your previous instance
<clever>
postgresql also goes the other direction
<clever>
srwxrwxrwx 1 postgres postgres 0 Jun 26 09:55 /var/run/postgresql/.s.PGSQL.5432
<mrvn>
It's fine to use a pipe pair or socket pair and pass the FD through fork/exec. If you wan't to have some lookup service for sockets across processes that better have some permissions.
<clever>
its emulating tcp ports over unix sockets
<mrvn>
-'
<heat>
a socket pair is just two UNIX sockets connected to each other
<heat>
*without* the filesystem
<mrvn>
heat: exactly.
<clever>
but how might you connect to something like the above postgresql socket?
<mrvn>
and I believe you can dup it to make more sockets
<heat>
if you wanted a way to get permissions on abstract unix sockets, that would be done ez
<mrvn>
clever: that needs a lookup service, like an FS.
<heat>
no need to use the fucking filesystem
<mrvn>
ez?
<heat>
yes
<mrvn>
what is ez supposed to mean?
<heat>
struct anon_name { uid_t owner; gid_t group; mode_t mode; }; <-- stick that in your struct unix_socket
<clever>
mrvn: like rpb.bind in nfs?
<mrvn>
That would work. All I'm saying is that you better have something like that.
<mrvn>
Assuming nobody can guess the name of some socket is just stupid. Esspecially for offering known services where the name is public.
<heat>
going through thousands and thousands more lines just to have a hierarchy and permissions is downright stupid
<heat>
VFS code + filesystem + block device
<mrvn>
not arguing that.
<clever>
unix sockets can live on a tmpfs
<clever>
the postgresql one above is on a tmpfs
<mrvn>
remove the stupid bits and keep the good bits (permissions)
<clever>
srwxrwxrwx 1 root root 0 Jun 26 08:36 /tmp/.X11-unix/X0
<clever>
another unix socket your likely using on a daily basis
<heat>
going to tmpfs is still stupid complex
<clever>
that is where DISPLAY=:0 points
<mrvn>
heat: it hardly matters. you open the socket once and then use it for ages.
<heat>
it does to me
<heat>
you want to reduce complexity
<mrvn>
it uses thousands of lines of code you already need and have.
<heat>
therefore, struct anon_name
<clever>
what if you want to expose a unix socket to a docker container?
<heat>
also, any connect/sendto will look that up
<clever>
with normal unix sockets, you can bind mount them into another mount namespace
<heat>
making it quite a bit slower
<clever>
but how do you clone an abstract socket into another namespace, such that connect() routes to accept()?
<mrvn>
heat: connect you do once. sendto takes an FD and doesn't do any FS lookups.
<heat>
wrong
<heat>
sendto takes a sockaddr
<clever>
heat: both right, sendto takes an open socket, and a sockaddr
<mrvn>
heat: is that used on a unix socket?
<heat>
yes
<clever>
udp is the case where having both matters the most
<heat>
SOCK_DGRAM is a possibly socket type for the socket
<clever>
the open socket FD, is the source udp port
<clever>
while the sockaddr is the dest ip/port
<mrvn>
"If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET) socket, the arguments dest_addr and addrlen are ignored
<mrvn>
"
<clever>
ah, and that, forgot about that
<heat>
AF_UNIX has SOCK_DGRAM support
<heat>
(and that sentence isn't correct on linux btw)
<mrvn>
How does that work with unix sockets? How would that get routed to the dest_addr?
<mrvn>
How do you specify your own address when listening?
<clever>
one min
<clever>
ive done something with wpa_supplicant before
<mrvn>
And how does a second process listen on the same unix socket?
<clever>
the client, must first bind to its own unix socket path
<clever>
and then can connect to the server
<clever>
when using DGRAM mode
<mrvn>
clever: yes, you bind with the path to the socket. Where do you set the address?
<clever>
and one bug i discovered, is that wpa_supplicant, isnt aware of you disconnecting, because its DGRAM mode
<clever>
the client picks its own client unix socket, and puts it wherever
<clever>
and binds as shown in the gist
<mrvn>
clever: the question is about the server
<clever>
the client can then connect() to the server's unix socket
<clever>
but because its datagram based, no actual connection is formed, its just the default for write()
<mrvn>
clever: and how does the server set the address it listens on?
<heat>
bind
<heat>
sockaddr_un
<mrvn>
heat: no, that's just the path of the socket.
<clever>
it calls bind() on its own socket, the same way, before it calls listen() and accept()
<heat>
if name[0] == '\0', it's a abstract socket
<heat>
I told you this before
<mrvn>
or I'm missing something.
arch-angel has quit [Ping timeout: 268 seconds]
<mrvn>
1) server creates the unix socket, e.g. /tmp/.X11-unix/X0. 2) client creates a socket. 3) client connects socket to /tmp/.X11-unix/X0. 4) client sendto(fd, buf, len, flags, addr, addrlen); where addr is something magic to pick which server gets the data
<clever>
the bug i ran into, is that beause wpa_supplicant is using a DGRAM socket, it has no idea when i connect or disconnect
<mrvn>
I don't see how addr is supposed to work with a unix socket even in DGRAM mode.
<clever>
and only when you send the ATTACH message, does the server become aware of you, and begin sending things to /tmp/wpa_client
<clever>
and critically, if you ATTACH twice, you get 2 messages for every event!
<clever>
mrvn: i believe when in DGRAM mode, the addr must be a sockaddr_un, and the client must also first bind to its own sockaddr_un
<mrvn>
clever: I think that if you use sendto then the address would be some (other) socket, like /tmp/.X11-unix/X1 and you basically operate in an unconnected mode.
<clever>
yeah
<clever>
but the X11 socket, is stream based, so that wouldnt happen there
<mrvn>
So then the answer is simple: don't do that with unix sockets. That's what connect is for. :)
<clever>
wpa_supplicant is designed to operate in DGRAM mode instead
<clever>
instead of maintaining one open FD to every client, it just keeps an array of every sockaddr_un that has attached, and calls sendto() to each, on the same FD
<mrvn>
At least I hope that if you connect if does the permissions check once and caches the socket instead of looking it up in the FS on every dgram.
<clever>
yeah, i dont know how permissions work with DGRAM
<mrvn>
clever: saves a lot of resources but has the drawback that you don't know when a client disconnects.
<clever>
yeah
<clever>
and it has a bug, where if a client restarts, and does ATTACH again (a msg you send to the server), your sockaddr_un gets into the list twice
<mrvn>
Should be easy to test. Open a unix DGRAM socket, connect, change the permissions in the FS and try sending.
<clever>
so now you get 2 of every event!
<mrvn>
clever: how does the client get the same address as before?
<clever>
on startup, it just deletes the unix socket, and listens on it again
<clever>
to abuse it, you restore a backup with a 777 directory, containing 1000 dummy files, and 1 known name
<clever>
then you race to symlink that 1 known name, to a special file in /etc/
<clever>
and boom, a special flag indicating that android is running under an emulator has been set
<mrvn>
clever: it doesn't even use open exclusive?
<clever>
since its under an emulator, there is no point in blocking root via adb
<clever>
mrvn: this is an ancient version of android
<clever>
the bug has likely been fixed years ago
<mrvn>
it's always amusing how many times basic bugs are reinvented.
<clever>
but, this is how i rooted my kindle fire
<clever>
that bug lets you write to a file, that disables all security, at the cost of also breaking hw accel
<clever>
but now you have root, and can create setuid root binaries anywhere you want, and undo that
<clever>
so you can just give yourself an su binary, that doesnt need the root pw (in the case of android, it talks to an android app, and confirms via the GUI)
<heat>
magisk does su with unix sockets
<mrvn>
Speaking of android: I'm looking for a shopping list app where I can GPS tag items when I find them in the shop and next time it can tell me where to find stuff, show near items from the list, draw a map. Does that exist or do I have to write one?
<clever>
mrvn: gps tends to not work that well indoors
xenos1984 has quit [Read error: Connection reset by peer]
<heat>
I bet 50% here have a nokia 3310
<heat>
and a 2005 thinkpad :)
<mrvn>
clever: possible. Using the cameras to build a map and locate itself sounds complicated.
<clever>
mrvn: open street map does have support for indoor mapping, and even mapping each floor of a building, so you can filter to 1 floor
<mrvn>
wifi hotspots or bluetooth for locating yourself in the store sounds fishy too
<clever>
but actually pointing to where you are on the map, wont work as well
<clever>
so you would still have to count the ailes yourself and compare the map to the world with your eyes
<mrvn>
the accelerometer might be ok to track positions inside the store.
<clever>
there are google services to give a rought gps location, based on what wifi mac's are near you
<clever>
so you can get "gps" without turning on the actual gps receiver
<mrvn>
clever: that's like 100m near you. Not "you are standing next to the milk" near you.
<clever>
yeah
<mrvn>
would be nice if shops had RFID or bluetooth tags on their shelfs.
<clever>
i think one of my local shops is using some form of rfid, but in a different way
<clever>
the price tags on the shelf, are now an e-ink module, i think with rfid for power/data
<clever>
so instead of printing a new price tag out every day, and generating waste
<clever>
they hold a device over the tag, and it just magically updates
<mrvn>
I've seen those online
<mrvn>
I think they have a very short range. Like a few cm.
<clever>
and they are unpowered
<clever>
so you cant really snoop the waves and find out your location
<clever>
the tag is powered by the writer
<mrvn>
a passive thing is fine if you could ping it from a few meters.
<clever>
yeah
<clever>
that reminds me, have you heard about how apple's "find my" network works?
<mrvn>
A map published by the store and QR codes on the shelfs would probably work best.
<clever>
basically, there is a private key held on every apple device you own, somehow synced between them when you add a device to your acct
<clever>
the OS will then use the private key, and the date, to generate a temporary key, for just today
<clever>
it will then broadcast the pubkey of the day over bluetooth, constantly
<clever>
if any other apple device (say an iphone) overhears that, it will encrypt its own gps location and time with the public key, and post the pubkey + ciphertext to apple
<clever>
apple lacks the private, so they cant track you
<clever>
the keypair changes every day, so a 3rd party cant track you by the signals your constantly emitting
<clever>
but if you want to find out where your ipad is, you generate the public for the last 5 days, and ask apple for all ciphertexts belonging to those publics
<clever>
you can then decrypt it, and find out where your ipad was last seen
<clever>
mrvn: does that sound like a sound design?
vdamewood has joined #osdev
andreas303 has joined #osdev
xenos1984 has joined #osdev
<ddevault>
hrm
<ddevault>
my binutils patch builds a linker script which seemingly leaves .data empty in the ELF file
<ddevault>
specifying a (sane) linker script manually "fixes" the problem
<heat>
what linker script are you using?
<ddevault>
I added my platform as a target to binutils
<zid`>
This loads the entire elf into memory at 0x4000000, then loads a part of the elf to 0x6013a8
<ddevault>
heat: I am missing a lot of stuff upstream musl would need
<ddevault>
such as a unix-like system
<heat>
doesn't matter
<heat>
hack it
<ddevault>
I probably will, at some point
<ddevault>
this also qualifies as hacking it
<ddevault>
it's not libc's fault, it's something with my loader or these elf files
<heat>
musl needs like arch_prctl (a way to set the TLS) and writev for a int main() { printf("Hello World\n"); while(1);}
<heat>
if you want to return, add an exit_group-like syscall
<ddevault>
my kernel does not even have write, let alone writev, nor does either syscall fit into its design
<ddevault>
anyway, not important right now. Just hacking together enough shit to get doom running and then I'm throwing this all out and doing more important things
<heat>
get a script to generate wrappers around stuff :)
<ddevault>
my system is not even written in C anyway
* zid`
hates magic ELF
<zid`>
I'm a non-magic ELF supremacist
<heat>
aout fan?
<ddevault>
what is magic ELF
<zid`>
it loads itself into memory rather than its contents
<zid`>
the easiest way to achieve that being to pass one of the nmagic/omagic options usually
<ddevault>
does this file do that? I don't think this file does that
Vercas has quit [Remote host closed the connection]
<zid`>
readelf says it does
<ddevault>
how do I get readelf to say so
<mrvn>
I just wahsed my keyboard and now I'm blinded
Vercas has joined #osdev
<zid`>
I'm looking at -a because I can never remember the options, it's under Program Headers:
<heat>
this is standard
<zid`>
I just hate them
<heat>
most programs do this so you can look at the phdrs at runtime
<zid`>
I am a racial supremacist afterall
<ddevault>
I wonder if it's because .data is aligned on good.elf
<ddevault>
page aligned, that is
<zid`>
good.elf has an empty 00 PHDR that does.. something
<ddevault>
yep
<ddevault>
my loader is dumb
<ddevault>
it assumes all sections are page aligned
<zid`>
yea I did ask why it was aligned to 16
<zid`>
I exclusively write and use dumb loaders
<zid`>
so I only load the text+ and data+ load segments from the middle of the elf, page aligned
<ddevault>
I could fix my loader, or I could align .data
<ddevault>
hmm.....
<ddevault>
one of these options takes about 30 seconds
<mrvn>
If all the data only needs 16 byte alignment and the linker script does not add page alignment then you get that.
<mrvn>
Usualy you page align so each section can be protectd by the MMU.
<heat>
the linker script does usually add some alignment iirc
<ddevault>
I must give gnu credit where it is due for teaching the world how not to write software
<heat>
writing an elf loader is surprisingly hard
<heat>
I needed a few years until I got mine 99% correct
<heat>
it's probably still broken sometimes
<ddevault>
I think it has something to do with the fact that the ELF specification (if you can even call it that) just kind of tells you what's in the file but not what to do with it
<ddevault>
and while it's intuitive enough to make guesses that mostly or somewhat work, there's no good reference for all of the right things to do
<mrvn>
and every arch add it's own rules
<heat>
and there are a lot of corner cases
<zid`>
yea that's why I have preferences
<zid`>
but I also don't think it's a bad thing, the platform just defines what a valid ELF for it looks like
<zid`>
so on my platform, program headers must refer to 4k aligned sections or I won't load it, simple
<zid`>
That's not a bug in my loader, it's a constraint
<mrvn>
but then you have to fix gcc which might be harder
blockhead has joined #osdev
wand has quit [Remote host closed the connection]
wand has joined #osdev
<heat>
i forgot how verbose the arm arm is
<heat>
yay
dennis95 has quit [Quit: Leaving]
<zid`>
I verily failed to put my utmost unto rememberance of the manual of the ARM provided by the company ARM.
<zid`>
's most profuse verbosity*
<heat>
arm
<heat>
armarmarmarmarmarmarmarmarm
pretty_dumm_guy has joined #osdev
<heat>
how do I get the address of a symbol relative to my PC?
<heat>
ldr x0, =symbol doesn't work, that gets the absolute value
<zid`>
does you need to put a special section into .text
<zid`>
.text.common.adrp.nonsense.pls
<zid`>
(literally just throwing out ideas)
<heat>
not a bad idea
<j`ey>
are they actually 4gb apart?
<heat>
no
<j`ey>
more than 4gb?
<heat>
the address is high up there in the -2GB space
<heat>
maybe that's the problem?
<j`ey>
for both of them? the page table and the instruction?
<heat>
yes
<mrvn>
did you set the mcmodel=kernel?
* heat
checks
<heat>
there's no mcmodel=kernel for arm64
<heat>
I have -mcmodel=small
<mrvn>
try something else
<heat>
no difference
<heat>
and this is assembly too
<mrvn>
does "ldr x0, =boot_page_tables" work?
<heat>
yes
<heat>
but I get the absolute address
<heat>
I don't want that
<mrvn>
and what code does it produce?
<mrvn>
is the absolute address within PC range?
<heat>
ldr x1, #0x40081070
<mrvn>
and #0x40081070 contains?
srjek|home has joined #osdev
<heat>
i dont know
<mrvn>
what does objdump show?
<heat>
that's the objdump
pseigo has joined #osdev
vdamewood has joined #osdev
<heat>
should equal "ldr x1, 0xffffffff80001070 <stack_top>" (the last one was taken from qemu)
<heat>
is it because the symbol values are absolute? Do I need to do something to the symbol beforehand?
SGautam has joined #osdev
JanC has quit [Remote host closed the connection]
JanC has joined #osdev
<mrvn>
ldr should point to a word in the constants section that contains the address of the table
vdamewood has quit [Killed (erbium.libera.chat (Nickname regained by services))]
vdamewood has joined #osdev
<heat>
0x40081070 is not a valid address
<zid`>
agreed
<psykose>
bullies, all of you
<psykose>
0x40081070 can be valid if it wants to be
mzxtuelkl has quit [Quit: Leaving]
<mrvn>
at least it isn't odd.
pseigo has quit [Ping timeout: 268 seconds]
zid` has quit [Ping timeout: 248 seconds]
foudfou has quit [Remote host closed the connection]
wand has quit [Remote host closed the connection]
foudfou has joined #osdev
lainon has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
* geist
yawns at everyone
* vdamewood
sticks an apple in geist's mouth
<heat>
kinky
<vdamewood>
Naw, kinky would be if it had a leather strap.
wand has joined #osdev
sprock has quit [Quit: Reconnecting]
sprock has joined #osdev
<heat>
oh wise geist, can you help me understand why adrp doesn't work
<geist>
sure
<heat>
well, it don't work
<geist>
i assume you've looked it up the manual and whatnot right?
<geist>
are you writing it in asm?
<heat>
yes
<heat>
ld.lld: error: arch/arm64/image.o:(.boot+0x64): has non-ABS relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol 'boot_page_tables' <-- "adrp x0, boot_page_tables"
<heat>
this should work right?
<heat>
the addresses are like almost next to each other
<geist>
possibly. probably has to do with how the symbol is declared
<heat>
what do you mean?
<geist>
the instruction should work, so it's not the instructions fault, but something to do with how you're linking it, declaring it, etc
<geist>
so it's definitely pretty standard stuff at that point
<geist>
i've seen lots of people ask about this relocation eerror in linker on the web but it's generally no answer
gxt has quit [Ping timeout: 268 seconds]
<geist>
and yeah, you're right about mcmodel=small being default. it's not so small on arm64 to be honest: text and data can be 4GB, and located anywhere
<geist>
it's a pretty relocatable and reacheable arch
<bslsk05>
github.com: llvm-project/InputSection.cpp at 16ca490f450ea3ceaeda92addd8546967af4b2e1 · llvm/llvm-project · GitHub
<geist>
aaaah so it was getting stripped from the link? are you using LTO?
<heat>
no, it wasn't getting stripped from the link
<geist>
just a non alloc section
<heat>
yup
<heat>
the linker thinks it's not getting loaded, but my linker script says otherwise
<geist>
cool! well there you go. general rules of the road: if it's a symbol within the same file you can generally just use the 'adr' instruction if you want PC rel since adr can reach i think 22 bits or so
<geist>
but if you try to use adr for an external symbol i think it'll fail
<heat>
can't the linker do relaxation there?
<geist>
and you know about the :lo12: thing right?
<heat>
yes, add reg, reg, :lo12:sym
<geist>
i dont think arm linkers relax, but the compiler generally is good about combining the 12 bit part with the instruction that actually uses it
<geist>
ie, `adrp reg, symbol; ldr another reg, [reg, :lo12:symbol]`
<geist>
so in that case there's nothing to really relax
<geist>
but yeah you see in my above paste that it didn't relax away the add instructions, even though it was a nop
<heat>
arm64 don't relax?
<heat>
i had the impression they did
<geist>
i dont think so. riscv does, but that's not arm64
<j`ey>
in my code add+adrp is turned into adr
<geist>
or at least not linux relaxations. when you get into that you have to emit a lot more relocations so the linker knows how to fix things up, and i dont think there are a suite of relaxation rels
<heat>
it does, for tls at least
<geist>
j`ey: in the same file?
<geist>
well i'm thinking specifically about *linker* relaxations
<geist>
within a single file where it knows where the target is sure
<j`ey>
geist: yeah in the same file
<heat>
yeah I can see the same thing
<geist>
yah that i expect. linker relaxations are a different can of worms. you need to have a bunch of rel entries for effectively every branch in the file so the linker knows how to fix things up
<heat>
the linker is doing this
<heat>
image.o has the adrp + add, the linker transforms it into an adr
<bslsk05>
github.com: llvm-project/AArch64.cpp at 056d63938a6f2ea6af9fb0934702dc664ee784e5 · llvm/llvm-project · GitHub
<heat>
no
<geist>
aaaah replaces it with a nop. that makes sense
<geist>
it's the shuffling around of instructions that's the issue in general
<geist>
but if it keeps the same code size then it's just a 1:1 replacement
<heat>
it tries this optimisation for all R_AARCH64_ADR_PREL_PG_HI21 and R_AARCH64_ADR_PREL_PG_HI21_NC
<geist>
yah dont think i've seen bfd do that, but that falls into linker optimization
<j`ey>
yeah adrp+add -> nop+adr
<geist>
makes sense. whether or not an adrp+add -> nop+addr is much of a win i dunno, since AFAIK most modern arm cores merge adrp+add in the instruction decoder
<geist>
but might be a win for lower end cores
<geist>
if you read the optimization guides for the at least 7x or higher cores they have a bunch of instruction fusing with things like that
<heat>
they also do a bunch of relaxation for tls, etc
<geist>
also the usual cmp + branch stuff
<heat>
bfd does this as well
<heat>
(not sure if it does this particular relaxation, probably not)
<geist>
yah i just checked a compile of LK and didn't see the optimization
<bslsk05>
github.com: [build] Use CC as a linker by heatd · Pull Request #324 · littlekernel/lk · GitHub
<geist>
ah yes
<geist>
i should look at that one
<geist>
they're basically two conflicting patch sets. but it's clear i need to provide some support for clang. i've seen like 4 variants of that patch since i know LK is used internally at $company for a bunch of projects, and about half of them have hacked the build system to use clang
<geist>
but virtually 100% of those internal hacks are 'i only care about 1 or 2 arches, so i just hack it'
<geist>
another common trait of internal hacks are 'jam some arch code right in the middle of kernel/thread.c' or whatnot
<heat>
are they conflicting?
<geist>
like works for them but unacceptable
<geist>
possibly. but i should look at it closer. i'll do so in aminute
<geist>
honestly i just really dont care about clang, but i gotta get my act together
<geist>
i mean i do care about clang, but i dont care in the sense that it's not *interesting* to me
<geist>
as far as LTO, how far did you get the link working?
<geist>
i've over the years fiddled with LTO on LK and there's always some fatal flaw that kills it in the end
<heat>
i can't remember
<geist>
usually runs afoul of the linker and GCed sections and whatnot
<heat>
I think I started sticking attribute((used)) on a bunch of places but then gave up?
<geist>
or works on one arch but totally broken on the other ones, etc
<geist>
yah same
<heat>
i should look at that again
<geist>
it ends up being very fragile such that i'm not sure i'd want to officially have it in there
<heat>
also issue #318 which I promised I would look at :)
<geist>
but again, should suck it up and do some work
zid has joined #osdev
<j`ey>
that VBAR trampoline thing is pretty funny
<geist>
PCC also has that 'fault the mmu to skip trapoline thing' yeah
<zid>
nice, scared the shit out of myself
<zid>
had a 15 min powercut, took the time to give my machine a dust and swap some dimms around
<zid>
machine is now triple channel and the bios crashes when entered
<mrvn>
geist: clang is bad with `mls` or `muls` multiply-and-subtract.
<zid>
swap the dimms back, still the same issue, think I've killed the slot
<geist>
j`ey: i'm torn about that. it's nice in that it removes a bunch of stuff, but then it makes things slightly less flexible (cant use the trampoline post boot to read low memory) and i'm worried there's some machine somewhere that that isn't kosher
<gamozo>
zid: Don't forget to rotate your bioses too!
<zid>
eventually pull them both and I'm on.. single channel!? one of the *other* dimms, that I hadn't changed, had popped out
<geist>
i *think* n at least one machine i use the trampoline in early boot to read the device tree or something out of 'low' memory
<gamozo>
Otherwise the bios can get worn in one hot path, which is bad for the BIOS
<mrvn>
geist: i'm not sure clang on arm64 is as good as gcc
<zid>
all good now, except the power cut nuking all of mirc's settings as usual
<j`ey>
geist: then have code that does trampline page tables for 4k, 16k, 64k!
<mrvn>
worse on arm
<geist>
j`ey: oh i already fixed it in zircon. it's an easy fix
<geist>
so i should do that anyway
<geist>
4k pages and remove the code for 64k
<mrvn>
(or godbold simply has old compilers)
<j`ey>
everything supports 4k, rite
<geist>
so i'll probably do that in a minute
<heat>
mrvn, clang is android's compiler
<heat>
so I hope so
<geist>
re: dimms. i have a dimm start generating a bad memory cell the last few days on one of my work test machines. fiddled with GRUB_BADMEM and it actually works
<geist>
heat: it's pretty mixed. we use clang on fuchsia too
lainon has joined #osdev
<mrvn>
heat: try compiling int foo(int a, int b) { return a * a - b * b; }
<heat>
we use clang at work too
<gamozo>
clang codegen is often really inconsistent and it makes me sad
<geist>
it has gotten better in the last few years. i'd probably say arm64 clang support is about par but it seems a little wonky the closer you look at it
<geist>
exactly, the codegen is inconsistent
<heat>
turns out V8 can't really reliably compile with a compiler that isn't the one it ships with
<geist>
but in general it's better over time
<geist>
it's pretty close at least
<mrvn>
On arm64 it does neg + multiplay-and-add instead of multiply-and-sub
<mrvn>
on arm it does mul, mul, sub
<raggi_>
Clang is much better at complex c++
<geist>
thing is comparing micro code sequences from compilers is mostly a fools errand. one can always pick and choose something one compiler does than the other
<mrvn>
raggi_: but laggs behind in c++23
<geist>
the key is overall how does it do, and i think they're basically on par nowadays
<mrvn>
geist: missing an opcode completely is pretty bad
<geist>
vs say 3 or 4 years ago when we were first really switching to clang
<raggi_>
mrvn: perhaps, but if g++ ooms I can't tell ;-p
<geist>
mrvn: shrug. that's just an optimizatino path that someone hasn't typed in, if that's the case
* geist
waves at raggi_
<mrvn>
geist: it's odd though that someone typed in multiply-and-add. I would expect both or none.
<raggi_>
Howdy :-)
<geist>
and as raggi_ says i think clang does a pretty good job with large complex c++ codebases
<mrvn>
large complex c++ codebases live a lot on the STL. You have to implement that to be compiler / memory friendly
<raggi_>
Lldb va gdb is similar too, and the symbolizes performance
<geist>
we use it at work because from a feature and maintainability point of view it's the compiler with a future, even if it's codegen started off worse
<mrvn>
The inconsistency of clang worries me more than bad code in the end.
<geist>
but as someone says it's micro codegen is just... wonky. its like an AI designed it's codegen and it's optimized for strange cases
<geist>
but in general performs about the same because modern cpus are pretty good at eating garbage
<zid>
Anything performance critical gets written in streams of avx intrinsics anyway :p
<geist>
whereas i tend to be able to 'see' the hand tuned code generator from gcc. for better or worse, it tends to be more stable
<mrvn>
I notice that with ocaml. It doesn't optimize at all, just generates good, simple code from the start and is usualy the same speed as c/c++
<gamozo>
Does the same compare twice, even though the flags still are active from the same compare above. The compare above doesn't at least jump past the second compare
<geist>
it feels a bit like clang is the reuslt of test driven optimizations. you can end up with weird decisions, but at the end of the day if it benchmarks >= older changes and you maintain that rule forever you end up driving it's optimizations into some local minima
<gamozo>
just so strange
<geist>
even if it doesn't 'make sense'
<zid>
uh oh machine is acting funny, gaah
<zid>
something's wrong
<mrvn>
I run into bubblesort the other day: gcc -O2 and clang -O2 is about the same. gcc -O3 is 5 times slower, clang -O3 is twice as fast.
<gamozo>
I feel like clang gets macro really well, but micro really poorly. I often see clang loading registers and then never using them, or overwriting them the instruction after. Things that I don't think should be possible "ever"
<geist>
vs stepping back and making good clear human centric decisions on how you apply optimizations
<zid>
no applications will start, neat
<geist>
gamozo: yah precisely. and if all the 'accept this change' decisions in the project itself are based on some sort of large test cases, it'll still pass the test because in the long run the large scale optimizations usually win over small ones
<raggi_>
The thing about rust codegen for cases like that is you have to remember it's a tall lazy iter apj that's been inline folded at a high level then optimized later
<geist>
so you end up with this. strange micro decisions that as long as they dont hurt the overall picture, make it in
<mrvn>
or std::optional<double>. Instead of just writing the bool and double for a std::optional it messes around with xmm0 registers constructing the thing on the stack and then copying it out.
<geist>
but... all this aside i've watched over the last few years clang get better and better with micro decisions, presumably as folks find misoptimizations, file bugs, and someone fixes em.
<mrvn>
gamozo: what I don't get is that the codegen doesn't do a final pass to eliminate dead code
<geist>
so it's one of those cases where eventually the project with the mindshare wins
<gamozo>
mrvn: I would hazard a lot of the things I see are on teh backend, I'm not sure. I'd imagine these "issues" don't exist in the IL but rather the backend
<geist>
but i have more trouble using it for smaller, less sophisticated cpu cores where actually the micro placement of instructions does kinda matter
<mrvn>
can you explain that rust code?
<raggi_>
The advantage clang has now is that it sucked a huge volume of the professionally funded toolchain teams, so it gets a ton of full time input
<geist>
vs a high end superscalar machine that generally reduces wonky codegen to more or less the same thing as good codegen (in a lot of cases)
zid has quit [Read error: No route to host]
<geist>
raggi_: yah basically it doesn't matter if it's better or not, it's simply where the money is
<gamozo>
mrvn: It requests the u8 at index 5, which returns an Option<&u8>. It can be None if it's out of bounds. I then apply a map to deref the inside to convert it to an Option<u8> instead of returning a reference to the byte
<gamozo>
It's just indexing a slice, but with out-of-bounds checking not resulting in a panic
<heat>
"the money" considerably backed off of llvm when the standard refused to break the ABI
<raggi_>
did it?
zid has joined #osdev
<heat>
c++20 compliance is still far off
<heat>
yes
<raggi_>
Apple, Google, meta, etc are still invested heavily
<heat>
don't get me wrong, they're still on it
<mrvn>
gamozo: line 4 loads the byte. But what does the rest do in the asm?
<heat>
but it seems like most of the invest is going into rust instead
<zid>
That was a fun crash, filesystem basically disappeared, I could interact with a bunch of stuff but programs wouldn't start and some actions locked up various programs
<zid>
then 30 seconds later, all the clicks I did finally caught up and a bunch of programs/files opened
<zid>
then it immediately bluescreened
<geist>
I'll count the money next time i go into the office and dive into the large pit of cold coins, Scrooge McDuck style
<raggi_>
I haven't heard of any mega corp or mega product teams switching to a non clang alternative
<zid>
My pc is now officially haunted
<gamozo>
mrvn: THis fnuction is not marked extern, thus it uses Rust's (undefined) calling convention. It would appear it uses two return values. al being the bool indicating if the option is Some or None (present or not), and dl holds the value contained in the option
<geist>
zid: if you want to keep your data you might want to be a bit more careful, ou can easily get a fata FS corruption if you have a known buggy machine
<heat>
raggi_: not a non-clang alternative, but a non-C++ alternative :)
<mrvn>
gamozo: I figured the al for that too
<heat>
which is understandable, but sad
<zid>
geist: yea has happened before, ntfs is even especially bad for it imo
<gamozo>
Without marking extern, Rust uses it's own (undefined) calling convention. Which allows the compiler to change up things as it sees fit. It's kinda interesting/neat
<mrvn>
gamozo: and "cmp rsi, 6"?
<j`ey>
checking the length of the slice/array
<j`ey>
to see if array[5] is ok
<raggi_>
heat: I ahevnt really heard of that either. Ms and AMZN are investing heavily in rust, and it's slowly making some inroads at Google but the c++ wall is solid too. That's all llvm investment
<gamozo>
&[u8] internally is a (void*, size_t). It's checking the "second argument" to the function, which is the size_t (length of the vector), to see if it's in bounds
GeDaMo has quit [Quit: There is as yet insufficient data for a meaningful answer.]
<gamozo>
this function, from an ABI perspective, is the same as fn foo(void*, size_t), and thus rsi is the second arg
<mrvn>
gamozo: so why isn't line 7 between 2 and 3?
<heat>
raggi_: I dunno, maybe I heard wrong. But even here at cloudflare lots of things are getting written in rust or go and not C++. Of course, no one is really rewriting core stuff to rust
<gamozo>
bad codegen :)
<raggi_>
heat: I think gos been taking more away from dynlangs than from c++
<mrvn>
gamozo: As to the rust source I would rather have the function prototyle say |a| >= 6
<geist>
it's definitely happening in fuchsia a lot. seems most new subsystems are implicitly rust based
<geist>
much to the chagrin of folks trying to build the OS
<gamozo>
In reality, they probably move the return value closest to the ret, to avoid reserving such a critical register such as 'al' in the middle of the function (and having to preserve it to the end). That's probably _why_ it's at the end. And another pass just didn't move it around from there
<raggi_>
geist: yeah, fuchsia is a rebel in Google in general
<j`ey>
gamozo: it's the same codegen for aarch64, where regs arent so important
<raggi_>
geist: by some measures Ms is moving faster here, with official windows sdks in rust already
<raggi_>
And they've written two network stacks in rust
<heat>
what
<heat>
two network stacks?
<raggi_>
Yep
<heat>
in the kernel? or user space?
<mrvn>
gamozo: buy more registers :)
<gamozo>
mrvn: But they just killed IA64
<geist>
says the person that insists on using arm32
<raggi_>
Cloud things with blurred lines
<raggi_>
Parts run on nics etc
<heat>
how do you get an itanium machine
<geist>
might be able to find one on ebay. but it'll almost certainly be a huge ass machine
<geist>
since there werne't a lot of workstations made over the years, and theones that were were still huge ass workstations
<gamozo>
(Actually MIPS beat ARM in this. I'm pretty sure every router chip I've looked at that uses MIPS uses absolutely proprietary opcodes and breaks the standard it's great)
<geist>
no. intel 64 == x86-64
<geist>
ia64 == itanium
<gamozo>
^
<geist>
they are completely different things
<heat>
wtf
<heat>
I prefer IA-32e
<zid>
they changed name like 3849 times
<heat>
much clearer naming
<zid>
32e was in use for a bit I swear
<geist>
x86-64 == ia32e == amd 64 == intel 64 == x64 == probably a few others
<heat>
it is the official name in the SDM I think
<geist>
itanium == ia64, period
<zid>
ia64 is itanium though
<zid>
I'd also call x64 arguably itanium but more people use it to mean amd64
<geist>
that's where the ia32 name came from they had to backronym it when they invented the ia64 moniker
<heat>
the proper way to refer to it is x86_64 (WITH THE UNDERSCORE)
<geist>
since at the time there was not going to be a x86-64
<heat>
anything else is heresy to me
<zid>
x86_64 definitely has an underscore yep
<gamozo>
heat over here in their own dimensions
<psykose>
amd64 is one less character hence better
<mrvn>
They should have kept amd64 as arch name
<zid>
intel architecture 32, and amd 64, it fits
<zid>
considering who designed which
<raggi_>
x64 is better beause it's easier to scan read next to arm64 xD
<geist>
it was going to be simply ia32 for x86 and ia64 for itanium and all future 64bit stuff would obviously be derived from itaniu,. i remember that koolaid flowed heavily all over the industry. it was a great new time to switch to a Real Architecture
<zid>
what was the crazy i4389 or whatever arch
_xor has quit [Quit: WeeChat 3.4.1]
<heat>
itanium was the peak of humanity
<zid>
can we have that instead for ia64
<geist>
raggi_: yah exactly. that's why i relented on the battle of what to call the arches in fuchsia. in exchange for arm64 i yielded x64
<heat>
we've gone downhill from thereon out
<gamozo>
Riscv is the future
<geist>
because aarch64 drives me nuts
<raggi_>
yeah
<raggi_>
i hate having to type eabi too
<geist>
every single time i see it i think of Samuel Jackson saying 'do i have a stutter?'
<mrvn>
geist: you stutter :)
<heat>
aarch64 and ia32e sounds great to me dunno what you're on about
<geist>
ARM is many things but inventors of good acronyms they are not
<mrvn>
geist: ARM ARM?
<heat>
sxtw
<geist>
the ARM ARM so you can program your ARM in your ARM computer
<geist>
though officially i think they changed it to arm instead of ARM a while back
<geist>
because rebranding
<heat>
a r m
<gamozo>
Lowercase is very trendy right now
<mrvn>
my robot arm has an arm controller so you have to read the ARM ARM ARM
<zid>
ARM: Advanced Recursive Manual
<raggi_>
hired a new brand lead, switched case, font and logo
<geist>
but i like to say ARM because it makes it clear it's te company/architecture, and not just another word
<heat>
ARM: ARM reference manual
<gamozo>
How can you justify the reorg unless you change random things?
<geist>
and it's pretty easy to type with right shift, so no biggie
<heat>
yall use the right shift?
<raggi_>
yes
<heat>
nah nah nah nah nah what
<geist>
i almost exclusively use right shift, though i'm trying to mix in the left shift more dynamically
<heat>
i don't think i've ever used the right shift
<geist>
but years of typing has be pretty much fixed on right shift, left ctrl
<raggi_>
i started using right shift more after i stopped flying between eurpean and us regions regularly
<raggi_>
before that, right shift would change shape, which made it unreliable
<geist>
is ther eno right shift on european layouts?
<heat>
there is
<gamozo>
There's a right shift key?
<geist>
oh differnet shape, yeah
<raggi_>
it's there, but there's often an extra key there, making it shorter
<heat>
thank you gamozo
<geist>
at least for US keyboards it's at least pretty symmetric. there's a right and left shift of all the modifiers
<raggi_>
i rarely use right ctrl
<heat>
my right shift and right ctrl are longer
<raggi_>
mostly for a one handed solute
<heat>
maybe this is my gamer hands talking
<geist>
yah but when i do it it's nice
<heat>
all the left buttons are closer to wasd
<geist>
like when i dynamically mix in a left shift because i'm typing on the right side of the keyboard, etc
<gamozo>
My right shift, right ctrl, right alt, right menu, and right super are all fully textured on my ~15 year old keyboard
<geist>
it feels good when yuor muscle memory pulls off something complicated like that
<raggi_>
i type quite poorly, but i'm ok with that, because i don't get bad rsi from typing
<raggi_>
every time i try to type "correctly" i hurt myself
<heat>
do you mean %rsi
<geist>
I think i use right shift since for the most part i like to yse the opposite modifier for the thing i'm typing, and statiscally speaking i think more capitalized first letters (in english at least) are on the leftish side of the keyboard
<geist>
except I of course
<heat>
hehehehehehehe
<geist>
but then i usually dont bother capitalizing I
<raggi_>
i only capitalize Serious Business
<raggi_>
and THREADRIPPER
<heat>
srs biz
<geist>
EL TORITO
<heat>
EL TORITO
<raggi_>
:)
<gamozo>
raggi_: Yeah, I never formally learned how to type. Which I think means I learned naturally instead of what some person taught me. And I've never had RSI
<geist>
though now that i think about it a lot of programming keys are shift on the rght side: ()_+", etc
<geist>
and i think i justone hand those
<raggi_>
yeah, i do too, it's probably the most dangerous part of my typing, and part of why i enjoy languages wtih punctuation elision grammars
<geist>
bu it's also why i dont feel particular hatred for _ like a lot of folks do
<geist>
to me it's just another key because i just one hand shift - it
<raggi_>
where i have a choice i prefer snake case to camel case, i don't really hate _, but in cli's etc, i prefer -
<geist>
100% i really dont like camel case, but it's not a hill to die on
<raggi_>
google style --foo_bar flags are just unpleasant to my eyes
<heat>
oh yeah those are horrible
<zid>
yea fuck that
<heat>
they're just not right
<mrvn>
__help__ any better?
<geist>
tiny admission: i'm starting to not terribly hate the trailing _ for member stuff in C++ classes
<zid>
I'm already on - from typing --
<heat>
oh yeah I like the trailing _
<geist>
i thought it was terrible at first, but honestly i'm starting to stockholm symdrome that
<zid>
also good news I'm about to have an ocular migraine
<raggi_>
geist: that's how it happens, that's why python is heavily infected now
<geist>
it looks terrible with foo_->bar_->baz but
<heat>
the good part of the trailing _ is that you can have a class c { private: char *data_; public char *data() {return data_;}}
<geist>
i was working on an older project of mine where i ws using mFoo and i'd prefer foo_ over that now
<geist>
or m_foo
<mrvn>
geist: you don't use _ for arguments that confcit with members?
<geist>
m_foo actually doesn't bug me too much but still
<geist>
mrvn: yeah but those are leading
<heat>
lpFoo
<mrvn>
nah, leading is a big nono
<geist>
sure but fuck the man
<raggi_>
unpopular opinion puffin: if you need those sigils, there are other code problems
<geist>
leading in global scope sure. but if it's some local thing it doesn't matter if you use leading
<heat>
C standard: "nooo only the implementation can use leading underscores" geist: "I am the implementation"
<mrvn>
this->foo for member variables sucks too
<geist>
if it conflicts with global scope the compiler will tell you
<geist>
but yeah in general i try to avoid args conflicting with things. sometimes if it's a single liner i dont care that much
<mrvn>
constructors and setters are a problem there
<geist>
but usually if it's a trailing _ for members the problem goes away
<geist>
void set_foo(int foo) { foo_ = foo; }
<mrvn>
void set_foo(int foo_) { foo = foo_; }
<heat>
the whole problem would go away if we STLified all our C++ code
<geist>
nooooo!
<heat>
int _Foo;
<heat>
looks beautiful
<raggi_>
then you just get constructor variance problems
<geist>
honestly (unpopular opinion) what i really hate is over use of <algorithm>
<geist>
where you get that kinda code that everything is an amalgamation of existing algorithms, instead of just writing what you mean
<raggi_>
c++ stdlib is kind of apalling
<geist>
i get it, i understand why that's 'better' in a lot of cases, but i dont think it helps with readability at all
<heat>
or <functional>
<heat>
or fucking <array>
<mrvn>
I'm missing a range-for with index
<geist>
yah
<heat>
you also import a huge header full of crap
<heat>
making your compile time slower
<geist>
like i dunno i was staring at some code the other day that took me a while to grok because it was some complicated scheme where it was using std::optional and std::uh what is it that calls one of N functions based on what the input is?
<mrvn>
or looping over 2 or more things in parallel
<geist>
i get it, it's kinda neat. rust has shit like that
<geist>
but... the codegen is atrocious, and it was used for a case where the number of std::optional cases is like 2 or 3
<mrvn>
geist: std::variant
<mrvn>
and lambda with overloads
<raggi_>
geist: a friend roped me into helping them overcome issues in a codebase full of boost variant and boost reflect recently, and i wanted to smash things
<geist>
std::variant yeah. so you end up with a lot of boilerplate to define all of this stuff so that you just end up with functionally a 3 entry switch statement
<raggi_>
^^
<raggi_>
that, very much that
<heat>
C++ codegen will never be as good as rust's on that stuff because all of C++'s codegen is built on classes and templates and all that crap
<geist>
but it's hard to argue against it in a code review, because you're telling someone to undo some 'beautiful' code that they just spent this time on
<geist>
to do something 'dumber'
<raggi_>
the argument "this will reduce cost of extension in the future" is nebulous, and sadly often bs, but hard to resolve in a review
<geist>
the best argument i have against it is std::variant *can* generate a vtable and a bunch of functions. there's no guarantee it'll inline it
<mrvn>
c++ lacks a match statement and the function overloading needs too much boilerplate
<geist>
what i really dont like is it's hard to grok precisely which variant will be called in any given case. it puts the onus on the reader of the code to manually match what goes where
<raggi_>
it gets worse
<geist>
but this is the sort of thing i feel like a stick in the mud about a lot, since i feel like i'm generally being outgunned at work with this sort of code being more the norm
<raggi_>
if you use gcc, and there are conflicts, by default in some cases it'll "jsut pick one"
<geist>
because it's better and more templateable and thus more unit testable, etc
<raggi_>
clang at least will error on that by default
<mrvn>
raggi_: it complains when it is ambiguos
<raggi_>
not always
<mrvn>
c++ has strict rules about it. Nobody understands them but they are there
<raggi_>
i literally fixed one of these cases about two months ago
<gamozo>
C++ has rules?
<raggi_>
xD
<zid>
I can't see a damn thing
<heat>
that's assuming that compiler writers interpret the standard the same
<zid>
thank god I can still type and annoy you all regardless
<geist>
baiscally i like enough C++ to give me better type safety, better control over memory allocation (safe pointers, etc), and ability to structure object oriented code the way I was probalby already basically writing it in C
<gamozo>
I thought C++ just allowed compiling of /dev/urandom. The fact that C++ "looks the way it does" is just random chance that the undefined behavior lines up that way
<geist>
and that seems like a nice balance, especially for lower end hardware
<heat>
geist, +1
<raggi_>
geist: i know you don't like rust much, but you might actually enjoy nostd from that perspective
<heat>
my C++ is just C with classes, some light templates and RAII wrappers
<raggi_>
as that's mostly all it provides
<geist>
when you use a lot of std:: just to use it i think it starts to quickly spiral into some other language that really does not help on the readability front
* kingoffrance
adds "unpopular opinion puffin" to aethernet / unix "a gnome buffers your characters" / pixel faeries / daemon/dragon / pypy etc. list of technical terms
<geist>
raggi_: yah i dont really dislike it i just need to put more effort into it
<geist>
my main gripe is its really slow to compile large projects. feels like it exponentially scales up the compiling side of things
<raggi_>
that's mostly choice side effects, and c++ does the same
<geist>
yah but it feels like the exponential scale factor is somewhat higher
<raggi_>
if you spent time wiht it in nostd with your kind of code style it'll mostly perform like c
<geist>
like 3.5 instead of 1.5 or something
<raggi_>
i think the exponential is a perception distortion
<gamozo>
Rust is fine for build times, it's just really bad decisions from third party stuff. I have multiple 50-100k LoC rust codebases that build in 1-2 seconds
<gamozo>
But the second I bring in a third party crate it goes to 30-60 seconds :sigh:
<mrvn>
geist: mostly a problem of templates and sfinae
<geist>
perhaps? we have tools within the tree now that are taking 35 *minutes* of compile time
<raggi_>
e.g. slow parts in the fuchsia code base when i left was like ffx, which links like 50% of the fidl code in teh code base
<geist>
and 8GB of memory
<geist>
yep. ffx. it's gotten a lot worse, and i dont see how that can scale
<raggi_>
no other program in the tree does that, and wall time wise it's doing pretty well
<gamozo>
Yeah, that's absurd to me. That being said, I know it happens. I've never had a problem with my own code bases. I think there are a few big crates out there that are doing some nasty things that serialize the build and heavily use generics
<geist>
i keep raising the flag but i dont think there's any will/way to fix it
<raggi_>
if it was split into hundreds of programs, it woudl take similar time
<raggi_>
you just wouldn't see it, because it'd be 32 one minute compiles, rather than one 32 minute compile
<geist>
problem is it also needs to be recompiled/linked at the drop of a hat since it links with everything
<raggi_>
right, so that's a build system/toolchain problem
<gamozo>
I'd hazard rust build times being bad are less about rust build times, and more about the crate-culture which makes it so easy to pull in massive deps just to use 1-2 simple functions
<geist>
and now the build system depends on it since it's used n a step, so yo ucan't just skip it either
<raggi_>
treating it like a c compiler when you optimize it doesn't work out well
<gamozo>
You can just invoke rustc and generate objects, and then link them together at the end like C
<geist>
but anyway that's work, which is not weekend
<geist>
but you're right, it'snot fair to penalize the language for a bad case
<raggi_>
gamozo: fuchsia does that, but that's not entirely true
<gamozo>
If you're willing to write rust like -ffreestanding C/C++, I have _never_ had build time issues at all
<geist>
hell, zstd.c still takes like 2 minutes to compile, goma just helps with that
<geist>
and that's *C*
<gamozo>
Correct, you need forwards declarations
<heat>
there was a change a few weeks back that started verifying some stuff after building fuchsia and that stopped 8GB + 8GB systems from compiling fuchsia
<heat>
nuts
<geist>
heat: it was that. ffx
<geist>
it keeps accidentally bumping it's size
<raggi_>
yeah, doesn't entirely surprise me
<raggi_>
the fact that it's doing lto doesn't help
<geist>
i had it blowing out my /tmp the other day, since at some phase of rustc apparently rustc creates a dir in /tmp and writes out copies of all the input rlibs
<geist>
and it was 6.8GB
<raggi_>
rust defers a lot to link time, and none of the fuchsia toolchain optimizations optimize that yet
<gamozo>
That being said, I do think Rust could get 10-100x build time speedups without sacrificing codegen. It's just not super parallel. It also serializes pretty heavily at crate-levels when you hit generics, where in reality it should build as much as it can, until it needs it's generic dependencies to be compiled
<heat>
being parallel doesn't help IMO
<raggi_>
gamozo: that would bloat memory usage further, in a significant way
<heat>
most build systems expect a single job to only use a single thread
<raggi_>
gamozo: and make linking even more expensive
<gamozo>
It is something I'm disappointed with. But, for my own OSdev stuff where I'm not using crates, I've never had problems with absurdly complex macros, generics, etc, causing any issues. My entire IL is generic across the size of the architecture, and it's still sub-second build times
<geist>
someone at work explained to me how the cpu time can jump up a lot on rustc when using parallel lto. basically each job in the lto re-expands all the generics
<zid>
hoorah it stopped, I can see again
<raggi_>
right, so user choices count for a ton
<gamozo>
raggi_: Not necessarily. Yes, if they bolted it on, sure. but in reality they could do a lot better job with that memory usage and linking
<geist>
and can't share cpu/memory while they're running
<mrvn>
stop making a single file use 8GB to compiler and you can use -j8 again
<gamozo>
^
<geist>
so the more threads you add to the LTO it his some scaling point where it's diminishing returns time wise because the amount of duplicated work doesn't help
<raggi_>
if you say, code generate generics that produce expensive and bloaty monomorphizations and then make that mandatory for every api on the system, you'll have poor compile times
<gamozo>
There's really no reason Rust can't be "converted" into C-like-rust where you extern "rust" {} for your forward declarations and compile nearly everything in parallel
<mrvn>
gamozo: nd inline nothing?
<raggi_>
well there is, that severely limits optimizations
<gamozo>
You can inline at the linker stage
<raggi_>
you can't type fold there though
<heat>
tldr reject modernity, embrace C99
<mrvn>
gamozo: that's the part that takes all the time
<raggi_>
so it breaks down fast
<gamozo>
Keep in mind, compiling doesn't have to be to native arch, it can be to a simple IL that's easy to inline at
<geist>
so -j1 it might lto in say 5 minutes of cpu time, -j2 may be like 8, -j3 may be like 12, etc. in that it doesn't just take the initial 5 minutes and subdivide it among cpus
<heat>
in fact, C89 is ok too
<gamozo>
linking takes long because linkers are written like absolute garbage. We've already seen that there's 100x gains in linker times
<geist>
the overhead of addiing more cpus is not linearly dividing the time, since each job duplicately performs the same tasks
<gamozo>
(with mold)
<heat>
ld.lld is pretty good
<gamozo>
Pretty much all our toolchains, and linkers were written for single-core CPUs. We're missing so much perf
<raggi_>
heat: yeah, it's much better at hard tasks
<mrvn>
gamozo: linking is rather trivial compared with the optimizer
<geist>
omg rant: someone has set my email as their notification for their ADT security system. i get notifications about windows being left open, door to the garage opened
<heat>
i'm not convinced on doing things in parallel here
<psykose>
multithreading can't give you magic performance though; mold is 100x faster not because of 100 threads, but because it's fast on one and then also scales
<gamozo>
I disagree, I genuinely think the way we're doing last-minute inlining, generics, is just really poorly done. There's no reason we can't have a super simplifed IL that's designed for inlining at LTO (rather than more complex graph optimizations)
<zid>
geist: Your fly is undone
<geist>
i can't log into their account and shut it off because they have 2 factor
<j`ey>
gamozo: just wish it did linkerscripts
<mrvn>
gamozo: lat-minute inlining is whole program optimization, not linking
<heat>
geist, complain to ADT?
<raggi_>
geist: eugh, though i'd rather ahve that than the jerk who signs me up for hard right wing newsletters
<gamozo>
j`ey: yeah, I think it's still only Rei working on it. It'll definietly be a while. I'm honestly impressed it can build chrome and clang lol
<geist>
raggi_: oh i get that too.
<geist>
i mean i can just filter it into the trash
<gamozo>
mrvn: I'd hazard inlining can relax some of the optimizations. There's a lot of optimization passes that will just not really do anything when you're ready to inline
<gamozo>
I think it could be a simplified optimization pass
<gamozo>
I'm not talking about perfect optimization. Of course perfect optmization you have to pull everything into one compile unit
<gamozo>
But I think we're using a massive hammer for a stage where you don't really need it
<j`ey>
gamozo: yeah, but he has stated linkerscript as a non-goal
<raggi_>
geist: yeah, i am gunna move to my own domains eventually, but i want a mailserver that does zk encryption on arrival that doesn't require insane amounts of weekly maintenance
<gamozo>
j`ey: awhh. Well, I think he has plans for his own linker-script replacement. Which I approve of, as linker scripts are absolutely fail-open garbage
<geist>
yah i remember back when i used to run my own spamassassin
<geist>
that eventually became a losing battle
<raggi_>
maddy is really close
<gamozo>
I think he wants to make a stricter linker scripting environment? Which thus, won't be backwards compat
<mrvn>
gamozo: I doubt it. The benefit of inlining isn't so much the saved function call anymore, it's that you optimize the code to the local usage. register allocation alone is a major cost factor and speed gain
<raggi_>
maddy folds about 7 daemons into one binary, which helps, but i still want encryption and some spam stuff
<gamozo>
mrvn: Yeah, you can do that really cheaply though. You can do that effectively without graph analysis. Source: Working on my own IL for whole-program optimization which is insanely fast
<gamozo>
So, my current view (which could be wrong, research eh?) is that a faster inlining allows more inlining, which is better than fewer inlinings with "better" optimizations
<mrvn>
gamozo: great. seems like you solved P == NP.
<gamozo>
I only do a single forward and reverse pass of the IL
<raggi_>
gamozo: how do you deal with duplicate eliminiation?
<gamozo>
No graph traversals
<raggi_>
(and other forms of bloat)
<gamozo>
raggi_: I can only remove/alias duplications if they happen above in teh graph, in a dominator. But that's really no different than any other IL
<raggi_>
this is important to measure, in very large programs it ends up becoming geometric
<gamozo>
But we'll see, I have a very special use case. So far it's been absolutely mindblowing for perf. I'm not sure if it's generically applicable yet though? Idk. Working on my OS right now, got sick of working on my IL on Linux
<mrvn>
raggi_: don't write code with duplications, don't generate IL with duplication
<raggi_>
mrvn: never call the same function twice xD
<raggi_>
gamozo: nothign wrong with fit-for-purpose, as long as it's used for the purpose for which it fits
<mrvn>
raggi_: not with the same argumenta at least if it's pure
<gamozo>
So, my current IL is designed for treating all memory as constant until proven otherwise, and it's wild
<gamozo>
If you define write(stdout) to be a no-op (eg. no console), it will bubble up and remove printf() in your code
<gamozo>
it's so good
<gamozo>
and it does that in microseconds
<raggi_>
yeah, there's a lot of rust stuff that produces those patterns
<gamozo>
To make this work, it _has_ to _compile_/JIT fast. I'm oaky with "sloppy" allocations, because the micro-optimizations are less important than the macro optimizations
<gamozo>
Cause I end up re-compiling/optimizing the same code thousands or millions of times, and thus it has to be absurdly fast
raggi_ is now known as raggi
<gamozo>
Thus the entire optimizer works on a Vec<Op>, and it does one linear forward pass, and one linear backwards pass, such that the CPU can prefetch during optimization. No graphs, no graph traversals, no maps, no dicts, etc
<gamozo>
any of those things effectively make this unusably slow as you get 100-150x slowdowns. But, that limits what I can optmiize. But it's "worth" it
<raggi>
i'm getting Factor vibes
xenos1984 has quit [Read error: Connection reset by peer]
<gamozo>
it allows things like dynamic configuration (globals), config files, registry keys, etc. To be optimized into your language and constpropped
<gamozo>
It's actually really really interseting and probablym y favorite work (and it's why I'm back to writing OSes so I have a better env to dev it in)
andreas303 has quit [Ping timeout: 248 seconds]
<gamozo>
Any if(logging) code paths just get completely deleted, it's so cool
<gamozo>
printf("%s", foo) turns into write(), etc, etc
<j`ey>
I wrote a clang rewriter tool that rewrote if statements in clang to add '&& false' to conditions I knew could never happen
<j`ey>
(similar kinda thing)
<gamozo>
The main operating principal of my work is that it will const-prop things without knowing they're constant. When memory is treated as constant it is marked with metadata saying "this was used as constant". if a write to it is ever observed, then the JITs which made that assumption are invalidated and the JIT is re-entered
<gamozo>
"constant until proven guilty"
<gamozo>
And alas, you can see why this will re-JIT many many times (as it learns what is and isn't constant). And thus, why compile speed matters more. The faster I can compile, the wider I can inline things. My eggs are in the basket that removing massive amounts of code with shitty one-pass optimizations will out-perform doing micro optmiizations that are more robust
<gamozo>
It's designed for snapshot fuzzing. With the idea that if you give constant input to a program (eg, the same file input to like a PNG parser). It will have _no_ conditional operations in the optimized program. It will only be memory side effects (if threads are enabled), or simply, entirely collapse to a 'ret' if you don't have threads (and thus writes aren't "volatile")
<gamozo>
You'll just either get a massive function of millions of writes with no branches, or a ret. As you mutate the input, parts of the code flow will "come back", but only the things you have caused. Which is really interesting for static analysis, as you can "see" the program that you're observing rather than the original program
andreas303 has joined #osdev
xenos1984 has joined #osdev
<heat>
i should get a domain but then I need a server
<gamozo>
For the right price I'll host for you
<heat>
1 cent a day
<heat>
deal?
<gamozo>
I was thinking like $100/hour
<gamozo>
Electricity is expensive right now
<heat>
hmm
<heat>
what's the hardware?
<heat>
gameboy color?
<gamozo>
I have a gameboy pocket
<heat>
no deal
<heat>
I'm not confident that it can run gerrit
_xor has joined #osdev
<gamozo>
ugh fine
<heat>
i wondered if I could run git on the edge but now im playing doom on the edge
<heat>
go figure
<heat>
does doom have its own software rasterizer?
xenos1984 has quit [Quit: Leaving.]
pretty_dumm_guy has quit [Quit: WeeChat 3.5]
<heat>
the arm arm keeps redirecting me to pages
<heat>
why couldn't they just describe the whole MMU in one go
<gamozo>
Section 1.3 MMU: vaddr -> paddr
<heat>
"here's the descriptor format; for more information on attributes, see page 2151515151; page 2151515151: here's a summary of the attributes, for more information, see page 599999999999"
dude12312414 has joined #osdev
<heat>
it's full of cross fucking references aaaaaaaaaaaaaaaaaaa
<sbalmos>
heat: page 599999999999: If you've read this far, you have experienced a real-life example of our implementation of 4-level page tables
<heat>
AF, bit[10] The Access flag, see The Access flag on page D4-2165.
<heat>
they are fucking trolling me
<heat>
sbalmos, PML5 at this point
<sbalmos>
heh
<heat>
geist, what does "Secure" mean in the ARM world?
<heat>
kernel?
<geist>
no it's a hardware feature. specifically the cpu is either in secure mode or not at any point in time
<geist>
which doesn't really affect the performance of the cpu except that it tosses a secure bit on AXI transactions on the bus, so the SOC can accept/deny/modify it's behavior based on if the cpu is in secure mode or not
<heat>
in which mode are you usually running?
<heat>
non-secure?
<geist>
then the arm arch has a complex set of rules regarding setting/clearing the secure bit (hint: it's at EL level transitions and follows the uusal logic of you can only drop when going down a level, and only raise going up)
<heat>
(and then theoretically firmware or that trusted firmware thing would be on secure)
<geist>
correct. if the cpu implements secure bit (all i know of do *Except* apple M1)
<geist>
then the cpu boots with secure mode on implicitly
<geist>
and it's up to the firmare to decide to drop it when going to a lower level. usually it does
<geist>
such that secure mode is 'controlled' by EL3 firmware. it can choose to drop to a lower level with the bit set
<geist>
but lower code cannot set the bit
<geist>
and this is why you se references to running secure OSes alongside your insecure OS (say trusty (secure) alongside linux (insecure))
<geist>
linux makes calls into EL3 firmware which switches modes and drops into the secure OS, which has the secure bit set
<geist>
when it switches back to linux (via EL3) it drops the secure bit
<geist>
and thus memory transactions the secure OS makes can access hardware that is locked off behind the secure mode stuff, including the physical memory it's living in
<geist>
fairly simple strategy, but fairly effective
<heat>
interesting
<sbalmos>
I couldnt' decide whether to say interesting, cute, or go full Spock fascinating
<clever>
so EL3 is always in secure mode, and runs the "secure monitor"
<clever>
EL2 can be both secure and non-secure, and runs either the normal or secure hypervisor
<clever>
then EL1 is where either the normal or secure kernel lives
<clever>
and EL0 can be either normal or secure userland
<geist>
right, but the rules also follow that a lower EL can't run with a higher secureness than a higher one
<clever>
and each time you transition to a lesser EL, you can optionally also reduce the bit width, but that lower EL can then never increase the bit width
<geist>
without bouncing through a mode that has it
<geist>
right, more or less the same rules as bitness
<geist>
though i'm sure there are subtle details. i forget if you can unset your own secure bit for example, which you can't do with bitness (without an exception)
<clever>
so now everything is forced to be aarch32
<geist>
note that apple M1 doesn't implement secure mode, and as a result they dont implement EL3
<heat>
any advantage/disadvantage to that?
<geist>
which is actually perfectly valid. thus the cpu boots directly into EL3 in 64bit mode, no secure bit set
<clever>
so the cpu is running in EL2, secure or non-secure, when it comes out of reset?
<gamozo>
huh
<geist>
they just decided they didn't want/need it, so they left it out. and if you dont have secure mode there's really no point implementing EL3
<clever>
heat: EL2 and EL3 are optional, and can just be omited from a design to save transistors
<geist>
s/cpu boots directly in EL3/EL2/
<heat>
why would you have secure mode? secret sauce for the SoC?
<geist>
the arch allows for both of EL3 and EL2 to be optional. and the bitness at every level is optional, except higher ELs must implement at least the superset of the lower
<clever>
heat: a way to access secret keys in a secure manner
<geist>
yah basically, or the ability to build some sort of secure enclave of code that the insecure os can't see
<clever>
heat: for example, secure mode could implement a TPM in software
<clever>
which reminds me, netflix has various security levels
<geist>
so you can (and do) implement say some address decoding logic in the memory controller that says (for example) 0-64MB is secure mode only. now when linux is running in insecure mode it simply can't decode that address. doesn't matter how hard it tries, it'll generate some sort of external sync abort
<clever>
and 4k video streaming, is only authorized on devices with a proper secure enclave
<heat>
but couldn't you just stick that in the hypervisor?
<geist>
but if you have a trusted os you can load it in that range, and it can run just fine because secure bit is set
<clever>
which makes stealing the 4k content far harder
<geist>
the model is not to even trust the hypervisor
<clever>
it also saves the cost of having to deal with a second set of paging tables
<geist>
idea is whatever kernel/os/hypervisor/etc is loaded on the cpu is insecure, so treat it as such
<clever>
you can just hard-wire the ram controller, such that non-secure can just never touch a defined range of ram
<geist>
and put secure bits instead of inside some second processor (liek you get on intel or AMD) but in some trusted OS
<geist>
that lives off in its own world
<clever>
so its enforced by dedigated logic in the chip, rather then a paging table that could corrupt
<geist>
there's more advanced stuff you can do with it, but i think there may be too many cooks right now. want to make sure heat groks it first
* clever
backs off
<heat>
how do you get to the secure mode though? considering nothing else is trusted
<geist>
the cpu starts in secure mode
<heat>
yes but you're down the chain
<geist>
and thus if the firmware dropped secure mode right off the bat and remained in EL3 you cannot get it back
<geist>
but once you're down the chain, in a lower EL without secure mode set, you hve to make some sort of call into a higher EL that has it
<geist>
and then it's a software problem: does it 'bless' you with secure mode?
<heat>
yes, my question is: how do you know you're actually calling it
<geist>
or (more generally) does it do an operation based on its secureness
<geist>
there's an instruction to make a EL3 (or EL2) call
<geist>
HVC for EL2 and SMC for EL3
<geist>
operates exactly like SVC (EL0 -> EL1) in that it just switches to that mode and calls the exception handler
<j`ey>
and the DT will tell you what to call
<j`ey>
(for stuff like PSCI)
<geist>
so there's a standardized firmware call layout to request secure operations from your firmware
<geist>
op code, args, etc
<geist>
so *usually* what you do as an insecure os is make a SMC call to your firmware to send some message to a secure os implementation to go do something for you
<heat>
oh I see
<geist>
EL3 traps it, decides it's legit, saves cpu context, then loads secure OS context and drops to the secure OS with the secure bit set
<heat>
EL3 always has secure mode if it exists
<geist>
right
<geist>
the secure bit is basically latched in every level in a register that can only be seen by that level and above
<heat>
you smc, the secure monitor chucks that request down the secure mode stack, and it goes to trusty, trusty does its thing
<geist>
i forget precisely what the bit is called in what register, but when yuo switch to the new mode it intrinsically is secure or not based on the bit being set
<geist>
ie SECURE_BIT_EL3, SECURE_BIT_EL2, SECURE_BIT_EL1, etc. (that's not the name but it's something in one of the banked regs)
<heat>
whats the point of having a non-secure bit in the page tables then?
<heat>
"For memory accesses from Secure state, specifies whether the output address is in
<heat>
the Secure or Non-secure address map"
<geist>
oh gosh i totally forget. probably some ability to mask off the secureness for safety purposes
<geist>
maybe a secure OS sets that when creating mappings in its own page tables to see pages from a non secure OS
<geist>
so that it doesn't access them with the secure bit going across the bus for Reasons
<geist>
most likely non secure OSes have no need for it
<geist>
at the end of the day that's all the secure mode stuff is. it's just a bit that goes along with the AXI transaction, and its up to hardware to do something with it or ignore it. it doesn't get saved to memory or whatot
<geist>
but i do think it has complex interactions with the cache and it's a bit in the TLBs
<geist>
so there's some rules there to deal with nonsecure oses using cache lines generated from a secure os, etc
<geist>
all told it's kinda like a 1 bit coarse granular iommu but for cpus. kinda.
<clever>
and for dma, you could hard-wire the secure bit on axi to non-secure, so dma cant be used to read secure memory
<geist>
yah and/or have special secure mode dma controllers that you can mask off their registers to program them from insecure oses
<heat>
ARMv8.0 requires that software manages the Access flag. This means an Access flag fault is generated whenever
<heat>
an attempt is made to read into the TLB a translation table descriptor entry for which the value of Access flag is 0.
<heat>
oh wow
<geist>
or even latch the secureness of the dma transactions based on the secure bit at the time the cpu accessed the registers
<geist>
yeah, modified flag too, which is really strange and a head scratcher
<geist>
v8.1 or so adds hardware support for A and D bit, but they're kinda a can of worms. frankly it's kinda nice to have software implemented A and D bits for reasons
<heat>
i don't see anything about the software D bit
<heat>
where's the READ bit?
<geist>
yeah because it's implemented in a wonky way. it's not a D bit per se, but a bit that says IIRC 'its okay for hardware to modify the page table entry from RO -> RW'
<heat>
for execute-only behavior
<geist>
but there's a bit that controls that. it's a weird implementation
<geist>
i dont know why they did it that way vs just having the cpu writeback to a D bit
<geist>
probably some clever reason it's technically more efficient, though hardware for software to deal with
<geist>
okay so what question are we on now?
<geist>
we have overlapping questions, dunno where the current stack pointer for questions is at
<heat>
<heat> where's the READ bit?
<heat>
<heat> for execute-only behavior
<geist>
that's kinda two questions. it's not implemented as RWX but a table of 3 bits that has a bunch of permutations
<geist>
well, not that even. it's kinda wonky
<geist>
i al;ways have to go back to the code to see, hang on
<geist>
ah yeah, it's *two* bits to control 4 permutations of the RW permissions
<geist>
it sets bit 6, which intrinsically conversts a RO page to RW
<geist>
so they arranged for the bit encoding to double as permissions and D bit
<geist>
but *then* i forget how you arm this D bit mode, since you dont want it to just unilaterally convert RO pages to RW
<heat>
what kind of horrible voodoo do I need to do for caching?
<geist>
not to much. you just have to implement the standard cache flush routines
<heat>
but the mappings seem to have attributes
<geist>
and then apply them at appropriate times. generally only need to do it for dealing with various dma bits in hardware
SGautam has quit [Quit: Connection closed for inactivity]
<geist>
yeah you just pre-can the MAIR and then you have 8 types. basically similar to PAT in x86
<geist>
ie, a MAIR register has 8 fields of 4 bits with a bunch of permutiations, but only like 2 or 3 actually matter, and then you write the index into it for the page table entries
<bslsk05>
github.com: lk/mmu.h at master · littlekernel/lk · GitHub
<geist>
then MAIR is probably intrinsically zeroed (hopefully) and then when you have to write an index field in your page tables it selects one of the 0ed entries
<geist>
which is probably looks like `Device-nGnRnE`
<geist>
whichi s 'strongly ordered'
<geist>
which means it'll run like shit
<geist>
that's effectively Hella Uncached
<geist>
see line 208
<heat>
i see
<geist>
in practice basically every OS on the planet sets the MAIR to the same 3 or 4 entries and then just uses it. since most of the permutations of the bits dont matter
<heat>
I think I'll skip this for now since I don't quite understand it
<heat>
I just want to get a flat identity mapping for now
<heat>
full of 1GB pages
<heat>
that seems nice
<geist>
qemu probably wont emulate any of it so you'll probably be fine just leaving MAIR zeroed (you should explicitly zero it at least) and then just put zero in the index field of the page tables
<heat>
oh yeah also what's with the shareable stuff
<geist>
ah re: the dirty bit, it's bit 51. i just dont have a #define for it in my code. it's the DBM bit (dirty bit modifier)
<geist>
just always mark everything sharable. it's legacy
<geist>
from the arm32 days
<geist>
iirc it means 'do you both implementing inter-cpu cache coherency on this page'
<geist>
and the answer is yes. for some sort of per cpu mapping you could probably unset it and hypothetically it's faster
<geist>
i have no idea if modern cpus implement that
<heat>
inner or outer?
<geist>
you only care about inner
<geist>
outer is also kinda legacy, or at least so largely unused you dont really need it
<geist>
oh god i just read the 5 or 6 pages of the ARM ARM talking about the dirty bit (and ingeneral writing back to page table entries by hardware, A bit included) and my eyes are bleeding already
<geist>
it's so complicated. that's why we haven't implemented it in zircon. there's something very ordered and nice about just taking a page fault and doing it there
<heat>
that's a common side effect of reading the ARM ARM
<heat>
<heat> AF, bit[10] The Access flag, see The Access flag on page D4-2165.
<geist>
though to be fair x86 is completely underspecified there WRT precisely how page tables are written back when setting A and D bits
<heat>
wanna know a cool fact: x86 CPUs can possibly hang trying to write to ROM
<geist>
arm goes into it with extreme detail, especially with regards to how precisely the writeback is ordered relative to the instruction that triggered it, and how it nests in a multi translation scheme (S2 + S1), etc
<heat>
which is why firmware sets the accessed bit in the GDT for the ones in ROM: so the CPU doesn't try to writeback the access bit to ROM
<geist>
and what kind of transaction can trigger it, including atomics and cache ops etc etc. this is the sort of detail that sometimes is nice to the ARM ARM but you kinda wish they'd have a TL;DR version of things and then a section that says 'if you really wanna know how it works XYZ'
<geist>
the riscv manual on page tables is like 'theres an A and B bit you know what this does LOL'
<heat>
the riscv manual annoyed me
<heat>
but now I really appreciate it
<geist>
yah it's like the trashy indie band version of architectures
<geist>
they're the Melvins vs late stage Metallica