gcl-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gcl-devel] Re: __divq et.al


From: Camm Maguire
Subject: [Gcl-devel] Re: __divq et.al
Date: Tue, 03 Jul 2007 18:34:26 -0400
User-agent: SEMI/1.14.3 (Ushinoya) FLIM/1.14.3 (Unebigory ōmae) APEL/10.3 Emacs/21.2 (i386-debian-linux-gnu) MULE/5.0 (SAKAKI)

Greetings, and thanks so much for your very helpful reply.

=============================================================================
Camm Maguire <address@hidden> writes:

> Greetings!  Is there any way I can instruct gcc not to put these
> hidden library calls into the .o output? 

No. The Alpha CPU does not have an integer division instruction, so a
libcall is needed. (Incidentally, I have a patch that makes gcc emit
code that uses the FPU instead (at least for 32 bit ops), but that's
not part of mainstream gcc.)

=============================================================================

OK

=============================================================================

> GCL needs a permanent address for them, which is problematic as they
> are in a shared lib, yet I cannot redirect the call through a
> pointer at the C level (there is no call at the C level), nor is it
> clear how to provide a stationary wrapper/trampoline, as the (C)
> call semantics are opaque (to me).

I don't think I really understand the issue. Is it that the code must
not use use any symbol from a shared library whatsoever? Then why is
that and can't it be fixed? And if so, how would a wrapper work
anyway?

-- 
        Falk


=============================================================================

Shared library symbols can be and are used extensively.  It is just
that code referencing them, once loaded into and relocated by GCL,
needs updating if the image is saved and re-executed at a later time,
as the shared library can be in a different place.

Here is how we handle "cos" from libm, for example:

