Upcoming ABI Breakage in RELENG_7

David Southwell david at vizion2000.net
Wed Jul 30 10:48:57 UTC 2008


On Wednesday 30 July 2008 03:11:54 Heiko Wundram wrote:
> Am Mittwoch, 30. Juli 2008 11:47:34 schrieb David Southwell:
> > For those of us who are not as well informed and experienced  as others
> > could someone please explain what is meant by an  ABI breakage, its
> > implications and how to deal with them.
>
> ABI (Application Binary Interface) is a term used to describe the
> characteristics of binary (i.e. object-) code when accessed from other
> binary code. Generally, this entails everything from method signatures over
> structure sizes to global data (exported symbols) sizes.
>
> One example of ABI-breakage, if you're somewhat proficient in C, could be
> the following:
>
> -- Old code (library header)
>
> /* Some structure which contains a long, and so has total size four bytes
> on i386. */
> struct x {
> 	long y;
> } __attribute__((packed))__;
>
> /* Get access to two x objects. This function is implemented in a shared
> library. It returns a pointer to eight bytes of memory (2*struct x). */
> extern const struct x* getSomeData();
>
> -- Old code (user)
>
> long test() {
> 	const struct x* ref = getSomeData();
> 	return ref[0].y + ref[1].y;
> }
>
> --
>
> Now, when compiling the user code, it will pick up the specification of the
> structure x through the library supplied header file, seeing that
> ref[...].y is a long value (four bytes on i386), and so that will be
> translated to some machine code which adds four bytes from offset zero
> (ref[0].y) of the pointer that getSomeData() returns to four bytes from
> offset four (ref[1].y), and returns the result as a long value.
>
> What happens if the following change to the library is made?
>
> -- New code (library header)
>
> /* Some structure which now contains a short. This reduces the size of the
> structure to two bytes on i386. */
> struct x {
> 	short y;
> } __attribute__((packed))__;
>
> /* Get access to two x objects. This function is implemented in a shared
> library. Due to the change in struct x, this now returns a pointer to
> (only!) four bytes of storage (2*struct x). */
> extern const struct x* getSomeData();
>
> --
>
> The size of the structure member y of structure x has now been reduced to
> two bytes (because the type was changed from long to short), but the user
> code doesn't know this, because it was compiled with the old headers. When
> installing the changed shared library, the old user code will load (!) as
> before, because the symbol getSomeData() is still exported from the shared
> library, but will now erraneously load in total eight bytes from a location
> (because that's hardcoded in the machine code produced for the user binary)
> where it should only load four bytes from after the incompatible change to
> the layout of the structure.
>
> If you were to recompile the user code after installing the updated shared
> library, everything would go back to functioning normally, because now the
> user code picks up the redefined structure x specification which now says
> that it should load only two bytes from offset zero (ref[0].y) and two
> bytes from offset two (ref[1].y) of the returned pointer.
>
> The API has not changed, because the user code would still compile
> properly, but the ABI has, and as such object code compiled before the
> change in the shared library breaks (most often in very mysterious ways).
>
> I don't know exactly what will be changed in the kernel to warrant the
> heads up for this specific case, but as was said, the vnode structure is
> changed (because data was added to it), and as such the structure
> specification has changed. If you now have a KLM which expects the old
> structure layout (because it was compiled before the change), you're bound
> for trouble, because it does not yet know that the offsets for members and
> the total size of the vnode structure has changed, and as such all offsets
> it uses in the vnode structure are broken.
>
> So, if you have a binary only kernel module which requires access/uses the
> vnode structure, you'll have a problem. If not, you don't.
>
> Does this help?

It sure helps the understanding bit but how about specific instructions about 
who is to what to do in this instance?

i.e. Circumstances and what commands to apply in those circumstances?

The general helps understanding.. the specifics provide solutions for the 
problems!!
Thanks again

David


More information about the freebsd-stable mailing list