Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
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.