Big changes to AcessNative
authorJohn Hodge <[email protected]>
Tue, 18 Jan 2011 12:47:12 +0000 (20:47 +0800)
committerJohn Hodge <[email protected]>
Tue, 18 Jan 2011 12:47:12 +0000 (20:47 +0800)
- ld-acess can now execute an application
 > the syscall interface is not yet completed, so nothing happens
- Getting ld-acess working required some changes to the Usermode build
  system, specifically making ld-acess.so actually a shared library.
 > It was being linked statically, causing the AcessNative versions of
   syscalls to not be used (and causing segfaults on "int 0xAC")

12 files changed:
AcessNative/ld-acess.so_src/Makefile
AcessNative/ld-acess.so_src/binary.c
AcessNative/ld-acess.so_src/elf.c
AcessNative/ld-acess.so_src/main.c
AcessNative/ld-acess.so_src/request.c
AcessNative/ld-acess.so_src/request.h [new file with mode: 0644]
AcessNative/ld-acess.so_src/syscalls.c
AcessNative/syscalls.h
Usermode/Applications/Makefile.cfg
Usermode/Libraries/Makefile.tpl
Usermode/Libraries/acess.ld_src/acess.ld.h
Usermode/Libraries/ld-acess.so_src/Makefile

index 08e12c8..4fb6ae2 100644 (file)
@@ -14,9 +14,10 @@ ifeq ($(PLATFORM),win)
 endif
 ifeq ($(PLATFORM),lin)
        BIN := ../ld-acess
+       LD += -m elf_i386
 endif
 
-CFLAGS += -Wall -Werror -g
+CFLAGS += -Wall -Werror -g -m32
 
 .PHONY: all clean
 
@@ -25,9 +26,14 @@ all: $(BIN)
 clean:
        $(RM) $(BIN) $(OBJ)
 
-$(BIN): $(OBJ)
-       $(CC) -g -o $@ $(OBJ)
+$(BIN): link.ld.$(PLATFORM) $(OBJ)
+#      $(LD) -g -o $@ $(OBJ) -T link.ld.$(PLATFORM)
+       $(CC) -g -o $@ $(OBJ) -m32 -Wl,-T,link.ld.$(PLATFORM)
 
 %.o.$(PLATFORM): %.c
        $(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)
 
+# Modify the default makefile to put the executable at 1MB instead
+link.ld.lin:
+       $(LD) --verbose | awk '{ if( substr($$0,0,5) == "====="){ bPrint = !bPrint; } else { if(bPrint){ print $$0;} } }' | sed 's/\b0x0[08][0-9]*\b/0x00100000/g' > $@
+
index 7f97edd..b8f6e71 100644 (file)
@@ -45,6 +45,10 @@ char *Binary_LocateLibrary(const char *Name)
         int    nameLen = strlen(Name);
        FILE    *fp;
        
