From: Chris Hanson Date: Thu, 5 Oct 1995 03:34:50 +0000 (+0000) Subject: Implement changes needed for Linux ELF binary format. This format, X-Git-Tag: 20090517-FFI~5917 X-Git-Url: https://birchwood-abbey.net/git?a=commitdiff_plain;h=f234224a6c837d80cd502d5d9ea94c964866c5c0;p=mit-scheme.git Implement changes needed for Linux ELF binary format. This format, 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. --- diff --git a/v7/src/microcode/cmpauxmd/i386.m4 b/v7/src/microcode/cmpauxmd/i386.m4 index 94fd6e8af..3adcb5e0f 100644 --- a/v7/src/microcode/cmpauxmd/i386.m4 +++ b/v7/src/microcode/cmpauxmd/i386.m4 @@ -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)') 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) 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(` diff --git a/v7/src/microcode/cmpintmd/i386.h b/v7/src/microcode/cmpintmd/i386.h index e9064a5ed..ebe5e41d2 100644 --- a/v7/src/microcode/cmpintmd/i386.h +++ b/v7/src/microcode/cmpintmd/i386.h @@ -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 \ diff --git a/v7/src/microcode/config.h b/v7/src/microcode/config.h index b94f32535..197fc564a 100644 --- a/v7/src/microcode/config.h +++ b/v7/src/microcode/config.h @@ -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 */ #ifdef mips diff --git a/v7/src/microcode/s/linux.h b/v7/src/microcode/s/linux.h index ba5c8c542..5acc0c126 100644 --- a/v7/src/microcode/s/linux.h +++ b/v7/src/microcode/s/linux.h @@ -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 diff --git a/v7/src/microcode/uxtop.c b/v7/src/microcode/uxtop.c index c1baa53d1..b553230fc 100644 --- a/v7/src/microcode/uxtop.c +++ b/v7/src/microcode/uxtop.c @@ -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 +#include +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); } + +/* 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 */