Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Aug 2004 13:59:29 -0700 (PDT)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        Alexander Kabaev <kan@freebsd.org>
Cc:        FreeBSD Current List <current@freebsd.org>
Subject:   Other unit-at-a-time issues (Re: HEADS UP! boot2 problems)
Message-ID:  <200408062059.i76KxTBW026143@apollo.backplane.com>
References:  <4109B4EF.605@samsco.org> <20040730152119.GA43119@freefall.freebsd.org>

Next in thread | Previous in thread | Raw E-Mail | Index | Archive | Help
    I tracked down one problem with the unit-at-a-time code.... it's not
    compatible with -mrtd.  Bad code is produced, specifically a missing
    pop in a call.

    After removing -mrtd the DFly boot code progressed a bit farther before
    crashing, but unfortunately it still crashed.  -fno-unit-at-a-time is 
    still required to produce a good 'boot2' boot block even when -mrtd is
    removed.

    I was able to determine that the issue is solely with boot2... the
    /boot/loader built with the (default) unit-at-a-time feature appear
    to work just fine.

    I have not tracked down the additional bad assembly being produced,
    but it is not an impossible task.  The boot2 objdump is not
    actually all that big, but the functions are reordered and I didn't
    want to spend all day tracking down the remaining bugs.

    --

    I would appreciate it if someone in FreeBSD land would submit this bug
    to the GCC folks.

						-Matt


/*
 * X.C -	demonstrate -mrtd and unit-at-a-time conflict with gcc-3.4
 *		Note the bad assembly produced (also included below)
 *
 * Tracked down by Matthew Dillon, The DragonFly Project.
 *
 * cc -v:
 *   Using built-in specs.
 *   Configured with: ./configure --prefix=/usr --host=i386-just-dragonflybsd
 *   Thread model: posix
 *   gcc version 3.4.1 20040618 [DragonFly] (propolice, prerelease)
 *
 * Compile with:

cc -elf -Os -fno-builtin -fno-stack-protector \
        -fomit-frame-pointer -mrtd \
        -ffreestanding -mpreferred-stack-boundary=2 \
        -S x.c

 */
extern void fubar(int c);
extern void v86int(void);
extern void sio_putc(int c);
extern int opts;

#define RBF_VIDEO	0x0001
#define RBF_SERIAL	0x0002

static void xputc(int);

static struct {
    int addr;
    int eax;
    int ebx;
} v86;

static inline void
putc(int c)
{
    v86.addr = 0x10;
    v86.eax = 0xe00 | (c & 0xff);
    v86.ebx = 0x7;
    v86int();
}

static void
xputc(int c)
{
    if (opts & RBF_VIDEO)   
        putc(c);
    if (opts & RBF_SERIAL)
        sio_putc(c);
}

void
fubar(int c)
{
    if (c == '\n')
	xputc('\r');
    xputc(c);
    sio_putc(c);
    putc(c);
}




	.file	"x.c"
	.version	"01.01"
gcc2_compiled.:
.text
	.p2align 2,0x90
		.type		 xputc,@function
xputc:
	pushl %ebx
	movl 8(%esp),%ebx
	testb $1,opts
	je .L4
	movl $16,v86
	movl %ebx,%eax
	andl $255,%eax
	orb $14,%ah
	movl %eax,v86+4
	movl $7,v86+8
	call v86int
.L4:
	testb $2,opts
	je .L6
	pushl %ebx
	call sio_putc
			<<<<<<<<<<<<<<<<<<<< MISSING POP!!!!
.L6:
	popl %ebx
	ret $4
.Lfe1:
		.size		 xputc,.Lfe1-xputc
	.p2align 2,0x90
.globl fubar
		.type		 fubar,@function
fubar:
	pushl %ebx
	movl 8(%esp),%ebx
	cmpl $10,%ebx
	jne .L8
	pushl $13
	call xputc
.L8:
	pushl %ebx
	call xputc
	pushl %ebx
	call sio_putc
	movl $16,v86
	movzbl %bl,%ebx
	orb $14,%bh
	movl %ebx,v86+4
	movl $7,v86+8
	call v86int
	popl %ebx
	ret $4
.Lfe2:
		.size		 fubar,.Lfe2-fubar
	.local	v86
	.comm	v86,12,4
	.ident	"GCC: (GNU) c 2.95.4 20020320 [DragonFly]"



Want to link to this message? Use this URL: <http://docs.FreeBSD.org/cgi/mid.cgi?200408062059.i76KxTBW026143>