+       if( strcmp(Name, "libld-acess.so") == 0 ) {
+               return strdup("libld-acess.so");
+       }
+       
        // Try the environment ACESS_LIBRARY_PATH
        if( envPath && envPath[0] != '\0' )
        {
@@ -103,6 +107,7 @@ void *Binary_LoadLibrary(const char *Name)
        printf("Binary_LoadLibrary: ret = %p, entry = %p\n", ret, entry);
        if( entry ) {
                char    *argv[] = {NULL};
+               printf("Calling '%s' entry point %p\n", Name, entry);
                entry(0, argv, NULL);
        }
 
@@ -117,6 +122,12 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
        uintptr_t       entry = 0;
        tBinFmt *fmt;
 
+       // Ignore loading ld-acess
+       if( strcmp(Filename, "libld-acess.so") == 0 ) {
+               *EntryPoint = 0;
+               return (void*)-1;
+       }
+
        {
                tBinary *bin;
                for(bin = gLoadedBinaries; bin; bin = bin->Next)
@@ -145,7 +156,8 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
                fclose(fp);
                return NULL;
        }
-
+       
+       printf("fmt->Load(%p)...\n", fp);
        ret = fmt->Load(fp);
        printf("fmt->Load(%p): %p\n", fp, ret);
        if( !ret ) {
@@ -199,16 +211,12 @@ int Binary_GetSymbol(const char *SymbolName, uintptr_t *Value)
         int    i;
        tBinary *bin;
        
-       // TODO: Search list of loaded binaries
-       for(bin = gLoadedBinaries; bin; bin = bin->Next)
-       {
-               if( !bin->Ready )       continue;
-               printf("Binary_GetSymbol: bin = %p{%p, %s}\n", bin, bin->Base, bin->Path);
-               if( bin->Format->GetSymbol(bin->Base, (char*)SymbolName, Value) )
-                       return 1;
-       }
+       printf("Binary_GetSymbol: (SymbolName='%s', Value=%p)\n",
+               SymbolName, Value);
 
        // Search builtins
+       // - Placed first to override smartarses that define their own versions
+       //   of system calls
        for( i = 0; i < ciNumBuiltinSymbols; i ++ )
        {
                if( strcmp(caBuiltinSymbols[i].Name, SymbolName) == 0 ) {
@@ -216,6 +224,17 @@ int Binary_GetSymbol(const char *SymbolName, uintptr_t *Value)
                        return 1;
                }
        }
+       
+       // TODO: Search list of loaded binaries
+       for(bin = gLoadedBinaries; bin; bin = bin->Next)
+       {
+               if( !bin->Ready )       continue;
+               printf(" Binary_GetSymbol: bin = %p{%p, %s}\n", bin, bin->Base, bin->Path);
+               if( bin->Format->GetSymbol(bin->Base, (char*)SymbolName, Value) )
+                       return 1;
+       }
 
+       printf("Binary_GetSymbol: RETURN 0, not found\n");
+       
        return 0;
 }
index 11bd2df..3ab5a50 100644 (file)
 #define PTRMK(_type,_val)      MKPTR(_type,_val)\r
 #define PTR(_val)      ((void*)(uintptr_t)(_val))\r
 \r
-#if 0\r
+#if DEBUG\r
 # define ENTER(...)\r
 # define LOG(s, ...)   printf("%s: " s, __func__, __VA_ARGS__)\r
 # define LOGS(s)       printf("%s: " s, __func__)\r
 # define LEAVE(...)\r
 #else\r
-#define ENTER(...)\r
-#define LOG(...)\r
-#define LOGS(...)\r
-#define LEAVE(...)\r
+# define ENTER(...)\r
+# define LOG(...)\r
+# define LOGS(...)\r
+# define LEAVE(...)\r
 #endif\r
 \r
 // === PROTOTYPES ===\r
@@ -274,9 +274,16 @@ uintptr_t Elf_Relocate(void *Base)
        // Alter Symbols to true base\r
        for(i = 0; i < iSymCount; i ++)\r
        {\r
-               dynsymtab[i].value += iBaseDiff;\r
                dynsymtab[i].nameOfs += (uintptr_t)dynstrtab;\r
-               LOG("Sym '%s' = 0x%x (relocated)\n", MKPTR(char,dynsymtab[i].name), dynsymtab[i].value);\r
+               if( dynsymtab[i].shndx == SHN_UNDEF )\r
+               {\r
+                       LOG("Sym '%s' = UNDEF\n", MKPTR(char,dynsymtab[i].name));\r
+               }\r
+               else\r
+               {\r
+                       dynsymtab[i].value += iBaseDiff;\r
+                       LOG("Sym '%s' = 0x%x (relocated)\n", MKPTR(char,dynsymtab[i].name), dynsymtab[i].value);\r
+               }\r
        }\r
        \r
        // === Add to loaded list (can be imported now) ===\r
index d9bad13..e310a84 100644 (file)
@@ -37,7 +37,14 @@ int main(int argc, char *argv[], char **envp)
        printf("base = %p\n", base);
        if( !base )     return 127;
        
-       return appMain(appArgc, appArgv, envp);
+       __asm__ __volatile__ (
+               "push %0;\n\t"
+               "push %1;\n\t"
+               "push %2;\n\t"
+               "jmp *%3;\n\t"
+               : : "r" (envp), "r" (appArgv), "r" (appArgc), "r" (appMain) );
+       //return appMain(appArgc, appArgv, envp);
+       return -1;
 }
 
 void Warning(const char *Format, ...)
index 79db625..f9526b3 100644 (file)
 # include <sys/socket.h>
 # include <netinet/in.h>
 #endif
+#include "request.h"
+#include "../syscalls.h"
 
 #define        SERVER_PORT     0xACE
 
 // === GLOBALS ===
 #ifdef __WIN32__
 WSADATA        gWinsock;
