Bournegol (2014)

8 points by icefox


fanf

This provoked me to try to remind myself about the details of the Bourne shell memory allocator, because it has a reputation for causing horrible problems when porting the shell from the PDP11 to other computers.

But tbh, I’m not sure how it worked…

The intro to Bournegol is the macros that make C look vaguely like Algol 68 https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/mac.h

But there are also macros that make C look more like BCPL (which is amazing given how close C was to BCPL already).

And there are signs in the code that suggest to me that some of the macros predate the introduction of cast syntax (type)value into C, which happened some time between 6th edition unix and k&r, which was shortly before 7th edition unix.

The fun part of the allocator that caused the portability headaches was in https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/fault.c where the signal handler says

	IF sig==MEMF
	THEN	IF setbrk(brkincr) == -1
		THEN	error(nospace);
		FI

MEMF is an alias for SIGSEGV, so when that happens it just asks the kernel to extend its segment and returns from the signal handler.

Which implies that the allocator just walks off the end of its segment hoping for the best, and the segv handler tries to make the best happen.

So let’s take a look at the allocator in https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/blok.c

BLKPTR		bloktop=BLK(end);	/*top of arena (last blok)*/
…
	bloktop=bloktop->word=BLK(Rcheat(bloktop)+reqd);
	bloktop->word=BLK(ADR(end)+1);

There’s a lot of magic happening here!

    /* the following nonsense is required
     * because casts turn an Lvalue
     * into an Rvalue so two cheats
     * are necessary, one for each context.
     */
    union { int _cheat;};
    #define Lcheat(a)	((a)._cheat)
    #define Rcheat(a)	((int)(a))
    /* heap storage */
     struct blk {
    	BLKPTR	word;
    };

both of those quotes from https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/mode.h

/* stack */
#define		BLK(x)	((BLKPTR)(x))
#define		BYT(x)	((BYTPTR)(x))
#define		STK(x)	((STKPTR)(x))
#define		ADR(x)	((char*)(x))
lorddimwit

Each day we stray farther from God’s light.