<nrdmn>
ah, okay. I'll write a function instead to access it that returns a slice.
<andrewrk>
that's reasonable. a u8 pointer to the beginning of the struct + @sizeOf(StructWithoutThatField) will point to the right address, then you have to ptr cast it
<andrewrk>
I think this could be done with a fairly reasonable API in userland
<nrdmn>
ok, now I've got a struct with two such arrays.. the efi spec is full of that kind of structs
<nrdmn>
I think I've seen one that contains a null-terminated array, an array of which the size is given inside the struct and a third array that fills out the rest of the struct. You get the total length of the struct when you request the struct from an efi function
<nrdmn>
I can't find it now, but I remember it was file access related
<fengb>
Oh a dumb edgecase: the compiler crashes if the struct is usize bytes
<andrewrk>
I don't know how I thought I was going to type up release notes and fix multiple bugs per day
knebulae has quit [Read error: Connection reset by peer]
knebulae has joined #zig
<nrdmn>
you can install new fonts in uefi that are used for the config menus 🤔
waleee-cl has quit [Quit: Connection closed for inactivity]
<andrewrk>
I always thought of std.heap.DirectAllocator as being pretty simple, but I'm realizing now there have been a lot of contributions to this code
<nrdmn>
there's still a lot to do. Some essential ueif protocols haven't been implemented yet and I'll probably move things around. The uefi spec assumes a flat namespace for structs and types and that makes it a bit difficult to put them in a meaningful hierarchy
<andrewrk>
it's ok to mirror that flat namespace
<knebulae>
@nrdmn: very cool!
<knebulae>
My ultimate thought on UEFI was that you only need so much of it to get going; namely the memory map and the output ability. The filesystem access helps too. But at the end of the day, it is much, much, much easier to wrap the C libraries (either gnu-efi or TianoCore). I mean the spec is around 3k pages. It was a fool's errand-- at least for me.
<nrdmn>
there's so much fun stuff in pre-OS land
<nrdmn>
I've only ever used exitBootServices() once
<knebulae>
@nrdmn: I spent 20 years there. That time is over for me, lol.
<andrewrk>
nrdmn, seems like an improvement to me, ship it
slice has quit [Ping timeout: 268 seconds]
slice has joined #zig
<Tetralux_>
How do you get to that UI?
<Tetralux_>
Is that part of UEFI and you're just changing the font?
<nrdmn>
Tetralux_: basically yes
<nrdmn>
I'm reading the default font, redraw all characters with freetype and replace the default font with the one I just generated, then exit and return back to the menu
FireFox317 has joined #zig
<andrewrk>
hahahha that is so much better than what I thought you were doing before
<FireFox317>
🤮 comic sans, great work tho nrdmn!
<nrdmn>
actually it's comic neue
_Vi has joined #zig
<FireFox317>
Oh hahah, close. Never thought this would be possible tho
<nrdmn>
neither did I
<nrdmn>
there are functions to change various UI parts, see chapters 33, 34 and 35 of the spec (as of version 2.8). Or more specifically, I'm using the EFI_HII_DATABASE_PROTOCOL functions
<Tetralux_>
nrdmn: Oh, so your program has side effects (changing the font) and then you return, which goes back to the menu?
<Tetralux_>
Or do you have to issue a "return to menu" command, kinda-thing?
<nrdmn>
yes
Tetralux_ is now known as Tetralux
<Tetralux>
Hmmm.
<Tetralux>
Interesting.
<nrdmn>
the default (on most firmwares) is to return back to the boot manager
<Tetralux>
.. when you return from main?
<nrdmn>
yes
<Tetralux>
And you changed the font with a "syscall" essentially
<Tetralux>
Or is it more a UEFI library that you just call into.
<andrewrk>
nrdmn, ppl on twitter are requesting meme gifs in BIOS next
<nrdmn>
It's kind of a syscall. UEFI provides a struct of function pointers to my main function. These function pointers are used to access UEFI services such as access to devices (including touch screens and network) and loading other operating systems and UEFI drivers.
<nrdmn>
I wrote some wrapper structs in Zig so I can use Zig types instead of C's void pointers
<nrdmn>
Tetralux: an UEFI OS is supposed to 'exit boot services' when it is done initializing, i.e. tell the firmware it is done using UEFI facilities. The firmware then removes all UEFI drivers from memory and the UEFI app is completely on its own, has full control over the hardware, and can't return any more.
<nrdmn>
So normally you can't use these features in an operating system, but technically you don't have to tell the firmware you're done
<Tetralux>
So, if you're making your own OS, you just never return, but if your more of a UEFI app of some kind, you can return, and it'll just return to UEFI loader.
<knebulae>
It's essentially what the BIOS utilities use to make their new & improved UEFI UIs.
<nrdmn>
Tetralux: correct
<knebulae>
s/utilities/companies
<Tetralux>
Except that, even if you are an OS, you can choose to exitBootServices and cause the UEFI to leave you to it.
<Tetralux>
Or not.
<Tetralux>
In which case
<Tetralux>
You retain access to all the UEFI stuff.
<knebulae>
@Tetralux: you actually don't lose framebuffer access through the UEFI GOP. And you are required to ExitBootServices to do anything serious. There's a catch-22 that is escaping my mind at the moment.
<knebulae>
@Tetralux: I should have clarified that on emulators and the limited hardware I've tested on.
<Tetralux>
I see.
<Tetralux>
So the expected pattern is: run main from UEFI, "initialize yourself", exitBootServices, actually finish loading your OS. (like firing off the login screen.)
<Tetralux>
And then you're on your own
<nrdmn>
knebulae: using multiple cores while in pre-os mode is undefined behaviour IIRC
<Tetralux>
But still have access to the screen via UEFI
<nrdmn>
yes
<knebulae>
UEFI will exclude its code & data from the memory map
<knebulae>
So if you follow it, you won't step on UEFI
<nrdmn>
actually you can use a few UEFI services after exitBootServices, see chapter 8 (runtime services). For example, access to the clock, EFI variables (anything you can access through efi-readvar and efibootmgr), and rebooting the system
<knebulae>
I was just reviewing some code to see where the catch-22 for calling ExitBootServices was, because I remember wanting to stay there forever. I'm fairly certain that you need to ExitBootServices in order to enable paging, but there may be a way around that.
<nrdmn>
paging is enabled and all memory is identity mapped
<Tetralux>
Paging>
<Tetralux>
?
<nrdmn>
I can imagine UEFI doesn't like it when you remap the memory
<nrdmn>
Tetralux: a mapping between 'virtual memory', i.e. the addresses that normal applications see, and the addresses where the bytes actually go
<nrdmn>
this mapping supports setting permissions, e.g. some parts may be writable but not executable or vice-versa
<Tetralux>
Okay - so basically just a synonym for 'virtual memory.'
<nrdmn>
ye
<nrdmn>
ss
<Tetralux>
Gotcha.
<Tetralux>
I wonder if it's possible to never exit boot services and then on demand, write some data to disk and then return to UEFI and have it immmediately fire up your program again.
<Tetralux>
So that you could have a "rapid-reboot" option./
<Tetralux>
(in your OS.)
<Tetralux>
Which basically just returns to UEFI, asking it to immediately try to run your UEFI app agian.
<andrewrk>
i'll move on to other stuff and come back to this tomorrow in case anyone takes me up on it
<knebulae>
@nrdmn: I wanted to specify that by "enabling paging" I meant *my* paging :) I figured that was too much for here.
Akuli has quit [Quit: Leaving]
<mikdusan>
note to self: when upgrading system compiler, nuke all zig-cache directories from worktree (especially for tests)
<andrewrk>
mikdusan, why's that? it shouldn't matter
<andrewrk>
it makes sense to save space
<andrewrk>
I mean, that's a good idea to save space, but have you discovered a cache issue?
<mikdusan>
not hashing issue, sys_include_dir on macOS points to product of `cc -E -Wp,-v -xc /dev/null` which in turn is related to the current xcode installation path.
<mikdusan>
upgrading xcode changes that path if you have multiple xcode's installed
<andrewrk>
linux users are isolated from that issue since zig brings its own libc headers for glibc & musl
<mikdusan>
so this can be spooky behavior because i ran tests. ALL passed. then I upgraded from Xcode_11.beta to Xcode_11.0 and _nuked_ the old beta.
<mikdusan>
in that case it gave me a nice "can't find assert.h" error. but the worst part? if i didn't delete the old install, then my zig-caches would still be using the beta's include tree
<andrewrk>
I hope the license of apple's libc headers is MIT compatible
<andrewrk>
that is a bit spooky. the root question is: when is it the correct time to re-detect the system libc include path?
<andrewrk>
if we ship darwin libc headers this question goes away
<fengb>
Most of it is Apple licensed
<mikdusan>
apple headers like `assert.h` have 4-clause BSD. others like `sys/_endian.h` have some opensource apple license. i suspect there are more license clauses too
<andrewrk>
that sounds compatible. I'm guessing it has to be since proprietary software is allowed to link against libc without the license infecting
<fengb>
There was at least one that's "ALL RIGHTS RESERVED" and really dumb
<fengb>
'Google claimed that the header files were clean of any copyright-able work, reducing them to non-copyrightable "facts", and thus not covered by the GPL. This interpretation was challenged by Raymond Nimmer, a law professor at the University of Houston Law Center.'
<fengb>
Type definitions are facts right? We can win in court 🙃
<andrewrk>
the real court is if debian accepts your package without patches
<andrewrk>
that's who you gotta convince
<mikdusan>
how about something like: `zig libc-rebind` which bumps a serialnum key in ~/Library/Application Support/zig; then zig-cache logic can punt and recalc libc associated settings if serial is diff
<mikdusan>
meh. probably just easier to nuke zig-cache
<andrewrk>
it's just zig-cache/native_libc.txt
<akhetopnu>
hi, i've got a question about returning pointers to stack allocated structures. When I have a function like fn create() &Object { return &Object { .value = 5 }; } then zig doesn't complain and everything works fine, however if I try to do that in C i get a warning/error -Wreturn-local-addr. Is this a bad thing to do or is it just an arbitrary default limitation imposed by gcc/clang
<Tetralux>
You should note return a ptr to a value on the stack.
<andrewrk>
akhetopnu, that should be a compile error
<akhetopnu>
so the fact that zig allows to do it should be treated as a compiler error?
<akhetopnu>
i see
<Tetralux>
should not*
<Tetralux>
If you find yourself wanting to do that, either allocate it somewhere or return a value instead.
<andrewrk>
it might be making a global const, in which case it's ok because it's a static reference, but then it should be a compile error because the pointer is mutable
<akhetopnu>
i mean, if I return a pointer to a locally stack-allocated struct then after the function returns that value is no longer available, but for some reason i can log that out to console
<akhetopnu>
i'm guessing it's some sort of inlining/optimization
<Tetralux>
It's because the variable has not been overwritten yet.
<akhetopnu>
i used that create() function inside main, so it shouldn't be global
<Tetralux>
It will be when you call another function.
<akhetopnu>
hm, you mean the same physical address on the stack was not overwritten yet?
<Tetralux>
That's right.
<andrewrk>
akhetopnu, what you're observing is a lack of runtime safety for this particular flavor of undefined behavior ("use-after-free")
<andrewrk>
this is one of the things I plan to investigate adding safety for in the next release cycle
<akhetopnu>
i see, good to know
FireFox317 has quit [Remote host closed the connection]
<mikdusan>
calling struct methods `foo.doit()` works when `doit` is a FnProto. but it doesn't work (not found) when `doit` is a VarDecl of type function
<andrewrk>
mikdusan, I think I agree with you that should work
<andrewrk>
can you do a proposal though? I want to run it by josh
<mikdusan>
yup
<andrewrk>
mikdusan, never mind - I have proof that it should work
<andrewrk>
it will necessarily get solved with the implementation of #1717. but feel free to file another issue (or PR) if you have interest in solving it in the meantime
<mikdusan>
ah yes i remember that one now.
halosghost has quit [Quit: WeeChat 2.6]
<mikdusan>
oh. my. gawd. I can use this to split out the struct methods of a large struct into other files grouped by functionality or whatever. this is unexpectedly nice.
<andrewrk>
ah yes
<fengb>
I have a big refactor of my decode table waiting on this :)
<andrewrk>
I think zig has comptime closures
<andrewrk>
I've never tested it
<companion_cube>
`const f = if (…) fn(a:i32) … else fn(a: i64) …` 🤔
<companion_cube>
seems like a lot of cool possibilities
<mikdusan>
this works with a comptime fn if that's what you're asking
wootehfoot has quit [Read error: Connection reset by peer]
dimenus has quit [Quit: Leaving]
akhetopnu has quit [Quit: Lost terminal]
rohlem has joined #zig
<rohlem>
andrewrk, that last example code of "comptime closures" is not _intended_ to work... is it?
<rohlem>
Since, at runtime, it would be a case of accessing a freed stack variable. I would find it counter-intuitive to allow that during comptime but error for detected runtime uses.
<rohlem>
Since, well, if a user does it during comptime and it works, they might use it in runtime, and if there's a yet-undetected usage pattern, that's undetected UB.
<Tetralux>
andrewrk: Wait - that works?
<rohlem>
(And if the code returned the entire struct, made `i` a member variable and gave `c.f`a `*@This` parameter, it would be "the (only) obvious way" that works at both runtime and comptime.
<rohlem>
(note there would be no comptime-cache-spoofing required with a mutable pointer in the parameter list either... at least last time I tried it)