-SOCKET gSocket;
+SOCKET gSocket = INVALID_SOCKET;
 #else
- int   gSocket;
 # define INVALID_SOCKET -1
+ int   gSocket = INVALID_SOCKET;
 #endif
+// Client ID to pass to server
+// TODO: Implement such that each thread gets a different one
+static int     siSyscall_ClientID = 0;
 
 // === CODE ===
 int _InitSyscalls()
@@ -75,9 +80,72 @@ int _InitSyscalls()
        }
        return 0;
 }
-#if 0
-int _Syscall(const char *ArgTypes, ...)
+
+int SendRequest(int RequestID, int NumOutput, tOutValue **Output, int NumInput, tInValue **Input)
 {
+       tRequestHeader  *request;
+       tRequestValue   *value;
+       char    *data;
+        int    requestLen;
+        int    i;
+       
+       // See ../syscalls.h for details of request format
+       requestLen = sizeof(tRequestHeader) + (NumOutput + NumInput) * sizeof(tRequestValue);
+       
+       // Get total param length
+       for( i = 0; i < NumOutput; i ++ )
+               requestLen += Output[i]->Length;
+       
+       // Allocate request
+       request = malloc( requestLen );
+       value = request->Params;
+       data = (char*)&request->Params[ NumOutput + NumInput ];
+       
+       // Set header
+       request->ClientID = siSyscall_ClientID;
+       request->CallID = RequestID;    // Syscall
+       request->NParams = NumOutput;
+       request->NReturn = NumInput;
+       
+       // Set parameters
+       for( i = 0; i < NumOutput; i ++ )
+       {
+               switch(Output[i]->Type)
+               {
+               case 'i':       value->Type = ARG_TYPE_INT32;   break;
+               case 'I':       value->Type = ARG_TYPE_INT64;   break;
+               case 'd':       value->Type = ARG_TYPE_DATA;    break;
+               default:
+                       return -1;
+               }
+               value->Length = Output[i]->Length;
+               
+               memcpy(data, Output[i]->Data, Output[i]->Length);
+               
+               data += Output[i]->Length;
+       }
+       
+       // Set return values
+       for( i = 0; i < NumInput; i ++ )
+       {
+               switch(Input[i]->Type)
+               {
+               case 'i':       value->Type = ARG_TYPE_INT32;   break;
+               case 'I':       value->Type = ARG_TYPE_INT64;   break;
+               case 'd':       value->Type = ARG_TYPE_DATA;    break;
+               default:
+                       return -1;
+               }
+               value->Length = Input[i]->Length;
+       }
+       
+       // Send it off
+       send(gSocket, request, requestLen, 0);
+       
+       // Wait for a response
+       recv(gSocket, request, requestLen, 0);
+       
+       // Parse response out
+       
        return 0;
 }
-#endif
diff --git a/AcessNative/ld-acess.so_src/request.h b/AcessNative/ld-acess.so_src/request.h
new file mode 100644 (file)
index 0000000..8c89e6f
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Acess2 - AcessNative
+ * ld-acess
+ *
+ * request.h - IPC Request common header
+ */
+
+#ifndef _REQUEST_H_
+#define _REQUEST_H_
+
+typedef struct {
+       char    Type;
+        int    Length;
+       char    Data[];
+}      tOutValue;
+
+typedef struct {
+       char    Type;
+        int    Length;
+       void    *Data;
+}      tInValue;
+
+extern int SendRequest(int RequestID, int NumOutput, tOutValue **Output,
+       int NumInput, tInValue **Input);
+
+#endif
index e26ae35..ec4af01 100644 (file)
 /*
  */
-//#include <acess/sys.h>
+#include "../../Usermode/include/acess/sys.h"
 #include "common.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <stdarg.h>
+#include <string.h>
+#include "request.h"
+
+// === Types ===
 
 // === IMPORTS ===
 
 // === CODE ===
