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
<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>
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>
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."
<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
<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]
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
<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.
<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?
<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
<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
<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
<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>
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>
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
<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
<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
<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>
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>
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.
<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
<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
<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.
<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?
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.
<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>
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