Re: _syscall2 in PIC code on ix86

From: Horst von Brand (vonbrand@sleipnir.valparaiso.cl)
Date: Sun Jan 16 2000 - 10:53:18 EST


Chris Noe <stiker@northlink.com> said:

[...]

> gcc pic_sys.c -fPIC -o pic_sys
> syscall.c: In function `getsid':
> syscall.c:7: fixed or forbidden register 3 (bx) was spilled for class BREG.
> This may be due to a compiler bug or to impossible asm
> statements or clauses.

%ebx is used to hold a pointer to the GOT for PIC, and syscalls are trying
to use ot for the second argument.

> I tried listing it in the clobbers, to no avail. I'm a bit more familiar
> with just gas, without all this C crap on top of it :) :)

You can't do anything to %ebx, it is reserved and out of limits.

> btw, does it matter that I've split the "pushl %ebx / int 0x80" over two
> separate asm lines?

If you are using separate asm()s, they are considered separately by the
compiler. Without volatile it might just move them around, and it might try
to place instructions in betweeen regardless. You have to write each one as
a single strech in one asm().

> I wouldn't think so because of the volatile, but I'm
> not 100% sure. The reason I did it was so that the pushl/popl would be
> consistent with one percent sign; if it were inside the asm with "int
> $0x80" then it'd need two percents.

They need two anyway, % is used in asm() just like in printf(3) to
introduce special formatting (%0 is replaced by whatever text the first arg
gives, etc). So to get '%' you have to write '%%'. You'll have to juggle
them into the right registers yourself.

BTW, how is this important? glibc is doing it right, I'd say leave it along
(and perhaps point people who want to build their own shlib using raw
syscalls to glibc for ideas)

> --- /usr/src/linux-2.3.39/include/asm/unistd.h Wed Jan 12 18:21:12 2000
> +++ linux/include/asm/unistd.h Sat Jan 15 11:29:32 2000
> @@ -311,6 +311,90 @@
> __syscall_return(type,__res); \
> }
>
> +/* PIC versions of the above (push/pop %ebx) */
> +
> +/* no need to save %ebx for syscall0, as it isn't used */
> +#define _syscall0_pic(type,name) _syscall0(type,name)
> +
> +#define _syscall1_pic(type,name,type1,arg1) \
> +type name(type1 arg1) \
> +{ \
> +long __res; \
> +__asm__ volatile ("pushl %ebx"); \
> +__asm__ volatile ("int $0x80" \
> + : "=a" (__res) \
> + : "0" (__NR_##name),"b" ((long)(arg1))); \
                            ^^^
                             Can't use %ebx here, off limits
> +__asm__ volatile ("popl %ebx"); \
> +__syscall_return(type,__res); \
> +}

-- 
Horst von Brand                             vonbrand@sleipnir.valparaiso.cl
Casilla 9G, Viņa del Mar, Chile                               +56 32 672616

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Jan 23 2000 - 21:00:13 EST