Search logs:

channel logs for 2004 - 2010 are archived at ·· can't be searched

#osdev2 = #osdev @ Libera from 23may2021 to present

#osdev @ OPN/FreeNode from 3apr2001 to 23may2021

all other channels are on OPN/FreeNode from 2004 to present

Friday, 10 June 2022

00:00:00 <zid`> about spending 80 hours figuring out a bitflip in pipe()
00:00:00 <heat> there's an internal channel of people that really like linux's network stack
00:01:00 <heat> and i love that
00:01:00 <zid`> yea I remember one of their blog posts being about the linux stack.. a couple of times
00:01:00 <zid`> some seq sequence rollover bug or something?
00:07:00 <heat> there are a lot of network stack posts
00:08:00 <zid`>
00:08:00 <bslsk05> ​ Please Wait... | Cloudflare
00:08:00 <zid`> yea there's a bunch of good ones, I liked this one
00:09:00 <heat> yeah I linked that one here
00:09:00 <zid`> Did you study it as homework for your interview
00:14:00 <heat_> luv me router
00:14:00 <heat_> no, i'm not touching the network stack
00:14:00 <heat_> i'm on the cloudflare workers runtime team
00:15:00 <heat> basically workers takes a bunch of untrusted javascript or web assembly and runs it in cf's edge servers
00:15:00 <mrvn> Couldn't I do this without the `T` in List?
00:15:00 <bslsk05> ​ Compiler Explorer
00:15:00 <heat> so you can run your service in every cf datacenter, no need for your own server
00:15:00 <heat> it's pretty cool
00:18:00 <heat> and *thankfully* I won't be touching JS ;)
03:06:00 <Jari--> hi all
03:08:00 <mrvn> Can one make std::construct_at a friend of a class so it can call a private constructor?
03:10:00 <Jari--> make it global ;-]
03:12:00 <mrvn> the std::construct_at?
03:12:00 <Griwes> why are you trying to make construct_at be able to call a private constructor?
03:12:00 <mrvn> So you can construct an instance on the heap
03:13:00 <mrvn> std::make_shared()
03:13:00 <Griwes> so you want *some* of the clients of the class to be able to invoke that constructor through stdlib functions? possibly just the class itself?
03:15:00 <mrvn> the class itself, static member function calling make_shared
03:15:00 <Griwes> okay, there's another way
03:18:00 <Griwes>
03:18:00 <mrvn> Foo *foo = new Foo(5); return std::shared_ptr<Foo>(foo);
03:18:00 <Griwes> you make the ctor itself public, but accept a private type as one of its arguments
03:19:00 <mrvn> That's a stupid hack and has overhead. :)
03:19:00 <Griwes> then only specific users can invoke it, as if it was private, but you can invoke it through stdlib wrappers
03:19:00 <Griwes> lol.
03:29:00 <mrvn> Griwes: While I don't need it here can you make the same thing work with making construct_at a friend function instead of struct key?
03:36:00 <Griwes> I don't know, I don't think you can reliably do it since you can't depend on specific function overloads of stdlib functions
03:36:00 <Griwes> but if you make construct_at a friend, you may as well make the constructor public because it would be public at that point
03:39:00 <mrvn> It should be as simple as copying the function definition and adding friend.
03:40:00 <Griwes> you can't reliably know what the signature of stdlib functions are
03:41:00 <Griwes> sd-8 tells you that if you depend on it, you don't get to complain if your code breaks because a stdlib or the standard change
03:42:00 <mrvn> Should still work right now.
03:42:00 <mrvn> I tried adding a template specialization for construct_at too and making that friend. But it doesn't even get used.
03:47:00 <Griwes> trying to do things with function specializations is bound to cause you more pain than anything else
03:52:00 <mrvn> but so much fun
04:54:00 <Jari--> good brains wasted on migraines
04:54:00 <Jari--> its over now
04:54:00 <Jari--> TempleOS developer I heard had some similar symptoms
05:37:00 <kazinsal> RTX 3080 go brrrrrrrrr
05:37:00 <kazinsal> actually it goes more "whooooosh". way quieter than my 1080 Ti was
05:38:00 <Jari--> hmm
05:39:00 <klange> Other things in the vicinity of my desk are far louder and I don't really notice the sounds of my 1080 FE.
05:40:00 <kazinsal> yeah, even with max fan speed my server and layer 3 switch are much louder
05:42:00 <Jari--> In my opinion, VirtualBox should scale, stretch, the view.
05:47:00 <klange> Host key + C will switch to scaled/stretched.
09:13:00 <FatAlbert> is experimenting with os stuff that can potentially break the OS best than in containers ?
09:13:00 <FatAlbert> s/than/done
09:13:00 <mrvn> no, that's boring
09:14:00 <FatAlbert> the only problem i have with that approach is that containers are not really full OS'es
09:14:00 <mrvn> they aren't oses at all. they are containers
09:14:00 <FatAlbert> but i guess that bare minimum will do for explroing OS stuff at least funtionality wise
09:15:00 <mrvn> editors aren't OSes too if we are listing things that aren't OSes
09:15:00 <FatAlbert> editors ARE os'es what you talking about ?
09:18:00 <FatAlbert> i have a full IDA PRO license for free
09:19:00 <FatAlbert> mrvn: ^
09:19:00 <FatAlbert> it's an OS
09:21:00 <FatAlbert> mrvn
09:21:00 <FatAlbert> mrvn:
09:22:00 <FatAlbert> mrvn:
09:24:00 <FatAlbert> mrvn:
09:25:00 <kazinsal> pinging someone five times in as many minutes is not a good way to make them want to interact with you
09:25:00 <kazinsal> just a pro IRC tip
09:25:00 <kazinsal> slash human interaction tip
09:26:00 <FatAlbert> kazinsal: it's a punishment for being an asshole
09:26:00 <dminuoso> 11:15:20 mrvn | editors aren't OSes too if we are listing things that aren't OSes
09:26:00 <dminuoso> mrvn: emacs users would disagree with you here.
09:26:00 <dminuoso> :>
09:26:00 <kazinsal> also not a good way to win you any friends
09:26:00 <FatAlbert> kazinsal: you are under the impression that i need frinends
09:26:00 <FatAlbert> why is tat ?
09:27:00 <FatAlbert> dat
09:27:00 <FatAlbert> i don't
09:27:00 <FatAlbert> i gave up on this idea on the age of 13
09:27:00 <FatAlbert> im flying solo
09:27:00 <kazinsal> it is a figure of speech
09:27:00 <dminuoso> Surely someone here has administrative powers to remove this hostile troll.
09:27:00 <FatAlbert> dminuoso: you have the power with /ignore add <name here>
09:28:00 <FatAlbert> if you don't like what i have to say yo ucan ignore it in two ways:
09:28:00 <kazinsal> pretty much the wrong time zone in general for someone around who has buttons I think
09:28:00 <FatAlbert> 1. read my messages and ignore them ..
09:28:00 <FatAlbert> 2. read my second last statement before rule 1
09:29:00 <FatAlbert> kazinsal: i think deep inside i never gave up on the idea of friendship
09:30:00 <FatAlbert> infact .. i never give up
09:30:00 <FatAlbert> in a sense ..
09:31:00 <FatAlbert> the only circles that im being accepted is with gays and in the peace core .. both communities which im scared to death with
09:31:00 <FatAlbert> so im still solo
09:31:00 <kazinsal> good news, I'd wager half of the modern tech sphere is gay
09:31:00 <kazinsal> be careful or we might infect you
09:32:00 <kazinsal> the infosec sphere is also primarily gay *and* furries
09:32:00 <FatAlbert> it's not going to happen
09:32:00 <FatAlbert> im staying strong
09:32:00 <kazinsal> (it's impressive, a bunch of my friends' customers who they build fursuits for are in infosec)
09:33:00 <GeDaMo> All the colours of the rainbow :P
09:33:00 <kazinsal> I was over at their house the other night having a few beers and one of them handed me a fursuit head
09:33:00 <kazinsal> put the thing on and it was actually surprisingly comfortable
09:33:00 <kazinsal> decent airflow, alright vision although I had to take my glasses off
09:34:00 <FatAlbert> kazinsal: ok quiet
09:34:00 <kazinsal> neat little plastic hinge mechanism attaching your jaw to the fursuit head's jaw so really emotive talking moved the jaw
09:34:00 <FatAlbert> are you sure they didn't try the reverse bear trap on you ?
09:35:00 <kazinsal> I joked that if I rebuilt their website I'd accept a discount on one if I could hang out behind the table with them at some cons
09:35:00 <FatAlbert> you should be careful who you socialize with .. an advice that i myself need to embrace but in my desperation ...
09:35:00 <kazinsal> so now I'm poking around at building a new website for a fursuit studio
09:35:00 <FatAlbert> GeDaMo: mute him
09:35:00 <kazinsal> I've known these cats for like, 20+ years, they're some of the best people I've ever hung out with
09:35:00 <FatAlbert> he's way pass the wierdness of this chat
09:36:00 <kazinsal> anyways I've spent probably a decade and a half in this IRC if you count the freenode era
09:36:00 <FatAlbert> geist: mute him
09:36:00 <FatAlbert> hallo !?
09:36:00 <kazinsal> and a lot of the people who run this place are not straight
09:36:00 <kazinsal> so take your weird shit elsewhere
09:36:00 <FatAlbert> geist: ???!?!?!?!?!?!?!?
09:37:00 <FatAlbert> ok im going
09:37:00 <kazinsal> this is and always has been an inclusive space
09:37:00 <kazinsal> fuck that was fun
09:37:00 <FireFly> ..wat
09:38:00 <kazinsal> nothing better than literally recounting my tuesday evening to troll a homophobe out of an IRC channel.
09:38:00 <dminuoso> Okay, so has anyone attempted to run emacs on bare metal?
09:39:00 <dminuoso> (Trying to shift the focus back on *serious* topics)
09:39:00 <mrvn> obviously
09:39:00 <kazinsal> emacs seems like waaaay too much of a mess to run on bare metal
09:39:00 <kazinsal> at least, gnu/emacs
09:39:00 <kazinsal> I'm sure you could probably reimplement classic TECO macro set emacs on top of bare metal
09:40:00 <mrvn> be sure to write systemd.el
09:40:00 <kazinsal> but considering gnu emacs is a combination of a bunch of things including a whole lisp virtual machine and a bunch of crazy gnu stuff I would not consider it bare metal portable
09:41:00 <dminuoso> Really? Id say that makes it bare metal portable in the first place. Your kernel just needs to provide the exact lisp functions that emacs needs.
09:41:00 <kazinsal> once upon a time the gnu/emacs build system involved "core undumping"
09:41:00 <dminuoso> (The kernel being the C-shell around emacs)
09:42:00 <klange> I think the preferred term was "unexecing"
09:43:00 <kazinsal> it was, yeah
09:43:00 <kazinsal> imo, "core undump" conveys a deeper sense of "oh no, that doesn't sound right at all"
09:45:00 <GeDaMo> There's an Emacs for DOS, presumably that wouldn't need much support
09:52:00 <jjuran> mrvn: You probably want to define construct_at() for your type in the same namespace in which the type is defined, and rely on two-phase lookup.
09:53:00 <jjuran> For generic code, you can preced with `using std::construct_at;` so both will be candidates.
09:53:00 <jjuran> *precede
09:53:00 <jjuran> Extending std:: is usually UB
10:24:00 <heat> >fursuit
10:25:00 <heat> >I've known these cats
10:25:00 <heat> hehehehehehe
10:28:00 <mrvn> the squirrels will be pissed for not getting metnioned.
10:39:00 <kazinsal> I should ask them if they've ever done a squirrel fursuit
10:42:00 <GeDaMo>
10:42:00 <bslsk05> ​ Squirrel Girl - Wikipedia
10:49:00 <heat> sooo i've recently learned that freebsd also does weird stuff with processes and threads and rfork() so it works similarly to linux and nptl and clone(2)
10:50:00 <mrvn> rfork?
10:50:00 <heat> makes me wonder if it's actually a totally valid idea
10:50:00 <heat> mrvn, Yes, see
10:50:00 <bslsk05> ​ rfork(2)
10:51:00 <heat> comes from plan9, it's pretty old
10:52:00 <heat> they even have a clone(2) emulation that uses rfork
10:53:00 <heat> like in reality do people really need the fine-grained sharing stuff
10:58:00 <mrvn> do you really need more than pthread_create and posix_spawn?
10:58:00 <heat> seems so
10:58:00 <heat> well, you need fork at least
10:59:00 <mrvn> what for?
10:59:00 <heat> creating processes
10:59:00 <mrvn> That's what posix_spawn is for
10:59:00 <heat> and/or doing the classic fork() server strategy
10:59:00 <heat> posix_spawn is limited
11:00:00 <mrvn> ok, you neede daemonize too
11:00:00 <kazinsal> rfork seems to be a rather bizarrely implemented system call for "create a new thread, and often other stuff too"
11:00:00 <heat> in fact, I would say any spawn() function is inherently limited
11:00:00 <mrvn> Although with systemd that's kind of dying out.
11:00:00 <heat> kazinsal, see: clone(2)
11:00:00 <kazinsal> eg rfork(NULL) seems to fork a new thread
11:00:00 <kazinsal> whereas rfork(FRPROC) forks a new process
11:01:00 <mrvn> heat: if you give users too many options then they will stgart abusing them.
11:01:00 <heat> passing NULL for an int should be a war crime
11:01:00 <mrvn> NULL could be an int
11:01:00 <heat> yes, it's valid C
11:01:00 <heat> still against the geneva convention
11:02:00 <kazinsal> I'm assuming rfork without RFPROC means "create thread" since it literally means "fork execution but the changes affect the current process"
11:02:00 <mrvn> it's valid either way. pointer or int. But NULL can be an int
11:02:00 <heat> mrvn, you should read
11:02:00 <kazinsal> so it's either "fork thread" or "do absolutely nothing"
11:02:00 <heat> even microsoft doesn't defend spawn() anymore
11:03:00 <kazinsal> also it looks like rfork is a bsd backport of a plan9 thing, hrm
11:03:00 <heat> kazinsal, "The flags argument is either RFSPAWN or the logical OR of some subset of"
11:03:00 <mrvn> HTTP request sent, awaiting response... 403 Forbidden
11:03:00 <kazinsal> thus ends my quasiauthoritative knowledge
11:03:00 <heat> mrvn, weird, looks good here
11:04:00 <kazinsal> so I guess rfork(RFTHREAD) is the formal call for "create thread"
11:04:00 <mrvn> are you in de?
11:04:00 <heat> no
11:04:00 <kazinsal> seems weird for "create process" and "create thread" to be the same syscall with different int flags
11:05:00 <heat> does video game censorship affect process creation whitepapers now? :P
11:05:00 <mrvn> heat: imagine the chaos it would cause if US papers could be read outside the US. Oh no.
11:05:00 <heat> kazinsal, that's how it works on most modern UNIXes
11:05:00 <heat> mrvn, i'm in portugal, not the US
11:05:00 <heat> there's no geoblocking at play here
11:07:00 <heat> kazinsal, fyi, for more insanity: linux's clone syscall's signature is different from the library function clone()
11:07:00 <mrvn> like half the syscalls
11:08:00 <heat> the library clone is thread-oriented (you even give it a function pointer)
11:08:00 <heat> the syscall is a fancy fork
11:08:00 <heat> if you want the fancy fork, you use syscall()
11:09:00 <heat> also for even more insanity: the libc writers need to do special hacks in assembly so vfork() can be entirely defined
11:09:00 <heat> and IMO it's still not entirely defined because who knows what the compiler is doing
11:10:00 <heat> (reminder: never use vfork() in not-C)
11:12:00 <heat> mrvn, anyway, if you could read the paper (pretty weird you're getting a 403), you'd see they discuss multiple alternatives to fork, like posix_spawn/CreateProcess and cross-process operations
11:13:00 <heat> but the underlying tone is that spawn() is limited and thus not a full fork replacement
11:14:00 <heat> personally I think that cross-process operations (like Fuchsia) is a super interesting option
11:14:00 <heat> more flexible at the very least
12:23:00 <ddevault> getting closer
12:23:00 <ddevault> my ISRs work in kernel space but GP fault when returning to userspace
12:23:00 <j`ey> so EFLAGS was the issue?
12:24:00 <ddevault> yeah, it was part of the issue for sure
12:27:00 <Jari--> retrying chat
12:28:00 <heat> ddevault, how does your stack look before iret?
12:29:00 <ddevault> that's what I'm looking into now
12:29:00 <ddevault> what confuses me is the stack looks wrong even when it does work
12:30:00 <gog> stacks always look weird
12:30:00 <gog> but if it looks wrong even when it's working maybe you have a sneaky problem there
12:30:00 <ddevault> nevermind, I was reading the stack fine
12:30:00 <ddevault> wrong*
12:30:00 <ddevault> it was fine
12:31:00 <gog> oh good :þ
12:32:00 <zid`> if you read that kaomoji do you get "thrrhrhhhhpppp"
12:32:00 <gog> yes
12:33:00 <ddevault> hrm
12:33:00 <ddevault> the cs on the stack when iretq is run is 0, not 8
12:33:00 <zid`> that's good
12:33:00 <zid`> cus 8 is ring0 in most setups
12:33:00 <ddevault> right
12:34:00 <zid`> were you the pmode guy?
12:34:00 <mrvn> but 0 is the null segment iirc
12:34:00 <ddevault> I am not the pmode guy, at least so far as I'm aware
12:34:00 <zid`> so this is long mode?
12:34:00 <zid`> oh I guess so with iretq actually
12:35:00 <ddevault> and yeah, I would expect cs to be 0x10
12:35:00 <ddevault> for userspace
12:35:00 <zid`> there's some weirdness with long mode where usermode doesn't actually give a shit about setting some selectors to 0
12:35:00 <zid`> I forget exactly how it works
12:36:00 <ddevault> or... 0x13? wut
12:36:00 <zid`> 13 yes
12:36:00 <heat> cs should be 0x1b
12:36:00 <zid`> it should be 0x23 fite me
12:36:00 <heat> syscall will fite u
12:36:00 <ddevault> in any case, it's set to 0 on the stack when the interrupt fires
12:36:00 <heat> s t a c k c o r r u p t i o n ?
12:37:00 <zid`> I have.. cs=23, es/ss/ds = 1b
12:37:00 <ddevault> I highly doubt that this is stack corruption
12:37:00 <zid`> dunno if that's backwards
12:37:00 <heat> zid` sucks, I want zid back
12:37:00 <ddevault> let me see what it looks like when the ISR begins, rather than ends
12:37:00 <heat> zid would have cs = 1b
12:37:00 <zid`> well it works
12:37:00 <zid`> and has always workied
12:37:00 <heat> cringe
12:38:00 <zid`> I think that's because compat mode is not used so I get to shift down by 1 set or something? idk
12:39:00 <mrvn> SASCALL/SYSRET needs the cs/ds in the proper order
12:39:00 <ddevault> my sysret works fine
12:40:00 <heat> actually I feel stupid now
12:40:00 <heat> i'm on 0x28 and 0x30
12:41:00 <heat> :(
12:41:00 <zid`> get rekt
12:41:00 <mrvn> cs32/ds32?
12:41:00 <zid`> and is 23 the compat mode cs?
12:41:00 <heat> I have NULL - Kernel CS - Kernel DS - 32 bit user CS - 32 bit user DS - User CS - User DS - TSS
12:42:00 <zid`> I have.. null, kcs, kdata, udata, ucs
12:42:00 <zid`> cus I am weird apparently
12:42:00 <zid`> I have no idea if I intentionally put them that way around
12:43:00 <heat> knowing you, you probably did that just to fuck with people
12:43:00 <ddevault> ah, my kernel was interrupted during a syscall, not userspace
12:43:00 <ddevault> that explains cs being weird
12:44:00 <ddevault> still no closer to an answer, though
12:44:00 <zid`> I don't enable interrupts during a syscall yet, sounds scary
12:44:00 <ddevault> I have ruled out stack corruption
12:44:00 <ddevault> well, I also get a GP fault when the interrupt occurs in userspace
12:44:00 <zid`> (I don't wanna write all the code for figuring out how many swapgs to do)
12:45:00 * ddevault shrugs, disables interrupts in syscalls
12:46:00 <ddevault> well, actually
12:46:00 <ddevault> how else am I going to get reports about kernel faults
12:46:00 <zid`> They start disabled
12:46:00 <heat> traps work with interrupts disabled
12:46:00 <zid`> exceptions are NMIs aren't they
12:47:00 <heat> traps are not interrupts as far as I understand it
12:47:00 <ddevault> ah
12:47:00 <heat> you can disable NMIs and the I flag and you'll still have them
12:47:00 <zid`> I think that's what the NM stands for :P
12:48:00 <heat> you can disable NMIs tho :)
12:48:00 <ddevault> okay, so I have disabled interrupts in syscalls and the behavior is the same (except that the interrupt only ever comes from userspace)
12:48:00 <heat> in the CMOS
12:48:00 <ddevault> but I may as well leave them disabled for now
12:48:00 <heat> code?
12:48:00 <zid`> soo.. how's your TSS looking?
12:48:00 <ddevault> I had that thought as well, let's see
12:49:00 <ddevault> this interrupt does not have IST set, for a start
12:49:00 <ddevault> which makes sense that it's still on the same stack
12:50:00 <ddevault> this is long mode btw
12:51:00 <zid`> rsp0 gets loaded from the TSS in an IRQ
12:51:00 <zid`> also what's your fault like? pf? gp?
12:51:00 <zid`> etc
12:51:00 <ddevault> gp
12:52:00 <zid`> error code, decoded address?
12:52:00 <ddevault> error code 16
12:52:00 <ddevault> decoded address?
12:53:00 <zid`> as in, what does the address mean
12:53:00 <ddevault> cs:rip is 0x8:0xffffffffc0024235
12:53:00 <ddevault> which is the location of the iretq
12:53:00 <zid`> and that's the iretq from the syscall, or from the irq?
12:53:00 <ddevault> the latter
12:53:00 <ddevault> my syscalls use syscall/sysret
12:53:00 <zid`> error code 16 means selector 0x10
12:54:00 <zid`> 0 means not selector related and "could be any fucking thing" :P
12:55:00 <heat> it can also mean "null selector" afaik
12:56:00 <zid`> right, 0 means not "positive selector value related" :P
13:34:00 <ddevault> I wonder if my %ss is not being set correctly when entering userspace
13:39:00 <ddevault> I don't think that makes sense, how would my syscalls be working correctly ordinarily if this were not correct
13:40:00 <zid`> because the syscall abi doesn't use the user stack
13:40:00 <zid`> ss only matters if you do pushes in usermode
13:41:00 <ddevault> well, I have a working stack in usermode
13:41:00 <ddevault> in any case, messing with IA32_STAR causes the gp fault to occur in the same place, but with different error codes, which is suggestive
13:42:00 <ddevault> definitely do not understand what I'm supposed to put in this MSR
13:44:00 <zid`> lemme see what I do
13:44:00 <heat>
13:44:00 <bslsk05> ​ Onyx/cpu.cpp at master · heatd/Onyx · GitHub
13:45:00 <zid`> star has 8<<32 | 10<<48, LSTAR has syscall_handler
13:45:00 <ddevault> thanks, heat
13:45:00 <zid`> and my cs selectors are 8 and.. 0x20
13:45:00 <ddevault> USER32_CS, is that for compatibility mode?
13:45:00 <zid`> I think it adds 16 to the latter or something?
13:45:00 <zid`> yea compat mode
13:45:00 <zid`> I don't have those so mine are probably lower than heat's
13:47:00 <ddevault> can I see your GDT, heat
13:49:00 <ddevault> page 232 of AMD manual vol 2
13:49:00 <ddevault> I think I need to reverse my user cs and ss in my GDT because sysret sets cs to the STAR value + 16 and ss to + 8
13:49:00 <ddevault> which is the reverse of the kernel mode selectors it uses
13:50:00 <ddevault> this is dumb -_-
13:51:00 <ddevault> why didn't I stick with riscv64
13:51:00 <zid`> yea it's weird that they decided to hardcode this in weird ways
13:53:00 <Mutabah> x86_64 keeps the x86 tradition of having some good ideas, and others that make you go "dafuq?"
13:55:00 <zid`> like, why have a bizzare offset, surely it's *more* work to add a random value to the msr internally
13:55:00 <zid`> than to just not bother and allow people free reign
13:55:00 <ddevault> this shit is going to drive me up the wall
13:59:00 <zid`> oh right FMASK exists
13:59:00 <ddevault> this is a nightmare architecture from hell
13:59:00 <zid`> had completely forgotten about that
13:59:00 <zid`> amd64's actually nice
13:59:00 <zid`> the braindamage is minimal and easy to work around
14:00:00 <ddevault> there is braindamage everywhere I look on this damn thing
14:00:00 <ddevault> a castle built on a house built on a shack built on sand
14:02:00 <Mutabah> zid`: That MSR (iirc) is used to derive all segment selectors
14:04:00 <Mutabah> and yeah, FMASK is also important
14:05:00 <Mutabah>
14:05:00 <bslsk05> ​ rust_os/start.asm at master · thepowersgang/rust_os · GitHub
14:06:00 <Mutabah> also
14:06:00 <bslsk05> ​ rust_os/start.asm at master · thepowersgang/rust_os · GitHub
14:06:00 <Mutabah> ^ my GDT, note the order and commnets for the user segments
14:16:00 <ddevault> thanks Mutabah
14:28:00 <ddevault> hrm
14:29:00 <ddevault> I don't have the PIT turned on and I haven't even configured the PIC
14:30:00 <ddevault> but when IT is enabled in userspace, I get a double fault some non-deterministic amount of time after jumping to userspace
14:30:00 <ddevault> during that time several syscalls work successfully
14:31:00 <ddevault> what's weird is I don't even get the first fault
14:31:00 <ddevault> and the error code is non-zero, which I wouldn't expect for a double fault...
14:31:00 <ddevault> the fuck
14:31:00 <Mutabah> have you disabled the PIC?
14:32:00 <Mutabah> i.e. masked every interrupt off
14:32:00 <ddevault> ah, no, that's it
14:33:00 <ddevault> okay, that fixes it
14:34:00 <ddevault> so now I'm back to the original problem, thankfully, which is that iretq from a PIC interrupt causes a GP fault
14:34:00 <ddevault> only from userspace, that is
14:36:00 <heat> ddevault, sorry, wasn't here
14:36:00 <ddevault> np heat
14:36:00 <heat> hopefully you got that fixed
14:36:00 <ddevault> well, at least I have ruled out some things
14:36:00 <heat> I think _STAR does +16 on each for the 64-bit segment and the 32-bit segment (?)
14:37:00 <heat> idk
14:37:00 <heat> it's been a long time since I touched that stuff
14:37:00 <zid`> This just reminded me *why* I spent ages fixing a stupid self inflicted bug
14:37:00 <zid`> I was going to get MSI working wasn't I
14:38:00 <heat> damn right
14:38:00 <heat> go get em girl
14:38:00 <ddevault> yes, I think I have my STAR set up right
14:38:00 <ddevault> wrmsr(msr::IA32_STAR, (seg::UCODE_32 << 16 | seg::KCODE) << 32);
14:38:00 <zid`> should just be a case of enabling them in the pci-e config space, masking the PIT, and checking my ioport acks to mmio acks I think
14:38:00 <ddevault> then my GDT is, in order, KCODE, KDATA, UCODE_32, UDATA_32, UCODE, UDATA
14:39:00 <ddevault> and UDATA_32 and UDATA are identical
14:39:00 <ddevault> the GP fault is on the IRETQ instruction and sets error code to 10
14:39:00 <zid`> then you loaded ucode32 as your selector for the stack maybe
14:39:00 <zid`> or kdata
14:40:00 * zid` forgets about null
14:40:00 <zid`> or kdata for cs
14:40:00 <ddevault> nah, because it adds 16
14:40:00 <ddevault> so it ends up being UCODE
14:40:00 <ddevault> AMD manual vol 2 page 172
14:40:00 <ddevault> the top of the stack on iretq is:
14:40:00 <bslsk05> ​ paste.txt —
14:41:00 <ddevault> 0x0000000000405504 is an address in the userspace's .text section, so presumably the return address
14:41:00 <ddevault> 0x00007fff8003fc68 is a userspace stack address
14:41:00 <zid`> and what's the exact value in _STAR?
14:42:00 <ddevault> 0x3000100000000
14:43:00 <zid`> so 0+16 for cs
14:43:00 <zid`> 0+8 for ss
14:44:00 <zid`> That's why my data/code are swapped and I load 0x18 into 47:63 of _STAR
14:44:00 <ddevault> did you ever link to your code?
14:44:00 <ddevault> curious to see your GDT and _STAR setup
14:45:00 <zid`> wrmsr(IA32_STAR, 0x8UL << 32 | 0x10UL << 48);
14:45:00 <zid`>
14:45:00 <bslsk05> ​ boros/gdt.c at master · zid/boros · GitHub
14:45:00 <ddevault> lemme try just dropping that in and see what happens
14:46:00 <ddevault> aaaand it just werks
14:46:00 <ddevault> well, good enough for me
14:46:00 <ddevault> thanks zid`!
14:46:00 <zid> Upgrade complete.
14:46:00 <zid> idk how people are supposedly having code, data, ???, code, data
14:47:00 <zid> I don't see how you achieve that given sysret loads ss=n+8 and cs=n
14:47:00 <zid> wait yes I do :D
14:47:00 <zid> basic addition is harrrrd
14:47:00 <zid> I just intended to move these around if I ever wanted 32bit selectors
14:47:00 <heat> zid` is evolving!
14:48:00 <ddevault> yeah I don't really see any point in having 32 bit support
14:48:00 <Ermine> ddevault: congrats
14:48:00 <ddevault> especially given that the language I'm writing this in doesn't even support 32-bit targets
14:48:00 <zid> yea not unless you have any legacy stuff to run
14:48:00 <heat> smaller pointers without x32 efforts
14:48:00 <zid> I wouldn't add it until I added a full x32 mode
14:48:00 <zid> and that isn't going to happen
14:48:00 <heat> or if you need to run native 32-bit code
14:49:00 <zid> or wine support I guess, which also not going to happen
14:50:00 <heat> yes but for example, what if you want to run a vbios
14:51:00 <zid> Did you not remember my JIT
14:51:00 <zid> that I never wrote
14:51:00 <heat> that's 32-bit code that you could then easily trap with signal handlers
14:51:00 <zid> oh right there's a 32bit extension mode thing isn't there
14:51:00 <zid> I completely forgot about that
14:52:00 <zid> what was it called?
14:52:00 <zid> My fuzzy ass memory suggests there's a like, int 10h,4C for pset for real mode, but int 10h,4200 is the pmode version, or just returns a function pointer for it
14:53:00 <zid> or does VBE 3.0 just mandate the entry point is polyglot
14:56:00 <heat> no clue
14:56:00 <zid> found the name at least
14:56:00 <heat> but most of it needs to be pmode
14:56:00 <zid> vesa 3.0 protected mode interface
14:56:00 <heat> a real mode driver can't touch PCI space
14:56:00 <zid> vbe*
14:57:00 <zid> My plan was just going to be to JIT it to amd64
14:58:00 <heat> lol
14:58:00 <heat> use the CPU's internal JITter, ez
14:59:00 <zid> I usually just write interperting emulators
14:59:00 <zid> but a JIT sounded more fun
15:00:00 <ddevault> nice how the only way to do graphics in long mode is to write a GPU driver
15:01:00 <heat> s/in long mode//g
15:01:00 <heat> :)
15:01:00 <ddevault> haha yeah
15:01:00 <ddevault> still, basic framebuffer drivers don't seem like too much work on most GPUs once you have PCI working
15:01:00 <heat> though you do have EFI's GOP
15:02:00 <heat> they're not what?
15:02:00 <heat> hahaahahahahahaahaha
15:02:00 <ddevault> when I boot from EFI my #1 goal is to make EFI fuck off as soon as possible
15:02:00 <ddevault> well, 9front's ihd driver is pretty small, a few hundred lines
15:02:00 <heat> 9front's code is all horrible
15:02:00 <heat> and there's no way you can do that
15:02:00 <heat> like no way
15:03:00 <heat> in < 1000 lines
15:03:00 <heat> ihd encompasses at least 11 gens, each gen has a different sequence to drive the display engine, each gen supports different outputs (HDMI, DP, eDP, VGA, DVI)
15:03:00 <ddevault> well, fair
15:03:00 <heat> each output requires its own multi-thousand-line code
15:03:00 <ddevault> still, only a few thousand lines tops
15:04:00 <ddevault> you don't have to, like, reimplement mesa or KMS from scratch
15:04:00 <heat> mesa isn't part of the kernel
15:04:00 <ddevault> aware
15:04:00 <ddevault> but it is necessary to do, say, OpenGL
15:04:00 <heat> the GPU kernel drivers are a good chunk of the linux kernel
15:04:00 <ddevault> given that I just got interrupts working properly I would say I'm some ways off from OpenGL support though
15:05:00 <zid> good news though, nvidia have made writing drivers even easier lately
15:05:00 <j`ey> heat: 90% of the kernel is AMD headers :P
15:05:00 <heat> and they're only good for power management, display, command submission
15:05:00 <heat> yup
15:05:00 <zid> the latest cards put the kernel driver into firmware on the card instead
15:05:00 <ddevault> on the one hand, that's fucking awful
15:05:00 <zid> so now the DRI interface is tinier than ever
15:05:00 <ddevault> on the other hand, nice for os devs
15:06:00 <heat> amdgpu's headers should maybe be firmware :)
15:06:00 <ddevault> I was thinking that it would be cool to port KMS/DRM to my kernel in The Future
15:06:00 <zid> The main idea is that updating drivers in a huge gpu cluster is a pain in the dick
15:06:00 <ddevault> it is at least somewhat isolated into a silo in linux
15:07:00 <ddevault> and has been ported to other kernels before
15:07:00 <j`ey> $ du -sh drivers/gpu/drm/amd/
15:07:00 <j`ey> 313M drivers/gpu/drm/amd/
15:07:00 <heat> you can totally do that
15:07:00 <j`ey> oof
15:07:00 <zid> so they just flash the card with the driver instead
15:07:00 <heat> j`ey, having the linux kernel checked out on your machine is such a kernel dev move from you :P
15:07:00 <ddevault> who doesn't have a copy of linux on their machine
15:08:00 <ddevault> have any hobby OSes ported KMS/DRM? maybe haiku has
15:08:00 <j`ey> how else am I going to build it!
15:08:00 <heat> ddevault, haiku is not a hobby OS
15:08:00 <heat> managarm might
15:08:00 <ddevault> yeah, but it is a niche OS at least
15:08:00 <zid> j`ey: I email my config to redhat
15:08:00 <heat> netbsd is also a niche OS
15:08:00 <ddevault> and it's at least as buggy as any hobby OS ;)
15:08:00 <zid> and they post me back a CD-ROM with my new krnel on it
15:09:00 <j`ey> zid: haha
15:09:00 <j`ey> 16M arch/x86 90M arch/arm64
15:09:00 <heat> that settles it
15:09:00 <heat> arm64 < x86
15:10:00 <j`ey> but 90 > 16
15:10:00 <ddevault> at least x86 has a standardized boot procedure
15:10:00 <ddevault> a stupid boot procedure, but standardized nevertheless
15:10:00 <zid> arch/x86_64 is 8k though
15:10:00 <j`ey> (arm64 includes all the .o, so not a fair comparison)
15:10:00 <zid> it contains boot/ and a symlink to bzImage :p
15:21:00 <ddevault> hm, any reason not to just use setjmp for context switching
15:22:00 <zid> Try it and find out, I'm interested in the answer
15:22:00 <ddevault> well, I'm a little ways from being able to try it, I actually have to prepare a second task to jump to in the first place
15:22:00 <ddevault> will let you know
15:22:00 <zid> same
15:23:00 <zid> I have one process happily running away
15:23:00 <zid> but its kernel stack is just a page out of my boot-time .bss and stuff, so I'd struggle to run two of them and schedule and stuff rn :P
15:24:00 <heat> why would you?
15:24:00 <heat> you need to save the context when entering the kernel
15:24:00 <zid> why would you want
15:25:00 <zid> words, geez
15:26:00 <zid> 'why would you?' what?
15:26:00 <heat> what if you setjmp inside a constructor or dtor
15:26:00 <heat> will bjarne bust my kneecaps
15:26:00 <heat> "<ddevault> hm, any reason not to just use setjmp for context switching"
15:26:00 <ddevault> I think I'm going to use my own setjmp-equivalent so that I can access its registers directly rather than work with the opaque jmpbuf
15:27:00 <zid> I mean, that's preferable, but I do wonder if anything would go wrong if you tried to use longjmp
15:27:00 <heat> like, context switching just uses what you pushed
15:27:00 <ddevault> only if your kernel is not preemptable, heat
15:27:00 <heat> you need to save more regs than setjmp
15:27:00 <heat> ddevault, no.
15:27:00 <ddevault> you don't longjmp to userspace
15:28:00 <ddevault> you longjmp to somewhere else in the kernel, but on a different stack
15:28:00 <ddevault> the rest of the registers are at the bottom of said stack
15:29:00 <heat> this seems like an extremely obtuse way of doing context switching when you can just use the things you've pushed
15:29:00 <ddevault> it allows you to have the kernel yield from anywhere
15:29:00 <heat> I can also yield from anywhere
15:29:00 <heat> how bout that
15:30:00 <ddevault> so what does your context switch look like
15:30:00 <ddevault> say, from kernel thread to kernel thread
15:30:00 <heat>
15:30:00 <bslsk05> ​ Onyx/interrupts.S at 6c51faf98d17eb298844aaccbdf1ad9ba7e4274f · heatd/Onyx · GitHub
15:31:00 <ddevault> so you just push an entire IRQ frame to the stack
15:31:00 <zid> I mean, in long mode you sort of have to
15:31:00 <zid> iret is the only op that can reload cs
15:31:00 <heat> ddevault, yes, that's how it usually works
15:31:00 <heat> you use what you push
15:32:00 <ddevault> call me crazy but I think the setjmp approach is simpler
15:32:00 <heat> you're crazy
15:32:00 <heat> :P
15:32:00 <ddevault> if (setjmp()) { /* got control back */ }; /* longjmp to next thread */
15:32:00 <ddevault> ez
15:33:00 <heat> the debugger wants to inspect the register state
15:33:00 <heat> what now
15:34:00 <zid> how come your .S is intel but not noprefix btw heat
15:34:00 <ddevault> heat: it just looks up that thread's kernel stack and pulls the registers off of it?
15:34:00 <ddevault> the debugger has no business inspecting the kernel's registers
15:37:00 <heat_> this fuckign router ahhhhhhh
15:37:00 <heat_> <heat> it's not intel
15:37:00 <heat_> <heat> this is raw, hardcore, at&t asm
15:37:00 <heat> ddevault, you'll need to debug your kernel too :)
16:07:00 <ddevault> heat: aye
16:19:00 <zid> heat: but it has no size affices!
18:53:00 <sonny> For people using rust, was there any hitch in setting up paging?
18:55:00 <j`ey> is there something in particular you think would be an issue?
19:03:00 <sonny> j`ey: no tbh
19:03:00 <sonny> I also just realized I can check that rust OS tutorial
19:11:00 * mjg_ wonders how many people think learning rust by writing an os in it is a good idea
19:15:00 * vdamewood raises his hand sheepishly
19:15:00 * mjg_ glares at vdamewood
19:15:00 <mjg_> how is it going
19:20:00 <vdamewood> I gave up after 2 minutes.
19:22:00 <vdamewood> With C, when the compiler complains that symbol foo is missing, I know how to implement foo. With rust, not so much.
19:22:00 <vdamewood> (where foo is part of the standard library or language internals)
19:22:00 <vdamewood> oh, also s/compiler/linker/
19:31:00 <gorgonical_> Porting is not exactly elegant work
19:32:00 <gorgonical_> I feel like I'm chasing continual build errors and fixing things where they aren't right and hoping this will be enough
19:39:00 * moon-child hands vdamewood libgcc and a set of strings functions
19:39:00 <vdamewood> gorgonical_: Just like Sam Beckett
19:42:00 <GeDaMo> "Sam Beckett never returned home" :|
19:56:00 <geist> Wait, what was this mute him crap from 10 hours ago?
19:56:00 <geist> I didn’t see anything. Maybe i had someone locally muted?
19:56:00 <geist> oh never mind, read more backlog
19:57:00 * geist shrugs
19:57:00 <geist> Anyway, hows everyone’s Friday. It’s Friday!
19:58:00 <geist> Unless it’s Saturday because you’re in another time zone
19:58:00 <geist> In which case, yay it’s Saturday!
20:00:00 <mrvn> Still 2 hours of friday left to celebrate
20:01:00 <geist> yay
20:14:00 <heat> had a nice day off here :)
20:14:00 <geist> yah i need one. been working on this fairly stressful project at work the last few weeks that has mostly drained me
20:15:00 <geist> that combined with summer allergies has been an un-fun last few weeks
20:15:00 <heat> :/
20:15:00 <heat> any details you can share?
20:15:00 <heat> or is it Top Secret(tm)
20:16:00 <mrvn> I could tell you -- but then I would have to k-line you. :)
20:16:00 <geist> oh nothing interesting, or it wouldn't be a slog
20:17:00 <geist> one of those 'need to frob all of this X into Y and a bunch of people are waiting on you'
20:17:00 <geist> so just stressful and un-fun with no redeeming quality
20:17:00 <heat> sucks
20:17:00 <geist> mostly out of my wheelhouse but they needed someone to thelp
20:18:00 <geist> help, so i pitched in
20:30:00 <zid> muhahaha someone linked a test rom and was like "bet you won't pass this one" and passed it
20:32:00 <heat> gameboy emulation dick measuring?
20:33:00 <zid> yup, it's fun sport
20:33:00 <zid> it's like code golf but you get a gameboy emulator at the end instead of a segfault
20:39:00 <gorgonical_> Is this typical: allocate a page for the task_struct and then use the difference between where the task_struct ends and the end of the page as the kernel stack?
20:40:00 <zid> could do I suppose, but why not just allocate a page?
20:41:00 <heat> gorgonical_, task_structs are big
20:41:00 <geist> can put the task struct at the top of the page and then start the stack just below it, if you want
20:41:00 <zid> you're going to trash your task struct eventually doing that
20:41:00 <zid> and it's going to be NOT FUN to debug
20:41:00 <gorgonical_> or I mean the other way around
20:41:00 <gorgonical_> My point being: you use the remainder of the minimum allocable size as the stack
20:42:00 <geist> i think some of the older unices did that for a while. you can also swap it out (though i dont thik most most modern kernels do that)
20:42:00 <geist> but in the Old Days when you fully swapped out a task, you could actually write out the kernel stack and it's TCB as well
20:42:00 <geist> but in general i'd just allocate the task struct out of your heap/slab/etc for other stuff
20:43:00 <geist> and then allocate 1 or more pages for the kernel stack out of the pmm
20:43:00 <gorgonical_> In the source I'm working with task_struct is actually in a task_union which is 4KB with the stack which is overall 4KB. The stack then should know how big it is and the difference between the bottom of the stack and the end
20:43:00 <geist> okay
20:43:00 <gorgonical_> I mean I agree with you fundamentally
20:43:00 <geist> it works, dunno precisely what the dsign goal there is, but if thats what they chose to do it works
20:44:00 <gorgonical_> It took me like 30 minutes to really understand where the kernel stack was, because it's sort of mushy
20:44:00 <geist> and yeah if the TCB is at the bottom of the page then if the stack overflows it'll cause havok
20:44:00 <heat> i remember x86 linux has something on top of the stack that points to the current thread
20:44:00 <geist> but it probably calls havok any way you cut it
20:44:00 <heat> then to get the current thread they do some bitops on the stack pointer and access it
20:44:00 <geist> if i were doing that i'd put the TCB at the top of the stack (higher addresses) and then start the SP just below it (aligned of course)
20:44:00 <geist> so the stack grows downwards, away from the TCB
20:45:00 <geist> and yeah that too. the only problem with the 'use the stack pointer to find some critical data structure at the top of it' strategy is it forces you to use a fixed size stack size
20:45:00 <geist> and it must be aligned on that boundary too. so a 16KB stack has to be 16KB aligned, etc
20:45:00 <geist> but if you're willing to live with that restriction, it works well
20:46:00 <gorgonical_> just to be clear because this confuses me a lot: growing downwards means e.g. 0x1000 is the end, then 0xfff?
20:46:00 <heat> 0x1000 is the top
20:46:00 <heat> 0xfff is the first usable byte
20:46:00 <geist> iirc that's part of how linux solves the ARM stack overflow problem: it fixes the stack size at say 8K, and always puts a guard page off the bottom that's 8K as well, so it can easily do pointer math in the first few instructions of the fault function to determine if it overflowed
20:46:00 <gorgonical_> Right yes
20:46:00 <gorgonical_> I said that wrong
20:47:00 <geist> yah i keep saying 'top' to mean 'higher address'
20:47:00 <geist> and virtually all arches out there (and any one you'll fiddle with) grow the stack downwards
20:47:00 <geist> except for things like safe stacks which may grow upwards, because they're software constructs
20:47:00 <gorgonical_> So then to e.g. the task goes at 0xff80 or something so that the task_struct ends at 0x1000?
20:48:00 <heat> we need an arch that starts in the middle and grows both ways
20:48:00 <heat> gorgonical_, seems about right yes
20:48:00 <heat> geist, btw why exactly do stacks grow downwards?
20:48:00 <geist> if you allocated a page that was from 0 - 0x1000, then you could put the task struct at 0xff0 (if it were say 0x10 bytes long) and then start the stack at 0xff0 so it grows downwards, 'away' from the task struct
20:49:00 <gorgonical_> Yes so this stack appears to grow upwards. regs = task + TASK_SIZE - 1
20:49:00 <geist> heat: good question, i think it's mostly because in the early single tasking days it was generally convenient to put the stack at the end of memory and grow it downwards, whereas the program and it's data grew upwards
20:49:00 <heat> oh and with all this, don't forget to align the stack!
20:49:00 <geist> still somewhat convenient, though in modern virtual memory it kinda doesn't matter
20:50:00 <geist> but pre-virtual memory it helped
20:50:00 <heat> cpus bend to the will of the mighty program - brk - stack layout!
20:50:00 <geist> so if you had a cpu with say 32KB ram, and 32KB rom with basic in it or something, you could put the stack at 0x8000 and grow downwards, and load your basic program and its heap at 0x1000+, etc
20:51:00 <geist> and then when segmentation and multitasking came along that still made sense
20:51:00 <geist> then when paging came along it sort of made it less important, but still useful
20:51:00 <heat> maybe paging makes it more important?
20:51:00 <heat> because you can kinda infinitely grow your stack that way
20:52:00 <geist> depends, with modern paging there's no distinction between stack and data, so it's all just regions of memory that you allocate in your VM
20:52:00 * heat laughs in linux vm
20:52:00 <geist> you can reserve space off either end in a modern VM. a bit more convenient to grow it upwards too, since usually it's easier to extend an existing region upwards
20:53:00 <geist> but stuff in the 70s and 80s still had stacks vs data heavily baked in. PDP11 segmentation knew about stacks directly, even VAX paging had two separate page tables per process, split in half, one grows upwards, one grows downwards
20:53:00 <geist> and of course x86 segmentation even has grow downwards segments
20:56:00 <geist> kinda makes 68k look even more modern in retrospect: in 1979 it was simply flat memory model, period. none of the extra stuff
20:56:00 <mrvn> Even with virtual memory it still makes sense to grow the stack down IF you only have one. You still have address space and you put heap at one end and stack at the other and never they shall meet in the middle.
20:56:00 <geist> and then a few years later it's paging chip and then integrated in 030 was also intrinsically flat
20:57:00 <mrvn> But with modern multithreading or even just sigaltstack you have to define how large the stack is and reserve the address space. Then it kind of becomes moot.
20:57:00 <geist> mrvn: sure. main downside nowadays is with multithreaded programs you can't just grow downwards forever, sinc eyou'll probably hit another thread's stack
20:57:00 <geist> yah
20:57:00 <geist> OTOH with 64bit we have space again
20:57:00 <mrvn> And stack is usualy limited in size anyway to prevent run-away recursion.
20:58:00 <geist> yah. modern code relatively speaking leans on the heap/secondary allocations more than ever before
20:59:00 <geist> some sort of chart of heap vs stack usage over time woud probably show something like that
21:04:00 <mrvn> One day I still want to try out just going back to the good old days. Just give the process the whole address space with demand paging. No brk, sbrk or mmap needed to allocate memory. Just have malloc use it as needed.
21:05:00 <mrvn> Optionally free() can have a syscall to unattach physical pages from a memory range.
21:06:00 <heat> that's how my vm worked in the beginning, before brk or mmap!
21:06:00 <mrvn> I've been using this intrusive linked list. Any way to get rid of the `typename T` without loosing the type safety?
21:06:00 <bslsk05> ​ Compiler Explorer
21:11:00 <mrvn> I need a covariant or contravariant thing in c+.
21:11:00 <mrvn> c++.
21:20:00 <mrvn> I want both getters and setters.
21:20:00 <bslsk05> ​ Compiler Explorer
22:25:00 <qookie> mrvn: what's the purpose of the U arg?
22:26:00 <mrvn> qookie: so you can inherit more than one List
22:27:00 <mrvn> just a tag
22:27:00 <qookie> ah
22:27:00 <qookie> tbh, for an intrusive list I'd make the class inherit the list node and not the whole list
22:28:00 <qookie> like here:
22:28:00 <bslsk05> ​ Compiler Explorer
22:29:00 <mrvn> doesn't change the question though, just adds another class to the problem.
22:36:00 <qookie> Hm I suppose I am a bit confused
22:36:00 <qookie> MyFoo is a member of a list and also has a list of children (forming a tree)?
22:37:00 <mrvn> each node in the tree has siblings and children
22:39:00 <mrvn> Could be Tasks with a list for task in the same process group and task that are threads of the same process
22:39:00 <mrvn> really just an example of inheriting more than one list
22:40:00 <qookie> yeah I don't think you can get around the T arg
22:41:00 <qookie> you could add a typedef to partially specialize it as not repeat it explicitly
22:41:00 <qookie> but as far as I can tell that's about it
22:44:00 <heat> list_head goes brrrrrrrrrrrrrrrrrrrrrrr
22:44:00 <mrvn> You mean like this? struct MyFoo; template<typename U> using FooList = List<MyFoo, U>;
22:49:00 <qookie> yeah
22:51:00 <geist> yah i worked on a bit of one of those a while back too
22:51:00 <geist> i really dont like the result, but it's The Way
22:53:00 <mrvn> I like it more than the way the STL is build. Trying to combined STL containers means you have to store iterators left and right in your data. And then half the time they invalidate.
23:14:00 <geist> yah not a big fan of that stuff indeed
23:18:00 <mrvn> the thrid option is the C way with container_of macro thats UB / implementation defined with &(nullptr->member)
23:34:00 <geist> yah worse, the copiler actually generates a warning about it that you have to squelch
23:36:00 <mrvn> I wonder why C++ still doesn't have a standard container_of
23:36:00 <heat> container_of is not defined for non-POD types
23:36:00 <heat> even if you use offset_of
23:37:00 <mrvn> so make it fail to compile when it makes no sense
23:37:00 <mrvn> As is the macro gives some result that may or may not work on non-POD types by chance.
23:38:00 <heat> no
23:38:00 <heat> it gives you a warning
23:38:00 <mrvn> Latest C++ also has a well defined order for all member variables in a class so I think it can work on more types now.
23:41:00 <mrvn> container_of should work on all standard layout classes, right?
23:41:00 <heat> yes
23:41:00 <heat> i believe so
23:41:00 <mrvn> and POD < standard layout iirc
23:43:00 <mrvn> is_pod is deprecated in c++20. What's the replacement? is_trivial? is_trivially_copyable?