+const char *ReadEntry(tOutValue **OutDest, tInValue **InDest,
+       int *Direction, const char *ArgTypes, va_list Args)
+{
+       uint64_t        val64, *ptr64;
+       uint32_t        val32, *ptr32;
+        int    direction = 0;  // 0: Invalid, 1: Out, 2: In, 3: Out
+       char    *str;
+        int    len;
+       
+       // Eat whitespace
+       while(*ArgTypes && *ArgTypes == ' ')    ArgTypes ++;
+       if( *ArgTypes == '\0' ) return ArgTypes;
+       
+       // Get direction
+       switch(*ArgTypes)
+       {
+       case '>':       direction = 1;  break;
+       case '<':       direction = 2;  break;
+       case '?':       direction = 3;  break;
+       default:
+               return NULL;
+       }
+       ArgTypes ++;
+       
+       // Eat whitespace
+       while(*ArgTypes && *ArgTypes == ' ')    ArgTypes ++;
+       if( *ArgTypes == '\0' ) return ArgTypes;
+       
+       // Internal helper macro
+       #define MAKE_OUT(_dest,_typeChar,_typeName,_value) do{if((_dest)){\
+               *(_dest) = (tOutValue*)malloc(sizeof(tOutValue)+sizeof(_typeName));\
+               (*(_dest))->Type=(_typeChar);(*(_dest))->Length=sizeof(_typeName);\
+               *(_typeName*)((*(_dest))->Data) = (_value);\
+               }}while(0)
+       #define MAKE_IN(_dest,_typeChar,_typeName,_value) do{if((_dest)){\
+               *(_dest) = (tInValue*)malloc(sizeof(tInValue));\
+               (*(_dest))->Type=(_typeChar);(*(_dest))->Length=sizeof(_typeName);\
+               (*(_dest))->Data = (_value);\
+               }}while(0)
+       
+       // Get type
+       switch(*ArgTypes)
+       {
+       case 'i':       // 32-bit integer
+               // Input?
+               if( direction & 2 )
+               {
+                       ptr32 = va_arg(Args, uint32_t*);
+                       MAKE_IN(InDest, 'i', uint32_t*, ptr32);
+                       if( direction & 1 )
+                               MAKE_OUT(OutDest, 'i', uint32_t, *ptr32);
+               }
+               else
+               {
+                       val32 = va_arg(Args, uint32_t);
+                       MAKE_OUT(OutDest, 'i', uint32_t, val32);
+               }
+               break;
+       case 'I':       // 64-bit integer
+               // Input?
+               if( direction & 2 )
+               {
+                       ptr64 = va_arg(Args, uint64_t*);
+                       MAKE_IN(InDest, 'I', uint64_t*, ptr64);
+                       if( direction & 1 )
+                               MAKE_OUT(OutDest, 'I', uint64_t, *ptr64);
+               }
+               else
+               {
+                       val64 = va_arg(Args, uint64_t);
+                       MAKE_OUT(OutDest, 'I', uint64_t, val64);
+               }
+               break;
+       case 's':
+               // Input string makes no sense!
+               if( direction & 2 ) {
+                       fprintf(stderr, "ReadEntry: Incoming string is not defined\n");
+                       return NULL;
+               }
+               
+               str = va_arg(Args, char*);
+               if( OutDest )
+               {
+                        int    len = strlen(str) + 1;
+                       *OutDest = malloc( sizeof(tOutValue) + len );
+                       (*OutDest)->Type = 's';
+                       (*OutDest)->Length = len;
+                       memcpy((*OutDest)->Data, str, len);
+               }
+               break;
+       
+       case 'd':
+               len = va_arg(Args, int);
+               str = va_arg(Args, char*);
+               
+               // Input ?
+               if( (direction & 2) && InDest )
+               {
+                       *InDest = (tInValue*)malloc( sizeof(tInValue) );
+                       (*InDest)->Type = 'd';
+                       (*InDest)->Length = len;
+                       (*InDest)->Data = str;
+               }
+               
+               // Output ?
+               if( (direction & 1) && InDest )
+               {
+                       *OutDest = (tOutValue*)malloc( sizeof(tOutValue) + len );
+                       (*OutDest)->Type = 'd';
+                       (*OutDest)->Length = len;
+                       memcpy((*OutDest)->Data, str, len);
+               }
+               break;
+       
+       default:
+               return NULL;
+       }
+       ArgTypes ++;
+       #undef MAKE_ASSIGN
+       
+       *Direction = direction;
+       
+       return ArgTypes;
+}
+
 /**
  * \param ArgTypes
  *
  * Whitespace is ignored
- * >i: Input Integer
+ * >i: Input Integer (32-bits)
  * >I: Input Long Integer (64-bits)
  * >s: Input String
  * >d: Input Buffer (Preceded by valid size)
  * <I: Output long integer
  * <d: Output Buffer (Preceded by valid size)
+ * ?d:  Bi-directional buffer (Preceded by valid size), buffer contents
+ *      are returned
  */
 int _Syscall(const char *ArgTypes, ...)
 {
-       // int  outBufSize = 0;
        va_list args;
+        int    outCount = 0;
+        int    inCount = 0;
+       const char      *str;
+       
+       tOutValue       **output;
+       tInValue        **input;
        
+       // Get data size
        va_start(args, ArgTypes);
+       str = ArgTypes;
+       while(*str)
+       {
+                int    dir;
+               
+               str = ReadEntry(NULL, NULL, &dir, str, args);
+               if( !str )      break;
+               
+               // Out!
+               if( dir & 1 )   outCount ++;
+               
+               // and.. In!
+               if( dir & 2 )   inCount ++;
+       }
        va_end(args);
+       
+       // Allocate buffers
+       output = malloc( outCount*sizeof(tOutValue*) );
+       input = malloc( inCount*sizeof(tInValue*) );
+       
+       // - re-zero so they can be used as indicies
+       outCount = 0;
+       inCount = 0;
+       
+       // Fill `output` and `input`
+       va_start(args, ArgTypes);
+       str = ArgTypes;
+       while(*str)
+       {
+               tOutValue       *outParam;
+               tInValue        *inParam;
+                int    dir;
+               
+               str = ReadEntry(&outParam, &inParam, &dir, str, args);
+               if( !str )      break;
+               
+               if( dir & 1 )
+                       output[outCount++] = outParam;
+               if( dir & 2 )
+                       input[inCount++] = inParam;
+       }
+       va_end(args);
+       
+       // Send syscall request
+       
+       
+       // Clean up
+       while(outCount--)       free(output[outCount]);
+       free(output);
+       while(inCount--)        free(input[inCount]);
+       free(input);
+       
        return 0;
 }
 