>(disassemble '(lambda (x) (declare (long-float x)) (cos x)) nil)

static double LI1(V2)

double V2;
{        VMB1 VMS1 VMV1
        goto TTL;
TTL:;
        /*(COS X)*/
        {double V3;
        V3= V2;
        {register double V4;
        V4= V3;
        {double V5 = ((double(*)(double))dlcos)(V4);VMR1
        (V5);}}}
        /* END (COS X)*/
}

...

static void *dlcos;

The compiler would like to write cos(V4), but instead writes a pointer
dlcos into the file and makes the call thereby.  dlcos is set to cos
when the .o file is loaded, and reset whenever the saved image is
re-executed. 

There is no C corresonding to the call to __divq, (nor _mcount, etc.),
so the above will not work here.  One idea is to have some sort of
trampoline/wrapper in the GCL .text section, and use that address as
the relocation destination when loading code calling __divq.  The
wrapper address will not move (across image-save/re-exec, which is
accomplished via emacs' unexec) and hence will not need
updating. ld.so will rather update the trampoline at re-exec time in
the normal fashion for all dynamically linked executables.

Alternatively, we could use the real __divq external address at load
time, and reset it when the image is re-executed.  The problem here is
that such addresses can be stored as 16bit hi/lo pairs in the actual
code, etc.  Reproducing that logic is not as simple as writing an
address to a specified location in memory.  If it could be made that
simple, this would also solve the problem.

Finally, I suppose we could include the assembler from glibc into the
gcl build and work around the multiple definitions, but of course I'd
like to avoid this.

(By way of background, GCL uses bfd's
bfd_get_relocated_section_contents, suitably patched for alpha and
mips, do to the relocation.  We cannot simply compile .so files and
dlopen them, primarily as the typical number of loads grealty exceeds
the number of allowable open file descriptors, and images are
typically copied from machine to machine where all the myriad .so
files may not be present.  )

Here is a gdb transcript on s390 showing the problems I'm having with
mcount_wrapper: 

=============================================================================
(gdb) r
Starting program: /home/camm/gclcvs-2.7.0/unixport/saved_pre_gcl 
GCL (GNU Common Lisp)  2.7.0 CLtL1  profiling  Jul  2 2007 21:13:33
Source License: LGPL(gcl,gmp,pargcl), GPL(unexec,bfd,xgcl)
Binary License:  GPL due to GPL'ed components: (BFD UNEXEC)
Modifications of this banner must retain notice of a compatible license
Dedicated to the memory of W. Schelter

Use (help) to get some basic information on how to use GCL.

Temporary directory for compiler files set to /tmp/

>(load "../lsp/gcl_listlib.o")

;; Loading ../lsp/gcl_listlib.o

Breakpoint 1, call_init (init_address=2142817640, memory=0x80148f52, 
    fasl_vec=0x7fb8cd88, fptr=0x20) at cmpaux.c:447
447     {object form;
(gdb) up
#1  0x00087df8 in fasload (faslfile=0xa81f60) at sfaslbfd.c:430
430       call_init(init_address,memory,data,0);
(gdb) p memory->cfd.cfd_start
$1 = 0x68b000 "Pàð\004§\025"
(gdb) add-symbol-file ../lsp/gcl_listlib.o 0x68b000
add symbol table from file "../lsp/gcl_listlib.o" at
        .text_addr = 0x68b000
(y or n) y
Reading symbols from /home/camm/gclcvs-2.7.0/lsp/gcl_listlib.o...done.
(gdb) c
Continuing.

Breakpoint 2, mcount_wrapper (u1=28541000, u2=28541000) at sfasli.c:43
warning: Source file is more recent than executable.
43      mcount_wrapper(unsigned long u1,unsigned long u2) __attribute__ 
((aligned (16))) {
(gdb) up
#1  0x0068b01a in init_gcl_listlib () at ../lsp/gcl_listlib.c:4
4       void init_gcl_listlib(){do_init((void *)VV);}
(gdb) c
Continuing.

Breakpoint 2, mcount_wrapper (u1=2142807032, u2=2148564964) at sfasli.c:43
43      mcount_wrapper(unsigned long u1,unsigned long u2) __attribute__ 
((aligned (16))) {
(gdb) up
#1  0x0068b062 in LI1__ENDP__listlib (V2=0x447d68) at ../lsp/gcl_listlib.c:10
10      {        VMB1 VMS1 VMV1
(gdb) c
Continuing.

Breakpoint 2, mcount_wrapper (u1=2142806928, u2=2013269528) at sfasli.c:43
43      mcount_wrapper(unsigned long u1,unsigned long u2) __attribute__ 
((aligned (16))) {
(gdb) up
#1  0x006be3ce in LnkTLI43 (first=0x7fb8a368) at ../lsp/gcl_listlib.c:14574
14574   static object  LnkTLI43(object first,...){object V1;va_list 
ap;va_start(ap,first);V1=(object )call_vproc_new(((object)VV[43]),0,32,(void 
**)(void *)&LnkLI43,first,ap);va_end(ap);return V1;} /* CHECK-TYPE-SYMBOL */
(gdb) c
Continuing.

Breakpoint 2, mcount_wrapper (u1=15, u2=1) at sfasli.c:43
43      mcount_wrapper(unsigned long u1,unsigned long u2) __attribute__ 
((aligned (16))) {
(gdb) up
#1  0x0068b062 in LI1__ENDP__listlib (V2=0x447d68) at ../lsp/gcl_listlib.c:10
10      {        VMB1 VMS1 VMV1
(gdb) disassemble
Dump of assembler code for function LI1__ENDP__listlib:
0x0068b048 <LI1__ENDP__listlib+0>:      st      %r14,4(%r15)
0x0068b04c <LI1__ENDP__listlib+4>:      bras    %r1,0x68b058 
<LI1__ENDP__listlib+16>
0x0068b050 <LI1__ENDP__listlib+8>:      .long   0x00087f44
0x0068b054 <LI1__ENDP__listlib+12>:     .long   0x006be828
0x0068b058 <LI1__ENDP__listlib+16>:     l       %r14,0(%r1)
0x0068b05c <LI1__ENDP__listlib+20>:     l       %r1,4(%r1)
0x0068b060 <LI1__ENDP__listlib+24>:     basr    %r14,%r14
0x0068b062 <LI1__ENDP__listlib+26>:     l       %r14,4(%r15)
0x0068b066 <LI1__ENDP__listlib+30>:     stm     %r6,%r15,24(%r15)
0x0068b06a <LI1__ENDP__listlib+34>:     basr    %r13,%r0
0x0068b06c <LI1__ENDP__listlib+36>:     ahi     %r15,-120
0x0068b070 <LI1__ENDP__listlib+40>:     lr      %r11,%r15
0x0068b072 <LI1__ENDP__listlib+42>:     st      %r2,96(%r11)
0x0068b076 <LI1__ENDP__listlib+46>:     mvc     108(4,%r11),96(%r11)
0x0068b07c <LI1__ENDP__listlib+52>:     l       %r1,108(%r11)
0x0068b080 <LI1__ENDP__listlib+56>:     ltr     %r1,%r1
0x0068b082 <LI1__ENDP__listlib+58>:     jl      0x68b0b2 
<LI1__ENDP__listlib+106>
0x0068b086 <LI1__ENDP__listlib+62>:     l       %r2,108(%r11)
0x0068b08a <LI1__ENDP__listlib+66>:     l       %r1,0(%r2)
0x0068b08e <LI1__ENDP__listlib+70>:     n       %r1,224(%r13)
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) i reg r14
r14            0x8068b062       -2140622750
(gdb) i reg r15
r15            0x7fb88610       2142799376
(gdb) i reg r6
r6             0x804    2052
(gdb) c
Continuing.

Breakpoint 2, mcount_wrapper (u1=2142838120, u2=2052) at sfasli.c:43
43      mcount_wrapper(unsigned long u1,unsigned long u2) __attribute__ 
((aligned (16))) {
(gdb) 
Continuing.

Breakpoint 2, mcount_wrapper (u1=15, u2=1) at sfasli.c:43
43      mcount_wrapper(unsigned long u1,unsigned long u2) __attribute__ 
((aligned (16))) {
(gdb) 
Continuing.

Breakpoint 2, mcount_wrapper (u1=2142838120, u2=2052) at sfasli.c:43
43      mcount_wrapper(unsigned long u1,unsigned long u2) __attribute__ 
((aligned (16))) {
(gdb) 
Continuing.

Breakpoint 2, mcount_wrapper (u1=15, u2=1) at sfasli.c:43
43      mcount_wrapper(unsigned long u1,unsigned long u2) __attribute__ 
((aligned (16))) {
(gdb) 
=============================================================================

Thanks so much again.  It would be also helpful if you could comment
on the simplest way to extract these codes from glibc (sysdeps/alpha)
and build them separately, just in case that is the only option.

Take care,
-- 
Camm Maguire                                            address@hidden
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah




reply via email to

[Prev in Thread] Current Thread [Next in Thread]