Implement changes needed for Linux ELF binary format. This format,
authorChris Hanson <org/chris-hanson/cph>
Thu, 5 Oct 1995 03:34:50 +0000 (03:34 +0000)
committerChris Hanson <org/chris-hanson/cph>
Thu, 5 Oct 1995 03:34:50 +0000 (03:34 +0000)
unlike the older a.out format, translates the data segment to begin at
0x08000000, and additionally changes the calling conventions so that
returned structures are allocated by the caller and passed in as
pointers.  We fix the first problem by extending the win32s segment
register manipulation to also be used with Linux ELF.  The second
problem is fixed by extending the OS/2 assembly-language patches to
also cover Linux ELF.

v7/src/microcode/cmpauxmd/i386.m4
v7/src/microcode/cmpintmd/i386.h
v7/src/microcode/config.h
v7/src/microcode/s/linux.h
v7/src/microcode/uxtop.c

index 94fd6e8af3808d9da4a187105d9f8826156dff37..3adcb5e0fcf7531ce2fab171c5c8deced21a8320 100644 (file)
@@ -1,6 +1,6 @@
 ### -*-Midas-*-
 ###
-###    $Id: i386.m4,v 1.37 1995/10/01 07:19:42 cph Exp $
+###    $Id: i386.m4,v 1.38 1995/10/05 03:32:24 cph Exp $
 ###
 ###    Copyright (c) 1992-95 Massachusetts Institute of Technology
 ###
