From 71a89ad748fb93b6f2ab3ae7afc19d339506efc8 Mon Sep 17 00:00:00 2001 From: sonic Date: Thu, 14 Jul 2011 10:04:10 +0000 Subject: [PATCH] - libloadseg.a is moved out of public libraries to gen/lib directory. It's too internal. - Build libloadseg.a from dos.library source code and only if needed. - Reverted partition.library to old version (direct linking to dos.library). partition.library should not have its own segment loader at all, it should use dos.library instead. This will be implemented when new boot process is implemented. TODO: Further reengineed InternalLoadSeg_ELF to be usable in all bootstraps. Current version is no way. git-svn-id: https://svn.aros.org/svn/aros/trunk/AROS@40081 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- arch/m68k-amiga/c/AROSBootstrap.c | 17 +- arch/m68k-amiga/c/mmakefile.src | 9 +- compiler/loadseg/include/loadseg.h | 18 -- compiler/loadseg/mmakefile.src | 25 --- compiler/loadseg/unloadsegment.c | 93 ----------- rom/dos/include/loadseg.h | 37 ++++ .../loadsegment.c => rom/dos/internalloadseg.c | 103 +++++++----- .../loadseg_intern.h => rom/dos/internalloadseg.h | 21 +-- .../dos/internalloadseg_aos.c | 186 +++++++++++++-------- .../dos/internalloadseg_elf.c | 153 ++++++----------- rom/dos/internalloadseg_support.c | 36 ++++ rom/dos/internalunloadseg.c | 34 +++- rom/dos/loadseg_overlay.c | 102 ----------- rom/dos/mmakefile.src | 15 +- rom/partition/mmakefile.src | 2 +- rom/partition/partitionrdb.c | 37 ++-- 16 files changed, 398 insertions(+), 490 deletions(-) delete mode 100644 compiler/loadseg/include/loadseg.h delete mode 100644 compiler/loadseg/mmakefile.src delete mode 100644 compiler/loadseg/unloadsegment.c create mode 100644 rom/dos/include/loadseg.h rename compiler/loadseg/loadsegment.c => rom/dos/internalloadseg.c (60%) rename compiler/loadseg/loadseg_intern.h => rom/dos/internalloadseg.h (75%) rename compiler/loadseg/loadsegment_aos.c => rom/dos/internalloadseg_aos.c (74%) rename compiler/loadseg/loadsegment_elf.c => rom/dos/internalloadseg_elf.c (84%) create mode 100644 rom/dos/internalloadseg_support.c delete mode 100644 rom/dos/loadseg_overlay.c diff --git a/arch/m68k-amiga/c/AROSBootstrap.c b/arch/m68k-amiga/c/AROSBootstrap.c index 7d8d3b8141..67dc65bac9 100644 --- a/arch/m68k-amiga/c/AROSBootstrap.c +++ b/arch/m68k-amiga/c/AROSBootstrap.c @@ -47,7 +47,7 @@ static inline void bug(const char *fmt, ...) } #endif -#include +#include struct DosLibrary *DOSBase; @@ -385,12 +385,21 @@ static AROS_UFH3(void, elfFree, AROS_USERFUNC_EXIT } +/* + * This routine is called from within libloadseg.a's ELF loader. + * In dos.library it's responsible for collecting debug information from the loaded file. + * Here it does nothing (FIXME ???) + */ +void register_elf(BPTR file, BPTR hunks, struct elfheader *eh, struct sheader *sh, struct DosLibrary *DOSBase) +{ + +} + static BPTR ROMLoad(BSTR bfilename) { gzFile gzf; UBYTE *filename; BPTR rom = BNULL; - SIPTR error; SIPTR funcarray[] = { (SIPTR)elfRead, (SIPTR)elfAlloc, @@ -405,9 +414,9 @@ static BPTR ROMLoad(BSTR bfilename) if ((gzf = gzopen(filename, "rb"))) { gzbuffer(gzf, 65536); - rom = LoadSegment((BPTR)gzf, BNULL, funcarray, NULL, &error, (struct Library *)DOSBase); + rom = LoadSegment((BPTR)gzf, BNULL, funcarray, NULL); if (rom == BNULL) { - WriteF("'%S': Can't parse, error %N\n", bfilename, error); + WriteF("'%S': Can't parse, error %N\n", bfilename, IoErr()); } gzclose_r(gzf); diff --git a/arch/m68k-amiga/c/mmakefile.src b/arch/m68k-amiga/c/mmakefile.src index e0c800756a..18361b70dd 100644 --- a/arch/m68k-amiga/c/mmakefile.src +++ b/arch/m68k-amiga/c/mmakefile.src @@ -24,6 +24,8 @@ USER_AFLAGS := -I$(GENINCDIR) -Os #MM workbench-c-m68k-setpatcharos-elf-quick \ #MM workbench-c-m68k-arosbootstrap-elf-quick +#MM workbench-c-m68k-arosbootstrap-elf : linklibs-loadseg + AROS_BOOT := $(BINDIR)/boot FILES := gdbstub gdbstop @@ -40,11 +42,12 @@ AFILES := newstackswap files=$(CFILES) asmfiles=$(AFILES) targetdir=$(AROS_BOOT) \ uselibs="loadseg arossupport amiga rom" -CFILES := AROSBootstrap -AFILES := +CFILES := AROSBootstrap +USER_INCLUDES := -isystem $(SRCDIR)/rom/dos/include +USER_LDFLAGS := -L$(GENDIR)/lib %build_prog mmake=workbench-c-m68k-arosbootstrap-elf progname=AROSBootstrap.elf \ - files=$(CFILES) asmfiles=$(AFILES) targetdir=$(AROS_BOOT) \ + files=$(CFILES) targetdir=$(AROS_BOOT) \ usestartup=no uselibs="loadseg arossupport amiga z rom" diff --git a/compiler/loadseg/include/loadseg.h b/compiler/loadseg/include/loadseg.h deleted file mode 100644 index 4ad78ed258..0000000000 --- a/compiler/loadseg/include/loadseg.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2011, The AROS Development Team. All rights reserved. - * Author: Jason S. McMullan - * - * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1 - */ - -#ifndef LOADSEG_LOADSEG_H -#define LOADSEG_LOADSEG_H - -#include -#include - -BPTR LoadSegment(BPTR fh, BPTR table, SIPTR *funcarr, LONG *stack, SIPTR *error, struct Library *lib); -BOOL UnLoadSegment(BPTR seglist , VOID_FUNC freefunc, struct DosLibrary *DOSBase); - - -#endif /* LOADSEG_LOADSEG_H */ diff --git a/compiler/loadseg/mmakefile.src b/compiler/loadseg/mmakefile.src deleted file mode 100644 index f558e18c83..0000000000 --- a/compiler/loadseg/mmakefile.src +++ /dev/null @@ -1,25 +0,0 @@ -# $Id$ -# -# Generate the loadseg.lib library (normally called libloadseg.a). -# -# This is used by dos.library, partition.library, and various -# AROSBoostrap routines. -# -include $(TOP)/config/make.cfg - -FILES := \ - loadsegment \ - loadsegment_elf \ - loadsegment_aos \ - unloadsegment - -#MM- core-linklibs : linklibs-loadseg -#MM- linklibs: linklibs-loadseg -#MM linklibs-loadseg : includes includes-copy kernel-aros-includes - -%build_linklib mmake=linklibs-loadseg libname=loadseg files="$(FILES)" - -INCLUDE_FILES := $(call WILDCARD, include/*.h) -%copy_includes mmake=compiler-includes path=loadseg dir=include - -%common diff --git a/compiler/loadseg/unloadsegment.c b/compiler/loadseg/unloadsegment.c deleted file mode 100644 index 70895dd1ff..0000000000 --- a/compiler/loadseg/unloadsegment.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - Copyright © 1995-2011, The AROS Development Team. All rights reserved. - $Id$ - - Desc: - Lang: english -*/ - -#include -#include -#include -#include -#include -#include - -#include "loadseg_intern.h" - -/***************************************************************************** - - NAME */ -#include - - BOOL UnLoadSegment( - -/* SYNOPSIS */ - BPTR seglist , - VOID_FUNC freefunc, - struct DosLibrary *DOSBase) - -/* LOCATION - - loadseg.lib - - FUNCTION - Unloads a seglist loaded with LoadSegment(). - - INPUTS - seglist - Seglist - freefunc - Function to be called to free memory - DOSBase - Required for AOS HUNK overlays only, otherwise NULL - - RESULT - DOSTRUE if everything wents O.K. - - NOTES - - EXAMPLE - - BUGS - - SEE ALSO - - INTERNALS - -*****************************************************************************/ -{ - BPTR next; - SIPTR funcarray[] = { (SIPTR)NULL, (SIPTR)NULL, (SIPTR)freefunc }; - - if (seglist) - { - APTR DebugBase; - - if ((DebugBase = OpenLibrary("debug.library", 0))) { - UnregisterModule(seglist); - CloseLibrary(DebugBase); - } - -#if (AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT) - if (DOSBase != NULL) { - /* free overlay structures */ - ULONG *seg = BADDR(seglist); - if (seg[2] == 0x0000abcd && seg[6] == (ULONG)DOSBase->dl_GV) { - Close((BPTR)seg[3]); /* file handle */ - ilsFreeVec((void*)seg[4]); /* overlay table, APTR */ - ilsFreeVec(BADDR(seg[5])); /* hunk table, BPTR */ - } - } -#endif - - while (seglist) - { - next = *(BPTR *)BADDR(seglist); - ilsFreeVec(BADDR(seglist)); - seglist = next; - } - - return DOSTRUE; - } - else - return DOSFALSE; - -} /* UnLoadSegment */ diff --git a/rom/dos/include/loadseg.h b/rom/dos/include/loadseg.h new file mode 100644 index 0000000000..021382dad8 --- /dev/null +++ b/rom/dos/include/loadseg.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2011, The AROS Development Team. All rights reserved. + * Author: Jason S. McMullan + * + * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1 + */ + +#ifndef LOADSEG_LOADSEG_H +#define LOADSEG_LOADSEG_H + +#include +#include + +/* This is called after ELF file is loaded. You may grab the debug info from it. */ +void register_elf(BPTR file, BPTR hunks, struct elfheader *eh, struct sheader *sh, struct DosLibrary *DOSBase); + +AROS_LD4(BPTR, InternalLoadSeg, + AROS_LDA(BPTR , fh , D0), + AROS_LDA(BPTR , table , A0), + AROS_LDA(LONG_FUNC *, funcarray , A1), + AROS_LDA(LONG * , stack , A2), + struct DosLibrary *, DOSBase, 126, Dos); + +/* + * Use LoadSegment() to call the linklib's loader. + * There's no counterpart since the loaded seglist can be freed by + * conventional IntrernalUnloadSeg(), even on old AmigaOS. + */ +#define LoadSegment(fh, table, funcarray, stack) \ + AROS_CALL4(BPTR, AROS_SLIB_ENTRY(InternalLoadSeg, Dos, 126), \ + AROS_LCA(BPTR , fh , D0), \ + AROS_LDA(BPTR , table , A0), \ + AROS_LDA(LONG_FUNC *, funcarray , A1), \ + AROS_LDA(LONG * , stack , A2), \ + struct DosLibrary *, DOSBase, 126, Dos) + +#endif /* LOADSEG_LOADSEG_H */ diff --git a/compiler/loadseg/loadsegment.c b/rom/dos/internalloadseg.c similarity index 60% rename from compiler/loadseg/loadsegment.c rename to rom/dos/internalloadseg.c index af0b79ad81..a2fbb29ba9 100644 --- a/compiler/loadseg/loadsegment.c +++ b/rom/dos/internalloadseg.c @@ -1,8 +1,8 @@ /* - Copyright © 1995-2010, The AROS Development Team. All rights reserved. + Copyright © 1995-2011, The AROS Development Team. All rights reserved. $Id$ - Desc: DOS function LoadSegment() + Desc: DOS function InternalLoadSeg() Lang: english */ @@ -13,65 +13,53 @@ #include #include #include - -#include "loadseg_intern.h" +#include "dos_intern.h" +#include "internalloadseg.h" /***************************************************************************** NAME */ -#include +#include - BPTR LoadSegment( + AROS_LH4(BPTR, InternalLoadSeg, /* SYNOPSIS */ - BPTR fh, - BPTR table, - SIPTR * funcarray, - LONG * stack, - SIPTR * error, - struct Library *lib) + AROS_LHA(BPTR , fh , D0), + AROS_LHA(BPTR , table , A0), + AROS_LHA(LONG_FUNC *, funcarray , A1), + AROS_LHA(LONG * , stack , A2), -/* LOCATION - loadseg.lib +/* LOCATION */ + struct DosLibrary *, DOSBase, 126, Dos) - FUNCTION - Loads from fh. Although specified as a BPTR, 'fh' is passed - to the funcarray routines unchanged, and is never inspected - nor modified by LoadSegment() +/* FUNCTION + Loads from fh. + Functionarray is a pointer to an array of functions. See below. - funcarray is a pointer to an array of functions. See below. - - This function really tries to load the AOS HUNK and AROS ELF - file formats. + This function really only tries to load the different file + formats aos, elf and aout. INPUTS fh : Filehandle to load from - table : BPTR to BPTR that will point to an array - of BPTRs to segments (AOS HUNK format only) + table : ignored funcarray : array of functions to be used for read, seek, alloc and free - FuncTable[0] -> bytes = ReadFunc(readhandle, buffer, length) lib + FuncTable[0] -> bytes = ReadFunc(readhandle, buffer, length), DOSBase D0 D1 A0 D0 A6 FuncTable[1] -> Memory = AllocFunc(size,flags), ExecBase D0 D0 D1 A6 FuncTable[2] -> FreeFunc(memory, size), ExecBase A1 D0 A6 - FuncTable[3] -> pos = SeekFunc(readhandle, pos, mode) lib - D0 D0 D1 D2 A6 + FuncTable[3] -> pos = SeekFunc(readhandle, pos, mode), DOSBase + D0 D0 D1 D2 stack : pointer to storage (LONG) for stacksize. (currently ignored) - error : DOS IoError() style error code return - lib : Library base to pass to FuncTable[0] and [3] RESULT seglist - pointer to loaded Seglist or NULL in case of failure. NOTES FuncTable[3] is not used for Amiga HUNK format files, but is required - for ELF. - - The returned segment should be deallocatable by Dos/UnloadSeg(), - so ensure that your AllocFunc() routine does *not* allocate - pooled memory! + for ELF. EXAMPLE @@ -85,14 +73,16 @@ *****************************************************************************/ { + AROS_LIBFUNC_INIT + typedef struct _segfunc_t { ULONG id; - BPTR (*func)(BPTR, BPTR, SIPTR *, LONG *, SIPTR *, struct Library *); + BPTR (*func)(BPTR, BPTR, SIPTR *, LONG *, struct DosLibrary *); D(CONST_STRPTR format;) } segfunc_t; - #define SEGFUNC(id, format) {id, LoadSegment_##format D(, (STRPTR)#format)} + #define SEGFUNC(id, format) {id, InternalLoadSeg_##format D(, (STRPTR)#format)} static const segfunc_t funcs[] = { @@ -109,15 +99,15 @@ ULONG id; LONG len; - *error = 0; + SetIoErr(0); len = ilsRead(fh, &id, sizeof(id)); if (len == sizeof(id)) { id = AROS_BE2LONG(id); for (i = 0; i < num_funcs; i++) { if (funcs[i].id == id) { - segs = (*funcs[i].func)(fh, table, (SIPTR *)funcarray, - stack, error, lib); - D(bug("[LoadSegment] %s loading %p as an %s object.\n", + segs = (*funcs[i].func)(fh, BNULL, (SIPTR *)funcarray, + stack, DOSBase); + D(bug("[InternalLoadSeg] %s loading %p as an %s object.\n", segs ? "Succeeded" : "FAILED", fh, funcs[i].format)); return segs; } @@ -125,17 +115,44 @@ } } - *error = ERROR_NOT_EXECUTABLE; + SetIoErr(ERROR_NOT_EXECUTABLE); return BNULL; + + AROS_LIBFUNC_EXIT +} /* InternalLoadSeg */ -} /* LoadSegment */ +int read_block(BPTR file, APTR buffer, ULONG size, SIPTR * funcarray, struct DosLibrary * DOSBase) +{ + LONG subsize; + UBYTE *buf=(UBYTE *)buffer; + + while(size) + { + subsize = ilsRead(file, buf, size); + if(subsize==0) + { + if (DOSBase) + ((struct Process *)FindTask(NULL))->pr_Result2=ERROR_BAD_HUNK; + return 1; + } + + if(subsize<0) + return 1; + buf +=subsize; + size -=subsize; + } + return 0; +} APTR _ilsAllocVec(SIPTR *funcarray, ULONG size, ULONG req) { UBYTE *p = ilsAllocMem(size, req); + + D(bug("allocmem %p %d\n", p, size)); if (!p) return NULL; - D(bug("allocmem %p %d\n", p, size)); + + /* Note that the result is ULONG-aligned even on 64 bits! */ *((ULONG*)p) = (ULONG)size; return p + sizeof(ULONG); } diff --git a/compiler/loadseg/loadseg_intern.h b/rom/dos/internalloadseg.h similarity index 75% rename from compiler/loadseg/loadseg_intern.h rename to rom/dos/internalloadseg.h index 6fc2a59350..a415bc3b4e 100644 --- a/compiler/loadseg/loadseg_intern.h +++ b/rom/dos/internalloadseg.h @@ -1,18 +1,21 @@ #ifndef INTERNALLOADSEG_H #define INTERNALLOADSEG_H -BPTR LoadSegment_AOS(BPTR file, BPTR table, +BPTR InternalLoadSeg_AOS(BPTR file, + BPTR table, SIPTR * funcarray, LONG * stacksize, - SIPTR * error, - struct Library *lib); + struct DosLibrary * DOSBase); -BPTR LoadSegment_ELF(BPTR file, BPTR table, +BPTR InternalLoadSeg_ELF(BPTR file, + BPTR hunk_table, SIPTR * funcarray, LONG * stacksize, - SIPTR * error, - struct Library *lib); + struct DosLibrary * DOSBase); +int read_block(BPTR file, APTR buffer, ULONG size, SIPTR * funcarray, struct DosLibrary * DOSBase); + +/* AllocVec() simulation using allocation function from the supplied array */ APTR _ilsAllocVec(SIPTR *funcarray, ULONG size, ULONG flags); void _ilsFreeVec(SIPTR *funcarray, void *buf); @@ -26,10 +29,9 @@ void _ilsFreeVec(SIPTR *funcarray, void *buf); AROS_UFCA(BPTR, file, D1), \ AROS_UFCA(void *, buf, D2), \ AROS_UFCA(LONG, size, D3), \ - AROS_UFCA(struct Library *, lib, A6) \ + AROS_UFCA(struct DosLibrary *, DOSBase, A6) \ ) - #define ilsAllocMem(size, flags) \ AROS_UFC3 \ ( \ @@ -39,7 +41,6 @@ void _ilsFreeVec(SIPTR *funcarray, void *buf); AROS_UFCA(struct ExecBase *, SysBase, A6) \ ) - #define ilsFreeMem(addr, size) \ AROS_UFC3 \ ( \ @@ -56,7 +57,7 @@ void _ilsFreeVec(SIPTR *funcarray, void *buf); AROS_UFCA(BPTR, file, D1), \ AROS_UFCA(LONG, pos, D2), \ AROS_UFCA(LONG, mode, D3), \ - AROS_UFCA(struct Library *, lib, A6) \ + AROS_UFCA(struct DosLibrary *, DOSBase, A6) \ ) #endif diff --git a/compiler/loadseg/loadsegment_aos.c b/rom/dos/internalloadseg_aos.c similarity index 74% rename from compiler/loadseg/loadsegment_aos.c rename to rom/dos/internalloadseg_aos.c index 8905a1a1a9..5c98d5f71a 100644 --- a/compiler/loadseg/loadsegment_aos.c +++ b/rom/dos/internalloadseg_aos.c @@ -12,27 +12,29 @@ #include #include #include +#include #include #include #include #include -#include "loadseg_intern.h" +#include "dos_intern.h" +#include "internalloadseg.h" -static int read_block(BPTR file, APTR buffer, ULONG size, SIPTR * funcarray, SIPTR *error, struct Library * lib); +#include #define GETHUNKPTR(x) ((UBYTE*)(BADDR(hunktab[x]) + sizeof(BPTR))) /* Seek forward by count ULONGs. * Returns 0 on success, 1 on failure. */ -static int seek_forward(BPTR fd, ULONG count, SIPTR *funcarray, SIPTR *error, struct Library *lib) +static int seek_forward(BPTR fd, ULONG count, SIPTR *funcarray, struct DosLibrary *DOSBase) { int err = 0; ULONG tmp; /* For AOS compatibility, we can't use DOS/Seek() here, - * as AOS callers to LoadSegment will not pass + * as AOS callers to InternalLoadSeg will not pass * in a Seek element of the funcarray, and the read * callback of funcarray may be for reading in-memory * instead of pointing to DOS/Read. @@ -40,21 +42,21 @@ static int seek_forward(BPTR fd, ULONG count, SIPTR *funcarray, SIPTR *error, st * Luckily, reading HUNKs is linear, so we can just * read ahead. */ - while (count && !(err = read_block(fd, &tmp, sizeof(tmp), funcarray, error, lib))) + while (count && !(err = read_block(fd, &tmp, sizeof(tmp), funcarray, DOSBase))) count--; return err; } -BPTR LoadSegment_AOS(BPTR fh, - BPTR table, - SIPTR * funcarray, - LONG * stacksize, - SIPTR * error, - struct Library * lib) +BPTR InternalLoadSeg_AOS(BPTR fh, + BPTR table, + SIPTR * funcarray, + LONG * stacksize, + struct DosLibrary * DOSBase) { #define ERROR(a) { *error=a; goto end; } + BPTR *hunktab = BADDR(table); BPTR firsthunk = BNULL, prevhunk = BNULL; ULONG hunktype, count, first, last, curhunk, numhunks; @@ -64,28 +66,32 @@ BPTR LoadSegment_AOS(BPTR fh, BPTR last_p = 0; UBYTE *overlaytable = NULL; ULONG tmp, req; + SIPTR dummy; #if DEBUG static STRPTR segtypes[] = { "CODE", "DATA", "BSS", }; #endif - if (lib) + + SIPTR *error = &dummy; + + if (DOSBase) error =&((struct Process *)FindTask(NULL))->pr_Result2; curhunk = 0; /* keep GCC quiet */ /* start point is HUNK_HEADER + 4 */ while (1) { - if (read_block(fh, &count, sizeof(count), funcarray, error, lib)) + if (read_block(fh, &count, sizeof(count), funcarray, DOSBase)) goto end; if (count == 0L) break; count = AROS_BE2LONG(count); count *= 4; - if (read_block(fh, name_buf, count, funcarray, error, lib)) + if (read_block(fh, name_buf, count, funcarray, DOSBase)) goto end; D(bug("\tlibname: \"%.*s\"\n", count, name_buf)); } - if (read_block(fh, &numhunks, sizeof(numhunks), funcarray, error, lib)) + if (read_block(fh, &numhunks, sizeof(numhunks), funcarray, DOSBase)) goto end; numhunks = AROS_BE2LONG(numhunks); @@ -98,14 +104,14 @@ BPTR LoadSegment_AOS(BPTR fh, ERROR(ERROR_NO_FREE_STORE); } - if (read_block(fh, &first, sizeof(first), funcarray, error, lib)) + if (read_block(fh, &first, sizeof(first), funcarray, DOSBase)) goto end; first = AROS_BE2LONG(first); D(bug("\tFirst hunk: %ld\n", first)); curhunk = first; - if (read_block(fh, &last, sizeof(last), funcarray, error, lib)) + if (read_block(fh, &last, sizeof(last), funcarray, DOSBase)) goto end; last = AROS_BE2LONG(last); @@ -121,7 +127,7 @@ BPTR LoadSegment_AOS(BPTR fh, continue; } - if (read_block(fh, &count, sizeof(count), funcarray, error, lib)) + if (read_block(fh, &count, sizeof(count), funcarray, DOSBase)) goto end; count = AROS_BE2LONG(count); @@ -145,7 +151,7 @@ BPTR LoadSegment_AOS(BPTR fh, case HUNKF_ADVISORY: D(bug("ADVISORY")); - if (read_block(fh, &req, sizeof(req), funcarray, error, lib)) + if (read_block(fh, &req, sizeof(req), funcarray, DOSBase)) goto end; req = AROS_BE2LONG(req); break; @@ -185,7 +191,7 @@ BPTR LoadSegment_AOS(BPTR fh, prevhunk = hunktab[i]; } - while(!read_block(fh, &hunktype, sizeof(hunktype), funcarray, error, lib)) + while(!read_block(fh, &hunktype, sizeof(hunktype), funcarray, DOSBase)) { hunktype = AROS_BE2LONG(hunktype); D(bug("Hunk Type: %d\n", hunktype & 0xFFFFFF)); @@ -208,24 +214,24 @@ BPTR LoadSegment_AOS(BPTR fh, -------------------- */ D(bug("HUNK_SYMBOL (skipping)\n")); - while(!read_block(fh, &count, sizeof(count), funcarray, error, lib) && count) + while(!read_block(fh, &count, sizeof(count), funcarray, DOSBase) && count) { count = AROS_BE2LONG(count) ; - if (seek_forward(fh, count+1, funcarray, error, lib)) + if (seek_forward(fh, count+1, funcarray, DOSBase)) goto end; } break; case HUNK_UNIT: - if (read_block(fh, &count, sizeof(count), funcarray, error, lib)) + if (read_block(fh, &count, sizeof(count), funcarray, DOSBase)) goto end; count = AROS_BE2LONG(count) ; count *= 4; - if (read_block(fh, name_buf, count, funcarray, error, lib)) + if (read_block(fh, name_buf, count, funcarray, DOSBase)) goto end; D(bug("HUNK_UNIT: \"%.*s\"\n", count, name_buf)); break; @@ -234,7 +240,7 @@ BPTR LoadSegment_AOS(BPTR fh, case HUNK_DATA: case HUNK_BSS: - if (read_block(fh, &count, sizeof(count), funcarray, error, lib)) + if (read_block(fh, &count, sizeof(count), funcarray, DOSBase)) goto end; count = AROS_BE2LONG(count); @@ -256,7 +262,7 @@ BPTR LoadSegment_AOS(BPTR fh, case HUNKF_ADVISORY: D(bug("ADVISORY")); - if (read_block(fh, &req, sizeof(req), funcarray, error, lib)) + if (read_block(fh, &req, sizeof(req), funcarray, DOSBase)) goto end; req = AROS_BE2LONG(req); @@ -272,7 +278,7 @@ BPTR LoadSegment_AOS(BPTR fh, D(bug(" memory\n")); if ((hunktype & 0xFFFFFF) != HUNK_BSS && count) { - if (read_block(fh, GETHUNKPTR(curhunk), count*4, funcarray, error, lib)) + if (read_block(fh, GETHUNKPTR(curhunk), count*4, funcarray, DOSBase)) goto end; } @@ -285,7 +291,7 @@ BPTR LoadSegment_AOS(BPTR fh, ULONG *addr; ULONG offset; - if (read_block(fh, &count, sizeof(count), funcarray, error, lib)) + if (read_block(fh, &count, sizeof(count), funcarray, DOSBase)) goto end; if (count == 0L) break; @@ -293,7 +299,7 @@ BPTR LoadSegment_AOS(BPTR fh, count = AROS_BE2LONG(count); i = count; - if (read_block(fh, &count, sizeof(count), funcarray, error, lib)) + if (read_block(fh, &count, sizeof(count), funcarray, DOSBase)) goto end; count = AROS_BE2LONG(count); @@ -301,7 +307,7 @@ BPTR LoadSegment_AOS(BPTR fh, D(bug("\tHunk #%ld:\n", count)); while (i > 0) { - if (read_block(fh, &offset, sizeof(offset), funcarray, error, lib)) + if (read_block(fh, &offset, sizeof(offset), funcarray, DOSBase)) goto end; offset = AROS_BE2LONG(offset); @@ -332,7 +338,7 @@ BPTR LoadSegment_AOS(BPTR fh, Wordcount++; - if (read_block(fh, &word, sizeof(word), funcarray, error, lib)) + if (read_block(fh, &word, sizeof(word), funcarray, DOSBase)) goto end; if (word == 0L) break; @@ -341,7 +347,7 @@ BPTR LoadSegment_AOS(BPTR fh, i = word; Wordcount++; - if (read_block(fh, &word, sizeof(word), funcarray, error, lib)) + if (read_block(fh, &word, sizeof(word), funcarray, DOSBase)) goto end; word = AROS_BE2WORD(word); @@ -352,7 +358,7 @@ BPTR LoadSegment_AOS(BPTR fh, { Wordcount++; /* read a 16bit number (2 bytes) */ - if (read_block(fh, &word, sizeof(word), funcarray, error, lib)) + if (read_block(fh, &word, sizeof(word), funcarray, DOSBase)) goto end; /* offset now contains the byte offset in it`s 16 highest bits. @@ -376,7 +382,7 @@ BPTR LoadSegment_AOS(BPTR fh, 16-bit word */ if (0x1 == (Wordcount & 0x1)) { UWORD word; - read_block(fh, &word, sizeof(word), funcarray, error, lib); + read_block(fh, &word, sizeof(word), funcarray, DOSBase); } } break; @@ -385,11 +391,11 @@ BPTR LoadSegment_AOS(BPTR fh, { D(bug("HUNK_END\n")); ++curhunk; - /* lib == NULL: Called from RDB filesystem loader which does not + /* DOSBase == NULL: Called from RDB filesystem loader which does not * know filesystem's original size. Exit if last HUNK_END. This can't * be done normally because it would break overlayed executables. */ - if (!lib && curhunk > last) + if (!DOSBase && curhunk > last) goto done; } break; @@ -411,13 +417,13 @@ BPTR LoadSegment_AOS(BPTR fh, ERROR(ERROR_BAD_HUNK); case HUNK_DEBUG: - if (read_block(fh, &count, sizeof(count), funcarray, error, lib)) + if (read_block(fh, &count, sizeof(count), funcarray, DOSBase)) goto end; count = AROS_BE2LONG(count); D(bug("HUNK_DEBUG (%x Bytes)\n",count)); - if (seek_forward(fh, count, funcarray, error, lib)) + if (seek_forward(fh, count, funcarray, DOSBase)) goto end; break; @@ -426,7 +432,7 @@ BPTR LoadSegment_AOS(BPTR fh, D(bug("HUNK_OVERLAY:\n")); if (table) /* overlay inside overlay? */ ERROR(ERROR_BAD_HUNK); - if (read_block(fh, &count, sizeof(count), funcarray, error, lib)) + if (read_block(fh, &count, sizeof(count), funcarray, DOSBase)) goto end; count = AROS_BE2LONG(count); D(bug("Overlay table size: %d\n", count)); @@ -436,7 +442,7 @@ BPTR LoadSegment_AOS(BPTR fh, overlaytable = ilsAllocVec(count, MEMF_CLEAR | MEMF_31BIT); if (overlaytable == NULL) ERROR(ERROR_NO_FREE_STORE); - if (read_block(fh, overlaytable, count - sizeof(ULONG), funcarray, error, lib)) + if (read_block(fh, overlaytable, count - sizeof(ULONG), funcarray, DOSBase)) goto end; goto done; } @@ -456,17 +462,16 @@ done: if (hunktab) { ULONG hunksize; - /* Clear caches */ - for (t = first; t < numhunks && t <= last; t++) + + if (SysBase->LibNode.lib_Version >= 36) { - hunksize = *((ULONG*)BADDR(hunktab[t]) - 1); - /* We check for SysBase's lib_Version, since some - * users of this library will be running on AOS 1.3 or lower - */ - if (hunksize && SysBase->LibNode.lib_Version >= 36) - { - CacheClearE(BADDR(hunktab[t]), hunksize, CACRF_ClearI | CACRF_ClearD); - } + /* Clear caches */ + for (t = first; t < numhunks && t <= last; t++) + { + hunksize = *((ULONG*)BADDR(hunktab[t]) - 1); + if (hunksize) + CacheClearE(BADDR(hunktab[t]), hunksize, CACRF_ClearI | CACRF_ClearD); + } } if (table) @@ -513,28 +518,73 @@ end: ilsFreeVec(hunktab); } return last_p; -} /* LoadSegment */ +} /* InternalLoadSeg */ + +#ifdef __mc68000 +static AROS_UFH4(LONG, ReadFunc, + AROS_UFHA(BPTR, file, D1), + AROS_UFHA(APTR, buffer, D2), + AROS_UFHA(LONG, length, D3), + AROS_UFHA(struct DosLibrary *, DOSBase, A6) +) +{ + AROS_USERFUNC_INIT + return FRead(file, buffer, 1, length); -static int read_block(BPTR file, APTR buffer, ULONG size, SIPTR * funcarray, SIPTR *error, struct Library * lib) + AROS_USERFUNC_EXIT +} + +static AROS_UFH3(APTR, AllocFunc, + AROS_UFHA(ULONG, length, D0), + AROS_UFHA(ULONG, flags, D1), + AROS_UFHA(struct ExecBase *, SysBase, A6) +) { - LONG subsize; - UBYTE *buf=(UBYTE *)buffer; + AROS_USERFUNC_INIT - while(size) - { - subsize = ilsRead(file, buf, size); - if(subsize==0) - { - *error = ERROR_BAD_HUNK; - return 1; - } + return AllocMem(length, flags); - if(subsize<0) - return 1; - buf +=subsize; - size -=subsize; - } - return 0; + AROS_USERFUNC_EXIT } +static AROS_UFH3(void, FreeFunc, + AROS_UFHA(APTR, buffer, A1), + AROS_UFHA(ULONG, length, D0), + AROS_UFHA(struct ExecBase *, SysBase, A6) +) +{ + AROS_USERFUNC_INIT + + FreeMem(buffer, length); + + AROS_USERFUNC_EXIT +} + +AROS_UFH4(BPTR, LoadSeg_Overlay, + AROS_UFHA(UBYTE*, name, D1), + AROS_UFHA(BPTR, hunktable, D2), + AROS_UFHA(BPTR, fh, D3), + AROS_UFHA(struct DosLibrary *, DosBase, A6)) +{ + AROS_USERFUNC_INIT + + void (*FunctionArray[3])(); + ULONG hunktype; + + FunctionArray[0] = (APTR)ReadFunc; + FunctionArray[1] = (APTR)AllocFunc; + FunctionArray[2] = (APTR)FreeFunc; + + D(bug("LoadSeg_Overlay. table=%x fh=%x\n", hunktable, fh)); + if (read_block(fh, &hunktype, sizeof(hunktype), (SIPTR*)FunctionArray, DosBase)) + return BNULL; + hunktype = AROS_BE2LONG(hunktype); + if (hunktype != HUNK_HEADER) + return BNULL; + return InternalLoadSeg_AOS(fh, hunktable, (SIPTR*)FunctionArray, NULL, DosBase); + + AROS_USERFUNC_EXIT +} + +#endif diff --git a/compiler/loadseg/loadsegment_elf.c b/rom/dos/internalloadseg_elf.c similarity index 84% rename from compiler/loadseg/loadsegment_elf.c rename to rom/dos/internalloadseg_elf.c index 9877d420eb..e805fb79a8 100644 --- a/compiler/loadseg/loadsegment_elf.c +++ b/rom/dos/internalloadseg_elf.c @@ -17,18 +17,17 @@ #include #include #include +#include #include -#include -/* For ELF module registration */ #include -#include +#include #include #include -#include - -#include "loadseg_intern.h" +#include "internalloadseg.h" +#include "dos_intern.h" +#include "include/loadseg.h" struct hunk { @@ -40,40 +39,20 @@ struct hunk #define BPTR2HUNK(bptr) ((struct hunk *)((void *)bptr - offsetof(struct hunk, next))) #define HUNK2BPTR(hunk) MKBADDR(&hunk->next) -static int read_block +static int elf_read_block ( BPTR file, ULONG offset, APTR buffer, ULONG size, SIPTR *funcarray, - SIPTR *error, - struct Library *lib + struct DosLibrary *DOSBase ) { - UBYTE *buf = (UBYTE *)buffer; - LONG subsize; - if (ilsSeek(file, offset, OFFSET_BEGINNING) < 0) - return 0; - - while (size) - { - subsize = ilsRead(file, buf, size); - - if (subsize <= 0) - { - if (subsize == 0) - *error = ERROR_BAD_HUNK; - - return 0; - } - - buf += subsize; - size -= subsize; - } + return 1; - return 1; + return read_block(file, buffer, size, funcarray, DOSBase); } static void *load_block @@ -82,8 +61,7 @@ static void *load_block ULONG offset, ULONG size, SIPTR *funcarray, - SIPTR *error, - struct Library *lib + struct DosLibrary *DOSBase ) { D(bug("[ELF Loader] Load Block\n")); @@ -93,18 +71,18 @@ static void *load_block void *block = ilsAllocMem(size, MEMF_ANY); if (block) { - if (read_block(file, offset, block, size, funcarray, error, lib)) + if (!elf_read_block(file, offset, block, size, funcarray, DOSBase)) return block; ilsFreeMem(block, size); } else - *error = ERROR_NO_FREE_STORE; + SetIoErr(ERROR_NO_FREE_STORE); return NULL; } -static ULONG read_shnum(BPTR file, struct elfheader *eh, SIPTR *funcarray, SIPTR *error, struct Library *lib) +static ULONG read_shnum(BPTR file, struct elfheader *eh, SIPTR *funcarray, struct DosLibrary *DOSBase) { ULONG shnum = eh->shnum; @@ -123,11 +101,11 @@ static ULONG read_shnum(BPTR file, struct elfheader *eh, SIPTR *funcarray, SIPTR struct sheader sh; if (eh->shoff == 0) { - *error = ERROR_NOT_EXECUTABLE; + SetIoErr(ERROR_NOT_EXECUTABLE); return 0; } - if (!read_block(file, eh->shoff, &sh, sizeof(sh), funcarray, error, lib)) + if (elf_read_block(file, eh->shoff, &sh, sizeof(sh), funcarray, DOSBase)) return 0; /* wider section header count is in the size field */ @@ -135,58 +113,21 @@ static ULONG read_shnum(BPTR file, struct elfheader *eh, SIPTR *funcarray, SIPTR /* sanity, if they're still invalid then this isn't elf */ if (shnum == 0) - *error = ERROR_NOT_EXECUTABLE; + SetIoErr(ERROR_NOT_EXECUTABLE); } return shnum; } -static void register_elf(BPTR file, BPTR hunks, struct elfheader *eh, struct sheader *sh, struct Library *lib) +static int load_header(BPTR file, struct elfheader *eh, SIPTR *funcarray, struct DosLibrary *DOSBase) { - APTR DOSBase = lib; - APTR DebugBase; - - /* If the passed in library is not DOS, then we can't get - * the name of ELF file. - */ - if (lib == NULL || strcmp(lib->lib_Node.ln_Name,"dos.library")!=0) - return; - - if ((DebugBase = OpenLibrary("debug.library", 0))) - { - char *buffer = AllocMem(512, MEMF_ANY); - - if (buffer) { - if (NameFromFH(file, buffer, 512)) - { - char *nameptr = buffer; - struct ELF_DebugInfo dbg = {eh, sh}; - - /* gdb support needs full paths */ -#if !AROS_MODULES_DEBUG - /* First, go through the name, till end of the string */ - while(*nameptr++); - /* Now, go back until either ":" or "/" is found */ - while(nameptr > buffer && nameptr[-1] != ':' && nameptr[-1] != '/') - nameptr--; -#endif - RegisterModule(nameptr, hunks, DEBUG_ELF, &dbg); - } - FreeMem(buffer, 512); - } - CloseLibrary(DebugBase); - } -} - -static int load_header(BPTR file, struct elfheader *eh, SIPTR *funcarray, SIPTR *error, struct Library *lib) { - ilsSeek(file, OFFSET_BEGINNING, 0); - if (!read_block(file, 0, eh, sizeof(struct elfheader), funcarray, error, lib)) + if (elf_read_block(file, 0, eh, sizeof(struct elfheader), funcarray, DOSBase)) return 0; if (eh->ident[0] != 0x7f || eh->ident[1] != 'E' || eh->ident[2] != 'L' || eh->ident[3] != 'F') { D(bug("[ELF Loader] Not an ELF object\n")); - *error = ERROR_NOT_EXECUTABLE; + SetIoErr(ERROR_NOT_EXECUTABLE); return 0; } D(bug("[ELF Loader] ELF object\n")); @@ -205,7 +146,7 @@ static int load_header(BPTR file, struct elfheader *eh, SIPTR *funcarray, SIPTR D(bug("[ELF Loader] EI_DATA is %d - should be %d\n", eh->ident[EI_DATA] , AROS_ELF_DATA )); D(bug("[ELF Loader] machine is %d - should be %d\n", eh->machine , AROS_ELF_MACHINE)); - *error = ERROR_NOT_EXECUTABLE; + SetIoErr(ERROR_NOT_EXECUTABLE); return 0; } @@ -219,8 +160,7 @@ static int load_hunk struct sheader *sh, SIPTR *funcarray, BOOL do_align, - SIPTR *error, - struct Library *lib + struct DosLibrary *DOSBase ) { struct hunk *hunk; @@ -277,13 +217,13 @@ static int load_hunk *next_hunk_ptr = &hunk->next; if (sh->type != SHT_NOBITS) - return read_block(file, sh->offset, sh->addr, sh->size, funcarray, error, lib); + return !elf_read_block(file, sh->offset, sh->addr, sh->size, funcarray, DOSBase); return 1; } - *error = ERROR_NO_FREE_STORE; + SetIoErr(ERROR_NO_FREE_STORE); return 0; } @@ -294,8 +234,7 @@ static int relocate struct sheader *sh, ULONG shrel_idx, struct sheader *symtab_shndx, - SIPTR *error, - struct Library *lib + struct DosLibrary *DOSBase ) { struct sheader *shrel = &sh[shrel_idx]; @@ -345,7 +284,7 @@ static int relocate else { if (symtab_shndx == NULL) { D(bug("[ELF Loader] got symbol with shndx 0xfff, but there's no symtab shndx table\n")); - *error = ERROR_BAD_HUNK; + SetIoErr(ERROR_BAD_HUNK); return 0; } shindex = ((ULONG *)symtab_shndx->addr)[ELF_R_SYM(rel->info)]; @@ -363,7 +302,7 @@ static int relocate if (strncmp((STRPTR)sh[SHINDEX(shsymtab->link)].addr + sym->name, "__aros_libreq_", 14) != 0) { D(bug("[ELF Loader] Undefined symbol '%s'\n", (STRPTR)sh[SHINDEX(shsymtab->link)].addr + sym->name)); - *error = ERROR_BAD_HUNK; + SetIoErr(ERROR_BAD_HUNK); return 0; } break; @@ -371,7 +310,7 @@ static int relocate case SHN_COMMON: D(bug("[ELF Loader] COMMON symbol '%s'\n", (STRPTR)sh[SHINDEX(shsymtab->link)].addr + sym->name)); - *error = ERROR_BAD_HUNK; + SetIoErr(ERROR_BAD_HUNK); return 0; @@ -534,7 +473,7 @@ static int relocate offset <= -0x02000000) { bug("[ELF Loader] Relocation type %d %d out of range!\n", i, ELF_R_TYPE(rel->info)); - *error = ERROR_BAD_HUNK; + SetIoErr(ERROR_BAD_HUNK); return 0; } offset += s - (ULONG)p; @@ -570,7 +509,7 @@ static int relocate offset <= -0x01000000) { bug("[ELF Loader] Relocation type %d %d out of range!\n", i, ELF_R_TYPE(rel->info)); - *error = ERROR_BAD_HUNK; + SetIoErr(ERROR_BAD_HUNK); return 0; } offset += s - (ULONG)p; @@ -647,7 +586,7 @@ static int relocate default: D(bug("[ELF Loader] Unrecognized relocation type %d %d\n", i, ELF_R_TYPE(rel->info))); - *error = ERROR_BAD_HUNK; + SetIoErr(ERROR_BAD_HUNK); return 0; } } @@ -655,14 +594,13 @@ static int relocate return 1; } -BPTR LoadSegment_ELF +BPTR InternalLoadSeg_ELF ( BPTR file, BPTR table __unused, SIPTR *funcarray, LONG *stack __unused, - SIPTR *error, - struct Library *lib + struct DosLibrary *DOSBase ) { struct elfheader eh; @@ -675,15 +613,15 @@ BPTR LoadSegment_ELF ULONG int_shnum; /* load and validate ELF header */ - if (!load_header(file, &eh, funcarray, error, lib)) + if (!load_header(file, &eh, funcarray, DOSBase)) return 0; - int_shnum = read_shnum(file, &eh, funcarray, error, lib); + int_shnum = read_shnum(file, &eh, funcarray, DOSBase); if (!int_shnum) return 0; /* load section headers */ - if (!(sh = load_block(file, eh.shoff, int_shnum * eh.shentsize, funcarray, error, lib))) + if (!(sh = load_block(file, eh.shoff, int_shnum * eh.shentsize, funcarray, DOSBase))) return 0; /* Iterate over the section headers in order to do some stuff... */ @@ -698,7 +636,7 @@ BPTR LoadSegment_ELF */ if (sh[i].type == SHT_SYMTAB || sh[i].type == SHT_STRTAB || sh[i].type == SHT_SYMTAB_SHNDX) { - sh[i].addr = load_block(file, sh[i].offset, sh[i].size, funcarray, error, lib); + sh[i].addr = load_block(file, sh[i].offset, sh[i].size, funcarray, DOSBase); if (!sh[i].addr) goto error; @@ -723,7 +661,7 @@ BPTR LoadSegment_ELF if (sh[i].flags & SHF_EXECINSTR) exec_hunk_seen = TRUE; - if (!load_hunk(file, &next_hunk_ptr, &sh[i], funcarray, exec_hunk_seen, error, lib)) + if (!load_hunk(file, &next_hunk_ptr, &sh[i], funcarray, exec_hunk_seen, DOSBase)) goto error; } } @@ -736,8 +674,8 @@ BPTR LoadSegment_ELF /* Does this relocation section refer to a hunk? If so, addr must be != 0 */ if ((sh[i].type == AROS_ELF_REL) && sh[SHINDEX(sh[i].info)].addr) { - sh[i].addr = load_block(file, sh[i].offset, sh[i].size, funcarray, error, lib); - if (!sh[i].addr || !relocate(&eh, sh, i, symtab_shndx, error, lib)) + sh[i].addr = load_block(file, sh[i].offset, sh[i].size, funcarray, DOSBase); + if (!sh[i].addr || !relocate(&eh, sh, i, symtab_shndx, DOSBase)) goto error; ilsFreeMem(sh[i].addr, sh[i].size); @@ -746,25 +684,28 @@ BPTR LoadSegment_ELF } /* Everything is loaded now. Register the module at kernel.resource */ - register_elf(file, hunks, &eh, sh, lib); + register_elf(file, hunks, &eh, sh, DOSBase); goto end; error: /* There were some errors, deallocate The hunks */ - UnLoadSegment(hunks, (VOID_FUNC)funcarray[2], NULL); + InternalUnLoadSeg(hunks, (VOID_FUNC)funcarray[2]); hunks = 0; end: - /* Clear the caches to let the CPU see the new data and instructions */ - /* We check for SysBase's lib_Version, since some - * users of this library will be running on AOS 1.3 or lower + /* + * Clear the caches to let the CPU see the new data and instructions. + * We check for SysBase's lib_Version, since this code is also built + * as linklib for AmigaOS version of AROS bootstrap, and it can be + * running on AOS 1.3 or lower. */ if (SysBase->LibNode.lib_Version >= 36) { BPTR curr = hunks; + while (curr) { struct hunk *hunk = BPTR2HUNK(BADDR(curr)); diff --git a/rom/dos/internalloadseg_support.c b/rom/dos/internalloadseg_support.c new file mode 100644 index 0000000000..450ab2cb19 --- /dev/null +++ b/rom/dos/internalloadseg_support.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include + +#include "dos_intern.h" +#include "internalloadseg.h" + +void register_elf(BPTR file, BPTR hunks, struct elfheader *eh, struct sheader *sh, struct DosLibrary *DOSBase) +{ + if (DebugBase) + { + char *buffer = AllocMem(512, MEMF_ANY); + + if (buffer) { + if (NameFromFH(file, buffer, 512)) + { + char *nameptr = buffer; + struct ELF_DebugInfo dbg = {eh, sh}; + + /* gdb support needs full paths */ +#if !AROS_MODULES_DEBUG + /* First, go through the name, till end of the string */ + while(*nameptr++); + /* Now, go back until either ":" or "/" is found */ + while(nameptr > buffer && nameptr[-1] != ':' && nameptr[-1] != '/') + nameptr--; +#endif + RegisterModule(nameptr, hunks, DEBUG_ELF, &dbg); + } + FreeMem(buffer, 512); + } + CloseLibrary(DebugBase); + } +} diff --git a/rom/dos/internalunloadseg.c b/rom/dos/internalunloadseg.c index d0d261c8bf..d49a1e548b 100644 --- a/rom/dos/internalunloadseg.c +++ b/rom/dos/internalunloadseg.c @@ -13,7 +13,7 @@ #include #include "dos_intern.h" -#include +#include "internalloadseg.h" /***************************************************************************** @@ -53,7 +53,37 @@ { AROS_LIBFUNC_INIT - return UnLoadSegment(seglist, freefunc, DOSBase); + BPTR next; + SIPTR funcarray[] = { (SIPTR)NULL, (SIPTR)NULL, (SIPTR)freefunc }; + + if (seglist) + { + if (DebugBase) + UnregisterModule(seglist); + +#ifdef __mc68000 + { + /* free overlay structures */ + ULONG *seg = BADDR(seglist); + if (seg[2] == 0x0000abcd && seg[6] == (ULONG)DOSBase->dl_GV) { + Close((BPTR)seg[3]); /* file handle */ + ilsFreeVec((void*)seg[4]); /* overlay table, APTR */ + ilsFreeVec(BADDR(seg[5])); /* hunk table, BPTR */ + } + } +#endif + + while (seglist) + { + next = *(BPTR *)BADDR(seglist); + ilsFreeVec(BADDR(seglist)); + seglist = next; + } + + return DOSTRUE; + } + else + return DOSFALSE; AROS_LIBFUNC_EXIT } /* InternalUnLoadSeg */ diff --git a/rom/dos/loadseg_overlay.c b/rom/dos/loadseg_overlay.c deleted file mode 100644 index a9a813af3c..0000000000 --- a/rom/dos/loadseg_overlay.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - Copyright © 1995-2011, The AROS Development Team. All rights reserved. - $Id$ - - Desc: - Lang: english -*/ -#define DEBUG 0 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "dos_intern.h" - -#if (AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT) && defined(__mc68000) -static AROS_UFH4(LONG, ReadFunc, - AROS_UFHA(BPTR, file, D1), - AROS_UFHA(APTR, buffer, D2), - AROS_UFHA(LONG, length, D3), - AROS_UFHA(struct DosLibrary *, DOSBase, A6) -) -{ - AROS_USERFUNC_INIT - - return FRead(file, buffer, 1, length); - - AROS_USERFUNC_EXIT -} - -static AROS_UFH3(APTR, AllocFunc, - AROS_UFHA(ULONG, length, D0), - AROS_UFHA(ULONG, flags, D1), - AROS_UFHA(struct ExecBase *, SysBase, A6) -) -{ - AROS_USERFUNC_INIT - - return AllocMem(length, flags); - - AROS_USERFUNC_EXIT -} - -static AROS_UFH3(void, FreeFunc, - AROS_UFHA(APTR, buffer, A1), - AROS_UFHA(ULONG, length, D0), - AROS_UFHA(struct ExecBase *, SysBase, A6) -) -{ - AROS_USERFUNC_INIT - - FreeMem(buffer, length); - - AROS_USERFUNC_EXIT -} - -AROS_UFH4(BPTR, LoadSeg_Overlay, - AROS_UFHA(UBYTE*, name, D1), - AROS_UFHA(BPTR, hunktable, D2), - AROS_UFHA(BPTR, fh, D3), - AROS_UFHA(struct DosLibrary *, DOSBase, A6)) -{ - AROS_USERFUNC_INIT - - void (*FunctionArray[3])(); - ULONG hunktype; - BPTR seg; - SIPTR error = RETURN_OK; - - FunctionArray[0] = (APTR)ReadFunc; - FunctionArray[1] = (APTR)AllocFunc; - FunctionArray[2] = (APTR)FreeFunc; - - D(bug("LoadSeg_Overlay. table=%x fh=%x\n", hunktable, fh)); - if (AROS_UFC4(LONG, ReadFunc, - AROS_UFCA(BPTR, fh, D1), - AROS_UFCA(void *, &hunktype, D2), - AROS_UFCA(LONG, sizeof(hunktype), D3), - AROS_UFCA(struct Library *, DOSBase,A6)) != sizeof(hunktype)) - return BNULL; - hunktype = AROS_BE2LONG(hunktype); - if (hunktype != HUNK_HEADER) - return BNULL; - seg = LoadSegment(fh, hunktable, (SIPTR*)FunctionArray, NULL, &error, (struct Library *)DOSBase); - if (seg == BNULL) - SetIoErr(error); - - return seg; - - AROS_USERFUNC_EXIT -} - -#endif diff --git a/rom/dos/mmakefile.src b/rom/dos/mmakefile.src index cb447dc2cf..dd54c10480 100644 --- a/rom/dos/mmakefile.src +++ b/rom/dos/mmakefile.src @@ -4,10 +4,15 @@ include $(TOP)/config/make.cfg USER_INCLUDES := -I$(GENDIR)/$(CURDIR) USER_CFLAGS := -D__DOS_NOLIBBASE__ +IMAGE_TYPES := aos elf + FILES := bcpl_support bstr_helper errorlist \ match_misc newcliproc rootnode fs_driver \ patternmatching internalseek internalflush \ - packethelper namefrom loadseg_overlay + packethelper namefrom internalloadseg_support + +LOADSEG_FILES := internalloadseg \ + $(foreach img, $(IMAGE_TYPES), internalloadseg_$(img)) FUNCTIONS := abortpkt addbuffers adddosentry addpart addsegment \ allocdosobject assignadd assignlate assignlock assignpath \ @@ -22,7 +27,7 @@ FUNCTIONS := abortpkt addbuffers adddosentry addpart addsegment \ freedosentry freedosobject fwrite getargstr getconsoletask \ getcurrentdirname getdeviceproc getfilesystask getprogramdir \ getprogramname getprompt getvar info inhibit input \ - internalloadseg internalunloadseg ioerr isfilesystem \ + internalunloadseg ioerr isfilesystem \ isinteractive loadseg lock lockdoslist lockrecord lockrecords \ makedosentry makelink matchend matchfirst matchnext matchpattern \ matchpatternnocase maxcli namefromfh namefromlock newloadseg nextdosentry \ @@ -51,8 +56,8 @@ FUNCTIONS := abortpkt addbuffers adddosentry addpart addsegment \ %build_module mmake=kernel-dos \ modname=dos modtype=library \ - files="dos_init $(FUNCTIONS) $(FILES)" \ - uselibs="loadseg rom" + files="dos_init $(FUNCTIONS) $(FILES) $(LOADSEG_FILES)" \ + uselibs="rom" $(GENDIR)/$(CURDIR)/errorlist.d : $(GENDIR)/$(CURDIR)/errorlist.h @@ -60,4 +65,6 @@ $(GENDIR)/$(CURDIR)/errorlist.h : $(SRCDIR)/$(CURDIR)/catalogs/dos.cd $(SRCDIR)/ @$(ECHO) Generating $@... @$(SRCDIR)/$(CURDIR)/genstrings.py $< > $@ +%build_linklib mmake=linklibs-loadseg libname=loadseg files="$(LOADSEG_FILES)" libdir=$(GENDIR)/lib + %common diff --git a/rom/partition/mmakefile.src b/rom/partition/mmakefile.src index 41be325743..d2b2b601b8 100644 --- a/rom/partition/mmakefile.src +++ b/rom/partition/mmakefile.src @@ -44,6 +44,6 @@ USER_CFLAGS := -DDEBUG=0 \ %build_module mmake=kernel-partition \ modname=partition modtype=library \ - files="partition_init $(FUNCS) $(FILES)" uselibs="debug loadseg rom" + files="partition_init $(FUNCS) $(FILES)" uselibs="debug rom" %common diff --git a/rom/partition/partitionrdb.c b/rom/partition/partitionrdb.c index c8c05d0991..ee680598e2 100644 --- a/rom/partition/partitionrdb.c +++ b/rom/partition/partitionrdb.c @@ -17,8 +17,6 @@ #include #include -#include - #include "partition_support.h" #include "platform.h" @@ -163,13 +161,33 @@ static BPTR LoadFS(struct FileSysNode *node, struct DosLibrary *DOSBase) #if (AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT) && defined(__mc68000) -static SIPTR AddFS(struct RDBData *data) +/* We can't use InternalLoadSeg() because DOS isn't initialized + * at this point. To allow this to be built as a relocatable + * library, we provide a dummy weak alias here, which will + * be overridden when linking the ROM image. + */ +static BPTR _InternalLoadSeg_AOS(BPTR fh, + BPTR table, + SIPTR * funcarray, + SIPTR * stack, + struct Library * DOSBase) +{ + return BNULL; +} + +BPTR InternalLoadSeg_AOS(BPTR fh, + BPTR table, + SIPTR * funcarray, + SIPTR * stack, + struct Library * DOSBase) + __attribute__((weak, alias("_InternalLoadSeg_AOS"))); + +static void AddFS(struct RDBData *data) { struct FileSysResource *fsr; struct FileSysNode *node; void (* FunctionArray[4])(); struct FileSysReader fakefile; - SIPTR error = RETURN_OK; FunctionArray[0] = (void(*))ReadFunc; FunctionArray[1] = __AROS_GETVECADDR(SysBase,33); /* AllocMem() */ @@ -178,7 +196,7 @@ static SIPTR AddFS(struct RDBData *data) fsr = OpenResource("FileSystem.resource"); if (!fsr) - return ERROR_INVALID_RESIDENT_LIBRARY; + return; ForeachNode(&data->fsheaderlist, node) { struct FileSysEntry *fsrnode; @@ -201,7 +219,7 @@ static SIPTR AddFS(struct RDBData *data) fakefile.size = size; fakefile.fsn = node; if (node->filesystem[0].lsb_LoadData[0] == 0x000003f3) { - BPTR seg = LoadSegment((BPTR)&fakefile, BNULL, (SIPTR*)FunctionArray, NULL, &error, NULL); + BPTR seg = InternalLoadSeg_AOS((BPTR)&fakefile, BNULL, (SIPTR*)FunctionArray, NULL, NULL); if (seg) { D(bug("RDB fs %08x %d.%d '%s' seg=%08x added\n", dostype, version >> 16, version & 0xffff, &node->fhb.fhb_FileSysName, seg)); @@ -211,8 +229,6 @@ static SIPTR AddFS(struct RDBData *data) } } } - - return error; } #endif @@ -566,10 +582,9 @@ UBYTE i; } FreeVec(buffer); #if (AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT) && defined(__mc68000) - return AddFS(data); -#else - return 0; + AddFS(data); #endif + return 0; } FreeMem(data, sizeof(struct RDBData)); } -- 2.11.4.GIT