+// --- VFS Calls
 int open(const char *Path, int Flags) {
        return _Syscall(">s >i", Path, Flags);
 }
@@ -47,25 +236,66 @@ size_t write(int FD, size_t Bytes, void *Src) {
        return _Syscall(">i >i >d", FD, Bytes, Bytes, Src);
 }
 
+int seek(int FD, int64_t Ofs, int Dir) {
+       return _Syscall(">i >I >i", FD, Ofs, Dir);
+}
+
 uint64_t tell(int FD) {
        uint64_t        ret;
        _Syscall("<I >i", &ret, FD);
        return ret;
 }
 
-int seek(int FD, uint64_t Ofs, int Dir) {
-       return _Syscall(">i >I >i", FD, Ofs, Dir);
+int ioctl(int fd, int id, void *data) {
+       // NOTE: 1024 byte size is a hack
+       return _Syscall(">i >i ?d", fd, id, 1024, data);
+}
+int finfo(int fd, t_sysFInfo *info, int maxacls) {
+       return _Syscall(">i <d >i", fd, maxacls*sizeof(t_sysFInfo), info, maxacls);
 }
 
+int readdir(int fd, char *dest) {
+       return _Syscall(">i <s", fd, dest);
+}
+
+int _SysOpenChild(int fd, char *name, int flags) {
+       return _Syscall(">i >s >i", fd, name, flags);
+}
+
+int _SysGetACL(int fd, t_sysACL *dest) {
+       return _Syscall(">i <d", fd, sizeof(t_sysACL), dest);
+}
+
+int _SysMount(const char *Device, const char *Directory, const char *Type, const char *Options) {
+       return _Syscall(">s >s >s >s", Device, Directory, Type, Options);
+}
+
+
+// --- Error Handler
+int    _SysSetFaultHandler(int (*Handler)(int)) {
+       return 0;
+}
+
+
 // === Symbol List ===
+#define DEFSYM(name)   {#name, name}
 const tSym     caBuiltinSymbols[] = {
-       {"open", open},
-       {"close", close},
-       {"read", read},
-       {"write", write},
-       {"tell", tell},
-       {"seek", seek},
-       {"_exit", exit}
+       {"_exit", exit},
+       
+       DEFSYM(open),
+       DEFSYM(close),
+       DEFSYM(read),
+       DEFSYM(write),
+       DEFSYM(seek),
+       DEFSYM(tell),
+       DEFSYM(ioctl),
+       DEFSYM(finfo),
+       DEFSYM(readdir),
+       DEFSYM(_SysOpenChild),
+       DEFSYM(_SysGetACL),
+       DEFSYM(_SysMount),
+       
+       {"_SysSetFaultHandler", _SysSetFaultHandler}
 };
 
 const int      ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]);