@@ -116,10 +116,18 @@ ifdef(`DOS',
       `define(IFNDOS,`')',
       `define(IFNDOS,`$1')')
 
+ifdef(`WINNT',
+      `define(IF_WINNT,`$1')',
+      `define(IF_WINNT,`')')
+
 ifdef(`OS2',
       `define(IFOS2,`$1')',
       `define(IFOS2,`')')
 
+ifdef(`LINUX_ELF',
+      `define(IF_LINUX_ELF,`$1')',
+      `define(IF_LINUX_ELF,`')')
+
 ifdef(`DISABLE_387',
       `define(IF387,`')',
       `define(IF387,`$1')')
@@ -138,9 +146,8 @@ ifdef(`DOS',
       `define(use_external_code,`      extrn _$1:near')',
       `define(use_external_code,`')')
 
-ifdef(`OS2',
-      `define(`SUPPRESS_LEADING_UNDERSCORE',1)',
-      `')
+IFOS2(`define(`SUPPRESS_LEADING_UNDERSCORE',1)')
+IF_LINUX_ELF(`define(`SUPPRESS_LEADING_UNDERSCORE',1)')
 
 ifdef(`SUPPRESS_LEADING_UNDERSCORE',
       `define(external_data_reference,`$1')',
@@ -158,7 +165,7 @@ ifdef(`DOS',
 
 ifdef(`DOS',
       `define(define_data,`    public _$1')',
-      `define(define_data,`    .globl external_code_reference($1)')')
+      `define(define_data,`    .globl external_data_reference($1)')')
 
 define(define_c_label,
 `define_code($1)
@@ -305,17 +312,20 @@ use_external_data(Free)
 use_external_data(Ext_Stack_Pointer)
 use_external_data(utility_table)
 
-ifdef(`WINNT',
-`      extrn _RegistersPtr:dword',
-`ifdef(`DOS',
-`use_external_data(Registers)',
-`define_data(Regstart)
+ifdef(`WINNT',`
+       extrn _RegistersPtr:dword
+',`ifdef(`DOS',`
+use_external_data(Registers)
+',`
+define_data(Regstart)
 allocate_space(Regstart,128)
+
 define_data(Registers)
-allocate_space(Registers,eval(REGBLOCK_SIZE_IN_OBJECTS*4))')')
+allocate_space(Registers,eval(REGBLOCK_SIZE_IN_OBJECTS*4))
+')
+')
 
-ifdef(`WINNT',
-`      extrn _winnt_address_delta:dword')
+IF_WINNT(`     extrn _winnt_address_delta:dword')
 
 define_data(i387_presence)
 allocate_longword(i387_presence)
@@ -326,27 +336,53 @@ allocate_longword(C_Stack_Pointer)
 define_data(C_Frame_Pointer)
 allocate_longword(C_Frame_Pointer)
 
-ifdef(`WINNT',`define_data(Scheme_Transfer_Address)
-allocate_longword(Scheme_Transfer_Address)')
+IF_WINNT(`define(HACK_SEGMENT_REGS,1)')
+IF_LINUX_ELF(`define(HACK_SEGMENT_REGS,1)')
 
-ifdef(`WINNT',`define_data(Scheme_Code_Segment_Selector)
+ifdef(`HACK_SEGMENT_REGS',`
+
+define_data(Scheme_Transfer_Address)
+allocate_longword(Scheme_Transfer_Address)
+
+define_data(Scheme_Code_Segment_Selector)
 allocate_word(Scheme_Code_Segment_Selector)
+
 define_data(Scheme_Data_Segment_Selector)
 allocate_word(Scheme_Data_Segment_Selector)
+
 define_data(Scheme_Stack_Segment_Selector)
 allocate_word(Scheme_Stack_Segment_Selector)
+
 define_data(C_Code_Segment_Selector)
 allocate_word(C_Code_Segment_Selector)
+
 define_data(C_Data_Segment_Selector)
 allocate_word(C_Data_Segment_Selector)
+
 define_data(C_Extra_Segment_Selector)
 allocate_word(C_Extra_Segment_Selector)
+
 define_data(C_Stack_Segment_Selector)
-allocate_word(C_Stack_Segment_Selector)',
-`IFDOS(`define_data(C_Stack_Segment_Selector)
 allocate_word(C_Stack_Segment_Selector)
+
+IF_WINNT(`define(RETF,`db      0cbh')')
+IF_LINUX_ELF(`define(RETF,`.byte       0xcb')')
+
+IF_WINNT(`define(SEGMENT_DELTA,`EDR(winnt_address_delta)')')
+IF_LINUX_ELF(`define(SEGMENT_DELTA,`IMM(0x08000000)')')
+
+',`IFDOS(`
+
+define_data(C_Stack_Segment_Selector)
+allocate_word(C_Stack_Segment_Selector)
+
 define_data(Scheme_Stack_Segment_Selector)
-allocate_word(Scheme_Stack_Segment_Selector)')')
+allocate_word(Scheme_Stack_Segment_Selector)
+
+')')
+
+IFOS2(`define(USE_STRUCS,1)')
+IF_LINUX_ELF(`define(USE_STRUCS,1)')
 \f
 DECLARE_CODE_SEGMENT()
 declare_alignment(2)
@@ -356,32 +392,40 @@ define_c_label(i386_interface_initialize)
        OP(mov,l)       TW(REG(esp),REG(ebp))
 
                                                        # Initialize selectors
-ifdef(`WINNT',
-`      lea     eax,cross_segment_transfer_point
-       mov     _Scheme_Transfer_Address,eax
-       mov     _C_Extra_Segment_Selector,es            ; This assumes it is constant
-
-       mov     _C_Code_Segment_Selector,cs
-       mov     ax,_Scheme_Code_Segment_Selector
-       cmp     ax,0
-       jne     skip_code_assignment
-       mov     _Scheme_Code_Segment_Selector,cs
+ifdef(`HACK_SEGMENT_REGS',`
+       OP(lea,l)       TW(ABS(cross_segment_transfer_point),REG(eax))
+       OP(mov,l)       TW(REG(eax),EDR(Scheme_Transfer_Address))
+       OP(mov,w)       TW(REG(es),EDR(C_Extra_Segment_Selector)) # This assumes it is constant
+
+       OP(mov,w)       TW(REG(cs),EDR(C_Code_Segment_Selector))
+       OP(mov,w)       TW(EDR(Scheme_Code_Segment_Selector),REG(ax))
+       OP(cmp,w)       TW(IMM(0),REG(ax))
+       jne             skip_code_assignment
+       OP(mov,w)       TW(REG(cs),EDR(Scheme_Code_Segment_Selector))
 skip_code_assignment:
 
-       mov     _C_Data_Segment_Selector,ds
-       mov     ax,_Scheme_Data_Segment_Selector
-       cmp     ax,0
-       jne     skip_data_assignment
-       mov     _Scheme_Data_Segment_Selector,ds
-skip_data_assignment:')
+       OP(mov,w)       TW(REG(ds),EDR(C_Data_Segment_Selector))
+       OP(mov,w)       TW(EDR(Scheme_Data_Segment_Selector),REG(ax))
+       OP(cmp,w)       TW(IMM(0),REG(ax))
+       jne             skip_data_assignment
+       OP(mov,w)       TW(REG(ds),EDR(Scheme_Data_Segment_Selector))
+skip_data_assignment:
 
-IFDOS(`        OP(mov,w)       TW(REG(ss),EDR(C_Stack_Segment_Selector))
+       OP(mov,w)       TW(REG(ss),EDR(C_Stack_Segment_Selector))
        OP(mov,w)       TW(EDR(Scheme_Stack_Segment_Selector),REG(ax))
        OP(cmp,w)       TW(IMM(0),REG(ax))
        jne             skip_stack_assignment
        OP(mov,w)       TW(REG(ds),EDR(Scheme_Stack_Segment_Selector))
-skip_stack_assignment:')
-
+skip_stack_assignment:
+',`IFDOS(`
+       OP(mov,w)       TW(REG(ss),EDR(C_Stack_Segment_Selector))
+       OP(mov,w)       TW(EDR(Scheme_Stack_Segment_Selector),REG(ax))
+       OP(cmp,w)       TW(IMM(0),REG(ax))
+       jne             skip_stack_assignment
+       OP(mov,w)       TW(REG(ds),EDR(Scheme_Stack_Segment_Selector))
+skip_stack_assignment:
+')
+')
        OP(xor,l)       TW(REG(eax),REG(eax))           # No 387 available
 
 # Unfortunately, the `movl cr0,ecx' instruction is privileged.
@@ -408,7 +452,8 @@ IF387(`
              `OP(or,w) TW(IMM(HEX(0220)),WOF(-2,REG(ebp)))')
        fldcw   WOF(-2,REG(ebp))
 
-i386_initialize_no_fp:')
+i386_initialize_no_fp:
+')
        OP(mov,l)       TW(REG(eax),EDR(i387_presence))
        leave
        ret
@@ -427,10 +472,11 @@ define_c_label(C_to_interface)
                                                        # Register block = %esi
                                                        # Scheme offset in NT
 
-       ifdef(`WINNT',
-       `mov    esi,dword ptr _RegistersPtr
-       sub     esi,_winnt_address_delta',      
-       `OP(lea,l)      TW(ABS(EDR(Registers)),regs)')
+ifdef(`WINNT',
+`      OP(mov,l)       TW(ABS(EDR(RegistersPtr)),regs)',
+`      OP(lea,l)       TW(ABS(EDR(Registers)),regs)')
+ifdef(`HACK_SEGMENT_REGS',
+`      OP(sub,l)       TW(SEGMENT_DELTA,regs)')
        jmp     external_code_reference(interface_to_scheme)
 
 define_c_label(asm_trampoline_to_interface)
@@ -446,38 +492,44 @@ define_debugging_label(scheme_to_interface_call)
 \f
 define_c_label(asm_scheme_to_interface)
 define_debugging_label(scheme_to_interface)
-ifdef(`WINNT',
-`      push    dword ptr 36[esi]                       ; 4th utility arg
-       push    eax                                     ; Save utility index
+ifdef(`HACK_SEGMENT_REGS',
+`      OP(push,l)      LOF(36,regs)                    # 4th utility arg
+       OP(push,l)      REG(eax)                        # Save utility index
 
-       mov     ax,es                                   ; C ds
-       mov     ds,ax
+       OP(mov,w)       TW(REG(es),REG(ax))             # C ds
+       OP(mov,w)       TW(REG(ax),REG(ds))
 
-       mov     ax,_C_Extra_Segment_Selector            ; C es
-       mov     es,ax
-       add     edi,_winnt_address_delta                ; Map Free to C data space
-       mov     _Free,edi
+       OP(mov,w)       TW(EDR(C_Extra_Segment_Selector),REG(ax)) # C es
+       OP(mov,w)       TW(REG(ax),REG(es))
 
-       mov     eax,esp                                 ; Map SP to C data space
-       add     eax,_winnt_address_delta
-       mov     _Ext_Stack_Pointer,eax
+# Map Free to C data space
+       OP(add,l)       TW(SEGMENT_DELTA,rfree)
+       OP(mov,l)       TW(rfree,EDR(Free))
 
-       mov     ss,_C_Stack_Segment_Selector            ; Switch stack segment
-       mov     esp,_C_Stack_Pointer
-       mov     ebp,_C_Frame_Pointer
+# Map SP to C data space
+       OP(mov,l)       TW(REG(esp),REG(eax))
+       OP(add,l)       TW(SEGMENT_DELTA,REG(eax))
+       OP(mov,l)       TW(REG(eax),EDR(Ext_Stack_Pointer))
 
-       xor     eax,eax
-       mov     ax,_C_Code_Segment_Selector
-       push    eax
-       push    _Scheme_Transfer_Address
-       db      0cbh                                    ; retf
+# Switch stack segment
+       OP(mov,w)       TW(EDR(C_Stack_Segment_Selector),REG(ss))
+       OP(mov,l)       TW(EDR(C_Stack_Pointer),REG(esp))
+       OP(mov,l)       TW(EDR(C_Frame_Pointer),REG(ebp))
 
-cross_segment_transfer_point:
+       OP(xor,l)       TW(REG(eax),REG(eax))
+       OP(mov,w)       TW(EDR(C_Code_Segment_Selector),REG(ax))
+       OP(push,l)      REG(eax)
+       OP(push,l)      EDR(Scheme_Transfer_Address)
+       RETF
 
-       mov     eax,_Ext_Stack_Pointer
-       push    dword ptr 4[eax]                        ; 4th utility arg
-       add     _Ext_Stack_Pointer,8
-       mov     eax, dword ptr [eax]                    ; utility index
+cross_segment_transfer_point:
+ifdef(`USE_STRUCS',`
+       OP(sub,l)       TW(IMM(8),REG(esp))     # alloc space for struct return
+')
+       OP(mov,l)       TW(EDR(Ext_Stack_Pointer),REG(eax))
+       OP(push,l)      LOF(4,REG(eax))                 # 4th utility arg
+       OP(add,l)       TW(IMM(8),EDR(Ext_Stack_Pointer))
+       OP(mov,l)       TW(IND(REG(eax)),REG(eax))      # utility index
 ',
 
 `      OP(mov,l)       TW(REG(esp),EDR(Ext_Stack_Pointer))
@@ -488,7 +540,8 @@ IFDOS(`     OP(mov,w)       TW(EDR(C_Stack_Segment_Selector),REG(ss))')     # Swap stack segme
        OP(mov,l)       TW(EDR(C_Stack_Pointer),REG(esp))
        OP(mov,l)       TW(EDR(C_Frame_Pointer),REG(ebp))
 
-IFOS2(`        OP(sub,l)       TW(IMM(8),REG(esp))     # alloc space for struct return
+ifdef(`USE_STRUCS',`
+       OP(sub,l)       TW(IMM(8),REG(esp))     # alloc space for struct return
 ')
        OP(push,l)      LOF(REGBLOCK_UTILITY_ARG4(),regs) # Utility args
 ')
@@ -496,7 +549,8 @@ IFOS2(`     OP(sub,l)       TW(IMM(8),REG(esp))     # alloc space for struct return
        OP(push,l)      REG(edx)
        OP(push,l)      REG(ecx)
 
-IFOS2(`        OP(mov,l)       TW(REG(esp),REG(ecx))   # push pointer to struct return
+ifdef(`USE_STRUCS',`
+       OP(mov,l)       TW(REG(esp),REG(ecx))   # push pointer to struct return
        OP(add,l)       TW(IMM(16),REG(ecx))
        OP(push,l)      REG(ecx)
 ')
@@ -504,22 +558,26 @@ IFOS2(`   OP(mov,l)       TW(REG(esp),REG(ecx))   # push pointer to struct return
        OP(xor,l)       TW(REG(ecx),REG(ecx))
        OP(mov,b)       TW(REG(al),REG(cl))
        OP(mov,l)       TW(SDX(EDR(utility_table),REG(ecx),4),REG(eax))
-       call    IJMP(REG(eax))
+       call            IJMP(REG(eax))
 
 define_debugging_label(scheme_to_interface_return)
-IFOS2(`        OP(add,l)       TW(IMM(4),REG(esp))     # pop pointer to struct return
+ifdef(`USE_STRUCS',`
+       OP(add,l)       TW(IMM(4),REG(esp))     # pop pointer to struct return
 ')
        OP(add,l)       TW(IMM(16),REG(esp))            # Pop utility args
 
-       ifdef(`WINNT',
-       `',
-`IFDOS(`OP(mov,l)      TW(LOF(4,REG(eax)),REG(edx))
-       OP(mov,l)       TW(IND(REG(eax)),REG(eax))')')
-
-IFOS2(`        OP(pop,l)       REG(eax)        # Pop struct return into registers
-       OP(pop,l)       REG(edx)')
+ifdef(`WINNT',`',`
+IFDOS(`
+       OP(mov,l)       TW(LOF(4,REG(eax)),REG(edx))
+       OP(mov,l)       TW(IND(REG(eax)),REG(eax))
+')
+')
 
-       jmp     IJMP(REG(eax))                          # Invoke handler
+ifdef(`USE_STRUCS',`
+       OP(pop,l)       REG(eax)        # Pop struct return into registers
+       OP(pop,l)       REG(edx)
+')
+       jmp             IJMP(REG(eax))                  # Invoke handler
 
 define_c_label(interface_to_scheme)
 IF387(`
@@ -533,59 +591,56 @@ IF387(`
        ffree   ST(5)
        ffree   ST(6)
        ffree   ST(7)
-interface_to_scheme_proceed:')
-ifdef(`WINNT',
-`      mov     edi,_Free                               ; Free pointer = %edi
-       sub     edi,_winnt_address_delta                ; as a scheme offset
-
-       mov     ebp,67108863                            ; pointer mask #x03ffffff
-
-       mov     eax,_Ext_Stack_Pointer                  ; Switch stacks
-       sub     eax,_winnt_address_delta
-       mov     ss,_Scheme_Stack_Segment_Selector
-       mov     esp,eax
-                               
-       sub     edx,_winnt_address_delta                ; Entry point to new space
-       xor     ecx,ecx                                 ; Setup cross-segment jump
-       mov     cx,_Scheme_Code_Segment_Selector
-
-       mov     ax,ds                                   ; Store C ds in es,
-       mov     es,ax                                   ;  unused by Scheme.
-       mov     ax,_Scheme_Data_Segment_Selector        ; Switch data segments
-       mov     ds,ax
-                                                       
-       push    ecx
-       push    edx
-
-       mov     eax,dword ptr 8[esi]                    ; Value/dynamic link
-       mov     ecx,eax                                 ; Preserve if used
-       and     ecx,ebp                                 ; Restore potential
-                                                       ;  dynamic link
-       mov     dword ptr 16[esi],ecx
-       db      0cbh                                    ; retf
+interface_to_scheme_proceed:
+')
+ifdef(`HACK_SEGMENT_REGS',
+`      OP(mov,l)       TW(EDR(Free),rfree)
+       OP(sub,l)       TW(SEGMENT_DELTA,rfree)
+       OP(mov,l)       TW(IMM(ADDRESS_MASK),rmask)
+
+       OP(mov,l)       TW(EDR(Ext_Stack_Pointer),REG(eax)) # Switch stacks
+       OP(sub,l)       TW(SEGMENT_DELTA,REG(eax))
+       OP(mov,w)       TW(EDR(Scheme_Stack_Segment_Selector),REG(ss))
+       OP(mov,l)       TW(REG(eax),REG(esp))
+
+       OP(sub,l)       TW(SEGMENT_DELTA,REG(edx))      # Entry point to new space
+       OP(xor,l)       TW(REG(ecx),REG(ecx))           # Setup cross-segment jump
+       OP(mov,w)       TW(EDR(Scheme_Code_Segment_Selector),REG(ecx))
+
+       OP(mov,w)       TW(REG(ds),REG(ax))             # Store C ds in es,
+       OP(mov,w)       TW(REG(ax),REG(es))             #  unused by Scheme.
+       OP(mov,w)       TW(EDR(Scheme_Data_Segment_Selector),REG(ax)) # Switch data segments
+       OP(mov,w)       TW(REG(ax),REG(ds))
+
+       OP(push,l)      REG(ecx)
+       OP(push,l)      REG(edx)
+
+       OP(mov,l)       TW(LOF(REGBLOCK_VAL(),regs),REG(eax)) # Value/dynamic link
+       OP(mov,l)       TW(REG(eax),REG(ecx))           # Preserve if used
+       OP(and,l)       TW(rmask,REG(ecx))              # Restore potential dynamic link
+       OP(mov,l)       TW(REG(ecx),LOF(REGBLOCK_DLINK(),regs))
+       RETF                                            # Perform cross-segment jump
 ',
 `      OP(mov,l)       TW(EDR(Free),rfree)             # Free pointer = %edi
-                                                       # Value/dynamic link
-       OP(mov,l)       TW(LOF(REGBLOCK_VAL(),regs),REG(eax))
+       OP(mov,l)       TW(LOF(REGBLOCK_VAL(),regs),REG(eax)) # Value/dynamic link
        OP(mov,l)       TW(IMM(ADDRESS_MASK),rmask)     # = %ebp
 
-                                                       # Swap stack segments
-IFDOS(`        OP(mov,w)       TW(EDR(Scheme_Stack_Segment_Selector),REG(ss))')
+IFDOS(`        OP(mov,w)       TW(EDR(Scheme_Stack_Segment_Selector),REG(ss))') # Swap stack segments
 
        OP(mov,l)       TW(EDR(Ext_Stack_Pointer),REG(esp))
        OP(mov,l)       TW(REG(eax),REG(ecx))           # Preserve if used
-       OP(and,l)       TW(rmask,REG(ecx))              # Restore potential
-                                                       #  dynamic link
+       OP(and,l)       TW(rmask,REG(ecx))              # Restore potential dynamic link
        OP(mov,l)       TW(REG(ecx),LOF(REGBLOCK_DLINK(),regs))
-       jmp     IJMP(REG(edx))')
+       jmp             IJMP(REG(edx))')
 
-ifdef(`WINNT',
-`      extrn   _WinntExceptionTransferHook:near
+IF_WINNT(`
+       extrn   _WinntExceptionTransferHook:near
 
        public  _callWinntExceptionTransferHook
 _callWinntExceptionTransferHook:
        call    _WinntExceptionTransferHook
-       mov     edx,eax')
+       mov     edx,eax
+')
 
 define_c_label(interface_to_C)
 IF387(`
index e9064a5ed92afd5462c01c4df5342fbf3f0ea58f..ebe5e41d2ef130b9079a37c761dd3349f496fe24 100644 (file)
@@ -1,8 +1,8 @@
 /* -*-C-*-
 
-$Id: i386.h,v 1.25 1994/11/28 04:05:21 cph Exp $
+$Id: i386.h,v 1.26 1995/10/05 03:32:49 cph Exp $
 
-Copyright (c) 1992-94 Massachusetts Institute of Technology
+Copyright (c) 1992-95 Massachusetts Institute of Technology
 
 This material was developed by the Scheme project at the Massachusetts
 Institute of Technology, Department of Electrical Engineering and
@@ -497,13 +497,8 @@ long i386_pc_displacement_relocation = 0;
 
 #define ASM_RESET_HOOK i386_reset_hook
 
-#if !defined(WINNT) || defined(WINNT_RAW_ADDRESSES)
-#  define HOOK_TO_SCHEME_OFFSET(hook)                                  \
-  ((unsigned long) (hook))
-#else
-extern unsigned long winnt_address_delta;
-#  define HOOK_TO_SCHEME_OFFSET(hook)                                  \
-  (((unsigned long) (hook)) - winnt_address_delta)
+#ifndef HOOK_TO_SCHEME_OFFSET
+#define HOOK_TO_SCHEME_OFFSET(hook) ((unsigned long) (hook))
 #endif
 
 #define SETUP_REGISTER(hook) do                                                \
index b94f325353b68c7991362d0f97e960bdca848597..197fc564a810ceba8e92bdcd87492fc6aadb8b11 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: config.h,v 9.90 1995/10/04 22:53:58 cph Exp $
+$Id: config.h,v 9.91 1995/10/05 03:32:04 cph Exp $
 
 Copyright (c) 1987-95 Massachusetts Institute of Technology
 
@@ -459,9 +459,35 @@ extern unsigned long winnt_address_delta;
 
 #define SCHEME_ADDR_TO_ADDR(saddr) (DATUM_TO_ADDRESS (saddr))
 #define ADDR_TO_SCHEME_ADDR(caddr) (ADDRESS_TO_DATUM (caddr))
+#define HOOK_TO_SCHEME_OFFSET(hook) (ADDRESS_TO_DATUM (hook))
 
 #endif /* WINNT && !WINNT_RAW_ADDRESSES */
 
+#if defined(__linux) && defined(__ELF__)
+
+/* Linux ELF adds a data-segment bit which must be translated away.
+   We'll use the same trick as Win32s since the code is there and it
+   maintains binary compatibility.  */
+
+#define _LINUX_ELF 1
+#define LINUX_ELF_DATA_SEGMENT_START 0x08000000
+#define LINUX_ELF_DATA_SEGMENT_LIMIT 0x04000
+
+#define DATUM_TO_ADDRESS(datum)                                                \
+  ((SCHEME_OBJECT *)                                                   \
+   (((unsigned long) (datum)) + LINUX_ELF_DATA_SEGMENT_START))
+
+#define ADDRESS_TO_DATUM(address)                                      \
+  ((SCHEME_OBJECT)                                                     \
+   (((unsigned long) (address)) - LINUX_ELF_DATA_SEGMENT_START))
+
+typedef unsigned long SCHEME_ADDR;
+#define SCHEME_ADDR_TO_ADDR(saddr) (DATUM_TO_ADDRESS (saddr))
+#define ADDR_TO_SCHEME_ADDR(caddr) (ADDRESS_TO_DATUM (caddr))
+#define HOOK_TO_SCHEME_OFFSET(hook) (ADDRESS_TO_DATUM (hook))
+
+#endif /* __linux && __ELF__ */
+
 #endif /* i386 */
 \f
 #ifdef mips
index ba5c8c54204046157fe7160fe7c839049a343845..5acc0c1263e916affd517a4ed6fdffce13e309c2 100644 (file)
@@ -1,7 +1,7 @@
 /* -*-C-*-
    System file for Linux
 
-$Id: linux.h,v 1.3 1995/10/01 07:19:07 cph Exp $
+$Id: linux.h,v 1.4 1995/10/05 03:34:50 cph Exp $
 
 Copyright (c) 1995 Massachusetts Institute of Technology
 
@@ -41,32 +41,8 @@ MIT in each case. */
 
 #define ALTERNATE_M4 s/ultrix.m4
 
-/* The following change is necessary if ELF binaries are used.
-   Unfortunately, it is insufficient, because the Linux ELF
-   implementation also moves the data segment to 0x08000000, which
-   means that all of the pointer manipulation code must be changed.
-   This is normal for some architectures, e.g. the MIPS and HPPA, but
-   it make the binaries for Linux ELF different for the binaries for
-   all other i386 machines.
-
-   Since I don't currently know any way to adjust the mapping of the
-   data segment, if ELF is in use, I'll just force the switch that
-   causes GCC to generate a.out format instead of ELF.  This is a
-   temporary patch, because one of these days a.out won't be
-   supported, but hopefully by then we'll know how to fix this
-   correctly.  */
-#if 0
 #ifdef __ELF__
-#define M4_SWITCH_SYSTEM -P "define(SUPPRESS_LEADING_UNDERSCORE,1)"
+#define M4_SWITCH_SYSTEM -P "define(LINUX_ELF,1)"
 #else
 #define M4_SWITCH_SYSTEM
 #endif
-#endif
-
-#ifdef __ELF__
-#define C_SWITCH_SYSTEM -b i486-linuxaout
-#define LD_SWITCH_SYSTEM -b i486-linuxaout
-#else
-#define C_SWITCH_SYSTEM
-#define LD_SWITCH_SYSTEM
-#endif
index c1baa53d19445ded0f004ecd4cc207835f6303b3..b553230fcf3b1b386b364b1125f05828012d3e9b 100644 (file)
@@ -1,8 +1,8 @@
 /* -*-C-*-
 
-$Id: uxtop.c,v 1.16 1994/12/02 20:38:54 cph Exp $
+$Id: uxtop.c,v 1.17 1995/10/05 03:34:14 cph Exp $
 
-Copyright (c) 1990-94 Massachusetts Institute of Technology
+Copyright (c) 1990-95 Massachusetts Institute of Technology
 
 This material was developed by the Scheme project at the Massachusetts
 Institute of Technology, Department of Electrical Engineering and
@@ -38,6 +38,14 @@ MIT in each case. */
 #include "uxutil.h"
 #include "errors.h"
 #include "option.h"
+#include "config.h"
+#include "extern.h"
+
+#ifdef _LINUX_ELF
+#include <linux/ldt.h>
+#include <linux/unistd.h>
+static void EXFUN (initialize_linux_elf_segments, (void));
+#endif
 
 extern void EXFUN (UX_initialize_channels, (void));
 extern void EXFUN (UX_initialize_ctty, (int interactive));
@@ -109,6 +117,9 @@ DEFUN_VOID (OS_initialize)
 #ifdef _SUNOS
   vadvise (VA_ANOM);           /* Anomolous paging, don't try to guess. */
 #endif
+#ifdef _LINUX_ELF
+  initialize_linux_elf_segments ();
+#endif
 }
 
 void
@@ -420,3 +431,54 @@ OS_syserr_names (unsigned int * length, unsigned char *** names)
   (*length) = ((sizeof (syserr_names_table)) / (sizeof (char *)));
   (*names) = ((unsigned char **) syserr_names_table);
 }
+\f
+/* Special hacking for Linux ELF memory management.  */
+
+#ifdef _LINUX_ELF
+
+extern unsigned short Scheme_Code_Segment_Selector;
+extern unsigned short Scheme_Data_Segment_Selector;
+extern unsigned short Scheme_Stack_Segment_Selector;
+
+static _syscall3 (int, modify_ldt, int, func, void *, buffer, unsigned long, nbytes)
+
+static void
+DEFUN_VOID (initialize_linux_elf_segments)
+{
+  struct modify_ldt_ldt_s mldt;
+
+  (mldt . entry_number) = 1;
+  (mldt . base_addr) = LINUX_ELF_DATA_SEGMENT_START;
+  (mldt . limit) = LINUX_ELF_DATA_SEGMENT_LIMIT;
+  (mldt . seg_32bit) = 1;
+  (mldt . contents) = MODIFY_LDT_CONTENTS_CODE;
+  (mldt . read_exec_only) = 1;
+  (mldt . limit_in_pages) = 1;
+  (mldt . seg_not_present) = 0;
+  if ((modify_ldt (1, (&mldt), (sizeof (mldt)))) != 0)
+    {
+      outf_fatal ("\n%s: unable to allocate code segment descriptor\n",
+              scheme_program_name);
+      Microcode_Termination (TERM_EXIT);
+    }
+  Scheme_Code_Segment_Selector = (((mldt . entry_number) << 3) | 0x7);
+    
+  (mldt . entry_number) = 2;
+  (mldt . base_addr) = LINUX_ELF_DATA_SEGMENT_START;
+  (mldt . limit) = LINUX_ELF_DATA_SEGMENT_LIMIT;
+  (mldt . seg_32bit) = 1;
+  (mldt . contents) = MODIFY_LDT_CONTENTS_DATA;
+  (mldt . read_exec_only) = 0;
+  (mldt . limit_in_pages) = 1;
+  (mldt . seg_not_present) = 0;
+  if ((modify_ldt (1, (&mldt), (sizeof (mldt)))) != 0)
+    {
+      outf_fatal ("\n%s: unable to allocate data segment descriptor\n",
+              scheme_program_name);
+      Microcode_Termination (TERM_EXIT);
+    }
+  Scheme_Data_Segment_Selector = (((mldt . entry_number) << 3) | 0x7);
+  Scheme_Stack_Segment_Selector = Scheme_Data_Segment_Selector;
+}
+
+#endif /* _LINUX_ELF */