klange changed the topic of #osdev to: Operating System Development || Don't ask to ask---just ask! || For 3+ LoC, use a pastebin (for example https://gist.github.com/) || Stats + Old logs: http://osdev-logs.qzx.com New Logs: https://libera.irclog.whitequark.org/osdev || Visit https://wiki.osdev.org and https://forum.osdev.org || Books: https://wiki.osdev.org/Books
bauen1 has joined #osdev
Burgundy has quit [Ping timeout: 256 seconds]
masoudd has quit [Ping timeout: 256 seconds]
Jari-- has joined #osdev
nanovad has quit [Quit: ZNC 1.7.5+deb4 - https://znc.in]
nanovad has joined #osdev
<mrvn> Hehe, who can tell me why this code is UB? char c; ... toupper(c);?
Vercas has quit [Remote host closed the connection]
Vercas has joined #osdev
<Griwes> is it because toupper takes an int and something bad happens for negative values of c when char is signed?
<mrvn> and the prize goes to griwes
<Griwes> the number of bugs related to char signedness that I've had to debug is larger than 1 so I immediately had a suspicion
<Griwes> all the char functions taking ints is such nonsense
<mrvn> Now that we have byte maybe char should be made no integer.
<Griwes> arguably this is an issue because char was allowed to be signed
<mrvn> I believe that stems from the fact that all the char functions took a register
<mrvn> implicit function definitions
<Griwes> what I'm saying is that regardless of the signatures, if char was never allowed to be signed, this would not be a problem
<mrvn> that too
<mrvn> I was refering to taking an int.
<Griwes> yeah
<mrvn> With big endian if you put a register (int) on the stack and read back a char you get 0.
<mrvn> and add stack alignment issues with pushing a char on the stack for more fun.
<heat> why is it UB?
<heat> i don't understand
<mrvn> heat: c = '"o'; so it is >128 and let char be signed.
<mrvn> toupper(-200); is UB
<heat> do they say it's UB for toupper?
<mrvn> "Like all other functions from <cctype>, the behavior of std::toupper is undefined if the argument's value is neither representable as unsigned char nor equal to EOF."
<heat> ah great
<heat> that works with a naive implementation
<mrvn> The had to allow for EOF because that appears in ASCII text.
<Griwes> > In all cases the argument is an int, the value of which shall be representable as an unsigned char or shall equal the value of the macro EOF.
<Griwes> quoting a C11 draft
<mrvn> They ...
<Griwes> blanket wording for all of the header lol
<mrvn> All the cctype functions have that char as int problem.
dmh has quit [Quit: rip]
eddof13 has joined #osdev
<Griwes> I'm fairly certain I have some uses of them that invoke this ub lol
<heat> ok I have a weird question
<Griwes> I assume most implementations do the sane thing here?
<heat> are struct sizes aligned to the alignment of the struct?
dmh has joined #osdev
<Griwes> yes
<heat> ah ok great
<Griwes> because sizeof(foo[n]) is sizeof(foo) * n, and all the array elements are aligned
<heat> yeah exactly
<heat> I always start to get confused when explaining arrays to C noobs
<Griwes> understandable
<heat> it makes me think of stuff you never really think about
<heat> like how does alignment work with arrays and structs
<mrvn> heat: bonus question: What is the size of struct { int x; char c[]; }?
<mrvn> and no running that through godbolt.
<gog> depends
<gog> wait it doesn
<gog> it's 4
<gog> or is it 8 o.o
<gog> hmm
<heat> mrvn, 5
<mrvn> heat: what did we just learn about array size and alignment?
<heat> oh lol 8
<heat> i was too busy thinking about the char c[]'s size
<Griwes> welcome to this week's installment of Cursed C Structures
<gog> flexible member array
<mrvn> gog: say you have struct { char c; char buf[]; } blob[10]; Consider what &blob[0].buf and &blob[1].c is.
<gog> it's 4
<mrvn> Hint: pointer to different objects must never be equal.
<Griwes> amend that in C++ to include "of the same type" ot make it worse
<mrvn> Griwes: isn't that C too?
<heat> wait it's 4
<mrvn> Plus the pointers must be within a single block of memory returned by malloc/new.
<mrvn> No, the answer is 8 because the address must be unique.
<Griwes> mrvn, idk, is it? in C++ the only sane way to do that is to use inheritance or [[no_unique_address]]
blockhead has joined #osdev
<heat> i know C++ and C have different rules regarding some of this weird stuff
<heat> empty structs for instance
<heat> mrvn, no the answer is 4 because the compiler says so
<bslsk05> ​godbolt.org: Compiler Explorer
<Griwes> hmm, we used to have geordi
<Griwes> anyway yeah flexible array members are... a Thing
<Griwes> best to ignore they exist and use other methods to get the end of structure address
eddof13 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<gog> i just wrote a test program it's 4
<gog> and the array is 40
<mrvn> heat: huh? Wait? What? that should be wrong.
<Griwes> welcome to hell, mrvn
eddof13 has joined #osdev
<gog> FMA stands for two things in this situation :p
<kazinsal> ha
<heat> fuck my add 🥵
<bslsk05> ​godbolt.org: Compiler Explorer
<gog> mrvn: those addresses are the same
<Griwes> yeah. the addresses are the same, the *pointers* aren't equal though
<bslsk05> ​godbolt.org: Compiler Explorer
<mrvn> Why can't I compile that as c++?
<Griwes> (pointer provenance is one hell of a drug)
<heat> the pointers aren't what?
<Griwes> equal
<Griwes> they compare equal but aren't
<heat> what
<heat> mrvn, because you're in C
<Griwes> as i said, pointer provenance is one hell of a drug
<heat> reject C/C++
<heat> become monke
<gog> yes
<gog> never code in C
<Griwes> { int a, b; } <- depending on stack order, (&a + 1) == &b evaluates to true, but *the pointers aren't equal* because pointers also track what object a pointer originates from
<Griwes> except they track it with information not represented in the integer value of the pointer object
<Griwes> again, it's one hell of a drug
<heat> i'm coding in llvm bitcode from now on
gog has quit [Quit: byee]
<heat> see you made gog leave
<Griwes> I'm quite sure that llvm also has pointer provenance
<Griwes> worse, llvm has poison values
<heat> fuck
<heat> i'm programing in noises from now on
gog has joined #osdev
<mrvn> At least -pedantic has it right: <source>:6:14: warning: invalid use of structure with flexible array member [-Wpedantic] 6 | struct s s[10];
<gog> aha
<mrvn> I swear the size used to be 8 to get around the addresses being equal. But it seems they made the wrong use of this illegal instead.
<mrvn> heat: One day when I have too much time I want to run all my usual programs with a malloc wrapper that initialized memory to CAFEEBABE.
eddof13 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<klange> Regardless of the spec, the size of a struct with a flexible member at the end should be the size of everything up to the start of the flexible member.
<mrvn> init=valgrind systemd
<klange> And asking for an array of them, or really any static allocation or initialization, doesn't make sense to me.
<mrvn> klange: that would be simplest and now it is +- alignment
<Griwes> mrvn, do it
<heat> use gentoo
<Griwes> and file all issues just to see poettering's reaction
<heat> compile everything with ASAN
<heat> glhf
<mrvn> struct s { int x; char a; char b[]; }; sizeof(struct s)==8
<mrvn> klange: do you think it should be 5?
<klange> I think 8 is right, because I _think_ b should need to be aligned, so 3 padding bytes included in the size of the defined portion sounds right
<Griwes> flexible array members are a cursed feature, just like VLAs
<mrvn> klange: but if the size of b is 3 then the alignment is wrong again.
<mrvn> klange: alignmentof(s) == 4 and sizeof(5) would be fine.
<klange> idgi
<klange> if size of that is 8, then that means b starts at offset 8.
<mrvn> klange: which wastes 3 byte for no reason.
<klange> padding do be like that
<bslsk05> ​godbolt.org: Compiler Explorer
<mrvn> plus up to 3 more to align b again.
<klange> what why do you need to align b again
<mrvn> klange: to place the next struct s
<klange> that's your problem
<mrvn> With align=4 and size=5 you have less wasted.
<mrvn> and compatible to struct s { int x; char a; char b[1]; }
<Griwes> yeah, less wasted, but also everyone around you is constantly screaming in terror at an unaligned size
<Scripted> All right guys, I'm disconnecting. See you tomorrow!
nyah has quit [Ping timeout: 240 seconds]
<Jari--> Scripted see you
Scripted has quit [Quit: WeeChat 3.4]
<Griwes> disconnecting? what a weird concept
<mrvn> klange: struct s { int x; char a; char b[]; }; has sizeof() = 8 and b at offset 5.
<mrvn> Griwes: if you allocate a dynamically siszed struct you have to align/padd it yourself. No way around that.
<kingoffrance> "*the pointers aren't equal* because pointers also track what object a pointer originates from" wait wait wait...this almost seems back to x86 real mode. i just read with segment:offset that means every byte of your giant 1MB can have 4096 or something possible pointers, 4096 ways to point to one of those locations... so c compilers used "huge" to avvoid this
<kingoffrance> point like its 1989
<mrvn> kingoffrance: memory returned from malloc() can not alias and arrays can only be 64k big. There is only one valid seg::addr for memory.
<mrvn> The 4095 other are UB
<klange> mrvn: yeah and I'm saying I think that's stupid :D
<kingoffrance> 4096 shades of pointers
<mrvn> klange: you want sizeof() == 8 and offset of b == 8?
<klange> yes, or sizeof() == 5 and offset = 5
<klange> depending on your own specifications of alignment requirements
<mrvn> makes no sense to align b to the alignment of the struct. 5/5 would make sense.
<mrvn> I want sizeof(struct s) + strlen(data) + 1 to give the right size for the struct without waste.
<klange> yeah, thinking about it more, 5/5 makes the most sense here, and I think my padding statement is dumb here for char[]
<klange> if it was int[] then see previous, should be 8/8, which it is
<klange> mrvn: yes! definitely where my mind is with this
<mrvn> ok, we agree. :)
<mrvn> Now if I can only find the place in the C standard where it says "struct s s[10];" is invalid use....
* gog flexes
hbag has joined #osdev
<klange> ooh, packing will get the size to 5...
<mrvn> klange: and make the int get accessed as 4 bytes.
<heat> yeah packing removes any alignment from the struct
<mrvn> never ever use packed unless you memcpy in/out of it.
<mrvn> or similar one time use.
<heat> it works in x86
<mrvn> heat: x86 allows unaligned access, ARM/Alpha/... throw an exception.
<heat> i know
<klange> it works on most everything, aligned access requirements and even unaligned access performance costs are less of a thing now
<klange> arm64 is totally cool with that shit
<klange> except on device memory, maybe, depends on *waves hand*
<mrvn> klange: clang on ARM does byte access, gcc does unaligend register reads which would fault the CPU on ARMv7
<clever> mrvn: i actually had a bug related to this, gcc by default did byte-access, but when you compile with -O, it switched to 32bit loads and assumed alignment, which then faulted if mis-aligned
<clever> i was using a packed struct to decode an MBR table, and some of the fields are mis-aligned
<mrvn> clever: tried it two days ago and got the bad code with -O2
<clever> without -O, gcc knew packed was unsafe and just did byte-wise
heat has quit [Remote host closed the connection]
<klange> mrvn: I unfairly consider 32-bit ARM targets to be dinosaurs
<mrvn> What does struct Foo __attribute__(("packed")) { volatile uint32_t x; } do?
<klange> let me live in my fantasy world
<mrvn> klange: same on aarch64
<mrvn> packed means it has to do bytes but volatile means every access is observable ... damn.
<clever> there is a control reg to allow un-aligned access
<clever> but i opted to just memcpy the whole record, which fixes alignment
<mrvn> clever: and you bet that will be set to fault on unaligned access for me.
<mrvn> clever: geist mentioned that it was mandatory on ARMv7 or something.
mctpyt has quit [Read error: Connection reset by peer]
<bslsk05> ​github.com: rpi-open-firmware/mbr_disk.cc at master · librerpi/rpi-open-firmware · GitHub
<klange> ARMv7 is 32-bit, so my previous statement applies.
<clever> mrvn: from memory, the bytes on line 58, cause the 32bit field on 51/52 to be mis-aligned
<clever> but the struct on 36-53 itself, is internally aligned, so if i just memcpy the whole MbrPartition out, the alignment is fixed
<mrvn> 8 bytes, 4 shorts, 2 ints. That's all aligned in MbrPartition. But then it's used with 2 byte offset *BOOM*
<clever> yep
<clever> and you can blame MBR for creating that mis-alignment
<mrvn> Couldn't put the mbr_sig before the parts?
<clever> changing any of the layout would break its ability to read a real partition table
<mrvn> back when they first made this obviously.
<mrvn> nobody ever has a data bus > 8 byte. ever.
<clever> i think it was only using 16bit offsets back then?
<mrvn> alignment, tzzzz
<mrvn> there is a reason for the "#if 0"
<clever> i assume thats to deal with the mis-alignment in another way, do 16bit aligned reads, and then re-assemble
<clever> from when this was in another codebase
<mrvn> exactly. That would be the fastest way without copy.
<bslsk05> ​en.wikipedia.org: Master boot record - Wikipedia
<clever> ah yes, LBA is a new addition
<clever> originally, it was all done using the CHS system
<mrvn> for some definition of new
<clever> yeah
<mrvn> CHS died with disks > 518MiB.
<clever> yeah, that "new" system, lol
<mrvn> remember when harddisk had numbers?
<clever> i remember having to brute-force the CHS config in the bios, when the hdd wasnt labeled
<mrvn> You go into the bios and you don't set a size or CHS, you said: This is disk type 21.
<clever> which makes me wonder, i didnt re-implement this when switching over to LK
<clever> how did geist solve this?
<mrvn> C §6.7.2.1, paragraph 3: "A structure or union shall not contain a member with incomplete or function type,… except that the last member of a structure with more than one named member may have incomplete array type; such a structure (and any union containing, possibly recursively, a member that is such a structure) shall not be a member of a structure or an element of an array."
<mrvn> clever: probably memcpy too
<bslsk05> ​github.com: lk/partition.c at master · littlekernel/lk · GitHub
<clever> mrvn: and the outer struct for the whole sector, is just missing
<clever> it just copies the records of interest in one sweep
<klange> mrvn: yay, a smoking gun
<bslsk05> ​github.com: rpi-open-firmware/mbr_disk.cc at master · librerpi/rpi-open-firmware · GitHub
<clever> mrvn: but i choose to copy one record at a time, in a for loop
<clever> i feel like LK's method is maybe a bit more efficient, copying more at once, but uses more ram
<clever> i'm probably just ricing my ram usage too much :P, my code already has the ram controller on by this point
<mrvn> does it matter? You can't plug in USB sticks fast enough to make this measurable.
<clever> for my codebase, this is only ran on bootup
<clever> so this impacts how fast the system boots
<mrvn> clever: do you have to copy all 4 structs? Don't you exit early when the first struct is bad and then safe time?
<mrvn> and how many cpu cycles does it take for copy those 64 bytes?
<clever> ....
<clever> i'm not even using the copied MbrPartition
<clever> what?
<clever> the only thing it does, is print the partition table
<clever> how is this even working?
<mrvn> If you want inefficient: Every time you need to lookup anything in the DT I parse it from scratch till I find the node.
<mrvn> err = bio_publish_subdevice(device, subdevice, part[i].lba_start, part[i].lba_length);
<clever> yeah, thats how LK did it
<clever> but back in mbr_disk.cc, which i was modifying
<mrvn> Oh, your code. No idea. Does it maybe just assume there is a FAT at a fixed offset on the disk?
<clever> MbrPartition& p = mbr->mbr_part[volume];
<clever> return mmc->read_block(p.part_start + sector, buf, count);
<clever> nope
<clever> ah, its reading it in 2 places
<mrvn> unaligned?
<clever> line 130, will read the entire MBR, into `Mbr* mbr` (a member variable on a class)
<clever> for for loop i linked, printf's things, and for some reason did unaligned 32bit loads when -O'd, so it needs the memcpy
<clever> but line 123, is doing an add, and gcc decided to do byte-wise loads for that
<clever> so i never fixed it, lol
<clever> mbr_disk.cc, implements a read-block function, that takes a partition#, sector#, and sector-count
Vercas7 has joined #osdev
<clever> but LK instead uses bio_publish_subdevice to create new block devices, that function like how sda1 functions in linux
<clever> enforcing the offset and new size as you would expect, and otherwise looking like any other block device
<clever> so you can skip partition tables if you want, without changing the api entirely
vdamewood has quit [Read error: Connection reset by peer]
Vercas has quit [Ping timeout: 240 seconds]
Vercas7 is now known as Vercas
<clever> LK is designed much better in that aspect
vdamewood has joined #osdev
<mrvn> indeed
<clever> the only problem ive run into with LK's design, is that it assumes a filesystem lives on a single block device
<clever> and there is no way to iterate over all block devices
<mrvn> no raid linear driver?
<mrvn> LVM?
<mrvn> aka device mapper
<clever> and no zfs
<mrvn> well yeah, licensing issues and complexity
<clever> raid and lvm, are possible, because those arent filesystems
<clever> you just open each bio by name, and register a new combined bio
<clever> zfs is the problem, because its both raid and fs
<mrvn> then your filesystem on two disks is just fs over raid
<clever> static status_t mount(const char *path, const char *device, const struct fs_api *api) {
<bslsk05> ​github.com: lk/fs.c at master · littlekernel/lk · GitHub
<mrvn> zfs has a fs and raid layer too, just interally
<clever> this function takes the block-device name (as a string), opens the BIO for you, then passes the BIO handle to the fs implementation's mount function
<clever> so you have no way to pass extra data to the mount
<clever> and no way to mount a psuedo-fs
<mrvn> you can separate the fs and raid layers but there might be some loss of functionality
<clever> it likely wouldnt even work
<clever> each pointer in the fs, includes a device-index on it
<kingoffrance> thats why i like freebsd geom, stack anything however you want. but then people tell me its not portable (meaning: noone ported it anywhere else)
<clever> to say which block device in the array its on
<mrvn> Your raid LINEAR the devices and then index * disk_size + offset
<clever> you cant just blindly raid all of the devices together, because the metadata doesnt treat it like that
<clever> the disks can be of mis-matched sizes
<mrvn> You have the pool metadata
<mrvn> I would actually just concat all the disks and let zfs pick them apart based on metadata again.
<clever> but you cant know where the 2nd disk starts in that mess
<mrvn> Keep the raid layer insíde the FS.
<clever> because the 1st disk may not occupy the entire block device
<mrvn> clever: first block of the raid is virtual and tells you or something.
<clever> if the device had been expanded, but the zfs not
<mrvn> basically a partition block where each partition is a disk.
<clever> the other problem, is that you have no way to iterate over all block devices in the system
<clever> now your describing pistorm, lol
<mrvn> that might be a bigger problem
<clever> each real MBR partition on an SD card, gets advertised to amigaos, as a seperate emulated disk
<mrvn> can a disk be resized?
<clever> yes, but only bigger
<mrvn> means you can probably hot-add the zfs disks to a pool device as you detect them.
<clever> you have no way to iterate over block devices in LK
<mrvn> can a disk in LK be resized
<clever> so you have to just know the bio name
<mrvn> the bio name is part of the zfs metadata
<clever> good question
<mrvn> get one and you have the rest
<clever> zfs doesnt really work like that
<clever> its entirely uuid based
<mrvn> not entirely.
<clever> your supposed to just scan all block devices, find the pieces, and put them back together
<mrvn> supposed to. but there is also a device path stored.
<clever> yeah
<clever> i think thats kinda there for auto-rebuilding
<clever> when a given path maps to a physical bay on the system
<mrvn> More for errors so you know which SATA port is missing a disk when you are short.
<clever> and if you replace the disk, the system can assume it should take the same role
<mrvn> nod
<clever> linux dynamically assigns all sata device names, so if sdb is missing, sdc just becomes sdb
<clever> if it was missing at-boot
<mrvn> That's why the FAQ says to use /dev/disk/by-path/
<bslsk05> ​github.com: lk/bio.h at master · littlekernel/lk · GitHub
<clever> LK expects you to define the size at creation
<clever> and probably wont be happy with the size changing
<mrvn> well, size = (~1)LLU
<clever> do you have the pdf i linked above open?
<mrvn> but you probably can't add more bios to the raid device later on too
<mrvn> No
<clever> it explains nearly everything about zfs
<mrvn> read ir or the same somewhere else
xenos1984 has quit [Read error: Connection reset by peer]
<clever> on page 8, is the details of the layout for a single vdev
<clever> each vdev has 4 duplicate copies of the vdev label, 2 at the head, 2 at the tail, each 256kb in size
<clever> each has a 16kb hole at the front, so partition tables can overlap with the vdev itself
<clever> then 112kb of name/value pairs, that describe the vdev tree, for reconstructing the array
<clever> and then 128kb of uberblocks, each one rounded up to 2^ashift bytes
<clever> i believe each time you sync a txg, it has to write the new uberblock, to all 4 labels, on every disk in the array
<clever> but fsync() from a userland app, can skip that, and just append to the ZIL (a type of journal) instead
<clever> upon recovery, it can just replay that journal
X-Scale` has joined #osdev
X-Scale has quit [Ping timeout: 256 seconds]
X-Scale` is now known as X-Scale
xenos1984 has joined #osdev
<geist> Yah if LK ever wanted FSes to span more than one device will probably need another mechanism
<geist> Or it’s the responsibility of the FS to scan the devices
<geist> Which may be what Linux does, i dunno
<geist> For btrfs at least you can mount on any sub device and it finds the rest
<geist> Presumably there’s some copy of the superblock on each of them
<clever> yeah
<clever> for zfs, the userland tools scan every block-dev in a directory (like /dev/disk/by-path) and checks for superblocks in the same pool
<clever> and i think it then passes an open file-handle for every device in the pool to a syscall
<clever> but LK both blocks iterating over devices, and inserting your own fs_mount into the mounts array
<clever> static struct list_node mounts = LIST_INITIAL_VALUE(mounts);
<clever> if this was public, or there was a function to append my own fs_mount into it, then i could create an fs_mount via my own api, passing it all BIO's involved
<clever> and bypass the existing fs_mount
* geist nods
<geist> Is this a feature you actually need?
<clever> not yet, i havent written a single line of code towards zfs support
<geist> Add it when you need it
<clever> and i lack usb support, so the 1 SD card is all i can read
<geist> It is The Way
<clever> so any zfs pool i would be importing, would be limited to 1 vdev anyways
<clever> so even when i do implement zfs, this problem wont exist until i also get usb-host support
<clever> mdadm and lvm wont have this issue, because they arent filesystems
<clever> i can just open every BIO child device, and register a new virtual BIO for the sum
Clockface has quit [Ping timeout: 240 seconds]
sonny has joined #osdev
pretty_dumm_guy has quit [Quit: WeeChat 3.4]
[_] has joined #osdev
[itchyjunk] has quit [Ping timeout: 240 seconds]
sonny has quit [Quit: Client closed]
rustyy has quit [Quit: leaving]
rustyy has joined #osdev
[_] is now known as [itchyjunk]
<kazinsal> geist: hey, do you remember how you set up scsi2sd for your vax? all my various bits have finally arrived but I'm having difficulty finding the device names etc I need to send for a CD-ROM device
srjek has quit [Ping timeout: 260 seconds]
ElectronApps has joined #osdev
ravan has joined #osdev
<klange> [cat reading newspaper] I should set up a VDSO...
<klange> Thinking about how I do signal return and thread exit, which is that I inject return addresses I expect to fault on, and... I mean, it's worked okay, I guess, but it's a bit too magic.
xenos1984 has quit [Remote host closed the connection]
xenos1984 has joined #osdev
eddof13 has joined #osdev
bradd has quit [Read error: Connection reset by peer]
bradd has joined #osdev
xenos1984 has quit [Remote host closed the connection]
xenos1984 has joined #osdev
vdamewood has quit [Read error: Connection reset by peer]
vdamewood has joined #osdev
[itchyjunk] has quit [Remote host closed the connection]
eddof13 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
the_lanetly_052 has joined #osdev
<geist> kazinsal: iirc, everything on scsi are DUA0: DUA1: etc
<geist> SHOW DEVICES will scan everything
<kazinsal> oh, sorry, I meant for the scsi2sd to report the device type as
<geist> oh hmm. i dont remember using any particularly funny settings
<geist> and i think the strings dont matter at all
<geist> you said for cdrom device, the disk LUN works?
<kazinsal> haven't booted it up yet, actually, getting the thing really going is tomorrow's project
<j`ey> kazinsal: you have your vax??
<geist> iirc when i tried to set up an emulated cdrom i simply copied the iso directly to a scsi disk, or an emulated scsi disk and the vax firmware didn't seem to care that it was an actual one
<geist> one of the firdt times i installed VMS on it i simply wrote the iso to a 2GB SCSI drive i had laying around, set that as ID 1 and installed onto another disk at ID 0
<geist> i think it was just BOOT DUA1: (the cdrom) and it didn't care the iso wasn't on a 2k device
<kazinsal> j`ey: yep. it's still packaged up because I've had a long day and I don't feel like cleaning up my workbench at midnight, haha
<geist> and i think i was able to basically do the same thing with a netbsd iso
<kazinsal> oh, nice
<kazinsal> so the firmware doesn't care about the actual device type. rad
<geist> only after fiddling with it a while did i get a scsi2sd but i do remember fiddling with it and using separate LUNs for iso and whatnot
<geist> yah i remember being kinda surprised
<j`ey> kazinsal: woot, finally!
<geist> the firmwre is pretty robust
Payam90 has joined #osdev
<kazinsal> hrm. whoops. don't have an SD card reader for my desktop. guess I need to use my macbook, heh
<kingoffrance> first someone has an older qemu than me, then you are missing a $1 or less microsd to usb stick........these are end times
eschaton has quit [Remote host closed the connection]
the_lanetly_052 has quit [Ping timeout: 256 seconds]
knusbaum has quit [Ping timeout: 256 seconds]
knusbaum has joined #osdev
ravan has quit [Remote host closed the connection]
bauen1 has quit [Ping timeout: 256 seconds]
nick64 has joined #osdev
ElectronApps has quit [Remote host closed the connection]
eschaton has joined #osdev
bauen1 has joined #osdev
lkurusa has joined #osdev
Vercas7 has joined #osdev
Vercas has quit [Ping timeout: 240 seconds]
Vercas7 is now known as Vercas
gog has quit [Quit: byee]
gog` has joined #osdev
gog` is now known as gog
dormito has joined #osdev
ElectronApps has joined #osdev
GeDaMo has joined #osdev
mlombard has quit [Ping timeout: 250 seconds]
Burgundy has joined #osdev
Electron has joined #osdev
ElectronApps has quit [Read error: Connection reset by peer]
ElectronApps has joined #osdev
Electron has quit [Ping timeout: 256 seconds]
Scripted has joined #osdev
<Scripted> I'm back
Jari-- has quit [Ping timeout: 240 seconds]
<bslsk05> ​'Win - You've Got The Power' by yossarian (00:03:26)
<bslsk05> ​'Hello Boys I'm Back' by Allan Carrington (00:00:14)
nick64 has quit [Quit: Connection closed for inactivity]
dormito10 has joined #osdev
dormito has quit [Ping timeout: 252 seconds]
dennis95 has joined #osdev
<gog> i'm front
<bslsk05> ​'qg4sy3t4yvl81' by [idk] (--:--:--)
<kazinsal> I'm top
<gog> same
<kazinsal> UwU
<gog> OwO
<mjg> PwP
<kazinsal> XwX
<GeDaMo> ಠ_ಠ
Scripted has quit [Quit: WeeChat 3.4]
SikkiLadho has joined #osdev
xenos1984 has quit [Remote host closed the connection]
xenos1984 has joined #osdev
xenos1984 has quit [Remote host closed the connection]
xenos1984 has joined #osdev
dormito has joined #osdev
dormito10 has quit [Ping timeout: 272 seconds]
nyah has joined #osdev
SikkiLadho has quit [Quit: Connection closed]
Scripted has joined #osdev
<Scripted> mrvn: Should I implement paging instead of segmentation?
Scripted has quit [Quit: WeeChat 3.4]
Scripted has joined #osdev
SikkiLadho has joined #osdev
gog` has joined #osdev
wand has quit [Remote host closed the connection]
gog` is now known as gog
gog has quit [Killed (osmium.libera.chat (Nickname regained by services))]
Guest7627 has joined #osdev
zaquest has quit [Remote host closed the connection]
wand has joined #osdev
<mrvn> scripted: segmentation is absolutely dead. Forget about it.
zaquest has joined #osdev
epony has quit [Ping timeout: 240 seconds]
<Scripted> mrvn: Now writing a MM makes me completely lost. The tutorial on osdev wants me to draw diagrams on how my memory should operate. If I do so, I still have no idea on how to program all of this. https://wiki.osdev.org/Writing_a_memory_manager
<bslsk05> ​wiki.osdev.org: Writing a memory manager - OSDev Wiki
<Scripted> I feel like paging is a better way to start since it has a way more detailed article on osdev. https://wiki.osdev.org/Paging
<bslsk05> ​wiki.osdev.org: Paging - OSDev Wiki
<GeDaMo> This uses sbrk but it might be worth a look https://danluu.com/malloc-tutorial/
<bslsk05> ​danluu.com: Malloc tutorial
<GeDaMo> There are some references at the bottom
<Scripted> Okay, thanks
Ermine has quit [Quit: Bye-Bye!]
Ermine has joined #osdev
<Scripted> GeDaMo: This seems like an awesome tutorial, but I still have no idea on how to implement sbrk and even doing so isn't recommended.
<GeDaMo> sbrk / mmap are in the kernel
<Scripted> yes but my kernel doesn't support sbrk/mmap
<GeDaMo> They manipulate page tables
<GeDaMo> Does your kernel support any kind of virtual memory / separate process address spaces?
<mrvn> scripted: why are you still on this? I thought your goal was to write a tmpfs. That's kernel code and has nothing to do with sbrk, mmap or malloc.
<Scripted> mrvn: I don't know.. really. Don't you need malloc/calloc for tmpfs?
<Scripted> Sorry, I'm so confused
<mrvn> You need some form to allocate memory. But that is a totaly different thing when you are in kernel and want to use paging.
<Scripted> mrvn: So I need to implement paging?
<mrvn> Yesterday I suggested to simply make everything use a page even if it needs less memory. Then all you need in the kernel is a function to allocate single pages.
<Scripted> Is there an article on osdev about this?
<mrvn> If you want paging then yes. Don't use any memory that isn't paged. If you don't want to use paging at all you can treat physical memory as a big heap and use malloc.
<Scripted> Yes but for malloc I need sbrk/mmap
<mrvn> scripted: nah, you initialize the memory pool with physical memory. The kernel owns all memory, it doesn't have to ask for it with sbrk/mmap.
<GeDaMo> malloc is a user level function, not kernel
<Scripted> oh
<Scripted> I really apprechiate your suggestions, but I have no clue on how to code all of this
<mrvn> scripted: Normaly malloc is a user space thing. So it has to beg the kernel for a big blob of memory first and then it cuts this into little parts. But in the kernel you take the memory from the memory map you get from the bios or bottloader.
<Scripted> How do I take memory from the memory map?#
<mrvn> Have you parsed the memory map? printed it out to screen?
<Scripted> No
<j`ey> scripted: have you got any code?
<Scripted> No
<GeDaMo> On the plus side, no bugs :P
<mrvn> Well, something too look into. Maybe start with writing something that just prints "Hello, world!" on the screen. That is hard enough.
<Scripted> No, that's not I mean lol
<Scripted> I have a functional kernel
<Scripted> I just haven't started with memory
<j`ey> is it online?
<Scripted> yes
<bslsk05> ​ScriptedDeveloper/CrazeOS - An amateur work-in-progress OS written from scratch! (0 forks/1 stargazers/GPL-3.0)
Brnocrist has quit [Read error: Connection reset by peer]
Brnocrist has joined #osdev
<SikkiLadho> in arm64, SMC instruction takes an immediate, but what if the fid is stored in a register, how would I call smc on the value stored in x0?
<j`ey> fid?
<j`ey> you have to do if (x0 == 0) smc #0 else if (x0 == 1) smc #1, I guess
<mrvn> SikkiLadho: most people don't use the immediate and only have one call that ignores the immediate
<j`ey> and that ^
<mrvn> You could mix it up. imm==0 means the real number is in X30 (or whatever is the asm scratch register). Otherwise it's the imm.
<mrvn> I see on aarch the #imm is in the Exception Syndrome Register. SO it's actually usable. On ARMv7 you have to fetch the opcode and bit mask the immediate out of it. Which makes it horrible.
<SikkiLadho> mrvn if i ignore the immediate, assembler gives me the " Error: missing immediate expression..." error
<mrvn> SikkiLadho: set it to 0. I ment to ingore it in the execption handler.
<SikkiLadho> thank you.
<mrvn> How come you have the syscall number in a register?
<mrvn> Meta programming with callbacks?
<SikkiLadho> I think i slipped. I'm trapping exceptions at hyperviosr. At first, I just want to trap the exception, and make the same smc call from hypervisor and then eret.
ElectronApps has quit [Remote host closed the connection]
<mrvn> Hmm, that's bad then. you need to pass the imm through then.
<mrvn> Guess you need to use < j`ey> you have to do if (x0 == 0) smc #0 else if (x0 == 1) smc #1
<SikkiLadho> okay, let me try
<j`ey> pretty sure linux only uses hvc #0
<mrvn> I assume you have a small table of allowed hypervisor calls?
<mrvn> If it's more than 2 use switch/case and check if you get a jump table.
<SikkiLadho> I'm still just learning in the process with trial and error, so I don't know a lot YET. I have setup an exception vector, passed the vector address to vbar_el2, set the HCR_EL2.TSC to 1, and printed something to check if the exception was trapped, which it did.  Now I want to make the same smc call and eret, so see if it doesn't break linux
<SikkiLadho> runnning at EL1.
srjek has joined #osdev
ZipCPU|Laptop has joined #osdev
<ddevault> hm, once I have a VESA framebuffer is the old BIOS text console no longer presumed valid
<mrvn> SikkiLadho: have you printed the Exception Syndrome Register? Is the imm==0 as j`ey suggested?
<mrvn> ddevault: if by valid you mean visible then yes.
<ddevault> not visible
<ddevault> nevermind, I need to narrow down my problem more
<mrvn> ddevault: In linux you can switch back between text mode and graphics. The text mode is totally valid just not visible.
<GeDaMo> Are there any guarantees about a VESA buffer overlaying old PC video memory?
<mrvn> I would say it's garanteed not to. Modern screen resolutions are to big for it to fit below 1MB.
<ddevault> weirdly it's full of ÿ when I add the _FB flag to multiboot
<mrvn> And by modern I mean those low resolution VESA modes.
<ddevault> this is what's weird
* ddevault shrugs
<mrvn> what address do you get for the FB?
<ddevault> whatever multiboot provides
<mrvn> and that is?
<ddevault> let's see
epony has joined #osdev
<ddevault> 0x69622e746f6f622f
<ddevault> that is a bizzare address
<gog> looks like opcodes
<ddevault> maybe my multiboot struct is wrong
<gog> or maybe ascii
<ddevault> yeah that is probably it, it's not packed
<mrvn> it's non-cannonical
lkurusa has quit [Quit: I probably fell asleep (or went out). Who will ever know.]
<GeDaMo> ib.toob/
<GeDaMo> Hmm ... :P
<GeDaMo> Maybe 'convert hex to ASCII' could be a useful tool to add to bslsk05
SikkiLadho has quit [Quit: Connection closed]
* kingoffrance .oO( makes note to use ascii noob saibot as canary, and add toasty! on kernel panic )
<ZipCPU|Laptop> I'm trying to evaluate the critical differences between unikernels, microkernels, and monolithic kernels prior to building my own OS. I think I've already judged that I don't want a unikernel, since I'd like to be able to load and run programs (and/or device drivers) at run time that were not previously planned.
<ZipCPU|Laptop> That leads me to the next kernel type I'm looking at: Microkernels.
<ZipCPU|Laptop> Those seem to be ideal from the minimalist implementation perspective. They seem to have the smallest amount of code required to build them, while suffering from a challenge in inter-process communication.
<mrvn> ZipCPU|Laptop: No such thing. All practical kernels are hybrids.
<ZipCPU|Laptop> mrvn: Maybe, but I'm just starting my journey ... I'm still at the simple point.
<ZipCPU|Laptop> ;)
<mrvn> ZipCPU|Laptop: For microkernels imho the main point is to encapsulate subsystems of the kernel as their own processes. This adds safety at the cost of having to to system calls to call other subsystems.
<ZipCPU|Laptop> I'm trying to look at it from a software encapsulation standpoint, not just safety
<ZipCPU|Laptop> Which kernel would be easier to modify and/or adjust with new features as time goes on?
<mrvn> If you take a monolitic kernel and transform all function calls and getter/setter calls into IPC then you have a microkernel.
<mrvn> ZipCPU|Laptop: that depends more on your design than the choice of kernel type.
<ZipCPU|Laptop> Sigh. Here I thought the choice would be simpler/easier, yet I do know that Linux supports module loading/unloading--an encapsulation feature--without being a microkernel.
<mrvn> ZipCPU|Laptop: I always recommend a microkernel because when you mess up you will get cpu excetions telling you so for many cases where a monolithic kernel would just corrupt memory and go on.
<mrvn> Look at module loading as late binding. It doesn't really change the kernel design, it's just a delayed loading.
<ZipCPU|Laptop> So, that's a good start. Hence, if a file system under test fails, you'd at least get a message to that extent w/o necessarily crashing the entire O/S
<mrvn> And if your design is good you could just restart the FS.
<ZipCPU|Laptop> (Fingers crossed)
* ZipCPU|Laptop ponders the "late binding" comment
<ddevault> well, it wasn't that
<mrvn> You can track all the resources the FS uses, like the block device it opens. So when it crashes the microkernel can release the block device just like you do with user processes. With a monolitic kernel you usualy don't have this tracking. Or the tracking data can be overwritten.
<ZipCPU|Laptop> Got it.
<ZipCPU|Laptop> So, digging into microkernels, the entire discussion seems to focus on the cost of IPC
<ZipCPU|Laptop> As an example of IPC (just to see if I have this right), let U be the user process, K be kernel mode, FS be file system, D be device driver, INT be an interrupt, then fread would require: U->K->FS->K->D->K (INT) -> K ->D -> K -> FS -> K -> U
<ZipCPU|Laptop> At issue is every context switch from user space to kernel space and back, no?
<ZipCPU|Laptop> So, as a CPU designer, should I be paying a lot of attention to the cost of that swap?
<mrvn> unless the hardware has a way to shortcut the move through K
<ZipCPU|Laptop> Right now, moving from U to K and back costs about 5 clocks each. That is, until you deal with the cache and swapping user registers to activate a new/different user context.
<ddevault> it would help if I had checked if the bootloader had even set up an fb
<ZipCPU|Laptop> Switching contexts requires saving registers (somewhere), and then loading user registers from somewhere else. That would seem to be the most expensive part.
<mrvn> the ->K transition is usually cheap. like SYSCALL on amd64. The switch out of K is expensive because you have to reload page tables and flush everything. ASID helps there.
<mrvn> saving registers I consider cheap. That's just copying a few bytes of data. It's the flush that kills you.
* ZipCPU|Laptop googles ASID
<ZipCPU|Laptop> What if the flush cost you only a pointer change? Load a new page table pointer into the MMU, and then the MMU handled loading pages as needed from wherever that pointer pointed to?
<mrvn> ZipCPU|Laptop: The flush removes all the TLB entries. Every access after it will have to walk the page tables.
<ZipCPU|Laptop> But if that's done in/by hardware, that'd be much faster, no?
<j`ey> it is done by HW
<ZipCPU|Laptop> If the hardware, not the CPU, can do the page table lookup?
<ZipCPU|Laptop> Oh.
<mrvn> it's still awfully slow compared to the TLB.
<ZipCPU|Laptop> I remember reading once that pages in Linux where always 1MB. Is this still the case? If so, wouldn't it take a while to need more than one page table entry when swapping?
<mrvn> pages are 4k or 8k with options for bigger ones.
<mrvn> The kernel itself might be mapped with bigger pages. But the kernel would be mapped global and not get flushed anyway.
<ZipCPU|Laptop> Okay, that helps explain things.
<ZipCPU|Laptop> So everytime the new task accesses something outside of its 8kB (or whatever), you have a minimum of a page fault and a page lookup.
<mrvn> That's actually something I do in my micro kernel. All code and rodata is mapped globally. So no TLB misses when switching between drivers because code is missing.
<mrvn> Access to data will cause a TLB miss though.
<ZipCPU|Laptop> Ok. Got it.
<ZipCPU|Laptop> And just to double check, the microkernel approach requires the MMU, right?
<mrvn> Would be pointless without it.
<ZipCPU|Laptop> Heh. Okay, got it. Thanks.
<ZipCPU|Laptop> This'll at least give me some thorough insight regarding what I need to do in order to build a better MMU than the (unusable) one I have.
<ZipCPU|Laptop> (Why was it unusable? 'cause I could never integrate it properly with the rest of the CPU--that should be a good reason.)
<gog> you can limit the effect of a tlb flush on kernel pages with PGE or asid
<gog> but going back to userspace on a full context switch it'll be trashed and have to do the page table walks again
* ZipCPU|Laptop tries to google pge, get PG&E tariffs ...
<ZipCPU|Laptop> PG&E Electric and Gas Service ...
<gog> page global extensions
<ZipCPU|Laptop> Thanks
<mrvn> ZipCPU|Laptop: In a microkernel the kernel should handle multitasking and IPC and imho memory. Everything else are processes.
<gog> it tells the tlb not to flush an entry when the paging context is changed
<mrvn> ZipCPU|Laptop: the PGE (or G on other arch) bit in the page table not to flush the TLB entry for this on switch.
<ZipCPU|Laptop> mrvn: From a UV lecture I was reading, the microkernel needs to handle processes, process swaps, interrupts, message passing, and the scheduler, no?
<ZipCPU|Laptop> Ah, thanks
<mrvn> processes, process swaps, scheduler == multitasking
<ZipCPU|Laptop> Well, that leads to another question I had. What constitutes a minimal "operating system"?
<mrvn> interrupts go into the kernel too, no way around that. But then you can redirect that to processes. So yeah, forgot irqs in the list.
<ZipCPU|Laptop> I mean, what's the minimum functionality that needs to be demonstrated in order to declare that you've even built one?
<mrvn> L4 has 5 syscals.
<ZipCPU|Laptop> *ONLY* five? Wow.
<clever> sendmsg, recvmsg, createproc, exit, memory?
gog has joined #osdev
<clever> but i can see how most of those could just be messages passed to the kernel
<mrvn> Think about the things you listed. What do you need for those? frok(), exit(), alloc_mem(), free_mem(), set_irq_handler(), yield/sleep/send_msg/read_msg which would be one syscall.
<clever> that would be 6 then?
<ZipCPU|Laptop> I think the minimum of what I would need would be multi-process, creation/destruction in real time, and the full C library. I can get much of C library from on line sources, but ... still need to figure out how to map the back end of the kernel
<ZipCPU|Laptop> Wouldn't a semaphore request require a system call? Something like (sleep until specified resource is available)?
<mrvn> ZipCPU|Laptop: I have a libutils that is mapped into every processes address space.
<mrvn> Studd like memcpy(), strlen(), ....
<clever> mrvn: but couldnt you also make fork/alloc/free/set-irq all a message you just pass to the kernel?
<mrvn> clever: yes. you can just have one send_get_msg() syscall that does everything. Will it be the fastest?
<clever> yeah, that could slow those down
<mrvn> Probably faster to have a alloc() syscall than having to parse messages.
<ZipCPU|Laptop> Might depend on how the case statement is written in the kernel to process the syscall
<clever> mrvn: that sounds like just sharing the libc.so .text between multiple procs
<mrvn> clever: yep
<clever> this also reminds me, about how dynamic linking is done on windows
<clever> all calls to external symbols, are done via a GOT (global offset table)
* ZipCPU|Laptop hears the words "dynamic linking" and screams.
<clever> each dynamic object (the exe, and each dll) has its own GOT
<clever> so when objects are relocated to different addresses in each proc, the .text can still be shared
<clever> and only the GOT is unique to each
<ZipCPU|Laptop> Wouldn't that normally be handled on the final linking during loading?
gareppa has joined #osdev
<ZipCPU|Laptop> Why retain a global offset table that needs to be ... adjusted on every use?
<clever> ZipCPU|Laptop: yeah, but if the linker patches every call opcode, then half your .text is unsharable
<clever> and your memory usage goes up
<mrvn> ZipCPU|Laptop: In my kernel I don't even have threads. Everything is designed like a car factory. I don't share any data, I pass data around between processes.
<ZipCPU|Laptop> So ... is the issue the library, not the user code?
gareppa has quit [Remote host closed the connection]
<clever> by having every call indirectly go thru a lookup table
<clever> you can pack all of that patching into a single page
<mrvn> ZipCPU|Laptop: So you don't have a semaphore that you wait on. You wait on an IPC message containing data.
<ZipCPU|Laptop> In order for the library to make calls to its own processes, not knowing where they are, it uses a GOT?
<clever> yeah
<ZipCPU|Laptop> But the user process only gets mapped once, so it doesn't need the GOT?
<mrvn> ZipCPU|Laptop: are you confusing the GOT and the PLT?
<ZipCPU|Laptop> Quite possibly.
<clever> mrvn: possibly
<clever> ZipCPU|Laptop: but if you reuse a given dynamic library in 1 processes, you can now share the pages backing the .text between 2 procs
sonny has joined #osdev
<clever> but that also requires a kernel capable of mmap, which isnt in the list of syscalls mrvn gave earlier
<mrvn> Afaik and simplified the GOT is just a list of constants too big to use immediates. The PLT is where the dynamic linking magic happens.
* ZipCPU|Laptop Googles PLT, discovers women's fashion and apparel from PrettyLittleThing USA
<clever> ZipCPU|Laptop: try "PLT patching" ?
<ZipCPU|Laptop> clever: Thanks, that's getting me closer
<bslsk05> ​www.technovelty.org <no title>
<mrvn> Every dynamic library call goes code -> PLT -> code. And then there is some magic that you start with the PLT pointing to a function that actually looks up the proper function in the libraries. That then modifies the PLT at runtime so the next call jumps to the right code directly.
<mrvn> The point of the PLT is that you have a) only one point you have to patch, b) all the parts that get written too in one segment of memory.
<clever> and i only know about this part of windows, because i was patching the PLT at runtime, to call my own routines
<clever> so i could hijack various functions
<clever> the goal, was to have the music i was listening to auto-pause if somebody spoke on ventrilo, and it was closed source
<clever> but it was using directx for the audio path and i never solved that issue
<mrvn> no LD_PRELOAD on windows?
<clever> i couldnt find one at the time i looked
<clever> that is also why i never learned how linux does it
<clever> LD_PRELOAD solves the entire need
<mrvn> it just loads that dynamic library first so it gets first spot in the symbol table.
<mrvn> First one to declare a symbol during loading gets everyone else calling it.
<clever> yep
gog has quit [Quit: byee]
Guest7627 is now known as gog
mahmutov has joined #osdev
masoudd has joined #osdev
xenos1984 has quit [Remote host closed the connection]
xenos1984 has joined #osdev
kkd has quit [Remote host closed the connection]
kkd has joined #osdev
dormito has quit [Ping timeout: 272 seconds]
ThinkT510 has quit [Quit: WeeChat 3.4]
ThinkT510 has joined #osdev
SikkiLadho has joined #osdev
sonny has quit [Quit: Client closed]
<SikkiLadho> I'm trapping smc calls from EL1(linux kernel) at EL2. How would I pass through all smc traps?
<j`ey> dont trap them?
<SikkiLadho> hahaha
<SikkiLadho> Actually, I'm waiting for linux to make an psci smc
<mrvn> SikkiLadho: scroll up. we already discussed this today.
<SikkiLadho> I will pass through all SMCs except the psci_cpu_on
<SikkiLadho> Thank you, I will look into it.
dennis95 has quit [Quit: Leaving]
<mrvn> 15:34 < SikkiLadho> in arm64, SMC instruction takes an immediate, but what if the fid is stored in a register, how would I call smc on the value stored in x0?
<mrvn> short memory
<j`ey> SikkiLadho: try: echo 0 | sudo tee /sys/devices/system/cpu/cpu1/online, that should hopefully get you a PSCI SMC
epony has quit [Read error: Connection reset by peer]
epony has joined #osdev
<clever> j`ey: i assume that requires DT to define core-1 as being controlled by PSCI first
<SikkiLadho> I modified the DT to change the enable method to psci and delete the release-addr prop.
<j`ey> clever: yes
<j`ey> SikkiLadho is using trusted firmware
<SikkiLadho> j`ey that should generate an psci smc, which will be trapped at el2(hypervisor), How should I pass it throught to TF-A?
<j`ey> execute an smc from el2
<SikkiLadho> After the hypervisor runs, it is stuck in the trap handler.
<j`ey> thats what we talked about earlier
<SikkiLadho> I executed smc, and should I also eret?
<mrvn> The EL3 will return to you after the smc. you then have to return to EL1.
<SikkiLadho> I tried both and it is stuck, but I can print to confirm that smc calls are being tapped.
<mrvn> print before and after
<SikkiLadho> mrvn, so just eret instruction will return to el1 or should I save the return address and move it elr_el2 before eret?
<mrvn> SikkiLadho: that's beyond me. Haven't reached execeptions and hypervisor in aarch64 yet.
<j`ey> ELR_EL1, if youre enterring EL1 again
<SikkiLadho> when I trap the smc, where should be the return address to el1? Therefore, I can save it.
<clever> you also need to properly translate things
<clever> when the guest does an SMC to turn a core on and start running code at a given pc
<clever> you need to run from that pc, on that core, in EL1 mode
<clever> but if you just blindly forward the SMC, it will probably be running in EL2
<clever> so, you need to parse the smc, understand what it means, then issue your own smc to psci, saying to run your hypervisor entry-point on that core
<clever> then eret down to EL1, at the PC the guest said
<mrvn> clever: isn't het still trying to get all the other hyper calls to work as passthrough?
<clever> probably?
<clever> but core on/off calls, must be handled properly, or your right back to the problem from a week ago, where the core's start in the wrong mode
<mrvn> skipwich: where are you add? What works and what doesn't?
<mrvn> SikkiLadho: ^^
dormito has joined #osdev
<SikkiLadho> clever, thank you. since smc fids are stored in x0, I will separate the logic to handle the SMCs by PSCI_CPU_ON smc calls and the rest of the calls. But first, I'm trying to just pass through the smc calls to see if it's working. Once I'm able to pass through all the smcs and linux is working as before,  I would then handle the PSCI_CPU_ON smc
<SikkiLadho> separately. step by step.
blockhead has quit []
<SikkiLadho> because all smc calls are being trapped, not just ones to wake up the secondary cpus, I guees?
<clever> yeah
<clever> and each probably has to be handled specially
Payam90 has quit [Quit: Client closed]
<SikkiLadho> so PSCI_CPU_ON needs to be handles specially, but others need to be carefully passed through and eret to the location they were executed by linux.
<SikkiLadho> but when the smc is trapped, where would be return location so that we can eret it later?
<SikkiLadho> just focusing on smc calls other than PSCI_CPU_ON.
<SikkiLadho> It would great if someone pointed out to some docs, thank you.
JanC has quit [Read error: Connection reset by peer]
JanC has joined #osdev
<j`ey> SikkiLadho: ELR_EL2
<j`ey> that should contain the address to return to
<SikkiLadho> Thank you j`ey
<bslsk05> ​developer.arm.com: Documentation – Arm Developer
* geist yawns
<geist> good morning folks
<geist> SikkiLadho: if you're implementing PSCI you should definitely read the PSCI documentation which will amog other things describe the precise register ABI of the call
<geist> which registers must be saved, and not, etc
<geist> and *please* do it properly. i've already had to deal with one buggy implementation that took a long time to debug (would trash registers occasionally it wasn't supposed to)
<SikkiLadho> Thank you @gei
<geist> you do have the PSCI spec right?
<SikkiLadho> spec what?
<geist> that describes PSCI, the calling convetion, etc
<mrvn> I don't. url please.
<bslsk05> ​developer.arm.com: Documentation – Arm Developer
dude12312414 has joined #osdev
<bslsk05> ​developer.arm.com: Documentation – Arm Developer
<SikkiLadho> This one describes the psci
<geist> yep. good. iirc i dont think it's desvtibed anywhere else, but i believe all SMC/HVC calls are supposed to follow the same convention
<geist> there's a way the opcode space is carved up, and PSCI is ust part of it
<geist> so hypothetically if you deal with SMC calls the way PSCI says it you'll also properly handle things like trust zone calls
<geist> but also the calling convention is pretty close if not identical to the standard ARM64 ABI
dude12312414 has quit [Client Quit]
<mrvn> Does C still have no alignof()?
<bslsk05> ​en.cppreference.com: _Alignof operator - cppreference.com
<mrvn> Ups, I read that as (since c++11)
<geist> there you go
<geist> i kinda thought so but didn't want to look it up
<geist> kazinsal: soooooooo does it work?
RAMIII has joined #osdev
sonny has joined #osdev
<Scripted> If I use BIOS functions to detect available memory, how do I read that value?
<mrvn> it returns you a list of structs describing the memory map in som register
<mrvn> but use a bootloader.
<Scripted> well I use multiboot
RAMIII has quit [Quit: WeeChat 2.8]
<mrvn> the multiboot infos contain memory information
<Scripted> any documentation on that?
<sonny> Are threads the only concurrency that operating systems have?
<mrvn> the multiboot specs
<Scripted> yeah but how do I read those
<mrvn> no,
<mrvn> what are threads? Threads don't exist. It's C99.
<mrvn> ever heard of processes?
<kingoffrance> you sound like me. c89 aint got no threads
<sonny> mrvn right, you are on unix
<Scripted> Why can't I do this? : asm("INT 0x15, AX = 0xE881");
<sonny> ok cool, cooperative multitasking makes sense to me now
<mrvn> sonny: I believe the core concept in kernels in called a Task. As in multitasking.
<mrvn> Threads ad Processes are implementations that use the multitasking in different ways.
<GeDaMo> Does interrupt handling count as concurrency?
<mrvn> scripted: becasue that is not valid asm
<sonny> yeah
bliminse has joined #osdev
<mrvn> GeDaMo: No such thing but equivalent to signals.
<Scripted> How do I implement those BIOS functions then?
<bslsk05> ​wiki.osdev.org: Detecting Memory (x86) - OSDev Wiki
<GeDaMo> mov ax, 0xe881; int 0x15 at a guess
<mrvn> scripted: you are using grub. you don't need the bios
<Scripted> I don't use grub
<geist> scripted: the way multiboot hands you this is well documented
<mrvn> 20:05 < scripted> well I use multiboot
<geist> so what are you using that uses multiboot?
<Scripted> pure multiboot
<geist> qemu -kernel will do it too
<mrvn> grub or compatible.
<geist> what do you mean 'pure multiboot'?
<Scripted> exactly geist
<Scripted> I use qemu -kernel option
<geist> okay, so then the multiboot spec describes how it works
<Scripted> all right
<geist> it's an array of entries basically, passed to you
<Scripted> including grub?
bliminse has quit [Client Quit]
<geist> grub was the originator of multiboot
<Scripted> so the grub section is for me
<geist> think of multiboot as the spec for declaring your binary conforms to a loading mechanism, and multiboot also defines how the loader will give you args
<geist> multiple loaders implement multiboot, though grub is the defacto standard
<geist> qemu -kernel also does multiboot
<Scripted> ok, I will try it, thank you
amine has quit [Quit: The Lounge - https://thelounge.chat]
amine has joined #osdev
<geist> however if you want to make bios calls directly you have to jump through some hoops so you probably dont want to
<geist> specifically you can only make them in real mode and qemu has probably handed cotrol to you in 32bit protected mode (as grub would too)
<geist> really its the main reason multiboot hands you the memory map, because it's already done the work of making the bios calls and it gives it to you because it's hard to 'go back' to real mode
SikkiLadho has quit [Quit: Connection closed]
<Scripted> Why does multiboot.h use unsigned variables instead of those defined in stdint.h?
<mrvn> becasue it's from the last millenium
<Scripted> Should I change it?
<mrvn> I wouldn't change it. it's 3rd party code.
<Scripted> yes but it's gnu license
<Scripted> 2.0
<Scripted> and my OS uses the same license
<Scripted> well not the same, but it's compatible with the license mentioned in multiboot.h
<mrvn> Say they update multiboot in the future? Now you can't copy it into our source without loosing all your changes.
<mrvn> your source
<Scripted> not so sure if they are gonna update ancient code instead of re-writing it
<Scripted> and honestly, it's not much I'm changing
<Scripted> all I have to press is enter
sonny has quit [Quit: Client closed]
<Scripted> https://pastebin.com/raw/ZrmKrNMn that was it
sonny has joined #osdev
<Scripted> now at least it doesn't use unsigned variables
<Scripted> and those from stdint.h
<Scripted> *instead
nomagno has joined #osdev
<nomagno> I think I just accidentally created ##osdev. Did I break some rule or can I keep it?
<mrvn> you broke it, you bought it
<GeDaMo> Beware of the basilisk :|
<nomagno> ... That's not a clear answer
<Scripted> lol
<nomagno> I'm in charge of one of the fake largest IRC communities now, I guess. Everyone praise me or be banned!
<nomagno> oh wait, wrong channel this is the real one
<clever> lol
<clever> 2022-03-11 15:33:26 [libera] -ChanServ(ChanServ@services.libera.chat)- ##osdev is not registered.
<clever> chanserv says it isnt registered
<nomagno> Well I am in it right now. Might not be registered
<clever> thats just how irc works, the first person to join a room gets @
<clever> if you leave, the channel ceases to exist
<nomagno> It's the matrix bridge creating rooms that aren't necessarily connected to IRC, I guess
<nomagno> So I'm technically in an phantom room. Not much better.
<Scripted> question, why do some people have colorful names?
<GeDaMo> Define 'colorful'
<Scripted> blue
<Scripted> purple
<Scripted> green
<clever> irc doesnt support colors in names
<Scripted> what
<clever> its always something added by your client
<nomagno> Seems like your client trying to make remembering people more easyu
<GeDaMo> IRC clients often colour nicks to help distinguish between them
<Scripted> Well, I use Weechat
<nomagno> Mine does it too
<Scripted> For example, nomagno is colored
<Scripted> or mrvn is
<GeDaMo> ALthough there's another channel I'm in and there are three or four people whose colours are almost identical, very confusing :P
<Scripted> Maybe they're some admins?
<Scripted> mrvn: are you an admin?
<nomagno> Anyways, the thing I was trying to get here for. I need help from the elder council: How do 6052 emulators and any emulators that need to emulate real hardwaree actually implement consistent cycle/instruction timing!?
<mrvn> do I look like an admin?
<mrvn> nomagno: verry carfully or not at all
blockhead has joined #osdev
<nomagno> scripted: Like I said, that's your client generating color from the name hash
<clever> ChanServ is the only @ in this channel, every other user is just a normal user
<nomagno> mrvn: Well I assume console emulators have to do it somehow
<nomagno> Any recommendations for a readable opah sauce NES emulator?
<mrvn> wrong channel
<Scripted> nomagno no but like, some people have just normal white names
<Scripted> from 10 people maybe 2 have this colorful name
<GeDaMo> There are a number of emulator channels on Libera
<nomagno> scripted: because your client also colors them white
<nomagno> Wait...
* blockhead wants an abnormal white name? :D
<Scripted> most of them are white
<Scripted> like 80%
<nomagno> Uh, no idea
<Scripted> yours is for example bluish
<nomagno> confirmation bias. Let me make my spammerbot fleet join the channel
<nomagno> ... /s, if it wasn't clear
<Scripted> um ok
<Scripted> should be possible though
<GeDaMo> Is it possible it only assigns colours to nicks who've mentioned youre nick?
<nomagno> Well yeah but I don't want to get banned.
<nomagno> This is EFNet!
<nomagno> No anarchists!
<Scripted> find some email service (like any with api access) reverse their API, use the email service to register by using a python IRC client and blow 'em up
<GeDaMo> What colour is my nick to you?
<Scripted> wait, let me get my translator
<Scripted> it's turquoise
bauen1 has quit [Ping timeout: 240 seconds]
<GeDaMo> I don't think I've mentioned your nick so it's probably not that
<Scripted> why are all these people with their original IP on IRC?!?
<Scripted> this drives me crazy
<Scripted> like this bauen dude
<nomagno> Uh... You know, the IP is like, the least private part of the things that can be logged
<Scripted> nomagno what about ddos tho
<nomagno> scripted: firewalls
<nomagno> You know how most routers don't have all ports open?
<nomagno> yeah, that
<Scripted> they don't have to have all ports open
<Scripted> 1 is enough
<mrvn> Why do you believe that is their IP and why would they care?
<geist> yah if you join a new channel it ust makes it in IRC
<gog> mew
<Scripted> mrvn because this is a residential ISP
<geist> anyway, so there's an actual question in there, what is it?
* geist pets gog
* gog prrs
<Scripted> Kabel Deutschland is at least a residential one
<mrvn> scripted: No. That is a random NAT router of a ISP.
<clever> mrvn: only true for ISP's doing CGNAT
<Scripted> mrvn Kabel Deustchland is residential what do you mean?
<mrvn> clever: who doesn't unless you special order
<clever> mrvn: i never did a special order, and i get a real public ip
<Scripted> *Deutschland
<gog> þyskaland takk
<clever> mrvn: and my ISP is still in the dark ages of v4 only, lol
<mrvn> scripted: IPv4 are out-of-stock. ISPs can't give every customer their own IP anymore so they have routers with one IPv4 that handles multiple customers.
<Scripted> Ah
<Scripted> well, time to switch to IPv6
<Scripted> anyways
<nomagno> I'd be more worried about using IP addresses as a form of geolocation, but honestly the IPv4 address space can only get so precise. If you want to hide your administrative region and/or country and/or continent of residence you are doing so alreadyy
<nomagno> IPv6 is kinda too small too
<nomagno> There's a non-zero chance this shit is going to get interplanetary at some point.
<nomagno> That, or insanely overpopulated
<Scripted> does pushing EBX and EAX to the stack mean doing push EAX
<Scripted> push EBXy
<Scripted> oops
<nomagno> Both end up requiring a new mega-expensive upgrade
<Scripted> push EAX push EBX
<GeDaMo> Those are two separate instructions but yes
<Scripted> yes they are
<Scripted> I don't know how to paste code in IRC
<Scripted> except using pastebin
<GeDaMo> Use a paste site
<Scripted> Yeah dude not for 2 lines of ASM
<GeDaMo> Semicolons are often used to separate statements even for languages which don't use them
<Scripted> when you can't use separate lines?
<Scripted> or for every line
<GeDaMo> You can get the same effect as push eax; push ebx; by doing sub esp, 8; mov [esp], ebx; mov [esp+4], eax;
<Scripted> thats a stupid question
<Scripted> yeah I just noticed
<Scripted> using so much C and ASM drives me crazy
<Scripted> I remember using python a year ago
<gog> me: never code in C, also me: only codes in C
<GeDaMo> No take, only throw :P
<gog> yes
<geist> so is there an osdev question here?
<geist> seems like there was but we got off track?
<Scripted> nono there is one
<klys> direction to the local paste site
<Scripted> under which catagory falls kernel panics
<Scripted> under GDT/IDT?
<geist> what do you mean?
<Scripted> I think I'm confusing exceptions with kernel panics
<geist> yes. they're different things
<gog> a kernel panic is independent of exceptions
<Scripted> yeah
<geist> though an exception may cause a kernel panic
<gog> but an exception cna trigger a panic
<gog> lol
<Scripted> stop
<Scripted> my brain
<gog> geist and i are a hivemind
<GeDaMo> A kernel panic occurs when something happens that the kernel isn't able to handle
<geist> a kernel panic is usually a software construct. as in it's a thing that you build in software to stop thek ernel and dump its state
<Scripted> okok
<Scripted> its ok
<geist> an exceptino is something the cpu does in hardware that software has to handle
<Scripted> I will just implement it in kernel.c
<Scripted> wait..
<Scripted> fuck
<Scripted> can I put in an exception function a kernel panic
<Scripted> or would that be incorrect use
<Scripted> like I did here
<geist> sure
<geist> a) you can do what you want, it's your code and
<bslsk05> ​github.com: CrazeOS/isr.c at main · ScriptedDeveloper/CrazeOS · GitHub
<geist> b) thats not unreasonable
<Scripted> all right
<Scripted> good
<Scripted> no need for changing
<gog> like you can have the default handler for exceptions call panic() or something
<geist> well, agai you dont 'need' to change anything. we can offer advice but it's your thing
<gog> if the handler isn't implemented
<geist> yah id' *suggest* making a panic() function that does what you have pasted over and over again (print themessage, disable ints, spin)
<geist> then yo ucan also call it whenever you get into a bad state
<geist> but that's just general code reuse and refactoring
<Scripted> to reduce code?
<geist> well, usual programming stuff
<Scripted> I mean, that would save a few lines
<geist> if you dupicate the same thing again and again you usually refactor it so you only have to type it once
<bslsk05> ​github.com: sophia/memory.c at restart · adachristine/sophia · GitHub
<nomagno> I just looked at the smallest, most portable NES emulator I could find and it literally just asks the implementation to start a kernel-level 1 hz timer
<nomagno> AKA it doesn't handle instruction timing
<nomagno> It just does back-of-the-envelope approximations
<geist> nomagno: that's not uncommon. unless you *need* cycle accurate it probably doesn't try
<geist> some do, some dont. depends on what you're emulating
<Scripted> I see what you mean
<Scripted> wil do it rn
<geist> i wrote a 6502 emulator years ago and just kept a running count of cycles and then every so often would call out into other parts of the emulator saying 'we're at tick N now'
<geist> so it could do scanline stuff
<geist> not tremendously efficient but then any halfway modern cpu emulating a 6502 can do it in its sleep
<geist> OTOH something like a 6502 can actually easily cycle count. only a few weird edge cases do instructions take additional cycles
<geist> like iirc branches crossing page boundaries or whatnot (think that was a behavioral change between 6502 and 65c02)
<nomagno> This NES emulator I'm looking at is literally only 1000 lines and it is fairly full-featured
<mjg> oh?
<nomagno> to be fair it uses Allegro for the rendering
<mjg> oh
<geist> ah i usually just use SDL or whatnot
<geist> need to finished convering some of my old code to SDL2, but i still haven't really grokked what the changes are there
<geist> SDL1 was way more straightforward (and limited)
<Scripted> gog goddamn you're saving me a ton lines of code
<nomagno> You know, I think I might replace SDL with allegro in my project
<bslsk05> ​floooh/sokol - minimal cross-platform standalone C headers (264 forks/3318 stargazers/Zlib)
<gog> scripted: how do you mean
<Scripted> wait nvm
<Scripted> you can't pass parameters while setting a desc
<Scripted> like this
<Scripted> idt_set_desc(0, (uint32_t)kpanic("DIVIDED BY ZERO"), 0x08, 0x8E);
<Scripted> sad
<gog> oh yeah
<gog> just make a stub handler for that
bauen1 has joined #osdev
<gog> that calls kpanic()
<Scripted> no idea how that works
<Scripted> my asm too bad for this
<Scripted> : (
<geist> well, this is an excellent opportunity to learn
<gog> feel free to go through my isr.h and isr.c files
<gog> in kc/core/cpu
* mjg names his routine panik to fsck with people
<gog> panic() at the exception
<geist> and no you can't do that. the IDT only instructs the cpu where to branch on that particular exception vector
<geist> but you usually just make a custom handler for each one, or via some trickery route them all into one
<Scripted> will take a look, thanks
<geist> where you can have a switch statement to decide what to do with each
<nomagno> What is the smallest very-portable library I can use to do the following? 1. Nonblockingly get input 2. Play sound nonblockingly (can overlay/mix the sounds) from a file 3. Get sprite pixel buffer from file 4. set screen pixel buffer
<geist> that's also very common
<gog> isr.S *
<geist> nomagno: on what platform? or bare metal?
<Scripted> left a star btw
<gog> lol thanks
<nomagno> geist: I asked for smallest very-portable. By very-portable I understand cross-platform.
<geist> 'portable' can mean 'runs on different architectures'
<nomagno> If it supports bare metal that's great, but at least the main OSes so I don't have something that no one can use
<geist> hence why i was asking you what you were asking for
<nomagno> Fair
<geist> sounnds like SDL might be what you want
<geist> cant say it's the smallest, but it's well supported and has all those features
<nomagno> SDL2 seems way too heavy for this, or at least it's the impression I guess
<geist> and can even hardware accellerate all of it
<nomagno> I'm looking for an extremely minimal abstraction to do singlethreaded software rendering
<geist> FWIW SDL is single threaded software rendering
<Scripted> What's a PIC?
<nomagno> geist: 'extremely minimal abstraction'
<GeDaMo> That sokol link from earlier is some C headers with cross platform graphics handling
<gog> programmable interrupt controller
tomaw has quit [Quit: Quitting]
<nomagno> and I'd do the software rendering myself
<nomagno> Not the library
<Scripted> oh ok
<geist> nomagno: okay. then i have no suggestions
<dh`> programmable interrupt controller? position independent code? performance instrumentation counter? pilot in command?
<nomagno> I have seen... uh what was the name of this thingy? Rawdraw
<nomagno> But I'd have to get a separate thingy for sound, I think
<gog> dh`: yes all of those too
<geist> but given what they've bee asking abut, i'm guessing the PIC in the IBM PC sense
<dh`> (I didn't read the scroll, suppose I should have)
<Scripted> By the way, are there some good assembly tutorials? I've already watch some but still feel like knowing not much about assembly
<nomagno> you know, I think for now I'm going to abstract over X11 for software rendering
<nomagno> and input
<bslsk05> ​www.egr.unlv.edu: x86 Assembly Language Programming with Ubuntu
<nomagno> then sound... I can use sndio but that's way too low level, I'd have to get a TON of abstraction layers inbetween
<geist> nomagno: abstracting over X11 doesn't seem that portable
<geist> again i'd really suggest something like SDL which has already handled this stuff. and it's pretty simple to use
<Scripted> nomagno: thanks
<geist> it looks big but you only have to use about 10 functions
<GeDaMo> nomagno: take a look at https://github.com/floooh/sokol
<dh`> X11 is terrible, you want something else
<Scripted> I will upload that to my homeserver
bliminse has joined #osdev
<Scripted> good idea to have a collection of useful PDFs
<nomagno> How is X11 not portable? It's literally a framebuffer with some input stuffs
<GeDaMo> You wish :P
bauen1 has quit [Ping timeout: 252 seconds]
<Scripted> Btw, how do I pass the magic number and multiboot info using assembly? https://wiki.osdev.org/Detecting_Memory_(x86)#Detecting_Low_Memory
<bslsk05> ​wiki.osdev.org: Detecting Memory (x86) - OSDev Wiki
<Scripted> I currently have this
<bslsk05> ​github.com: lk/start.S at master · littlekernel/lk · GitHub
<geist> been a while since i looked at it, but i think that's a fairly standard way to do it
<Scripted> can I use .S in .ASM?
tomaw has joined #osdev
<klys> no, see: at&t vs. intel x86 syntax
<Scripted> ah
<Scripted> right
<geist> yah thats at&t syntax, using gas
<Scripted> so I have to just switch them
<geist> yeah
<gog> scripted: the parameters are pushed to the stack in reverse order from what you declare in c
<Scripted> btw, at&t syntax is the best
<gog> so if you have func(int a, int b) you would push them t o the stack push b; push a; call func
<Scripted> OH
<Scripted> no, that's bad
<Scripted> very bad
<Scripted> no at&t syntax in C
<geist> hmm?
<Scripted> at&t syntax in c is just weird
<klys> c typically compiles to at&t (or tasm with -mintel) syntax.
<geist> if you'd care to be more specific we can help you
<geist> also what toolchain are you using?
<Scripted> I didn't really understand what gog said
<gog> the calling convention has nothing to do with the syntax
<geist> right
<Scripted> I'm not that familiar with asm
<gog> scripted: in ia32 for the sysv calling convention function parameters for C are pushed to the stack in right-to-left order
<bslsk05> ​github.com: CrazeOS/Makefile at main · ScriptedDeveloper/CrazeOS · GitHub
<gog> so a C function func(int a, int b)
<geist> okay, looks like you're on a posix system using standard gcc+binutls for i686. got it
<Scripted> yes
<gog> in an assembly routine that calls func
<Scripted> arch btw
<gog> it would push b, then a, then call func
<Scripted> but what if I reverse the order
<Scripted> like tell assembly push a first and then b
<klys> the reverse order is called stdcall
<gog> you can use stdcall
<gog> you can tell GCC to output stdcall functions by default
<Scripted> hmm, ok
<geist> but otherwise you probably want to stick to the default. and the default is right to left
<geist> it's such that the leftmost arg (the firt one) is 'first' on the stack if you count upwards
<gog> yeah
<gog> i recommend not doing anything fancy
<geist> right to left means higher address to lower since the stack grows 'downwards'
<geist> ie, from higher addres to lower
<Scripted> so I push the high address first?
<GeDaMo> This is used in vararg functions like printf, the first parameter specifies how many other parameters there are
<geist> the right most arg first, yes
<mrvn> I you have to pass parameters on the stack I believe you are doing something wrong.
<geist> mrvn: x86-32
<klys> push the high address first: yes, this is how the push instruction operates.
<mrvn> geist: dead, kill, burn
<gog> wait no stdcall is right-to-left too
<geist> mrvn: says someone that keeps futzing with arm32
<mrvn> geist: it's a few decades more moden. :)
<geist> decade here, decade there
<gog> i only write code for the 6502
<geist> anyway not judging what folks are trying to hack on, just trying to provide help
<geist> mrvn: i should also note that 68k uses stack to pass args too, which you also like a lot
<geist> your precious Amiga
<mrvn> Is there a compiler flag to make c++ initialize padding bytes in structs?
<mrvn> geist: m68k uses regs first
<mrvn> AmigaOS at least
<geist> yah, standard 68k uses args on stack: https://github.com/littlekernel/lk/blob/master/arch/m68k/asm.S#L12
<bslsk05> ​github.com: lk/asm.S at master · littlekernel/lk · GitHub
<mrvn> geist: then I have to ask: Why? You have 8+8 registers. Should be enough for a nice register calling convention.
<geist> go back to 1980 and ask them
<geist> i think it was just The Way at the time. stack was how you did stuff
<clever> geist: from what ive seen of the amigaos docs, a large chunk of the calling convention uses registers
<mrvn> and back then memory was fast
<geist> memory was fast, etc
<clever> i think its less that memory was fast, and more that the cpu was as slow as the memory!
<mrvn> On Amigas memory is slow. Half the bandwidth goes to the graphics chip basically.
<clever> accelerator cards with fastmem changes things
<mrvn> yeah, but back when they made AmigaOS those didn't exist.
<geist> makes sense. they were free tomake their own calling convention
<mrvn> So maybe someone thought about the hardware and what it means for the calling convention.
<clever> the most confusing part i see, is that args can be in either addr or data registers
<clever> and every function wants a different thing
immibis has joined #osdev
<clever> the general rule, seems to be that functions accepting pointers, accept them in an addr reg
<mrvn> Or they just didn't want to handle plucking variables from the stack with the different languages that got mixed in AmigaOS.
<clever> it looks very much like a performance thing
<mrvn> clever: A6 is always the *this of the library you call.
<clever> wanting the addresses in an addr reg, so it doesnt have to move around
bauen1 has joined #osdev
<geist> yah i didn't explore if gcc has alternate calling conventions or whatnot. just figured out what the default is and went with that
<mrvn> geist: AmigaOS is maybe a bit out of the box. It's verry object oriented and dynamic. A library is a pointer with data on the positive size and a virtual table on the negative side. First 6 functions are constructor, destructor and some other every lib must have.
<mrvn> As said a library must have A6 == *this of the lib
<clever> and the vtable can be patched to hook functions
<clever> and all of that, is supported by a kernel in the bloody boot rom!
<geist> yah and A7 is hard coded to SP iirc
<geist> so makes sense
<mrvn> There are even patch managers so virtual functions can be patched multiple times, composed, layered, removed even if they aren't on the top, ...
<clever> it makes dos relying on bios look like a step backwards
<clever> with bios calls being so messy
<geist> i forget what A6 does in this calling convention. i thik it might be the FP
<bslsk05> ​en.wikipedia.org: TRIPOS - Wikipedia
<geist> used to work with one of the amigaos guys. he is a real goofball, nice guy
<geist> RJ micah
<clever> ive been learning how it works, to help them with the pistorm stuff
<mrvn> Is the a g++/clang flag to make the compiler initialized padding bytes in structs?
<bslsk05> ​d0.se: d0 - The Classic M68k Amiga Developer Resource
<clever> as a random example, the DoIO function in the exec.library, expects a single argument, a pointer to a `struct IORequest` in the A1 register, and it returns an error code in D0
<mrvn> clever: I have a nice stack of RKRMs here (Rom Kernel Reference Manual). Like ARM ARMs.
<bslsk05> ​d0.se: d0 - The Classic M68k Amiga Developer Resource
<clever> the read command, is just an enum you shove into a field of `struct IORequest`
<geist> mrvn: we have a flag set in fuchsia that causes the compiler to pre-initialie everything
<bslsk05> ​d0.se: d0 - The Classic M68k Amiga Developer Resource
<mrvn> All the AmigaOS library functions where also provided machine parseable for generating Foreign Function Call stubs.
<geist> which isn't eactly the same thing
<geist> but basically if you make a struct (or a variable of any kind) on the stack it zeros it out first
<geist> then runs any constructor it might have
<mrvn> geist: what's the flag?
<geist> though the optimizer may then elide some of that
<geist> good question
<clever> and OpenDevice, accepts a device name string in A0, a unit number in D0, a blank? IORequest in A1, and some flags in D1
<geist> note it's clang only AFAIK
<clever> and OpenDevice populates the IORequest with function pointers
<geist> default-initialized? that may be the feature
<geist> maybe init-local-vars?
<mrvn> sounds both like it.
<geist> the fuchsia build system is so complicated i have no idea where to look, but maybe grep the internet for those
<geist> but i dont know if it's exactly what you want. this is kinda a safety feature if nothing else
<geist> and there are real speed downsides to it
<geist> fwiw there's an attribute to conditionally disable it though
<Scripted> am I just plain stupid or why can't I find the goddamn logs for this irc channel
<mrvn> geist: I don't want to leak stack contents because some bytes weren't initialized.
<geist> yes i know that Very well
<mrvn> geist: like when you send a padded struct over the network.
<geist> scripted: check the topic
<geist> there's a link there
<mrvn> Although, maybe the compiler should fail when someone tries sending padded data.
<Scripted> ah geist thanks very much
<geist> mrvn: also i've had some questions about exactly when padding is initialized (if at all)
<geist> i think for this switch it's the case.
<nomagno> GeDaMo: what portability issues does X11 have?
<mrvn> geist: Why should it? nothing should ever access it
<mrvn> UB
<geist> but for example if you have `struct foo bar = {};` and foo has padding. does it zero initialize padding?
<nomagno> I really want to get around OpenGL...
<nomagno> I'm doing software rendering
<nomagno> No good
<geist> then dont use opengl
<mrvn> I would assume any zero initialization just calls memset()
<geist> or a local equivalent
<nomagno> Well, then how do I portably do graphics stuff?
<geist> SDL
<geist> it does *precisely* what you want
<mrvn> And as soon as you have any custom constructor in there the padding is not init.
<nomagno> But SDL is literally the definition of bloat!
<mrvn> SDL does not sleep.
<nomagno> I'm abstracting, not abstracting over abstractions
<geist> you cant always get what you want
<geist> you want portability, the main way to achive that is to abstract
<geist> also you dont have to use most of it
<nomagno> ... I literally don't see what possible issues I could have with copying a pixel buffer to the X11 thingy
<geist> X11 isn't portable
<GeDaMo> "The proposed change for C23 is that the = {} (functionally equivalent to = { 0 } on modern compilers) will also initialize padding bits to 0" https://interrupt.memfault.com/blog/c-struct-padding-initialization
<bslsk05> ​interrupt.memfault.com: C Structure Padding Initialization | Interrupt
<geist> you said you wanted portability. do you want to now require someone has an X11 server on windows?
<geist> or macos?
<geist> mrvn: what do you mean SDL doesn't sleep? it has an event loop that you can just block in
<geist> works great IMO, except that you have to have this whole event loop thing
<geist> but you can run your main logic in other threads
<nomagno> geist: Uh... Do you seriously think I would bring up X11 without being happy about its platform support surface?
<nomagno> I'm taking about portability issues between the platform is does support
<geist> okay then. so in your case portability includes requiring X11 on the target platform. go for it
<nomagno> Bad phrasing on my part
<geist> oh well, then fine.
[itchyjunk] has joined #osdev
<geist> i guess we should have played 20 questions more when asking what you meant. by portability, but you were already acting annoyed that i didn't instantly kow what you wanted so it stopped
<geist> *this* is usually why i'm very precise about asking what people want before answering
<nomagno> What
xenos1984 has quit [Remote host closed the connection]
xenos1984 has joined #osdev
[itchyjunk] has quit [Max SendQ exceeded]
<nomagno> Can I get Hanlon's razor treatment please?
<Scripted> I'm kinda lost with passing the multiboot structure to the kernel
<nomagno> I prefer being called stupid than being accused of intentionally causing miscommunication.
<Scripted> I've found this https://github.com/proxypoke/osdev/blob/master/boot.s but it's giving me a clear terminal
<bslsk05> ​github.com: osdev/boot.s at master · proxypoke/osdev · GitHub
<Scripted> with nothing
<geist> nomagno: yah no worries. just a miscommunication
* geist buys nomagno a beer/sake/wine/water
<nomagno> I'm drinking a lot of water lately, thank you! Someone told me I should take a sip every time I feel hungry
<nomagno> It surprisingly works.
<geist> agreed. drinking lots of water is mostly just upsides
<geist> except having to go to the loo a lot
<nomagno> I don't think SDL is more portable than X11 by the way
<nomagno> It's just more accessible
<mrvn> geist: Maybe on function call the stack could be zeroed instead of doing this varibale by variable.
<geist> why not? runs great on windows/mac and lets you get handles to accelleration
<geist> also deals with sound, input and provides a generic threading library (though that you can usually get elsewhere)
<geist> seems like a pretty good solution to me
<geist> also deals with things like full screen, video mode selection, etc
<nomagno> ... My project is pedantic about pulling in dependencies
<geist> sure, and you've just stated that you're only only working on systems with X11 which changes the game completely
<geist> i think at least but anyway sounds like you have a different set of requirements and some subjective dislike for thigs as 'bloated' as SDL. so i thin that pretyt much ends the discussion
<nomagno> Considering I wrote the guidelines for my project, I can also tell you I wouldn't do this if it wasn't dead easy to swap out the graphics/audio/input backend
<geist> okay.
[itchyjunk] has joined #osdev
<geist> i thik this horse is well beaten
<nomagno> I currently have an SDL backend. I might just leave it in and add an X11/sndio hybrid as a macro option
<nomagno> Preprocessor statements have never hurt anyone... Have they!?
<kingoffrance> x11 i believe was portable...for 1980 or whatever. that is not a knock against it, i believe it was designed to lower common denominator atop hardware of the time...thats just to say there is a "when" factor in there somewhere
<kingoffrance> *1985 *lowest
<geist> DECwindows!
<klys> is there a set of simple opengl commands that can be used to create a transparent alpha channel?
<nomagno> I don't really get the definition of portable y'all are using. You seem to be conflating portability with accessibility
<Scripted> whats the stack_top defined here https://forum.osdev.org/viewtopic.php?t=30318
<bslsk05> ​forum.osdev.org: OSDev.org • View topic - QEMU Multiboot Invalid Memory Map
<nomagno> X11 is inaccessible on mainstream platforms, I agree that's a problem, but it works pretty much everywhere
<geist> well initially i conflated it with the *usual* definition of portability here. ie, running on different architectures
<geist> doubleplus so since this is a channel that usually concerns itself with bare metal programming
<kingoffrance> ^ there's two parts "potentially portable" "someone already ported it, here's a binary"
<nomagno> geist: that one was fair honestly
<klys> and by SDL do you mean SDL2 or SDL1.2 ?
<geist> indeed that too
<kingoffrance> i agree the word is used with many meanings and you have to guess what ppl mean
<geist> i actually still hvae to convert some of my stuff from SDL1.2 to 2
<geist> honstly o
<nomagno> klys: they have radically different platform support surfaces honestly
<geist> i've never heard someone mention accessibility in the way you're using it
<nomagno> Specially when you get into the console homebrew scene
<klys> nomagno, so do you use 1.2?
<geist> accessibility in my experience always means dealing with disabled people
<geist> ie, screen readers, high contrast, etc
<nomagno> geist: Uh... Capability of accessing
<nomagno> It's probably wrong terminology
<nomagno> But I mean capability of accessing it, or readiness of the work for use by the average person
<geist> availability maybe
<nomagno> NDS has 1.2 only support, 3DS has 2.0 only support
<nomagno> Availability is also wrong for my use case I'd say...
<nomagno> User-friendliness
<geist> oh, you're interested in running on homebrew consoles?
<nomagno> Yes, that's a better terms
<nomagno> geist: I'm making a pedantically portable game. I want to run this thing on a GBA someday!
<geist> oh gosh that changes everyting
<geist> again i should have asked more questions initially
<klys> qemu -display sdl,gl=es; is this using SDL2 ?
<nomagno> But I'm doing software rendering, so I just need a light backend to get input and display the pixel buffer for noor
<nomagno> for now*
<nomagno> 'Software' rendering is a mischaracterization
<klys> software rendering typically refers to the use of mesa?
<GeDaMo> nomagno: did I link you this thing? https://100r.co/site/uxn.html
<geist> well, most of us would probably just answer with 'write a portable OS, then run your code on it'
<bslsk05> ​100r.co: 100R — uxn
<nomagno> GeDaMo: That was oldlaptop I think, but I liked it. And I also have my own competitor to that thingy!
<bslsk05> ​halfworld.nomagno.xyz: 404 Not Found
<nomagno> Oh no
<bslsk05> ​halfworld.nomagno.xyz: Half-World Virtual Machine
<nomagno> This
<nomagno> I've talked about this thing on here already
<nomagno> Developed independently from uxn... Which you can tell because I'm following none of their sane architecturing principles
GeDaMo has quit [Remote host closed the connection]
<nomagno> I just threw a chimera system together and it works well enough, so I don't really with to touch it. All further developments will be done by building tooling in the form of assembly macros and 'stdlib'/example subroutines
<nomagno> GeDaMo: I'm quite impressed by uxn's system architecture honestly
<Scripted> it seems like that I'm triple faulting, not sure though. Can somebody help me? https://pastebin.com/zapZzS9q
<bslsk05> ​pastebin.com: bits32MAGIC equ 0x1BADB002stack_bottom:resb 0x4000stack_top:se - Pastebin.com
<nomagno> klys: Software rendering in this context means literally doing everything in my code, with my own sprite blitting and line drawing tools, then blitting the final framebuffer
<nomagno> ... Is there a better name for this? 'Self-contained rendering'?
amj has quit [Quit: WeeChat 3.0]
<Scripted> ah, I fixed it by adding the bss section
<Scripted> my magic number is still not correct though.
<Scripted> this is the code https://pastebin.com/raw/hK7W8p5v
<mrvn> Here is a cool project for anyone with too much time: Put valgrind into the hypervisor on AArch64.
<gorgonical> mrvn: how do you mean
<mrvn> Add some stubs where the kernel reports alloc/free and have it track memory usage and initialization.
<gorgonical> How does our hypergrind actually instrument the memory instructions?
<gorgonical> alloc/free can be wrapped with hypercalls
<mrvn> Is it running a VM or single stepping code?
<gorgonical> If we're single-stepping it's pretty easy, but why then would you want it in the hypervisor?
<gorgonical> Sounds more interesting if you can do this with a VM
<mrvn> gorgonical: I want to run it on any kernel.
<gorgonical> well not "pretty easy" but more like straightforward anyway
<gorgonical> You could imagine (though it would be messy) to force page faults for every memory access and then do them anyway
<mrvn> yep, that was my thought.
<mrvn> WHat other choice is there other than emulating ever opcode?
<mrvn> +y
<gorgonical> That captures actually only the memory accesses themselves, but you still need some kind of in-kernel option for hypercalls, right?
<gorgonical> That's at least the most generic approach
<gorgonical> I mean, how else do you capture memory free/allocs?
<mrvn> worst case you don't. free/alloc would basically just say: this page is now unititialized again.
sonny has quit [Quit: Client closed]
<mrvn> You could make the kernel return memory to the hypervisor on free and request new memory on alloc.
<mrvn> force balooning
<gorgonical> Yeah, that's what I was getting at. Some kind of hypercall down to the hypervisor to communicate this
<gorgonical> The hypervisor won't actually know when memory becomes freed otherwise, or when it's re-used then
<mrvn> In valgrind you have to instrument your malloc/free functions too. So that's basically the same on a lower level.
<gorgonical> This smells like something that should already exist, but maybe not valgrind/memcheck
<gorgonical> This is like "hypervisor enforced memory correctness" or something
<mrvn> any existing kernel would probably drown in false positives
<mrvn> allocate block, hand it NIC, read data. *BOOM* false positive
<mrvn> hand it to NIC
<gorgonical> There's PinOS which uses Xen to do this for x86: https://dl.acm.org/doi/pdf/10.1145/1254810.1254830?casa_token=x4oskS-luWIAAAAA:rkxCaSYLgD24KTYskTv6dMcXRUj6glQs-NMiIy_x8bWWSUaxVvJNZNqJogBizayEP9iPS-qWgyY
<bslsk05> ​dl.acm.org: PinOS | Proceedings of the 3rd international conference on Virtual execution environments
<gorgonical> And seems like maybe an attempt on MIPS64 is here: https://ieeexplore.ieee.org/abstract/document/7166630?casa_token=I8ygd5f69WkAAAAA:LGMVnHhYsoTBNfyzAeEhn4n3tlCZs2zzVJsFyT9ptFgKGsJ0tELzjcxeLVAFJUWe50qpGZo
<bslsk05> ​ieeexplore.ieee.org: Dynamic binary translation in a type-II hypervisor for Cavium Octeon MIPS64 based systems | IEEE Conference Publication | IEEE Xplore
<gorgonical> I gotta go but I'll think about this some more. An interesting idea if you can sort of attach this to an existing baremetal hypervisor and get valgrind capabilities like that
<mrvn> Is there some syntax style to show a function taking a pointer will initialize where it points to?
dormito has quit [Quit: WeeChat 3.3]
<mrvn> pure out parameter
<gorgonical> I think Ada does this
<gorgonical> Maybe?
<mrvn> (in c++ I should have said)
tds has quit [Quit: The Lounge - https://thelounge.github.io]
tds has joined #osdev
gorgonical_ has joined #osdev
gorgonical_ has quit [Read error: Connection reset by peer]
immibis has quit [Remote host closed the connection]
orthoplex64 has quit [Quit: Leaving]
<geist> i guess the C++ way of doing it would be to have some wrapper object, etc
<mrvn> In user space c++ code I just don't do that. If a function initializes something then it allocates it itself and returns it.
<geist> yah it's generally against the style guide at work
dude12312414 has joined #osdev
<mrvn> Maybe in kernel I should pass in an allocator that just allows one allocation of some uninitialized memory it holds.
<mrvn> or as you say a wrapper object like "UninitializedBlob<T>" or so.
dude12312414 has quit [Remote host closed the connection]
<mrvn> UninitializedBlob<T> could have operator(args...) that get forwarded to std::construct_at(mem, args...)
<mrvn> s/Blob// makes more sense.
friedy10- has quit [Ping timeout: 250 seconds]
<mrvn> Uninitialized<T> is something can that be constructed into a T.
<mrvn> +1 for rubber ducking on irc.
<geist> yah also lots of modern arches (x86-64 and arm64 in particular) can return up to two words of data without using the stack
<geist> so you can build a class to encapsulate a pointer + return code
<geist> Rust style
<geist> we're starting to move more stuff like that in the kernel
<geist> ie, zx::status<void *> or whatnot
andreas303 has quit [Ping timeout: 240 seconds]
<mrvn> I'm not sure how this works with c++ {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p} = foo();
<geist> would end iup allocating a thing on the stack and passing a pointer to it
<mrvn> DOes it optimize to passing by register for up to N variables and construct a std::tuple and picking values otherwise?
<geist> in arm64 there's an actual dedicated register in the ABI for it: x8
<geist> what you're asking is entirely ABI based
<geist> but i general i think the ruels are: there's <ABI SPECIFC> way to pack smaller structs into register
<mrvn> No, I mean what will the compiler make out of it when it optimizes this (maybe with LTO)
<geist> and return from functions can handle astructure up to <ABI SPECIFIC> size
<geist> well my experine ceis the compiler usually does about as good of a job as you can think of
<mrvn> I don't get this dedicated x8 register. Is that so it doesn't cause all the normal register to be shifted up by 1 for the return structure pointer?
scoobydoob has joined #osdev
Goodbye_Vincent4 has joined #osdev
dormito has joined #osdev
PyR3X_ has joined #osdev
<mrvn> To clarify: I don't get the dedicated bit
ornitorrincos_ has joined #osdev
cookie has joined #osdev
pie__ has joined #osdev
vancz_ has joined #osdev
rustyy_ has joined #osdev
pg12 has joined #osdev
<mrvn> My, arguably naive, view is that the ABI has argument registers e.g. X0-X7. So up to 8 args go into regs, why can't up to 8 args return in the same regs?
jack_rabbit has joined #osdev
<mrvn> If you need more args in it goes to the stack, more args out steal one arg in reg for the return
<mrvn> On ARM this is nicely symetrical: r0-r3 are arguments passed in and out.
<mrvn> I wanted to lookup AMD64 because there in and out regs differ. But https://en.wikipedia.org/wiki/Calling_convention seems to have every (common) arch but amd64.
<bslsk05> ​en.wikipedia.org: Calling convention - Wikipedia
Brnocrist has quit [Ping timeout: 240 seconds]
zaquest has quit [*.net *.split]
Burgundy has quit [*.net *.split]
knusbaum has quit [*.net *.split]
rustyy has quit [*.net *.split]
Matt|home has quit [*.net *.split]
nj0rd has quit [*.net *.split]
rb has quit [*.net *.split]
alpha2023 has quit [*.net *.split]
Goodbye_Vincent has quit [*.net *.split]
pie_ has quit [*.net *.split]
vancz has quit [*.net *.split]
MiningMarsh has quit [*.net *.split]
netbsduser has quit [*.net *.split]
koolazer has quit [*.net *.split]
pg12_ has quit [*.net *.split]
ssiyad has quit [*.net *.split]
scoobydoo has quit [*.net *.split]
ornitorrincos has quit [*.net *.split]
mavhq has quit [*.net *.split]
PyR3X has quit [*.net *.split]
ckie has quit [*.net *.split]
Goodbye_Vincent4 is now known as Goodbye_Vincent
scoobydoob is now known as scoobydoo
<clever> mrvn: ive run into some problematic functions on the rpi firmware, where 500 byte structures seem to be passed by-balue on the stack
<clever> its not allocated on the stack and passed by pointer, the called function is just expecting an argument in the stack of that size, indexed relative to the frame/base pointer
Brnocrist has joined #osdev
<mrvn> clever: as input arguments?
<clever> yes
<mrvn> So the called function builds the stack frame and leaves a hole where the struct comes in from outside? Nice.
<clever> the main problem, is that ghidra has trouble decompiling it
<mrvn> If you have a 512 byte red-zone that seems workable.
<clever> and it turns into a giant mess of conat(concat(concat(
<clever> it isnt redzone i think, its allocated onto the stack before calling the target function
<mrvn> imagine a signal comming right before the function call. it would overwrite the struct.
<clever> so its like any other argument that didnt fit into registers
<clever> the structure isnt valid until after the sp is decremented
<clever> i believe
<mrvn> You need the redzone to construct the data and then you can the function and the redzone becomes the stack fram.
<clever> i dont think this code has any redzone stuff
<mrvn> s/can/call/
Burgundy has joined #osdev
rb has joined #osdev
nj0rd has joined #osdev
MiningMarsh has joined #osdev
alpha2023 has joined #osdev
netbsduser has joined #osdev
ssiyad has joined #osdev
<mrvn> if it has signals then it needs a redzone for this.
zaquest has joined #osdev
<clever> no signals, but its in kernel mode, so it does have interrupts
<clever> i think redzone, is about allowing the compiler to use stuff the SP claims is unused
<mrvn> does the VC execute interrupts on the kernel stack or switch stacks?
<clever> depends, each irq can choose
<clever> with redzone off, the SP must decrement before you can use the thing
<clever> and the SP acts as the border between used and unused
<clever> always
<mrvn> yes, redzone allows you to place data below the SP and not have it get overwritten by signals/interrupt.
<clever> but with redzone off, you must move the SP first
koolazer has joined #osdev
<mrvn> Otherwise everything below the SP gets randomly corrupted.
mavhq has joined #osdev
<clever> yep
<mrvn> If you move the SP then it's different. That increases the stack frame. But you said it's the stack of the called function.
<clever> the caller will push all arguments onto the stack, including the 500 byte struct
<clever> it will then branch+link into the called function
<clever> which then will decrement sp further, by the size of the local vars
<mrvn> Ok, that sounds like just passing args via stack.
<clever> yep
<clever> but its just weird, to be shoving a whole 500 byte arg onto the stack like that
<mrvn> Sounded at first like the caller would construct the object on the future location of the callees stack frame.
<mrvn> well, what do you expect when you pass 500 bytes by value?
<clever> for your boss to slap you :P
<mrvn> hehe
<mrvn> Now you can see why I love functional programming. Every value is a reference, everything (almost) is immutable.
Ellenor is now known as Reinhilde
<clever> yep
<mrvn> The default calling convention is pass by const reference.
<mrvn> Oh, I pass in this big value. How big is it? 8 byte.
<mrvn> it's huge, it's my whole 4k image frame. It's 8 byte. :)
<clever> in haskell, the stack isnt even a stack
<clever> its a linked list
<clever> each element is one stack frame
<mrvn> A stack? What's a stack? stack frames are allocated on the heap. :)
<clever> exactly
<mrvn> It's great. you can just call_cc and the pointer to the old stack frame keeps it alive for later continuing the function.
<mrvn> coroutines, generators, async functions, ... all the same as every other function call.
<mrvn> monads *hide*
<mrvn> clever: by the way where did those 500 bytes comes from. Did it have 500 bytes on it's own stack frame and then those got copied? So 1000 byte stack gone? That would be like 10% of my stack.
<clever> *looks*
<clever> ok, so the function in question, according to the decompiler, takes 7 arguments
<clever> arg7 is an uint8_t[500]
<clever> and the function reads parts of it without first writing them
<clever> so it clearly expects it to be initialized by the caller
<mrvn> you have to find the caller to see where IT gets the 500 bytes from.
<clever> reading that now...
<clever> the decompiler is just treating it as having an uint8_t[424] as a local variable
<geist> what you are describing is exactly in the ABI
<geist> unless you're dealing with an undocumented arch of course
<clever> that may explain why there is a whack-load of CONCAT43664(..) calls
<clever> there is a 500 byte struct on the stack, passed by value (maybe LTO is cheating, and peeking into the callers frame?)
<clever> but the caller decompiled as having a 424 byte object, so the variables are all messed up
<mrvn> maybe it passes 424 bytes buffer and a long and a double and ... that are contiguous on the stack frame.
<clever> yeah
<mrvn> hard to say what compiler optiomization might have done from the decompile.
<clever> ok, very first thing the function does, is push r6/r7/r8/r9/r10/r11/r12/r13 and lr, onto the stack
<clever> 9 x 32bits
<mrvn> so it's calling another fucntion
<clever> yeah, this is the parent, where that 500 bytes came from
<mrvn> urgs, ABI violation? stack must be double word aligned normaly.
<clever> this arch only needs 32bit alignment
<clever> different rules
<mrvn> is this ARM or VC firmware?
<clever> VC
<mrvn> never mind me then. :)
<clever> it then "adds" -0x1c to the stack pointer (reducing it by 28)
<clever> which creates a hole bit enough for 7 x 32bit
<mrvn> so it expects to spill 7 words worst case
<mrvn> any more changes to SP?
<clever> it then calls memset(arg1, 0, 0xd84) to zero out the 1st argument it received
<mrvn> Doesn't look like it is passing the 500 bytes through multiple functions causing the stack to explode.
<clever> nope, no other changes to SP
sonny has joined #osdev
<clever> thats very strange
<clever> id almost say the called function is being decompiled wrongly
<mrvn> .oO(turning a reference passed arg into a value for the next function, odd)
<clever> and that 500 byte structure isnt valid
<mrvn> always possible :)
<clever> reading it next...
<clever> upon entry, it stored r6/r7/r8/lr to the stack, 4 x 32bit
andreas303 has joined #osdev
<clever> then does sp -= 8; to make room for local vars (but the decompile claims way more)
<mrvn> [Poll] Do you write 'int* p' or 'int *p'?
<clever> then it does a whack-ton of load and store operations, to populate a struct
<clever> i do `int *p`
<clever> because, if you do `int* foo, bar`, what is the type of foo? what is the type of bar?
<clever> i believe int*, and int
<mrvn> it's one thing I feel is horribly broken in C
<clever> and thats hella confusing :P
<clever> so i put the * on the other side, where its more obvious
<mrvn> the type it 'int *' but the int belongs to the line and the * just to the one variable. So your bar is an int.
<clever> int *foo, bar; is more clearly a pointer and an int
<mrvn> I would always split that in two lines.
<clever> usually the same
<clever> but i still put it on the "right" side
<mrvn> third option: int * p;
<clever> lol
<mrvn> is that a product?
<clever> ok, so the reason ghidra thinks there is a 500 byte arg, is because of `ld r4, (sp+0x2c)` and similar
<mrvn> Somehow all 3 ways are bad.
<clever> ok, do the evil thing, `auto p = &foo;`
<clever> auto every variable :P
<mrvn> 0x2c is kind of way below 500
<clever> you have a point
<clever> the biggest offset is just sp+0x30
<clever> so ghidra just had a brain-fart, and pulled 500 out of its ass, lol
<mrvn> The function pushed 4 regs = 0x10, -8 = 0x18. What is 0x2c?
<clever> let me change the size of this first, and see what happens
<mrvn> From what you said it looks like access to the callers stack frame. Which would be something the optimizer could do by specializing the function for one specific caller.
<clever> yeah, thats why i mentioned LTO earlier
<clever> i have noticed this compiler violating rules about clobbered registers
<clever> it peeked into a called function, knew what it actually clobbered, and then didnt bother with useless save/restore
<mrvn> could also just be specialized functions inside a single compilation unit.
<clever> that too
<mrvn> my whole boot.S is like that. I have a bunch of functions and every function has a list of registers that it uses. That's the ABI.
sonny has quit [Quit: Client closed]
<clever> ok, i created a struct to describe this mystery arg, and its now just a sizeof(foo) == 25
<mrvn> reasonable.
<clever> the called is still a horid mess though
<mrvn> might end in a char and gets aligned to 28
<clever> the argument is ZEXT2425(CONCAT(420(0x100,CONCAT416(0x.......
<clever> yeah, from the mix of ld and ldb, it ends in a single byte
<clever> and the rest are all 32bit fields
<clever> every single one is read
<clever> ahhh, and more confusion, the caller is also wanting a "500 byte" arg
<clever> it may be peeking into a stack frame 2 calls up?
<mrvn> maybe it's a lambda that was bount to a stack variable?
<mrvn> bound
<mrvn> then optimized away to access the atack directly.
<clever> its a piece of the video decode logic, called by 6 different codec init routines
ZipCPU|Laptop has quit [Ping timeout: 252 seconds]
kingoffrance has quit [Ping timeout: 240 seconds]
<clever> yeah, i cant make sense of whatever its doing
cookie is now known as ckie