|
Message-ID: <20130722175633.GA21457@brightrain.aerifal.cx> Date: Mon, 22 Jul 2013 13:56:33 -0400 From: Rich Felker <dalias@...ifal.cx> To: musl@...ts.openwall.com Subject: Last C++ ABI issue - request for comments The last remaining ABI issue is jmp_buf and sigjmp_buf, and it's the one that actually has a little bit of decision-making to go with it. Right now, musl's jmp_buf and sigjmp_buf are different types. The former has no need for space to store a saved signal mask, since musl does not support the legacy modes glibc supports where setjmp saves a signal mask. glibc however defines them both as the same type, and due to the way C++ name mangling works, the fact that they're the same type is encoded as part of the ABI. Here's where the hard part comes in: sigjmp_buf is A LOT larger than jmp_buf (in the sense of absolute size, and relative size on register-starved archs like i386) because sigset_t is 128 bytes. Despite only needing 8 (or 16, on MIPS) bytes to store a signal mask, sigset_t was defined as 128 bytes a long time ago by glibc out of an interest in imposing HURD's bad design choices on everbody else. Anyway, I see a couple possible options for moving forward with this: OPTION 1. Expand jmp_buf to match the current definition of sigjmp_buf. PROS: - Fully matches glibc ABI, including all type sizes. - Does not change the C ABI for sigjmp_buf. CONS: - Uses the most space. - Changes the current C ABI for jmp_buf (not the app-to-libc ABI, but the ABI between app and third-party libraries using jmp_buf in a structure in the library's public API). OPTION 2. Expand jmp_buf just enough to include the actually-used signal bits, and shrink sigjmp_buf to match PROS: - Size increase of jmp_buf is minimal. - Size of sigjmp_buf decreases. CONS: - Changes the current C ABI for both jmp_buf AND sigjmp_buf (see notes under option 1). My leaning at this point is to go for option 1. My reasoning is that, despite the fairly large size increase in jmp_buf, (1) it's only a large _relative_ increase on i386, i.e. on other archs the jmp_buf is already quite large, (2) it's less ugly than option 2, and (3) the size damage is already done in the sense that need for sigset_t is much more common than need for jmp_buf, and (4) there are workarounds for large size that applications should be doing anyway. In particular, since jmp_buf could be large, applications or libraries should NOT be including a jmp_buf in their data structures. Instead, they should use a pointer-to-jmp_buf. Since the validity of a jmp_buf is always tied to the block lifetime of the associated setjmp, it's always possible to use an automatic-storage jmp_buf declared at the point of the setjmp, and to set a pointer to this jmp_buf just before or just after the setjmp. Short of a really good argument for option 2 or a completely new idea, I'll probably go ahead with option 1 pretty soon. Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.