index 2784fd0..e298c94 100644 (file)
@@ -3,6 +3,30 @@
 #ifndef _NATIVE_SYSCALLS_H_
 #define _NATIVE_SYSCALLS_H_
 
+/*
+ * Request format
+ * 
+ * tRequestHeader      header
+ * tRequestValue       params[header.NParams]
+ * tRequestValue       retvals[header.NReturn]
+ * uint8_t     paramData[SUM(params[].Lengh)];
+ */
+
+typedef struct sRequestValue {
+       /// \see eArgumentTypes
+       uint16_t        Type;
+       uint16_t        Length;
+}      tRequestValue;
+
+typedef struct sRequestHeader {
+       uint16_t        ClientID;
+       uint16_t        CallID; //!< \see eSyscalls
+       uint16_t        NParams;
+       uint16_t        NReturn;
+       
+       tRequestValue   Params[];
+}      tRequestHeader;
+
 enum eSyscalls {
        SYS_NULL,
        SYS_OPEN
@@ -12,12 +36,7 @@ enum eArgumentTypes {
        ARG_TYPE_VOID,
        ARG_TYPE_INT32,
        ARG_TYPE_INT64,
-       ARG_TYPE_STRING,
        ARG_TYPE_DATA
 };
 
-#define ARG_DIR_TOSRV  0x10
-#define        ARG_DIR_TOCLI   0x20
-#define ARG_DIR_BOTH   0x30
-
 #endif
index 6b94696..2e64b9d 100644 (file)
@@ -14,5 +14,5 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../Makefile.cfg
 ASFLAGS = -felf
 CPPFLAGS = -I$(ACESSUSERDIR)/include/
 CFLAGS   = -fno-stack-protector $(CPPFLAGS)
-LDFLAGS  = -T $(OUTPUTDIR)Libs/acess.ld -rpath-link $(OUTPUTDIR)Libs -L $(OUTPUTDIR)Libs -I /Acess/Libs/ld-acess.so -lc
+LDFLAGS  = -T $(OUTPUTDIR)Libs/acess.ld -rpath-link $(OUTPUTDIR)Libs -L $(OUTPUTDIR)Libs -I /Acess/Libs/ld-acess.so -lld-acess -lc
 DIR = Bin
index 5f73632..9712bf8 100644 (file)
@@ -6,14 +6,14 @@ DEPFILES := $(addsuffix .d,$(OBJ))
 
 _BIN := $(OUTPUTDIR)Libs/$(BIN)
 
-.PHONY: all clean install
+.PHONY: all clean install postbuild
 
-all: $(_BIN)
+all: $(_BIN) postbuild
 
 clean:
        $(RM) $(_BIN) $(OBJ) $(_BIN).dsm $(DEPFILES)
 
-install: $(_BIN)
+install: all
        $(xCP) $(_BIN) $(DISTROOT)/Libs/
 
 $(_BIN): $(OBJ)
index c059c79..e81c0a5 100644 (file)
@@ -2,7 +2,7 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
 OUTPUT_ARCH(i386)\r
 ENTRY(start)\r
 SEARCH_DIR(__LIBDIR)\r
-INPUT(crt0.o ld-acess.so)\r
+INPUT(crt0.o)\r
 SECTIONS\r
 {\r
   /* Read-only sections, merged into text segment: */\r
index 48bb38f..3c02d3d 100644 (file)
@@ -10,7 +10,12 @@ BIN = ld-acess.so
 
 CFLAGS   = -Wall -fno-builtin -fno-leading-underscore -fno-stack-protector
 ASFLAGS  = -felf
-LDFLAGS  = -T link.ld -Map map.txt -Bstatic
+LDFLAGS  = -T link.ld -Map map.txt -Bstatic -shared
 
 include ../Makefile.tpl
 
+postbuild: $(OUTPUTDIR)Libs/libld-acess.so
+
+$(OUTPUTDIR)Libs/libld-acess.so:
+       ln -s $(_BIN) $(OUTPUTDIR)Libs/libld-acess.so
+

UCC git Repository :: git.ucc.asn.au