Index: .fossil-settings/clean-glob ================================================================== --- .fossil-settings/clean-glob +++ .fossil-settings/clean-glob @@ -25,10 +25,11 @@ docs extra.mk generators/gen_tables src/Info.plist src/bridge/Info.plist +src/inline.h src/objfw-defs.h src/runtime/amiga-library-functable.inc src/runtime/inline.h tests/EBOOT.PBP tests/Info.plist Index: .fossil-settings/ignore-glob ================================================================== --- .fossil-settings/ignore-glob +++ .fossil-settings/ignore-glob @@ -27,10 +27,11 @@ docs extra.mk generators/gen_tables src/Info.plist src/bridge/Info.plist +src/inline.h src/objfw-defs.h src/runtime/amiga-library-functable.inc src/runtime/inline.h tests/EBOOT.PBP tests/Info.plist Index: .gitignore ================================================================== --- .gitignore +++ .gitignore @@ -27,10 +27,11 @@ docs extra.mk generators/gen_tables src/Info.plist src/bridge/Info.plist +src/inline.h src/objfw-defs.h src/runtime/amiga-library-functable.inc src/runtime/inline.h tests/EBOOT.PBP tests/Info.plist Index: buildsys.mk.in ================================================================== --- buildsys.mk.in +++ buildsys.mk.in @@ -128,11 +128,11 @@ all: ${MAKE} -s pre-all ${MAKE} -s subdirs ${MAKE} -s depend - ${MAKE} -s ${STATIC_LIB} ${STATIC_LIB_NOINST} ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST} ${SHARED_LIB} ${SHARED_LIB_NOINST} ${FRAMEWORK} ${FRAMEWORK_NOINST} ${AMIGA_LIB} ${AMIGA_LIB_NOINST} ${PLUGIN} ${PLUGIN_NOINST} ${PROG} ${PROG_NOINST} ${JARFILE} locales + ${MAKE} -s ${STATIC_LIB} ${STATIC_LIB_NOINST} ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST} ${STATIC_AMIGA_LIB} ${STATIC_AMIGA_LIB_NOINST} ${SHARED_LIB} ${SHARED_LIB_NOINST} ${FRAMEWORK} ${FRAMEWORK_NOINST} ${AMIGA_LIB} ${AMIGA_LIB_NOINST} ${PLUGIN} ${PLUGIN_NOINST} ${PROG} ${PROG_NOINST} ${JARFILE} locales ${MAKE} -s subdirs-after ${MAKE} -s post-all pre-all post-all: @@ -323,10 +323,48 @@ for i in $$ars; do \ dir=".$$(echo $$i | sed 's/\//_/g').objs"; \ rm -fr $$dir; \ done; \ fi + +${STATIC_AMIGA_LIB} ${STATIC_AMIGA_LIB_NOINST}: ${EXT_DEPS} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA} + ${LINK_STATUS} + rm -f $@ + out="$@"; \ + objs=""; \ + ars=""; \ + for i in ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA}; do \ + case $$i in \ + *.a) \ + ars="$$ars $$i" \ + ;; \ + *.o) \ + objs="$$objs $$i" \ + ;; \ + esac \ + done; \ + for i in $$ars; do \ + dir=".$$(echo $$i | sed 's/\//_/g').objs"; \ + rm -fr $$dir; \ + mkdir -p $$dir; \ + cd $$dir; \ + ${AR} x ../$$i; \ + for j in *.o; do \ + objs="$$objs $$dir/$$j"; \ + done; \ + cd ..; \ + done; \ + if ${AR} cr $@ $$objs && ${RANLIB} $@; then \ + ${LINK_OK}; \ + else \ + rm -f $@; false; \ + ${LINK_FAILED}; \ + fi; \ + for i in $$ars; do \ + dir=".$$(echo $$i | sed 's/\//_/g').objs"; \ + rm -fr $$dir; \ + done locales: ${MO_FILES} .c.o: ${COMPILE_STATUS} @@ -646,11 +684,11 @@ else \ ${INSTALL_FAILED}; \ fi \ done - for i in "" ${STATIC_LIB} ${STATIC_PIC_LIB}; do \ + for i in "" ${STATIC_LIB} ${STATIC_PIC_LIB} ${STATIC_AMIGA_LIB}; do \ test x"$$i" = x"" && continue; \ ${INSTALL_STATUS}; \ if ${MKDIR_P} ${DESTDIR}${libdir} && ${INSTALL} -m 644 $$i ${DESTDIR}${libdir}/$$i; then \ ${INSTALL_OK}; \ else \ @@ -752,11 +790,11 @@ fi \ done rmdir ${DESTDIR}${prefix}/Library/Frameworks >/dev/null 2>&1 || true rmdir ${DESTDIR}${prefix}/Library >/dev/null 2>&1 || true - for i in "" ${STATIC_LIB} ${STATIC_PIC_LIB}; do \ + for i in "" ${STATIC_LIB} ${STATIC_PIC_LIB} ${STATIC_AMIGA_LIB}; do \ test x"$$i" = x"" && continue; \ if test -f ${DESTDIR}${libdir}/$$i; then \ if rm -f ${DESTDIR}${libdir}/$$i; then \ ${DELETE_OK}; \ else \ @@ -845,11 +883,11 @@ ${DIR_LEAVE}; \ done : >.deps - for i in "" ${DEPS} ${OBJS} ${OBJS_EXTRA} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA} ${PLUGIN_OBJS} ${PROG} ${PROG_NOINST} ${SHARED_LIB} ${SHARED_LIB_NOINST} ${AMIGA_LIB} ${AMIGA_LIB_NOINST} ${STATIC_LIB} ${STATIC_LIB_NOINST} ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST} ${FRAMEWORK} ${PLUGIN} ${PLUGIN_NOINST} ${CLEAN_LIB} ${MO_FILES} ${CLEAN}; do \ + for i in "" ${DEPS} ${OBJS} ${OBJS_EXTRA} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA} ${PLUGIN_OBJS} ${PROG} ${PROG_NOINST} ${SHARED_LIB} ${SHARED_LIB_NOINST} ${AMIGA_LIB} ${AMIGA_LIB_NOINST} ${STATIC_LIB} ${STATIC_LIB_NOINST} ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST} ${STATIC_AMIGA_LIB} ${STATIC_AMIGA_LIB_NOINST} ${FRAMEWORK} ${PLUGIN} ${PLUGIN_NOINST} ${CLEAN_LIB} ${MO_FILES} ${CLEAN}; do \ test x"$$i" = x"" && continue; \ if test -f $$i -o -d $$i; then \ if rm -fr $$i; then \ ${DELETE_OK}; \ else \ Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -53,20 +53,21 @@ enable_files="yes" # Required for reading ENV: enable_shared="no" supports_amiga_lib="yes" AS_IF([test x"$enable_amiga_lib" != x"no"], [ + AC_SUBST(OBJFW_AMIGA_LIB, objfw68k.library) AC_SUBST(OBJFWRT_AMIGA_LIB, objfwrt68k.library) AC_SUBST(SFDC_TARGET, m68k-amigaos) AC_SUBST(SFD_FILE, amigaos3.sfd) AC_SUBST(SFDC_INLINE_H, inline.h) dnl For 68000, GCC emits calls to helper functions that dnl do not work properly in a library. - t="-mcpu=68020 -fbaserel -noixemul" + t="-mcpu=68020 -fbaserel32 -noixemul" AC_SUBST(AMIGA_LIB_CFLAGS, "$t -ffreestanding") AC_SUBST(AMIGA_LIB_LDFLAGS, - "$t -resident -nostartfiles") + "$t -resident32 -nostartfiles") ]) AC_SUBST(LIBBASES_M, libbases.m) ;; powerpc-*-amigaos*) @@ -88,10 +89,11 @@ enable_files="yes" # Required for reading ENV: supports_amiga_lib="yes" check_pedantic="no" # Breaks generated inlines AS_IF([test x"$enable_amiga_lib" != x"no"], [ + AC_SUBST(OBJFW_AMIGA_LIB, objfw.library) AC_SUBST(OBJFWRT_AMIGA_LIB, objfwrt.library) AC_SUBST(CVINCLUDE_INLINE_H, inline.h) t="-mresident32 -ffreestanding -noixemul" AC_SUBST(AMIGA_LIB_CFLAGS, $t) t="-mresident32 -nostartfiles -nodefaultlibs" @@ -398,10 +400,25 @@ AC_SUBST(INVOCATION_A, "invocation.a") AC_SUBST(INVOCATION_INVOCATION_A, "invocation/invocation.a") AC_SUBST(LOOKUP_ASM_A, "lookup-asm.a") AC_SUBST(LOOKUP_ASM_LOOKUP_ASM_A, "lookup-asm/lookup-asm.a") ]) + +AS_IF([test x"$enable_amiga_lib" != x"no"], [ + AC_SUBST(EXCEPTIONS_AMIGALIB_A, "exceptions.amigalib.a") + AC_SUBST(EXCEPTIONS_EXCEPTIONS_AMIGALIB_A, + "exceptions/exceptions.amigalib.a") + AC_SUBST(FORWARDING_AMIGALIB_A, "forwarding.amigalib.a") + AC_SUBST(FORWARDING_FORWARDING_AMIGALIB_A, + "forwarding/forwarding.amigalib.a") + AC_SUBST(INVOCATION_AMIGALIB_A, "invocation.amigalib.a") + AC_SUBST(INVOCATION_INVOCATION_AMIGALIB_A, + "invocation/invocation.amigalib.a") + AC_SUBST(LOOKUP_ASM_AMIGALIB_A, "lookup-asm.amigalib.a") + AC_SUBST(LOOKUP_ASM_LOOKUP_ASM_AMIGALIB_A, + "lookup-asm/lookup-asm.amigalib.a") +]) AC_DEFINE_UNQUOTED(PLUGIN_SUFFIX, "$PLUGIN_SUFFIX", [Suffix for plugins]) AS_IF([test x"$enable_files" != x"no" -a x"$PLUGIN_SUFFIX" != x""], [ AC_SUBST(USE_SRCS_PLUGINS, '${SRCS_PLUGINS}') AC_SUBST(TESTPLUGIN, "plugin") @@ -415,10 +432,14 @@ TESTPLUGIN_LIBS="-L../../src -L../../src/runtime" TESTPLUGIN_LIBS="$TESTPLUGIN_LIBS -lobjfw \${RUNTIME_LIBS}" ]) AC_SUBST(TESTPLUGIN_LIBS) ]) + +AS_IF([test x"$enable_amiga_lib" != x"no"], [ + AC_SUBST(LINKLIB, linklib) +]) AC_MSG_CHECKING(whether we need -D_GNU_SOURCE) AC_EGREP_CPP(egrep_cpp_yes, [ #include @@ -531,11 +552,10 @@ AC_SUBST(RUNTIME_FRAMEWORK_LIBS, "-framework ObjFWRT") ]) AS_IF([test x"$enable_amiga_lib" != x"no"], [ AC_SUBST(RUNTIME_LIBS, "-lobjfwrt.library") - AC_SUBST(LINKLIB, linklib) tmp="../src/runtime/linklib/libobjfwrt.library.a" AC_SUBST(LIBOBJFWRT_DEP, "$tmp") AC_SUBST(LIBOBJFWRT_DEP_LVL2, "../$tmp") ], [ AC_SUBST(RUNTIME_LIBS, "-lobjfwrt") @@ -888,10 +908,15 @@ AC_SUBST(ENCODINGS_ENCODINGS_LIB_A, "encodings/encodings.lib.a") ]) AS_IF([test x"$enable_static" = x"yes" -o x"$enable_shared" = x"no"], [ AC_SUBST(ENCODINGS_A, "encodings.a") AC_SUBST(ENCODINGS_ENCODINGS_A, "encodings/encodings.a") + ]) + AS_IF([test x"$enable_amiga_lib" != x"no"], [ + AC_SUBST(ENCODINGS_AMIGALIB_A, "encodings.amigalib.a") + AC_SUBST(ENCODINGS_ENCODINGS_AMIGALIB_A, + "encodings/encodings.amigalib.a") ]) ]) AC_CHECK_FUNC(arc4random, [ AC_DEFINE(OF_HAVE_ARC4RANDOM, 1, [Whether we have arc4random()]) Index: extra.mk.in ================================================================== --- extra.mk.in +++ extra.mk.in @@ -1,8 +1,9 @@ OBJFW_SHARED_LIB = @OBJFW_SHARED_LIB@ OBJFW_STATIC_LIB = @OBJFW_STATIC_LIB@ OBJFW_FRAMEWORK = @OBJFW_FRAMEWORK@ +OBJFW_AMIGA_LIB = @OBJFW_AMIGA_LIB@ OBJFW_LIB_MAJOR = 9 OBJFW_LIB_MINOR = 1 OBJFW_LIB_MAJOR_MINOR = ${OBJFW_LIB_MAJOR}.${OBJFW_LIB_MINOR} OBJFWRT_SHARED_LIB = @OBJFWRT_SHARED_LIB@ @@ -21,37 +22,47 @@ BIN_PREFIX = @BIN_PREFIX@ BRIDGE = @BRIDGE@ CVINCLUDE_INLINE_H = @CVINCLUDE_INLINE_H@ ENCODINGS = @ENCODINGS@ ENCODINGS_A = @ENCODINGS_A@ +ENCODINGS_AMIGALIB_A = @ENCODINGS_AMIGALIB_A@ ENCODINGS_ENCODINGS_A = @ENCODINGS_ENCODINGS_A@ +ENCODINGS_ENCODINGS_AMIGALIB_A = @ENCODINGS_ENCODINGS_AMIGALIB_A@ ENCODINGS_ENCODINGS_LIB_A = @ENCODINGS_ENCODINGS_LIB_A@ ENCODINGS_LIB_A = @ENCODINGS_LIB_A@ ENCODINGS_SRCS = @ENCODINGS_SRCS@ EXCEPTIONS_A = @EXCEPTIONS_A@ +EXCEPTIONS_AMIGALIB_A = @EXCEPTIONS_AMIGALIB_A@ EXCEPTIONS_EXCEPTIONS_A = @EXCEPTIONS_EXCEPTIONS_A@ +EXCEPTIONS_EXCEPTIONS_AMIGALIB_A = @EXCEPTIONS_EXCEPTIONS_AMIGALIB_A@ EXCEPTIONS_EXCEPTIONS_LIB_A = @EXCEPTIONS_EXCEPTIONS_LIB_A@ EXCEPTIONS_LIB_A = @EXCEPTIONS_LIB_A@ FISH_COMPLETIONS = @FISH_COMPLETIONS@ FORWARDING_A = @FORWARDING_A@ +FORWARDING_AMIGALIB_A = @FORWARDING_AMIGALIB_A@ FORWARDING_FORWARDING_A = @FORWARDING_FORWARDING_A@ +FORWARDING_FORWARDING_AMIGALIB_A = @FORWARDING_FORWARDING_AMIGALIB_A@ FORWARDING_FORWARDING_LIB_A = @FORWARDING_FORWARDING_LIB_A@ FORWARDING_LIB_A = @FORWARDING_LIB_A@ INSTANCE_M = @INSTANCE_M@ INVOCATION_A = @INVOCATION_A@ +INVOCATION_AMIGALIB_A = @INVOCATION_AMIGALIB_A@ INVOCATION_INVOCATION_A = @INVOCATION_INVOCATION_A@ +INVOCATION_INVOCATION_AMIGALIB_A = @INVOCATION_INVOCATION_AMIGALIB_A@ INVOCATION_INVOCATION_LIB_A = @INVOCATION_INVOCATION_LIB_A@ INVOCATION_LIB_A = @INVOCATION_LIB_A@ LIBBASES_M = @LIBBASES_M@ LIBOBJFWRT_DEP = @LIBOBJFWRT_DEP@ LIBOBJFWRT_DEP_LVL2 = @LIBOBJFWRT_DEP_LVL2@ LIBOBJFW_DEP = @LIBOBJFW_DEP@ LIBOBJFW_DEP_LVL2 = @LIBOBJFW_DEP_LVL2@ LINKLIB = @LINKLIB@ LOOKUP_ASM_A = @LOOKUP_ASM_A@ +LOOKUP_ASM_AMIGALIB_A = @LOOKUP_ASM_AMIGALIB_A@ LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LIB_A@ LOOKUP_ASM_LOOKUP_ASM_A = @LOOKUP_ASM_LOOKUP_ASM_A@ +LOOKUP_ASM_LOOKUP_ASM_AMIGALIB_A = @LOOKUP_ASM_LOOKUP_ASM_AMIGALIB_A@ LOOKUP_ASM_LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LOOKUP_ASM_LIB_A@ MAP_LDFLAGS = @MAP_LDFLAGS@ OFARC = @OFARC@ OFDNS = @OFDNS@ OFHASH = @OFHASH@ Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -1,14 +1,23 @@ include ../extra.mk SUBDIRS = ${RUNTIME} exceptions ${ENCODINGS} forwarding invocation -SUBDIRS_AFTER = ${BRIDGE} +SUBDIRS_AFTER = ${LINKLIB} ${BRIDGE} +CLEAN = amiga-end.amigalib.dep \ + amiga-end.amigalib.o \ + amiga-glue.amigalib.dep \ + amiga-glue.amigalib.o \ + amiga-library-functable.inc \ + amiga-library.amigalib.dep \ + amiga-library.amigalib.o \ + inline.h DISTCLEAN = Info.plist objfw-defs.h SHARED_LIB = ${OBJFW_SHARED_LIB} STATIC_LIB = ${OBJFW_STATIC_LIB} FRAMEWORK = ${OBJFW_FRAMEWORK} +AMIGA_LIB = ${OBJFW_AMIGA_LIB} LIB_MAJOR = ${OBJFW_LIB_MAJOR} LIB_MINOR = ${OBJFW_LIB_MINOR} SRCS = OFASN1BitString.m \ OFASN1Boolean.m \ @@ -236,15 +245,32 @@ LIB_OBJS_EXTRA = ${RUNTIME_RUNTIME_LIB_A} \ ${EXCEPTIONS_EXCEPTIONS_LIB_A} \ ${ENCODINGS_ENCODINGS_LIB_A} \ ${FORWARDING_FORWARDING_LIB_A} \ ${INVOCATION_INVOCATION_LIB_A} +AMIGA_LIB_OBJS_START = amiga-library.amigalib.o +AMIGA_LIB_OBJS_EXTRA = amiga-glue.amigalib.o \ + ${EXCEPTIONS_EXCEPTIONS_AMIGALIB_A} \ + ${ENCODINGS_ENCODINGS_AMIGALIB_A} \ + ${FORWARDING_FORWARDING_AMIGALIB_A} \ + ${INVOCATION_INVOCATION_AMIGALIB_A} \ + amiga-end.amigalib.o include ../buildsys.mk -CPPFLAGS += -I. -I.. -Iexceptions -Iruntime +${OBJFW_AMIGA_LIB}: inline.h + +${SFDC_INLINE_H}: ${SFD_FILE} + sfdc -q --target=${SFDC_TARGET} --mode=macros -o $@ $<; \ + +CPPFLAGS += -I. -I.. -Iexceptions -Iruntime \ + -DOBJFW_AMIGA_LIB=\"${OBJFW_AMIGA_LIB}\" \ + -DOBJFW_LIB_MAJOR=${OBJFW_LIB_MAJOR} \ + -DOBJFW_LIB_MINOR=${OBJFW_LIB_MINOR} +AMIGA_LIB_CFLAGS += -DOF_COMPILING_AMIGA_LIBRARY LD = ${OBJC} FRAMEWORK_LIBS := -Fruntime \ ${RUNTIME_FRAMEWORK_LIBS} \ ${REEXPORT_RUNTIME_FRAMEWORK} \ ${LIBS} -LIBS := -Lruntime ${RUNTIME_LIBS} ${REEXPORT_RUNTIME} ${LIBS} +LIBS := -Lruntime -Lruntime/linklib ${RUNTIME_LIBS} ${REEXPORT_RUNTIME} ${LIBS} +AMIGA_LIB_LIBS = ${LIBS} Index: src/OFFileManager.m ================================================================== --- src/OFFileManager.m +++ src/OFFileManager.m @@ -71,43 +71,11 @@ #endif @interface OFDefaultFileManager: OFFileManager @end -const of_file_attribute_key_t of_file_attribute_key_size = - @"of_file_attribute_key_size"; -const of_file_attribute_key_t of_file_attribute_key_type = - @"of_file_attribute_key_type"; -const of_file_attribute_key_t of_file_attribute_key_posix_permissions = - @"of_file_attribute_key_posix_permissions"; -const of_file_attribute_key_t of_file_attribute_key_posix_uid = - @"of_file_attribute_key_posix_uid"; -const of_file_attribute_key_t of_file_attribute_key_posix_gid = - @"of_file_attribute_key_posix_gid"; -const of_file_attribute_key_t of_file_attribute_key_owner = - @"of_file_attribute_key_owner"; -const of_file_attribute_key_t of_file_attribute_key_group = - @"of_file_attribute_key_group"; -const of_file_attribute_key_t of_file_attribute_key_last_access_date = - @"of_file_attribute_key_last_access_date"; -const of_file_attribute_key_t of_file_attribute_key_modification_date = - @"of_file_attribute_key_modification_date"; -const of_file_attribute_key_t of_file_attribute_key_status_change_date = - @"of_file_attribute_key_status_change_date"; -const of_file_attribute_key_t of_file_attribute_key_creation_date = - @"of_file_attribute_key_creation_date"; -const of_file_attribute_key_t of_file_attribute_key_symbolic_link_destination = - @"of_file_attribute_key_symbolic_link_destination"; - -const of_file_type_t of_file_type_regular = @"of_file_type_regular"; -const of_file_type_t of_file_type_directory = @"of_file_type_directory"; -const of_file_type_t of_file_type_symbolic_link = @"of_file_type_symbolic_link"; -const of_file_type_t of_file_type_fifo = @"of_file_type_fifo"; -const of_file_type_t of_file_type_character_special = - @"of_file_type_character_special"; -const of_file_type_t of_file_type_block_special = @"of_file_type_block_special"; -const of_file_type_t of_file_type_socket = @"of_file_type_socket"; +#include "OFFileManager_constants.m" #ifdef OF_AMIGAOS4 # define CurrentDir(lock) SetCurrentDir(lock) #endif ADDED src/OFFileManager_constants.m Index: src/OFFileManager_constants.m ================================================================== --- /dev/null +++ src/OFFileManager_constants.m @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019, 2020 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +const of_file_attribute_key_t of_file_attribute_key_size = + @"of_file_attribute_key_size"; +const of_file_attribute_key_t of_file_attribute_key_type = + @"of_file_attribute_key_type"; +const of_file_attribute_key_t of_file_attribute_key_posix_permissions = + @"of_file_attribute_key_posix_permissions"; +const of_file_attribute_key_t of_file_attribute_key_posix_uid = + @"of_file_attribute_key_posix_uid"; +const of_file_attribute_key_t of_file_attribute_key_posix_gid = + @"of_file_attribute_key_posix_gid"; +const of_file_attribute_key_t of_file_attribute_key_owner = + @"of_file_attribute_key_owner"; +const of_file_attribute_key_t of_file_attribute_key_group = + @"of_file_attribute_key_group"; +const of_file_attribute_key_t of_file_attribute_key_last_access_date = + @"of_file_attribute_key_last_access_date"; +const of_file_attribute_key_t of_file_attribute_key_modification_date = + @"of_file_attribute_key_modification_date"; +const of_file_attribute_key_t of_file_attribute_key_status_change_date = + @"of_file_attribute_key_status_change_date"; +const of_file_attribute_key_t of_file_attribute_key_creation_date = + @"of_file_attribute_key_creation_date"; +const of_file_attribute_key_t of_file_attribute_key_symbolic_link_destination = + @"of_file_attribute_key_symbolic_link_destination"; + +const of_file_type_t of_file_type_regular = @"of_file_type_regular"; +const of_file_type_t of_file_type_directory = @"of_file_type_directory"; +const of_file_type_t of_file_type_symbolic_link = @"of_file_type_symbolic_link"; +const of_file_type_t of_file_type_fifo = @"of_file_type_fifo"; +const of_file_type_t of_file_type_character_special = + @"of_file_type_character_special"; +const of_file_type_t of_file_type_block_special = @"of_file_type_block_special"; +const of_file_type_t of_file_type_socket = @"of_file_type_socket"; Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -1314,11 +1314,16 @@ extern void objc_autoreleasePoolPop(void *_Null_unspecified pool); #endif extern id of_alloc_object(Class class_, size_t extraSize, size_t extraAlignment, void *_Nullable *_Nullable extra); extern void OF_NO_RETURN_FUNC of_method_not_found(id self, SEL _cmd); +#ifndef OF_AMIGAOS extern uint32_t of_hash_seed; +#else +extern uint32_t *_Nonnull of_hash_seed_ref(void); +# define of_hash_seed (*of_hash_seed_ref()) +#endif #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -99,12 +99,24 @@ #define PRE_MEM(mem) ((struct pre_mem *)(void *)((char *)mem - PRE_MEM_ALIGN)) static struct { Class isa; } allocFailedException; + +#ifdef OF_AMIGAOS +# undef of_hash_seed +#endif uint32_t of_hash_seed; + +#ifdef OF_AMIGAOS +uint32_t * +of_hash_seed_ref(void) +{ + return &of_hash_seed; +} +#endif static const char * typeEncodingForSelector(Class class, SEL selector) { Method method; Index: src/OFRunLoop.m ================================================================== --- src/OFRunLoop.m +++ src/OFRunLoop.m @@ -43,11 +43,11 @@ #import "OFTimer+Private.h" #import "OFDate.h" #import "OFObserveFailedException.h" -const of_run_loop_mode_t of_run_loop_mode_default = @"of_run_loop_mode_default"; +#include "OFRunLoop_constants.m" static OFRunLoop *mainRunLoop = nil; @interface OFRunLoopState: OFObject #ifdef OF_HAVE_SOCKETS ADDED src/OFRunLoop_constants.m Index: src/OFRunLoop_constants.m ================================================================== --- /dev/null +++ src/OFRunLoop_constants.m @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019, 2020 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +const of_run_loop_mode_t of_run_loop_mode_default = @"of_run_loop_mode_default"; Index: src/OFStdIOStream.h ================================================================== --- src/OFStdIOStream.h +++ src/OFStdIOStream.h @@ -134,10 +134,11 @@ #ifdef __cplusplus extern "C" { #endif /*! @file */ +#ifndef OF_AMIGAOS /*! * @brief The standard input as an OFStream. */ extern OFStdIOStream *_Nullable of_stdin; @@ -148,18 +149,34 @@ /*! * @brief The standard error as an OFStream. */ extern OFStdIOStream *_Nullable of_stderr; +#else +extern OFStdIOStream *_Nonnull *_Nullable of_stdin_ref(void); +extern OFStdIOStream *_Nonnull *_Nullable of_stdout_ref(void); +extern OFStdIOStream *_Nonnull *_Nullable of_stderr_ref(void); +# define of_stdin (*of_stdin_ref()) +# define of_stdout (*of_stdout_ref()) +# define of_stderr (*of_stderr_ref()) +#endif /*! - * @brief Log the specified printf-style format to @ref of_stderr. + * @brief Logs the specified printf-style format to @ref of_stderr. * * This prefixes the output with the date, timestamp, process name and PID and * allows `%@` as a printf-style formatted to print objects. */ extern void of_log(OFConstantString *format, ...); + +/*! + * @brief Logs the specified printf-style format to @ref of_stderr. + * + * This prefixes the output with the date, timestamp, process name and PID and + * allows `%@` as a printf-style formatted to print objects. + */ +extern void of_logv(OFConstantString *format, va_list arguments); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END Index: src/OFStdIOStream.m ================================================================== --- src/OFStdIOStream.m +++ src/OFStdIOStream.m @@ -55,14 +55,40 @@ _reference_to_OFWin32ConsoleStdIOStream(void) { [OFWin32ConsoleStdIOStream class]; } #endif + +#ifdef OF_AMIGAOS +# undef of_stdin +# undef of_stdout +# undef of_stderr +#endif OFStdIOStream *of_stdin = nil; OFStdIOStream *of_stdout = nil; OFStdIOStream *of_stderr = nil; + +#ifdef OF_AMIGAOS +OFStdIOStream ** +of_stdin_ref(void) +{ + return &of_stdin; +} + +OFStdIOStream ** +of_stdout_ref(void) +{ + return &of_stdout; +} + +OFStdIOStream ** +of_stderr_ref(void) +{ + return &of_stderr; +} +#endif #ifdef OF_AMIGAOS OF_DESTRUCTOR() { [of_stdin dealloc]; @@ -72,27 +98,34 @@ #endif void of_log(OFConstantString *format, ...) { + va_list arguments; + + va_start(arguments, format); + of_logv(format, arguments); + va_end(arguments); +} + +void +of_logv(OFConstantString *format, va_list arguments) +{ void *pool = objc_autoreleasePoolPush(); OFDate *date; OFString *dateString, *me, *msg; - va_list arguments; date = [OFDate date]; dateString = [date localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"]; #ifdef OF_HAVE_FILES me = [OFApplication programName].lastPathComponent; #else me = [OFApplication programName]; #endif - va_start(arguments, format); msg = [[[OFString alloc] initWithFormat: format arguments: arguments] autorelease]; - va_end(arguments); [of_stderr writeFormat: @"[%@.%03d %@(%d)] %@\n", dateString, date.microsecond / 1000, me, getpid(), msg]; objc_autoreleasePoolPop(pool); ADDED src/amiga-end.m Index: src/amiga-end.m ================================================================== --- /dev/null +++ src/amiga-end.m @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019, 2020 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "platform.h" + +#ifdef OF_MORPHOS +__asm__ ( + ".section .ctors, \"aw\", @progbits\n" + " .long 0\n" +); +#else +__asm__ ( + "" +); +#endif ADDED src/amiga-glue.m Index: src/amiga-glue.m ================================================================== --- /dev/null +++ src/amiga-glue.m @@ -0,0 +1,418 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019, 2020 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFApplication.h" +#import "OFHTTPRequest.h" +#import "OFHTTPResponse.h" +#import "OFMethodSignature.h" +#import "OFObject.h" +#import "OFStdIOStream.h" +#import "OFString.h" +#import "OFZIPArchiveEntry.h" + +#import "amiga-library.h" +#import "of_strptime.h" +#import "pbkdf2.h" +#import "platform.h" +#import "scrypt.h" +#import "socket.h" + +#ifdef OF_AMIGAOS_M68K +# define PPC_PARAMS(...) (void) +# define M68K_ARG OF_M68K_ARG +#else +# define PPC_PARAMS(...) (__VA_ARGS__) +# define M68K_ARG(...) +#endif + +#ifdef OF_MORPHOS +/* All __saveds functions in this file need to use the SysV ABI */ +__asm__ ( + ".section .text\n" + ".align 2\n" + "__restore_r13:\n" + " lwz %r13, 44(%r12)\n" + " blr\n" +); +#endif + +bool __saveds +glue_of_init PPC_PARAMS(unsigned int version, struct of_libc *libc, FILE **sF) +{ + M68K_ARG(unsigned int, version, d0) + M68K_ARG(struct of_libc *, libc, a0) + M68K_ARG(FILE **, sF, a1) + + return of_init(version, libc, sF); +} + +int __saveds +glue_of_application_main PPC_PARAMS(int *argc, char ***argv, + id delegate) +{ + M68K_ARG(int *, argc, a0) + M68K_ARG(char ***, argv, a1) + M68K_ARG(id , delegate, a2) + + return of_application_main(argc, argv, delegate); +} + +const char *__saveds +glue_of_http_request_method_to_string PPC_PARAMS( + of_http_request_method_t method) +{ + M68K_ARG(of_http_request_method_t, method, d0) + + return of_http_request_method_to_string(method); +} + +of_http_request_method_t __saveds +glue_of_http_request_method_from_string PPC_PARAMS(OFString *string) +{ + M68K_ARG(OFString *, string, a0) + + return of_http_request_method_from_string(string); +} + +OFString *__saveds +glue_of_http_status_code_to_string PPC_PARAMS(short code) +{ + M68K_ARG(short, code, d0) + + return of_http_status_code_to_string(code); +} + +size_t __saveds +glue_of_sizeof_type_encoding PPC_PARAMS(const char *type) +{ + M68K_ARG(const char *, type, a0) + + return of_sizeof_type_encoding(type); +} + +size_t __saveds +glue_of_alignof_type_encoding PPC_PARAMS(const char *type) +{ + M68K_ARG(const char *, type, a0) + + return of_alignof_type_encoding(type); +} + +uint32_t *__saveds +glue_of_hash_seed_ref(void) +{ + return of_hash_seed_ref(); +} + +OFStdIOStream **__saveds +glue_of_stdin_ref(void) +{ + return of_stdin_ref(); +} + +OFStdIOStream **__saveds +glue_of_stdout_ref(void) +{ + return of_stdout_ref(); +} + +OFStdIOStream **__saveds +glue_of_stderr_ref(void) +{ + return of_stderr_ref(); +} + +void __saveds +glue_of_logv PPC_PARAMS(OFConstantString *format, va_list arguments) +{ + M68K_ARG(OFConstantString *, format, a0) + M68K_ARG(va_list, arguments, a1) + + of_logv(format, arguments); +} + +of_string_encoding_t __saveds +glue_of_string_parse_encoding PPC_PARAMS(OFString *string) +{ + M68K_ARG(OFString *, string, a0) + + return of_string_parse_encoding(string); +} + +OFString *__saveds +glue_of_string_name_of_encoding PPC_PARAMS(of_string_encoding_t encoding) +{ + M68K_ARG(of_string_encoding_t, encoding, d0) + + return of_string_name_of_encoding(encoding); +} + +size_t __saveds +glue_of_string_utf8_encode PPC_PARAMS(of_unichar_t c, char *UTF8) +{ + M68K_ARG(of_unichar_t, c, d0) + M68K_ARG(char *, UTF8, a0) + + return of_string_utf8_encode(c, UTF8); +} + +ssize_t __saveds +glue_of_string_utf8_decode PPC_PARAMS(const char *UTF8, size_t len, + of_unichar_t *c) +{ + M68K_ARG(const char *, UTF8, a0) + M68K_ARG(size_t, len, d0) + M68K_ARG(of_unichar_t *, c, a1) + + return of_string_utf8_decode(UTF8, len, c); +} + +size_t __saveds +glue_of_string_utf16_length PPC_PARAMS(const of_char16_t *string) +{ + M68K_ARG(const of_char16_t *, string, a0) + + return of_string_utf16_length(string); +} + +size_t __saveds +glue_of_string_utf32_length PPC_PARAMS(const of_char32_t *string) +{ + M68K_ARG(const of_char32_t *, string, a0) + + return of_string_utf32_length(string); +} + +OFString *__saveds +glue_of_zip_archive_entry_version_to_string PPC_PARAMS(uint16_t version) +{ + M68K_ARG(uint16_t, version, d0) + + return of_zip_archive_entry_version_to_string(version); +} + +OFString *__saveds +glue_of_zip_archive_entry_compression_method_to_string PPC_PARAMS( + uint16_t compressionMethod) +{ + M68K_ARG(uint16_t, compressionMethod, d0) + + return of_zip_archive_entry_compression_method_to_string( + compressionMethod); +} + +size_t __saveds +glue_of_zip_archive_entry_extra_field_find PPC_PARAMS(OFData *extraField, + uint16_t tag, uint16_t *size) +{ + M68K_ARG(OFData *, extraField, a0) + M68K_ARG(uint16_t, tag, d0) + M68K_ARG(uint16_t *, size, a1) + + return of_zip_archive_entry_extra_field_find(extraField, tag, size); +} + +void __saveds +glue_of_pbkdf2 PPC_PARAMS(const of_pbkdf2_parameters_t *param) +{ + M68K_ARG(const of_pbkdf2_parameters_t *, param, a0) + + of_pbkdf2(*param); +} + +void __saveds +glue_of_salsa20_8_core PPC_PARAMS(uint32_t *buffer) +{ + M68K_ARG(uint32_t *, buffer, a0) + + of_salsa20_8_core(buffer); +} + +void __saveds +glue_of_scrypt_block_mix PPC_PARAMS(uint32_t *output, const uint32_t *input, + size_t blockSize) +{ + M68K_ARG(uint32_t *, output, a0) + M68K_ARG(const uint32_t *, input, a1) + M68K_ARG(size_t, blockSize, d0) + + of_scrypt_block_mix(output, input, blockSize); +} + +void __saveds +glue_of_scrypt_romix PPC_PARAMS(uint32_t *buffer, size_t blockSize, + size_t costFactor, uint32_t *tmp) +{ + M68K_ARG(uint32_t *, buffer, a0) + M68K_ARG(size_t, blockSize, d0) + M68K_ARG(size_t, costFactor, d1) + M68K_ARG(uint32_t *, tmp, a1) + + of_scrypt_romix(buffer, blockSize, costFactor, tmp); +} + +void __saveds +glue_of_scrypt PPC_PARAMS(const of_scrypt_parameters_t *param) +{ + M68K_ARG(const of_scrypt_parameters_t *, param, a0) + + of_scrypt(*param); +} + +const char *__saveds +glue_of_strptime PPC_PARAMS(const char *buf, const char *fmt, struct tm *tm, + int16_t *tz) +{ + M68K_ARG(const char *, buf, a0) + M68K_ARG(const char *, fmt, a1) + M68K_ARG(struct tm *, tm, a2) + M68K_ARG(int16_t *, tz, a3) + + return of_strptime(buf, fmt, tm, tz); +} + +void __saveds +glue_of_socket_address_parse_ip PPC_PARAMS(of_socket_address_t *address, + OFString *IP, uint16_t port) +{ + M68K_ARG(of_socket_address_t *, address, a0) + M68K_ARG(OFString *, IP, a1) + M68K_ARG(uint16_t, port, d0) + + *address = of_socket_address_parse_ip(IP, port); +} + +void __saveds +glue_of_socket_address_parse_ipv4 PPC_PARAMS(of_socket_address_t *address, + OFString *IP, uint16_t port) +{ + M68K_ARG(of_socket_address_t *, address, a0) + M68K_ARG(OFString *, IP, a1) + M68K_ARG(uint16_t, port, d0) + + *address = of_socket_address_parse_ipv4(IP, port); +} + +void __saveds +glue_of_socket_address_parse_ipv6 PPC_PARAMS(of_socket_address_t *address, + OFString *IP, uint16_t port) +{ + M68K_ARG(of_socket_address_t *, address, a0) + M68K_ARG(OFString *, IP, a1) + M68K_ARG(uint16_t, port, d0) + + *address = of_socket_address_parse_ipv6(IP, port); +} + +void __saveds +glue_of_socket_address_ipx PPC_PARAMS(of_socket_address_t *address, + const unsigned char *node, uint32_t network, uint16_t port) +{ + M68K_ARG(of_socket_address_t *, address, a0) + M68K_ARG(const unsigned char *, node, a1) + M68K_ARG(uint32_t, network, d0) + M68K_ARG(uint16_t, port, d1) + + *address = of_socket_address_ipx(node, network, port); +} + +bool __saveds +glue_of_socket_address_equal PPC_PARAMS(const of_socket_address_t *address1, + const of_socket_address_t *address2) +{ + M68K_ARG(const of_socket_address_t *, address1, a0) + M68K_ARG(const of_socket_address_t *, address2, a1) + + return of_socket_address_equal(address1, address2); +} + +uint32_t __saveds +glue_of_socket_address_hash PPC_PARAMS(const of_socket_address_t *address) +{ + M68K_ARG(const of_socket_address_t *, address, a0) + + return of_socket_address_hash(address); +} + +OFString *__saveds +glue_of_socket_address_ip_string PPC_PARAMS(const of_socket_address_t *address, + uint16_t *port) +{ + M68K_ARG(const of_socket_address_t *, address, a0) + M68K_ARG(uint16_t *, port, a1) + + return of_socket_address_ip_string(address, port); +} + +void __saveds +glue_of_socket_address_set_port PPC_PARAMS(of_socket_address_t *address, + uint16_t port) +{ + M68K_ARG(of_socket_address_t *, address, a0) + M68K_ARG(uint16_t, port, d0) + + of_socket_address_set_port(address, port); +} + +uint16_t __saveds +glue_of_socket_address_get_port PPC_PARAMS(const of_socket_address_t *address) +{ + M68K_ARG(const of_socket_address_t *, address, a0) + + return of_socket_address_get_port(address); +} + +void __saveds +glue_of_socket_address_set_ipx_network PPC_PARAMS(of_socket_address_t *address, + uint32_t network) +{ + M68K_ARG(of_socket_address_t *, address, a0) + M68K_ARG(uint32_t, network, d0) + + of_socket_address_set_ipx_network(address, network); +} + +uint32_t __saveds +glue_of_socket_address_get_ipx_network PPC_PARAMS( + const of_socket_address_t *address) +{ + M68K_ARG(const of_socket_address_t *, address, a0) + + return of_socket_address_get_ipx_network(address); +} + +void __saveds +glue_of_socket_address_set_ipx_node PPC_PARAMS(of_socket_address_t *address, + const unsigned char *node) +{ + M68K_ARG(of_socket_address_t *, address, a0) + M68K_ARG(const unsigned char *, node, a1) + + of_socket_address_set_ipx_node(address, node); +} + +void __saveds +glue_of_socket_address_get_ipx_node PPC_PARAMS( + const of_socket_address_t *address, unsigned char *node) +{ + M68K_ARG(const of_socket_address_t *, address, a0) + M68K_ARG(unsigned char *, node, a1) + + of_socket_address_get_ipx_node(address, node); +} ADDED src/amiga-library.h Index: src/amiga-library.h ================================================================== --- /dev/null +++ src/amiga-library.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019, 2020 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "macros.h" + +#ifdef OF_MORPHOS +# include +# define OF_M68K_ARG(type, name, reg) type name = (type)REG_##reg; +#else +# define OF_M68K_ARG(type, name, reg) \ + register type reg_##name __asm__(#reg); \ + type name = reg_##name; +#endif + +typedef void (*of_sig_t)(int); + +struct of_libc { + /* + * Needed by the runtime. Some of them are also used by ObjFW, but we + * need all of them to pass them along to the runtime. + */ + void *_Nullable (*_Nonnull malloc)(size_t); + void *_Nullable (*_Nonnull calloc)(size_t, size_t); + void *_Nullable (*_Nonnull realloc)(void *_Nullable, size_t); + void (*_Nonnull free)(void *_Nullable); + int (*_Nonnull vfprintf)(FILE *_Nonnull restrict, + const char *_Nonnull restrict, va_list); + int (*_Nonnull fflush)(FILE *_Nonnull); + void (*_Nonnull abort)(void); +#ifdef HAVE_SJLJ_EXCEPTIONS + int (*_Nonnull _Unwind_SjLj_RaiseException)(void *_Nonnull); +#else + int (*_Nonnull _Unwind_RaiseException)(void *_Nonnull); +#endif + void (*_Nonnull _Unwind_DeleteException)(void *_Nonnull); + void *_Nullable (*_Nonnull _Unwind_GetLanguageSpecificData)( + void *_Nonnull); + uintptr_t (*_Nonnull _Unwind_GetRegionStart)(void *_Nonnull); + uintptr_t (*_Nonnull _Unwind_GetDataRelBase)(void *_Nonnull); + uintptr_t (*_Nonnull _Unwind_GetTextRelBase)(void *_Nonnull); + uintptr_t (*_Nonnull _Unwind_GetIP)(void *_Nonnull); + uintptr_t (*_Nonnull _Unwind_GetGR)(void *_Nonnull, int); + void (*_Nonnull _Unwind_SetIP)(void *_Nonnull, uintptr_t); + void (*_Nonnull _Unwind_SetGR)(void *_Nonnull, int, uintptr_t); +#ifdef HAVE_SJLJ_EXCEPTIONS + void (*_Nonnull _Unwind_SjLj_Resume)(void *_Nonnull); +#else + void (*_Nonnull _Unwind_Resume)(void *_Nonnull); +#endif +#ifdef OF_AMIGAOS_M68K + void (*_Nonnull __register_frame_info)(const void *_Nonnull, + void *_Nonnull); + void *_Nullable (*_Nonnull __deregister_frame_info)( + const void *_Nonnull); +#endif + + /* Needed only by ObjFW. */ + int (*_Nonnull vsnprintf)(char *_Nonnull restrict, size_t, + const char *_Nonnull restrict, va_list); +#ifdef OF_AMIGAOS_M68K + /* strtod() uses sscanf() internally */ + int (*_Nonnull vsscanf)(const char *_Nonnull restrict, + const char *_Nonnull restrict, va_list); +#endif + void (*_Nonnull exit)(int); + of_sig_t _Nullable (*_Nonnull signal)(int, of_sig_t _Nullable); + char *_Nullable (*_Nonnull setlocale)(int, const char *_Nullable); + int (*_Nonnull _Unwind_Backtrace)(int (*_Nonnull)(void *_Nonnull, + void *_Null_unspecified), void *_Null_unspecified); +}; + +extern bool of_init(unsigned int version, struct of_libc *libc, FILE **sF); ADDED src/amiga-library.m Index: src/amiga-library.m ================================================================== --- /dev/null +++ src/amiga-library.m @@ -0,0 +1,720 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019, 2020 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#include +#include +#include +#include + +#import "OFHTTPRequest.h" +#import "OFStdIOStream.h" +#import "OFString.h" + +#import "amiga-library.h" +#import "macros.h" +#import "socket.h" + +#define CONCAT_VERSION2(major, minor) #major "." #minor +#define CONCAT_VERSION(major, minor) CONCAT_VERSION2(major, minor) +#define VERSION_STRING CONCAT_VERSION(OBJFW_LIB_MAJOR, OBJFW_LIB_MINOR) + +#if defined(OF_AMIGAOS_M68K) +# define DATA_OFFSET 0x7FFE +#elif defined(OF_MORPHOS) +# define DATA_OFFSET 0x8000 +#endif + +#ifdef OF_AMIGAOS_M68K +# define OF_M68K_REG(reg) __asm__(#reg) +#else +# define OF_M68K_REG(reg) +#endif + +/* This always needs to be the first thing in the file. */ +int +_start() +{ + return -1; +} + +struct ObjFWBase { + struct Library library; + void *segList; + struct ObjFWBase *parent; + char *dataSeg; + bool initialized; +}; + +#ifdef OF_AMIGAOS_M68K +extern uintptr_t __CTOR_LIST__[]; +extern const void *_EH_FRAME_BEGINS__; +extern void *_EH_FRAME_OBJECTS__; +void __register_frame_info(const void *, void *); +void *__deregister_frame_info(const void *); +#endif + +extern bool glue_of_init(void); +extern int glue_of_application_main(void); +extern const char *glue_of_http_request_method_to_string(void); +extern of_http_request_method_t glue_of_http_request_method_from_string(void); +extern OFString *glue_of_http_status_code_to_string(void); +extern size_t glue_of_sizeof_type_encoding(void); +extern size_t glue_of_alignof_type_encoding(void); +extern uint32_t *glue_of_hash_seed_ref(void); +extern OFStdIOStream **glue_of_stdin_ref(void); +extern OFStdIOStream **glue_of_stdout_ref(void); +extern OFStdIOStream **glue_of_stderr_ref(void); +extern void glue_of_logv(void); +extern of_string_encoding_t glue_of_string_parse_encoding(void); +extern OFString *glue_of_string_name_of_encoding(void); +extern size_t glue_of_string_utf8_encode(void); +extern ssize_t glue_of_string_utf8_decode(void); +extern size_t glue_of_string_utf16_length(void); +extern size_t glue_of_string_utf32_length(void); +extern OFString *glue_of_zip_archive_entry_version_to_string(void); +extern OFString *glue_of_zip_archive_entry_compression_method_to_string(void); +extern size_t glue_of_zip_archive_entry_extra_field_find(void); +extern void glue_of_pbkdf2(void); +extern void glue_of_salsa20_8_core(void); +extern void glue_of_scrypt_block_mix(void); +extern void glue_of_scrypt_romix(void); +extern void glue_of_scrypt(void); +extern const char *glue_of_strptime(void); +extern of_socket_address_t glue_of_socket_address_parse_ip(void); +extern of_socket_address_t glue_of_socket_address_parse_ipv4(void); +extern of_socket_address_t glue_of_socket_address_parse_ipv6(void); +extern of_socket_address_t glue_of_socket_address_ipx(void); +extern bool glue_of_socket_address_equal(void); +extern uint32_t glue_of_socket_address_hash(void); +extern OFString *glue_of_socket_address_ip_string(void); +extern void glue_of_socket_address_set_port(void); +extern uint16_t glue_of_socket_address_get_port(void); +extern void glue_of_socket_address_set_ipx_network(void); +extern uint32_t glue_of_socket_address_get_ipx_network(void); +extern void glue_of_socket_address_set_ipx_node(void); +extern void glue_of_socket_address_get_ipx_node(void); + +#ifdef OF_AMIGAOS_M68K +void +__init_eh(void) +{ + /* Taken care of by of_init() */ +} +#endif + +#ifdef OF_MORPHOS +const ULONG __abox__ = 1; +#endif +struct ExecBase *SysBase; +struct of_libc libc; +FILE **__sF; + +#if defined(OF_AMIGAOS_M68K) +__asm__ ( + ".text\n" + ".globl ___restore_a4\n" + ".align 1\n" + "___restore_a4:\n" + " movea.l 42(a6), a4\n" + " rts" +); +#elif defined(OF_MORPHOS) +/* All __saveds functions in this file need to use the M68K ABI */ +__asm__ ( + ".section .text\n" + ".align 2\n" + "__restore_r13:\n" + " lwz %r13, 56(%r2)\n" + " lwz %r13, 44(%r13)\n" + " blr\n" +); +#endif + +static OF_INLINE char * +getDataSeg(void) +{ + char *dataSeg; + +#if defined(OF_AMIGAOS_M68K) + __asm__ ( + "move.l #___a4_init, %0" + : "=r"(dataSeg) + ); +#elif defined(OF_MORPHOS) + __asm__ ( + "lis %0, __r13_init@ha\n\t" + "la %0, __r13_init@l(%0)" + : "=r"(dataSeg) + ); +#endif + + return dataSeg; +} + +static OF_INLINE size_t +getDataSize(void) +{ + size_t dataSize; + +#if defined(OF_AMIGAOS_M68K) + __asm__ ( + "move.l #___data_size, %0\n\t" + "add.l #___bss_size, %0" + : "=r"(dataSize) + ); +#elif defined(OF_MORPHOS) + __asm__ ( + "lis %0, __sdata_size@ha\n\t" + "la %0, __sdata_size@l(%0)\n\t" + "lis %%r9, __sbss_size@ha\n\t" + "la %%r9, __sbss_size@l(%%r9)\n\t" + "add %0, %0, %%r9" + : "=r"(dataSize) + :: "r9" + ); +#endif + + return dataSize; +} + +static OF_INLINE size_t * +getDataDataRelocs(void) +{ + size_t *dataDataRelocs; + +#if defined(OF_AMIGAOS_M68K) + __asm__ ( + "move.l #___datadata_relocs, %0" + : "=r"(dataDataRelocs) + ); +#elif defined(OF_MORPHOS) + __asm__ ( + "lis %0, __datadata_relocs@ha\n\t" + "la %0, __datadata_relocs@l(%0)\n\t" + : "=r"(dataDataRelocs) + ); +#endif + + return dataDataRelocs; +} + +static struct Library * +lib_init(struct ObjFWBase *base OF_M68K_REG(d0), void *segList OF_M68K_REG(a0), + struct ExecBase *sysBase OF_M68K_REG(a6)) +{ +#if defined(OF_AMIGAOS_M68K) + __asm__ __volatile__ ( + "move.l a6, _SysBase" + :: "a"(sysBase) + ); +#elif defined(OF_MORPHOS) + __asm__ __volatile__ ( + "lis %%r9, SysBase@ha\n\t" + "stw %0, SysBase@l(%%r9)" + :: "r"(sysBase) : "r9" + ); +#endif + + base->segList = segList; + base->parent = NULL; + base->dataSeg = getDataSeg(); + + return &base->library; +} + +struct Library *__saveds +lib_open(void) +{ + OF_M68K_ARG(struct ObjFWBase *, base, a6) + + struct ObjFWBase *child; + size_t dataSize, *dataDataRelocs; + ptrdiff_t displacement; + + if (base->parent != NULL) + return NULL; + + base->library.lib_OpenCnt++; + base->library.lib_Flags &= ~LIBF_DELEXP; + + /* + * We cannot use malloc here, as that depends on the libc passed from + * the application. + */ + if ((child = AllocMem(base->library.lib_NegSize + + base->library.lib_PosSize, MEMF_ANY)) == NULL) { + base->library.lib_OpenCnt--; + return NULL; + } + + memcpy(child, (char *)base - base->library.lib_NegSize, + base->library.lib_NegSize + base->library.lib_PosSize); + + child = (struct ObjFWBase *)((char *)child + base->library.lib_NegSize); + child->library.lib_OpenCnt = 1; + child->parent = base; + + dataSize = getDataSize(); + + if ((child->dataSeg = AllocMem(dataSize, MEMF_ANY)) == NULL) { + FreeMem((char *)child - child->library.lib_NegSize, + child->library.lib_NegSize + child->library.lib_PosSize); + base->library.lib_OpenCnt--; + return NULL; + } + + memcpy(child->dataSeg, base->dataSeg - DATA_OFFSET, dataSize); + + dataDataRelocs = getDataDataRelocs(); + displacement = child->dataSeg - (base->dataSeg - DATA_OFFSET); + + for (size_t i = 1; i <= dataDataRelocs[0]; i++) + *(long *)(child->dataSeg + dataDataRelocs[i]) += displacement; + + child->dataSeg += DATA_OFFSET; + + return &child->library; +} + +static void * +expunge(struct ObjFWBase *base) +{ + void *segList; + + if (base->parent != NULL) { + base->parent->library.lib_Flags |= LIBF_DELEXP; + return 0; + } + + if (base->library.lib_OpenCnt > 0) { + base->library.lib_Flags |= LIBF_DELEXP; + return 0; + } + + segList = base->segList; + + Remove(&base->library.lib_Node); + FreeMem((char *)base - base->library.lib_NegSize, + base->library.lib_NegSize + base->library.lib_PosSize); + + return segList; +} + +static void *__saveds +lib_expunge(void) +{ + OF_M68K_ARG(struct ObjFWBase *, base, a6) + + return expunge(base); +} + +static void *__saveds +lib_close(void) +{ + OF_M68K_ARG(struct ObjFWBase *, base, a6) + + if (base->parent != NULL) { + struct ObjFWBase *parent; + +#ifdef OF_AMIGAOS_M68K + if (base->initialized) + for (size_t i = 1; i <= (size_t)_EH_FRAME_BEGINS__; i++) + __deregister_frame_info( + (&_EH_FRAME_BEGINS__)[i]); +#endif + + parent = base->parent; + + FreeMem(base->dataSeg - DATA_OFFSET, getDataSize()); + FreeMem((char *)base - base->library.lib_NegSize, + base->library.lib_NegSize + base->library.lib_PosSize); + + base = parent; + } + + if (--base->library.lib_OpenCnt == 0 && + (base->library.lib_Flags & LIBF_DELEXP)) + return expunge(base); + + return NULL; +} + +static void * +lib_null(void) +{ + return NULL; +} + +bool +of_init(unsigned int version, struct of_libc *libc_, FILE **sF) +{ +#ifdef OF_AMIGAOS_M68K + OF_M68K_ARG(struct ObjFWBase *, base, a6) +#else + register struct ObjFWBase *r12 __asm__("r12"); + struct ObjFWBase *base = r12; +#endif + uintptr_t *iter, *iter0; + + if (version > 1) + return false; + + if (base->initialized) + return true; + + memcpy(&libc, libc_, sizeof(libc)); + __sF = sF; + +#ifdef OF_AMIGAOS_M68K + if ((size_t)_EH_FRAME_BEGINS__ != (size_t)_EH_FRAME_OBJECTS__) + return false; + + for (size_t i = 1; i <= (size_t)_EH_FRAME_BEGINS__; i++) + __register_frame_info((&_EH_FRAME_BEGINS__)[i], + (&_EH_FRAME_OBJECTS__)[i]); + + iter0 = &__CTOR_LIST__[1]; +#elif defined(OF_MORPHOS) + __asm__ ( + "lis %0, ctors+4@ha\n\t" + "la %0, ctors+4@l(%0)\n\t" + : "=r"(iter0) + ); +#endif + + for (iter = iter0; *iter != 0; iter++); + + while (iter > iter0) { + void (*ctor)(void) = (void (*)(void))*--iter; + ctor(); + } + + base->initialized = true; + + return true; +} + +void * +malloc(size_t size) +{ + return libc.malloc(size); +} + +void * +calloc(size_t count, size_t size) +{ + return libc.calloc(count, size); +} + +void * +realloc(void *ptr, size_t size) +{ + return libc.realloc(ptr, size); +} + +void +free(void *ptr) +{ + libc.free(ptr); +} + +int +fprintf(FILE *restrict stream, const char *restrict fmt, ...) +{ + int ret; + va_list args; + + va_start(args, fmt); + ret = libc.vfprintf(stream, fmt, args); + va_end(args); + + return ret; +} + +int +vfprintf(FILE *restrict stream, const char *restrict fmt, va_list args) +{ + return libc.vfprintf(stream, fmt, args); +} + +int +fflush(FILE *restrict stream) +{ + return libc.fflush(stream); +} + +void +abort(void) +{ + libc.abort(); + + OF_UNREACHABLE +} + +#ifdef HAVE_SJLJ_EXCEPTIONS +int +_Unwind_SjLj_RaiseException(void *ex) +{ + return libc._Unwind_SjLj_RaiseException(ex); +} +#else +int +_Unwind_RaiseException(void *ex) +{ + return libc._Unwind_RaiseException(ex); +} +#endif + +void +_Unwind_DeleteException(void *ex) +{ + libc._Unwind_DeleteException(ex); +} + +void * +_Unwind_GetLanguageSpecificData(void *ctx) +{ + return libc._Unwind_GetLanguageSpecificData(ctx); +} + +uintptr_t +_Unwind_GetRegionStart(void *ctx) +{ + return libc._Unwind_GetRegionStart(ctx); +} + +uintptr_t +_Unwind_GetDataRelBase(void *ctx) +{ + return libc._Unwind_GetDataRelBase(ctx); +} + +uintptr_t +_Unwind_GetTextRelBase(void *ctx) +{ + return libc._Unwind_GetTextRelBase(ctx); +} + +uintptr_t +_Unwind_GetIP(void *ctx) +{ + return libc._Unwind_GetIP(ctx); +} + +uintptr_t +_Unwind_GetGR(void *ctx, int gr) +{ + return libc._Unwind_GetGR(ctx, gr); +} + +void +_Unwind_SetIP(void *ctx, uintptr_t ip) +{ + libc._Unwind_SetIP(ctx, ip); +} + +void +_Unwind_SetGR(void *ctx, int gr, uintptr_t value) +{ + libc._Unwind_SetGR(ctx, gr, value); +} + +#ifdef HAVE_SJLJ_EXCEPTIONS +void +_Unwind_SjLj_Resume(void *ex) +{ + libc._Unwind_SjLj_Resume(ex); +} +#else +void +_Unwind_Resume(void *ex) +{ + libc._Unwind_Resume(ex); +} +#endif + +#ifdef OF_AMIGAOS_M68K +void +__register_frame_info(const void *begin, void *object) +{ + libc.__register_frame_info(begin, object); +} + +void +*__deregister_frame_info(const void *begin) +{ + return libc.__deregister_frame_info(begin); +} +#endif + +int +vsnprintf(char *restrict str, size_t size, const char *restrict fmt, + va_list args) +{ + return libc.vsnprintf(str, size, fmt, args); +} + +#ifdef OF_AMIGAOS_M68K +int +sscanf(const char *restrict str, const char *restrict fmt, ...) +{ + int ret; + va_list args; + + va_start(args, fmt); + ret = libc.vsscanf(str, fmt, args); + va_end(args); + + return ret; +} +#endif + +void +exit(int status) +{ + libc.exit(status); + + OF_UNREACHABLE +} + +of_sig_t +signal(int sig, of_sig_t func) +{ + return libc.signal(sig, func); +} + +char * +setlocale(int category, const char *locale) +{ + return libc.setlocale(category, locale); +} + +int +_Unwind_Backtrace(int (*callback)(void *, void *), void *data) +{ + return libc._Unwind_Backtrace(callback, data); +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +static CONST_APTR functionTable[] = { +#ifdef OF_MORPHOS + (CONST_APTR)FUNCARRAY_BEGIN, + (CONST_APTR)FUNCARRAY_32BIT_NATIVE, +#endif + (CONST_APTR)lib_open, + (CONST_APTR)lib_close, + (CONST_APTR)lib_expunge, + (CONST_APTR)lib_null, +#ifdef OF_MORPHOS + (CONST_APTR)-1, + (CONST_APTR)FUNCARRAY_32BIT_SYSTEMV, +#endif + (CONST_APTR)glue_of_init, + (CONST_APTR)glue_of_application_main, + (CONST_APTR)glue_of_http_request_method_to_string, + (CONST_APTR)glue_of_http_request_method_from_string, + (CONST_APTR)glue_of_http_status_code_to_string, + (CONST_APTR)glue_of_sizeof_type_encoding, + (CONST_APTR)glue_of_alignof_type_encoding, + (CONST_APTR)of_hash_seed_ref, + (CONST_APTR)glue_of_stdin_ref, + (CONST_APTR)glue_of_stdout_ref, + (CONST_APTR)glue_of_stderr_ref, + (CONST_APTR)glue_of_logv, + (CONST_APTR)glue_of_string_parse_encoding, + (CONST_APTR)glue_of_string_name_of_encoding, + (CONST_APTR)glue_of_string_utf8_encode, + (CONST_APTR)glue_of_string_utf8_decode, + (CONST_APTR)glue_of_string_utf16_length, + (CONST_APTR)glue_of_string_utf32_length, + (CONST_APTR)glue_of_zip_archive_entry_version_to_string, + (CONST_APTR)glue_of_zip_archive_entry_compression_method_to_string, + (CONST_APTR)glue_of_zip_archive_entry_extra_field_find, + (CONST_APTR)glue_of_pbkdf2, + (CONST_APTR)glue_of_salsa20_8_core, + (CONST_APTR)glue_of_scrypt_block_mix, + (CONST_APTR)glue_of_scrypt_romix, + (CONST_APTR)glue_of_scrypt, + (CONST_APTR)glue_of_strptime, + (CONST_APTR)glue_of_socket_address_parse_ip, + (CONST_APTR)glue_of_socket_address_parse_ipv4, + (CONST_APTR)glue_of_socket_address_parse_ipv6, + (CONST_APTR)glue_of_socket_address_ipx, + (CONST_APTR)glue_of_socket_address_equal, + (CONST_APTR)glue_of_socket_address_hash, + (CONST_APTR)glue_of_socket_address_ip_string, + (CONST_APTR)glue_of_socket_address_set_port, + (CONST_APTR)glue_of_socket_address_get_port, + (CONST_APTR)glue_of_socket_address_set_ipx_network, + (CONST_APTR)glue_of_socket_address_get_ipx_network, + (CONST_APTR)glue_of_socket_address_set_ipx_node, + (CONST_APTR)glue_of_socket_address_get_ipx_node, + (CONST_APTR)-1, +#ifdef OF_MORPHOS + (CONST_APTR)FUNCARRAY_END +#endif +}; +#pragma GCC diagnostic pop + +static struct { + ULONG dataSize; + CONST_APTR *functionTable; + ULONG *dataTable; + struct Library *(*initFunc)( + struct ObjFWBase *base OF_M68K_REG(d0), + void *segList OF_M68K_REG(a0), + struct ExecBase *execBase OF_M68K_REG(a6)); +} init_table = { + sizeof(struct ObjFWBase), + functionTable, + NULL, + lib_init +}; + +struct Resident resident = { + .rt_MatchWord = RTC_MATCHWORD, + .rt_MatchTag = &resident, + .rt_EndSkip = &resident + 1, + .rt_Flags = RTF_AUTOINIT +#ifdef OF_MORPHOS + | RTF_PPC | RTF_EXTENDED +#endif + , + .rt_Version = OBJFW_LIB_MAJOR, + .rt_Type = NT_LIBRARY, + .rt_Pri = 0, + .rt_Name = (char *)OBJFW_AMIGA_LIB, + .rt_IdString = (char *)"ObjFW " VERSION_STRING + " \xA9 2008-2020 Jonathan Schleifer", + .rt_Init = &init_table, +#ifdef OF_MORPHOS + .rt_Revision = OBJFW_LIB_MINOR, + .rt_Tags = NULL, +#endif +}; + +#ifdef OF_MORPHOS +__asm__ ( + ".section .ctors, \"aw\", @progbits\n" + "ctors:\n" + " .long -1\n" + ".section .text" +); +#endif ADDED src/amigaos3.sfd Index: src/amigaos3.sfd ================================================================== --- /dev/null +++ src/amigaos3.sfd @@ -0,0 +1,46 @@ +==base _ObjFWBase +==basetype struct Library * +==libname objfw68k.library +==bias 30 +==public +* The following function is only for the linklib. +bool glue_of_init(unsigned int version, struct of_libc *_Nonnull libc, FILE *_Nonnull *_Nonnull sF)(d0,a0,a1) +int glue_of_application_main(int *_Nonnull argc, char *_Nullable *_Nonnull *_Nonnull argv, id delegate)(a0,a1,a2) +const char *_Nullable glue_of_http_request_method_to_string(of_http_request_method_t method)(d0) +of_http_request_method_t glue_of_http_request_method_from_string(OFString *string)(a0) +OFString *_Nonnull glue_of_http_status_code_to_string(short code)(d0) +size_t glue_of_sizeof_type_encoding(const char *type)(a0) +size_t glue_of_alignof_type_encoding(const char *type)(a0) +uint32_t *_Nonnull glue_of_hash_seed_ref(void)() +OFStdIOStream *_Nonnull *_Nullable glue_of_stdin_ref(void)() +OFStdIOStream *_Nonnull *_Nullable glue_of_stdout_ref(void)() +OFStdIOStream *_Nonnull *_Nullable glue_of_stderr_ref(void)() +void glue_of_logv(OFConstantString *format, va_list arguments)(a0,a1) +of_string_encoding_t glue_of_string_parse_encoding(OFString *string)(a0) +OFString *_Nullable glue_of_string_name_of_encoding(of_string_encoding_t encoding)(d0) +size_t glue_of_string_utf8_encode(of_unichar_t c, char *UTF8)(d0,a0) +ssize_t glue_of_string_utf8_decode(const char *UTF8, size_t len, of_unichar_t *c)(a0,d0,a1) +size_t glue_of_string_utf16_length(const of_char16_t *string)(a0) +size_t glue_of_string_utf32_length(const of_char32_t *string)(a0) +OFString *_Nonnull glue_of_zip_archive_entry_version_to_string(uint16_t version)(d0) +OFString *_Nonnull glue_of_zip_archive_entry_compression_method_to_string(uint16_t compressionMethod)(d0) +size_t glue_of_zip_archive_entry_extra_field_find(OFData *extraField, uint16_t tag, uint16_t *size)(a0,d0,a1) +void glue_of_pbkdf2(const of_pbkdf2_parameters_t *param)(a0) +void glue_of_salsa20_8_core(uint32_t *_Nonnull buffer)(a0) +void glue_of_scrypt_block_mix(uint32_t *_Nonnull output, const uint32_t *_Nonnull input, size_t blockSize)(a0,a1,d0) +void glue_of_scrypt_romix(uint32_t *buffer, size_t blockSize, size_t costFactor, uint32_t *tmp)(a0,d0,d1,a1) +void glue_of_scrypt(const of_scrypt_parameters_t *param)(a0) +const char *_Nullable glue_of_strptime(const char *buf, const char *fmt, struct tm *tm, int16_t *_Nullable tz)(a0,a1,a2,a3) +void glue_of_socket_address_parse_ip(of_socket_address_t *_Nonnull address, OFString *IP, uint16_t port)(a0,a1,d0) +void glue_of_socket_address_parse_ipv4(of_socket_address_t *_Nonnull address, OFString *IP, uint16_t port)(a0,a1,d0) +void glue_of_socket_address_parse_ipv6(of_socket_address_t *_Nonnull address, OFString *IP, uint16_t port)(a0,a1,d0) +void glue_of_socket_address_ipx(of_socket_address_t *_Nonnull address, const unsigned char *_Nonnull node, uint32_t network, uint16_t port)(a0,a1,d0,d1) +bool glue_of_socket_address_equal(const of_socket_address_t *_Nonnull address1, const of_socket_address_t *_Nonnull address2)(a0,a1) +uint32_t glue_of_socket_address_hash(const of_socket_address_t *_Nonnull address)(a0) +OFString *_Nonnull glue_of_socket_address_ip_string(const of_socket_address_t *_Nonnull address, uint16_t *_Nullable port)(a0,a1) +void glue_of_socket_address_set_port(of_socket_address_t *_Nonnull address, uint16_t port)(a0,d0) +uint16_t glue_of_socket_address_get_port(const of_socket_address_t *_Nonnull address)(a0) +void glue_of_socket_address_set_ipx_network(of_socket_address_t *_Nonnull address, uint32_t network)(a0,d0) +uint32_t glue_of_socket_address_get_ipx_network(const of_socket_address_t *_Nonnull address)(a0) +void glue_of_socket_address_set_ipx_node(of_socket_address_t *_Nonnull address, const unsigned char *_Nonnull node)(a0,a1) +void glue_of_socket_address_get_ipx_node(const of_socket_address_t *_Nonnull address, unsigned char *_Nonnull node)(a0,a1) Index: src/encodings/Makefile ================================================================== --- src/encodings/Makefile +++ src/encodings/Makefile @@ -1,9 +1,10 @@ include ../../extra.mk STATIC_PIC_LIB_NOINST = ${ENCODINGS_LIB_A} STATIC_LIB_NOINST = ${ENCODINGS_A} +STATIC_AMIGA_LIB_NOINST = ${ENCODINGS_AMIGALIB_A} SRCS = ${ENCODINGS_SRCS} include ../../buildsys.mk Index: src/exceptions/Makefile ================================================================== --- src/exceptions/Makefile +++ src/exceptions/Makefile @@ -1,9 +1,10 @@ include ../../extra.mk STATIC_PIC_LIB_NOINST = ${EXCEPTIONS_LIB_A} STATIC_LIB_NOINST = ${EXCEPTIONS_A} +STATIC_AMIGA_LIB_NOINST = ${EXCEPTIONS_AMIGALIB_A} SRCS = OFAllocFailedException.m \ OFChangeCurrentDirectoryPathFailedException.m \ OFChecksumMismatchException.m \ OFCopyItemFailedException.m \ Index: src/forwarding/Makefile ================================================================== --- src/forwarding/Makefile +++ src/forwarding/Makefile @@ -1,9 +1,10 @@ include ../../extra.mk STATIC_PIC_LIB_NOINST = ${FORWARDING_LIB_A} STATIC_LIB_NOINST = ${FORWARDING_A} +STATIC_AMIGA_LIB_NOINST = ${FORWARDING_AMIGALIB_A} SRCS = forwarding.S include ../../buildsys.mk Index: src/invocation/Makefile ================================================================== --- src/invocation/Makefile +++ src/invocation/Makefile @@ -1,9 +1,10 @@ include ../../extra.mk STATIC_PIC_LIB_NOINST = ${INVOCATION_LIB_A} STATIC_LIB_NOINST = ${INVOCATION_A} +STATIC_AMIGA_LIB_NOINST = ${INVOCATION_AMIGALIB_A} SRCS = call.S \ invoke.m include ../../buildsys.mk ADDED src/linklib/Makefile Index: src/linklib/Makefile ================================================================== --- /dev/null +++ src/linklib/Makefile @@ -0,0 +1,10 @@ +include ../../extra.mk + +STATIC_LIB = libobjfw.library.a +SRCS = linklib.m + +include ../../buildsys.mk + +CPPFLAGS += -I.. -I../.. -I../exceptions -I../runtime \ + -DOBJFW_AMIGA_LIB=\"${OBJFW_AMIGA_LIB}\" \ + -DOBJFW_LIB_MINOR=${OBJFW_LIB_MINOR} ADDED src/linklib/linklib.m Index: src/linklib/linklib.m ================================================================== --- /dev/null +++ src/linklib/linklib.m @@ -0,0 +1,630 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019, 2020 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "ObjFW.h" +#import "amiga-library.h" +#import "macros.h" + +#include + +struct ObjFWBase; + +#import "inline.h" + +#include +#include +#include + +#if defined(OF_AMIGAOS_M68K) +# include +# define SYM(name) __asm__("_" name) +#elif defined(OF_MORPHOS) +# include +# define SYM(name) __asm__(name) +#endif + +#ifdef HAVE_SJLJ_EXCEPTIONS +extern int _Unwind_SjLj_RaiseException(void *); +#else +extern int _Unwind_RaiseException(void *); +#endif +extern void _Unwind_DeleteException(void *); +extern void *_Unwind_GetLanguageSpecificData(void *); +extern uintptr_t _Unwind_GetRegionStart(void *); +extern uintptr_t _Unwind_GetDataRelBase(void *); +extern uintptr_t _Unwind_GetTextRelBase(void *); +extern uintptr_t _Unwind_GetIP(void *); +extern uintptr_t _Unwind_GetGR(void *, int); +extern void _Unwind_SetIP(void *, uintptr_t); +extern void _Unwind_SetGR(void *, int, uintptr_t); +#ifdef HAVE_SJLJ_EXCEPTIONS +extern void _Unwind_SjLj_Resume(void *); +#else +extern void _Unwind_Resume(void *); +#endif +#ifdef OF_AMIGAOS_M68K +extern void __register_frame_info(const void *, void *); +extern void *__deregister_frame_info(const void *); +#endif +extern int _Unwind_Backtrace(int (*)(void *, void *), void *); + +struct Library *ObjFWBase; +void *__objc_class_name_OFASN1BitString; +void *__objc_class_name_OFASN1Boolean; +void *__objc_class_name_OFASN1Enumerated; +void *__objc_class_name_OFASN1IA5String; +void *__objc_class_name_OFASN1Integer; +void *__objc_class_name_OFASN1NumericString; +void *__objc_class_name_OFASN1ObjectIdentifier; +void *__objc_class_name_OFASN1OctetString; +void *__objc_class_name_OFASN1PrintableString; +void *__objc_class_name_OFASN1UTF8String; +void *__objc_class_name_OFASN1Value; +void *__objc_class_name_OFApplication; +void *__objc_class_name_OFArray; +void *__objc_class_name_OFCharacterSet; +void *__objc_class_name_OFColor; +void *__objc_class_name_OFConstantString; +void *__objc_class_name_OFCountedSet; +void *__objc_class_name_OFData; +void *__objc_class_name_OFDate; +void *__objc_class_name_OFDictionary; +void *__objc_class_name_OFEnumerator; +void *__objc_class_name_OFFileManager; +void *__objc_class_name_OFGZIPStream; +void *__objc_class_name_OFHMAC; +void *__objc_class_name_OFInflate64Stream; +void *__objc_class_name_OFInflateStream; +void *__objc_class_name_OFInvocation; +void *__objc_class_name_OFLHAArchive; +void *__objc_class_name_OFLHAArchiveEntry; +void *__objc_class_name_OFList; +void *__objc_class_name_OFLocale; +void *__objc_class_name_OFMapTable; +void *__objc_class_name_OFMapTableEnumerator; +void *__objc_class_name_OFMD5Hash; +void *__objc_class_name_OFMessagePackExtension; +void *__objc_class_name_OFMethodSignature; +void *__objc_class_name_OFMutableArray; +void *__objc_class_name_OFMutableData; +void *__objc_class_name_OFMutableDictionary; +void *__objc_class_name_OFMutableLHAArchiveEntry; +void *__objc_class_name_OFMutablePair; +void *__objc_class_name_OFMutableSet; +void *__objc_class_name_OFMutableString; +void *__objc_class_name_OFMutableTarArchiveEntry; +void *__objc_class_name_OFMutableTriple; +void *__objc_class_name_OFMutableURL; +void *__objc_class_name_OFMutableZIPArchiveEntry; +void *__objc_class_name_OFNull; +void *__objc_class_name_OFNumber; +void *__objc_class_name_OFObject; +void *__objc_class_name_OFOptionsParser; +void *__objc_class_name_OFPair; +void *__objc_class_name_OFRIPEMD160Hash; +void *__objc_class_name_OFRunLoop; +void *__objc_class_name_OFSandbox; +void *__objc_class_name_OFSecureData; +void *__objc_class_name_OFSeekableStream; +void *__objc_class_name_OFSet; +void *__objc_class_name_OFSHA1Hash; +void *__objc_class_name_OFSHA224Hash; +void *__objc_class_name_OFSHA224Or256Hash; +void *__objc_class_name_OFSHA256Hash; +void *__objc_class_name_OFSHA384Hash; +void *__objc_class_name_OFSHA384Or512Hash; +void *__objc_class_name_OFSHA512Hash; +void *__objc_class_name_OFSortedList; +void *__objc_class_name_OFStdIOStream; +void *__objc_class_name_OFStream; +void *__objc_class_name_OFString; +void *__objc_class_name_OFSystemInfo; +void *__objc_class_name_OFTarArchive; +void *__objc_class_name_OFTarArchiveEntry; +void *__objc_class_name_OFThread; +void *__objc_class_name_OFTimer; +void *__objc_class_name_OFTriple; +void *__objc_class_name_OFURL; +void *__objc_class_name_OFURLHandler; +void *__objc_class_name_OFValue; +void *__objc_class_name_OFXMLAttribute; +void *__objc_class_name_OFXMLCDATA; +void *__objc_class_name_OFXMLCharacters; +void *__objc_class_name_OFXMLComment; +void *__objc_class_name_OFXMLElement; +void *__objc_class_name_OFXMLElementBuilder; +void *__objc_class_name_OFXMLNode; +void *__objc_class_name_OFXMLParser; +void *__objc_class_name_OFXMLProcessingInstructions; +void *__objc_class_name_OFZIPArchive; +void *__objc_class_name_OFZIPArchiveEntry; +#ifdef OF_HAVE_FILES +void *__objc_class_name_OFFile; +void *__objc_class_name_OFINICategory; +void *__objc_class_name_OFINIFile; +void *__objc_class_name_OFSettings; +#endif +#ifdef OF_HAVE_SOCKETS +void *__objc_class_name_OFDNSQuery; +void *__objc_class_name_OFDNSResolver; +void *__objc_class_name_OFDNSResourceRecord; +void *__objc_class_name_OFADNSResourceRecord; +void *__objc_class_name_OFAAAADNSResourceRecord; +void *__objc_class_name_OFCNAMEDNSResourceRecord; +void *__objc_class_name_OFHINFODNSResourceRecord; +void *__objc_class_name_OFMXDNSResourceRecord; +void *__objc_class_name_OFNSDNSResourceRecord; +void *__objc_class_name_OFPTRDNSResourceRecord; +void *__objc_class_name_OFRPDNSResourceRecord; +void *__objc_class_name_OFSOADNSResourceRecord; +void *__objc_class_name_OFSRVDNSResourceRecord; +void *__objc_class_name_OFTXTDNSResourceRecord; +void *__objc_class_name_OFDNSResponse; +void *__objc_class_name_OFDatagramSocket; +void *__objc_class_name_OFHTTPClient; +void *__objc_class_name_OFHTTPCookie; +void *__objc_class_name_OFHTTPCookieManager; +void *__objc_class_name_OFHTTPRequest; +void *__objc_class_name_OFHTTPResponse; +void *__objc_class_name_OFHTTPServer; +void *__objc_class_name_OFSequencedPacketSocket; +void *__objc_class_name_OFStreamSocket; +void *__objc_class_name_OFTCPSocket; +void *__objc_class_name_OFUDPSocket; +void *__objc_class_name_OFKernelEventObserver; +#endif +#ifdef OF_HAVE_THREADS +void *__objc_class_name_OFCondition; +void *__objc_class_name_OFMutex; +void *__objc_class_name_OFRecursiveMutex; +void *__objc_class_name_OFThreadPool; +#endif +void *__objc_class_name_OFAllocFailedException; +void *__objc_class_name_OFChangeCurrentDirectoryPathFailedException; +void *__objc_class_name_OFChecksumMismatchException; +void *__objc_class_name_OFCopyItemFailedException; +void *__objc_class_name_OFCreateDirectoryFailedException; +void *__objc_class_name_OFCreateSymbolicLinkFailedException; +void *__objc_class_name_OFEnumerationMutationException; +void *__objc_class_name_OFException; +void *__objc_class_name_OFGetOptionFailedException; +void *__objc_class_name_OFHashAlreadyCalculatedException; +void *__objc_class_name_OFInitializationFailedException; +void *__objc_class_name_OFInvalidArgumentException; +void *__objc_class_name_OFInvalidEncodingException; +void *__objc_class_name_OFInvalidFormatException; +void *__objc_class_name_OFInvalidJSONException; +void *__objc_class_name_OFInvalidServerReplyException; +void *__objc_class_name_OFLinkFailedException; +void *__objc_class_name_OFLockFailedException; +void *__objc_class_name_OFMalformedXMLException; +void *__objc_class_name_OFMemoryNotPartOfObjectException; +void *__objc_class_name_OFMoveItemFailedException; +void *__objc_class_name_OFNotImplementedException; +void *__objc_class_name_OFNotOpenException; +void *__objc_class_name_OFOpenItemFailedException; +void *__objc_class_name_OFOutOfMemoryException; +void *__objc_class_name_OFOutOfRangeException; +void *__objc_class_name_OFReadFailedException; +void *__objc_class_name_OFReadOrWriteFailedException; +void *__objc_class_name_OFRemoveItemFailedException; +void *__objc_class_name_OFRetrieveItemAttributesFailedException; +void *__objc_class_name_OFSandboxActivationFailedException; +void *__objc_class_name_OFSeekFailedException; +void *__objc_class_name_OFSetItemAttributesFailedException; +void *__objc_class_name_OFSetOptionFailedException; +void *__objc_class_name_OFStillLockedException; +void *__objc_class_name_OFTruncatedDataException; +void *__objc_class_name_OFUnboundNamespaceException; +void *__objc_class_name_OFUnboundPrefixException; +void *__objc_class_name_OFUndefinedKeyException; +void *__objc_class_name_OFUnknownXMLEntityException; +void *__objc_class_name_OFUnlockFailedException; +void *__objc_class_name_OFUnsupportedProtocolException; +void *__objc_class_name_OFUnsupportedVersionException; +void *__objc_class_name_OFWriteFailedException; +#ifdef OF_HAVE_FILES +void *__objc_class_name_OFGetCurrentDirectoryPathFailedException; +#endif +#ifdef OF_HAVE_SOCKETS +void *__objc_class_name_OFAcceptFailedException; +void *__objc_class_name_OFAlreadyConnectedException; +void *__objc_class_name_OFBindFailedException; +void *__objc_class_name_OFConnectionFailedException; +void *__objc_class_name_OFDNSQueryFailedException; +void *__objc_class_name_OFHTTPRequestFailedException; +void *__objc_class_name_OFListenFailedException; +void *__objc_class_name_OFObserveFailedException; +void *__objc_class_name_OFResolveHostFailedException; +#endif +#ifdef OF_HAVE_THREADS +void *__objc_class_name_OFConditionBroadcastFailedException; +void *__objc_class_name_OFConditionSignalFailedException; +void *__objc_class_name_OFConditionStillWaitingException; +void *__objc_class_name_OFConditionWaitFailedException; +void *__objc_class_name_OFThreadJoinFailedException; +void *__objc_class_name_OFThreadStartFailedException; +void *__objc_class_name_OFThreadStillRunningException; +#endif +#include "OFFileManager_constants.m" +#include "OFRunLoop_constants.m" +/* The following __objc_class_name_* are only required for the tests. */ +void *__objc_class_name_OFBitSetCharacterSet; +void *__objc_class_name_OFMapTableSet; +void *__objc_class_name_OFMutableMapTableSet; +void *__objc_class_name_OFMutableUTF8String; +void *__objc_class_name_OFRangeCharacterSet; +void *__objc_class_name_OFSelectKernelEventObserver; +void *__objc_class_name_OFUTF8String; + +static void __attribute__((__used__)) +ctor(void) +{ + static bool initialized = false; + struct of_libc libc = { + .malloc = malloc, + .calloc = calloc, + .realloc = realloc, + .free = free, + .vfprintf = vfprintf, + .fflush = fflush, + .abort = abort, +#ifdef HAVE_SJLJ_EXCEPTIONS + ._Unwind_SjLj_RaiseException = _Unwind_SjLj_RaiseException, +#else + ._Unwind_RaiseException = _Unwind_RaiseException, +#endif + ._Unwind_DeleteException = _Unwind_DeleteException, + ._Unwind_GetLanguageSpecificData = + _Unwind_GetLanguageSpecificData, + ._Unwind_GetRegionStart = _Unwind_GetRegionStart, + ._Unwind_GetDataRelBase = _Unwind_GetDataRelBase, + ._Unwind_GetTextRelBase = _Unwind_GetTextRelBase, + ._Unwind_GetIP = _Unwind_GetIP, + ._Unwind_GetGR = _Unwind_GetGR, + ._Unwind_SetIP = _Unwind_SetIP, + ._Unwind_SetGR = _Unwind_SetGR, +#ifdef HAVE_SJLJ_EXCEPTIONS + ._Unwind_SjLj_Resume = _Unwind_SjLj_Resume, +#else + ._Unwind_Resume = _Unwind_Resume, +#endif +#ifdef OF_AMIGAOS_M68K + .__register_frame_info = __register_frame_info, + .__deregister_frame_info = __deregister_frame_info, +#endif + .vsnprintf = vsnprintf, +#ifdef OF_AMIGAOS_M68K + .vsscanf = vsscanf, +#endif + .exit = exit, + .signal = signal, + .setlocale = setlocale, + ._Unwind_Backtrace = _Unwind_Backtrace + }; + + if (initialized) + return; + + if ((ObjFWBase = OpenLibrary(OBJFW_AMIGA_LIB, + OBJFW_LIB_MINOR)) == NULL) { + /* + * The linklib can be used by other libraries as well, so we + * can't have the compiler optimize this to another function, + * hence the use of an unnecessary format specifier. + */ + fprintf(stderr, "Failed to open %s!\n", OBJFW_AMIGA_LIB); + abort(); + } + + if (!glue_of_init(1, &libc, __sF)) { + /* + * The linklib can be used by other libraries as well, so we + * can't have the compiler optimize this to another function, + * hence the use of an unnecessary format specifier. + */ + fprintf(stderr, "Failed to initialize %s!\n", OBJFW_AMIGA_LIB); + abort(); + } + + initialized = true; +} + +static void __attribute__((__used__)) +dtor(void) +{ + CloseLibrary(ObjFWBase); +} + +#if defined(OF_AMIGAOS_M68K) +ADD2INIT(ctor, -2); +ADD2EXIT(dtor, -2); +#elif defined(OF_MORPHOS) +CONSTRUCTOR_P(ObjFW, 4000) +{ + ctor(); + + return 0; +} + +DESTRUCTOR_P(ObjFW, 4000) +{ + dtor(); +} +#endif + +int +of_application_main(int *argc, char ***argv, + id delegate) +{ + return glue_of_application_main(argc, argv, delegate); +} + +const char * +of_http_request_method_to_string(of_http_request_method_t method) +{ + return glue_of_http_request_method_to_string(method); +} + +of_http_request_method_t +of_http_request_method_from_string(OFString *string) +{ + return glue_of_http_request_method_from_string(string); +} + +OFString * +of_http_status_code_to_string(short code) +{ + return glue_of_http_status_code_to_string(code); +} + +size_t +of_sizeof_type_encoding(const char *type) +{ + return glue_of_sizeof_type_encoding(type); +} + +size_t +of_alignof_type_encoding(const char *type) +{ + return glue_of_alignof_type_encoding(type); +} + +uint32_t * +of_hash_seed_ref(void) +{ + return glue_of_hash_seed_ref(); +} + +OFStdIOStream ** +of_stdin_ref(void) +{ + return glue_of_stdin_ref(); +} + +OFStdIOStream ** +of_stdout_ref(void) +{ + return glue_of_stdout_ref(); +} + +OFStdIOStream ** +of_stderr_ref(void) +{ + return glue_of_stderr_ref(); +} + +void +of_logv(OFConstantString *format, va_list arguments) +{ + glue_of_logv(format, arguments); +} + +of_string_encoding_t +of_string_parse_encoding(OFString *string) +{ + return glue_of_string_parse_encoding(string); +} + +OFString * +of_string_name_of_encoding(of_string_encoding_t encoding) +{ + return glue_of_string_name_of_encoding(encoding); +} + +size_t +of_string_utf8_encode(of_unichar_t c, char *UTF8) +{ + return glue_of_string_utf8_encode(c, UTF8); +} + +ssize_t +of_string_utf8_decode(const char *UTF8, size_t len, of_unichar_t *c) +{ + return glue_of_string_utf8_decode(UTF8, len, c); +} + +size_t +of_string_utf16_length(const of_char16_t *string) +{ + return glue_of_string_utf16_length(string); +} + +size_t +of_string_utf32_length(const of_char32_t *string) +{ + return glue_of_string_utf32_length(string); +} + +OFString * +of_zip_archive_entry_version_to_string(uint16_t version) +{ + return glue_of_zip_archive_entry_version_to_string(version); +} + +OFString * +of_zip_archive_entry_compression_method_to_string(uint16_t compressionMethod) +{ + return glue_of_zip_archive_entry_compression_method_to_string( + compressionMethod); +} + +size_t +of_zip_archive_entry_extra_field_find(OFData *extraField, uint16_t tag, + uint16_t *size) +{ + return glue_of_zip_archive_entry_extra_field_find( + extraField, tag, size); +} + +void +of_pbkdf2(of_pbkdf2_parameters_t param) +{ + glue_of_pbkdf2(¶m); +} + +void +of_salsa20_8_core(uint32_t *buffer) +{ + glue_of_salsa20_8_core(buffer); +} + +void +of_scrypt_block_mix(uint32_t *output, const uint32_t *input, size_t blockSize) +{ + glue_of_scrypt_block_mix(output, input, blockSize); +} + +void +of_scrypt_romix(uint32_t *buffer, size_t blockSize, size_t costFactor, + uint32_t *tmp) +{ + glue_of_scrypt_romix(buffer, blockSize, costFactor, tmp); +} + +void +of_scrypt(of_scrypt_parameters_t param) +{ + glue_of_scrypt(¶m); +} + +const char * +of_strptime(const char *buf, const char *fmt, struct tm *tm, int16_t *tz) +{ + return glue_of_strptime(buf, fmt, tm, tz); +} + +of_socket_address_t +of_socket_address_parse_ip(OFString *IP, uint16_t port) +{ + of_socket_address_t address; + + glue_of_socket_address_parse_ip(&address, IP, port); + + return address; +} + +of_socket_address_t +of_socket_address_parse_ipv4(OFString *IP, uint16_t port) +{ + of_socket_address_t address; + + glue_of_socket_address_parse_ipv4(&address, IP, port); + + return address; +} + +of_socket_address_t +of_socket_address_parse_ipv6(OFString *IP, uint16_t port) +{ + of_socket_address_t address; + + glue_of_socket_address_parse_ipv6(&address, IP, port); + + return address; +} + +of_socket_address_t +of_socket_address_ipx(const unsigned char *node, uint32_t network, + uint16_t port) +{ + of_socket_address_t address; + + glue_of_socket_address_ipx(&address, node, network, port); + + return address; +} + +bool +of_socket_address_equal(const of_socket_address_t *address1, + const of_socket_address_t *address2) +{ + return glue_of_socket_address_equal(address1, address2); +} + +uint32_t +of_socket_address_hash(const of_socket_address_t *address) +{ + return glue_of_socket_address_hash(address); +} + +OFString * +of_socket_address_ip_string(const of_socket_address_t *address, uint16_t *port) +{ + return glue_of_socket_address_ip_string(address, port); +} + +void +of_socket_address_set_port(of_socket_address_t *address, uint16_t port) +{ + glue_of_socket_address_set_port(address, port); +} + +uint16_t +of_socket_address_get_port(const of_socket_address_t *address) +{ + return glue_of_socket_address_get_port(address); +} + +void +of_socket_address_set_ipx_network(of_socket_address_t *address, + uint32_t network) +{ + glue_of_socket_address_set_ipx_network(address, network); +} + +uint32_t +of_socket_address_get_ipx_network(const of_socket_address_t *address) +{ + return glue_of_socket_address_get_ipx_network(address); +} + +void +of_socket_address_set_ipx_node(of_socket_address_t *address, + const unsigned char *node) +{ + glue_of_socket_address_set_ipx_node(address, node); +} + +void +of_socket_address_get_ipx_node(const of_socket_address_t *address, + unsigned char *node) +{ + glue_of_socket_address_get_ipx_node(address, node); +} Index: src/of_strptime.h ================================================================== --- src/of_strptime.h +++ src/of_strptime.h @@ -29,12 +29,12 @@ OF_ASSUME_NONNULL_BEGIN #ifdef __cplusplus extern "C" { #endif -extern const char *of_strptime(const char *buf, const char *fmt, - struct tm *tm, int16_t *tz); +extern const char *_Nullable of_strptime(const char *buf, const char *fmt, + struct tm *tm, int16_t *_Nullable tz); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END Index: src/runtime/Makefile ================================================================== --- src/runtime/Makefile +++ src/runtime/Makefile @@ -1,10 +1,17 @@ include ../../extra.mk SUBDIRS = lookup-asm SUBDIRS_AFTER = ${LINKLIB} -CLEAN = amiga-library-functable.inc inline.h +CLEAN = amiga-end.amigalib.dep \ + amiga-end.amigalib.o \ + amiga-glue.amigalib.dep \ + amiga-glue.amigalib.o \ + amiga-library-functable.inc \ + amiga-library.amigalib.dep \ + amiga-library.amigalib.o \ + inline.h SHARED_LIB = ${OBJFWRT_SHARED_LIB} STATIC_LIB = ${OBJFWRT_STATIC_LIB} FRAMEWORK = ${OBJFWRT_FRAMEWORK} AMIGA_LIB = ${OBJFWRT_AMIGA_LIB} @@ -39,12 +46,12 @@ includesubdir = ObjFWRT OBJS_EXTRA = ${LOOKUP_ASM_LOOKUP_ASM_A} LIB_OBJS_EXTRA = ${LOOKUP_ASM_LOOKUP_ASM_LIB_A} AMIGA_LIB_OBJS_START = amiga-library.amigalib.o -AMIGA_LIB_OBJS_EXTRA = amiga-glue.amigalib.o \ - ${LOOKUP_ASM_LOOKUP_ASM_A} \ +AMIGA_LIB_OBJS_EXTRA = amiga-glue.amigalib.o \ + ${LOOKUP_ASM_LOOKUP_ASM_AMIGALIB_A} \ amiga-end.amigalib.o include ../../buildsys.mk ${OBJFWRT_AMIGA_LIB}: inline.h Index: src/runtime/amiga-glue.m ================================================================== --- src/runtime/amiga-glue.m +++ src/runtime/amiga-glue.m @@ -16,23 +16,22 @@ */ #include "config.h" #import "ObjFWRT.h" -#import "private.h" +#import "amiga-library.h" #import "macros.h" +#import "private.h" #ifdef OF_AMIGAOS_M68K # define PPC_PARAMS(...) (void) # define M68K_ARG OBJC_M68K_ARG #else # define PPC_PARAMS(...) (__VA_ARGS__) # define M68K_ARG(...) #endif -extern bool objc_init(unsigned int, struct objc_libc *, FILE *, FILE *); - #ifdef OF_MORPHOS /* All __saveds functions in this file need to use the SysV ABI */ __asm__ ( ".section .text\n" ".align 2\n" @@ -42,18 +41,17 @@ ); #endif bool __saveds glue_objc_init PPC_PARAMS(unsigned int version, struct objc_libc *libc, - FILE *stdout_, FILE *stderr_) + FILE **sF) { M68K_ARG(unsigned int, version, d0) M68K_ARG(struct objc_libc *, libc, a0) - M68K_ARG(FILE *, stdout_, a1) - M68K_ARG(FILE *, stderr_, a2) + M68K_ARG(FILE **, sF, a1) - return objc_init(version, libc, stdout_, stderr_); + return objc_init(version, libc, sF); } void __saveds glue___objc_exec_class PPC_PARAMS(struct objc_module *module) { ADDED src/runtime/amiga-library.h Index: src/runtime/amiga-library.h ================================================================== --- /dev/null +++ src/runtime/amiga-library.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019, 2020 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "macros.h" + +#ifdef OF_MORPHOS +# include +# define OBJC_M68K_ARG(type, name, reg) type name = (type)REG_##reg; +#else +# define OBJC_M68K_ARG(type, name, reg) \ + register type reg_##name __asm__(#reg); \ + type name = reg_##name; +#endif + +struct objc_libc { + void *_Nullable (*_Nonnull malloc)(size_t); + void *_Nullable (*_Nonnull calloc)(size_t, size_t); + void *_Nullable (*_Nonnull realloc)(void *_Nullable, size_t); + void (*_Nonnull free)(void *_Nullable); + int (*_Nonnull vfprintf)(FILE *_Nonnull restrict, + const char *_Nonnull restrict, va_list); + int (*_Nonnull fflush)(FILE *_Nonnull); + void (*_Nonnull abort)(void); +#ifdef HAVE_SJLJ_EXCEPTIONS + int (*_Nonnull _Unwind_SjLj_RaiseException)(void *_Nonnull); +#else + int (*_Nonnull _Unwind_RaiseException)(void *_Nonnull); +#endif + void (*_Nonnull _Unwind_DeleteException)(void *_Nonnull); + void *_Nullable (*_Nonnull _Unwind_GetLanguageSpecificData)( + void *_Nonnull); + uintptr_t (*_Nonnull _Unwind_GetRegionStart)(void *_Nonnull); + uintptr_t (*_Nonnull _Unwind_GetDataRelBase)(void *_Nonnull); + uintptr_t (*_Nonnull _Unwind_GetTextRelBase)(void *_Nonnull); + uintptr_t (*_Nonnull _Unwind_GetIP)(void *_Nonnull); + uintptr_t (*_Nonnull _Unwind_GetGR)(void *_Nonnull, int); + void (*_Nonnull _Unwind_SetIP)(void *_Nonnull, uintptr_t); + void (*_Nonnull _Unwind_SetGR)(void *_Nonnull, int, uintptr_t); +#ifdef HAVE_SJLJ_EXCEPTIONS + void (*_Nonnull _Unwind_SjLj_Resume)(void *_Nonnull); +#else + void (*_Nonnull _Unwind_Resume)(void *_Nonnull); +#endif +#ifdef OF_AMIGAOS_M68K + void (*_Nonnull __register_frame_info)(const void *_Nonnull, + void *_Nonnull); + void *_Nullable (*_Nonnull __deregister_frame_info)( + const void *_Nonnull); +#endif +}; + +extern bool objc_init(unsigned int, struct objc_libc *_Nonnull, + FILE *_Nonnull *_Nonnull); Index: src/runtime/amiga-library.m ================================================================== --- src/runtime/amiga-library.m +++ src/runtime/amiga-library.m @@ -16,10 +16,11 @@ */ #include "config.h" #import "ObjFWRT.h" +#import "amiga-library.h" #import "private.h" #include #include #include @@ -151,12 +152,11 @@ #ifdef OF_MORPHOS const ULONG __abox__ = 1; #endif struct ExecBase *SysBase; struct objc_libc libc; -FILE *stdout; -FILE *stderr; +FILE **__sF; #if defined(OF_AMIGAOS_M68K) __asm__ ( ".text\n" ".globl ___restore_a4\n" @@ -392,12 +392,11 @@ { return NULL; } bool -objc_init(unsigned int version, struct objc_libc *libc_, FILE *stdout_, - FILE *stderr_) +objc_init(unsigned int version, struct objc_libc *libc_, FILE **sF) { #ifdef OF_AMIGAOS_M68K OBJC_M68K_ARG(struct ObjFWRTBase *, base, a6) #else register struct ObjFWRTBase *r12 __asm__("r12"); @@ -405,14 +404,16 @@ #endif uintptr_t *iter, *iter0; if (version > 1) return false; + + if (base->initialized) + return true; memcpy(&libc, libc_, sizeof(libc)); - stdout = stdout_; - stderr = stderr_; + __sF = sF; #ifdef OF_AMIGAOS_M68K if ((size_t)_EH_FRAME_BEGINS__ != (size_t)_EH_FRAME_OBJECTS__) return false; @@ -707,11 +708,11 @@ .rt_Version = OBJFWRT_LIB_MAJOR, .rt_Type = NT_LIBRARY, .rt_Pri = 0, .rt_Name = (char *)OBJFWRT_AMIGA_LIB, .rt_IdString = (char *)"ObjFWRT " VERSION_STRING - " \xA9 2008-2019 Jonathan Schleifer", + " \xA9 2008-2020 Jonathan Schleifer", .rt_Init = &init_table, #ifdef OF_MORPHOS .rt_Revision = OBJFWRT_LIB_MINOR, .rt_Tags = NULL, #endif Index: src/runtime/amigaos3.sfd ================================================================== --- src/runtime/amigaos3.sfd +++ src/runtime/amigaos3.sfd @@ -2,11 +2,11 @@ ==basetype struct Library * ==libname objfwrt68k.library ==bias 30 ==public * The following function is only for the linklib. -bool glue_objc_init(unsigned int version, struct objc_libc *libc, FILE *stdout, FILE *stderr)(d0,a0,a1,a2) +bool glue_objc_init(unsigned int version, struct objc_libc *_Nonnull libc, FILE *_Nonnull *_Nonnull sF)(d0,a0,a1) void glue___objc_exec_class(struct objc_module *_Nonnull module)(a0) IMP _Nonnull glue_objc_msg_lookup(id _Nullable object, SEL _Nonnull selector)(a0,a1) IMP _Nonnull glue_objc_msg_lookup_stret(id _Nullable object, SEL _Nonnull selector)(a0,a1) IMP _Nonnull glue_objc_msg_lookup_super(struct objc_super *_Nonnull super, SEL _Nonnull selector)(a0,a1) IMP _Nonnull glue_objc_msg_lookup_super_stret(struct objc_super *_Nonnull super, SEL _Nonnull selector)(a0,a1) Index: src/runtime/linklib/Makefile ================================================================== --- src/runtime/linklib/Makefile +++ src/runtime/linklib/Makefile @@ -3,10 +3,9 @@ STATIC_LIB = libobjfwrt.library.a SRCS = linklib.m include ../../../buildsys.mk -CPPFLAGS += -I.. -I../.. -I../../.. \ +CPPFLAGS += -I.. -I../.. -I../../.. \ -DOBJC_COMPILING_AMIGA_LINKLIB \ -DOBJFWRT_AMIGA_LIB=\"${OBJFWRT_AMIGA_LIB}\" \ -DOBJFWRT_LIB_MINOR=${OBJFWRT_LIB_MINOR} -LD = ${OBJC} Index: src/runtime/linklib/linklib.m ================================================================== --- src/runtime/linklib/linklib.m +++ src/runtime/linklib/linklib.m @@ -16,12 +16,13 @@ */ #include "config.h" #import "ObjFWRT.h" -#import "private.h" +#import "amiga-library.h" #import "macros.h" +#import "private.h" #include struct ObjFWRTBase; @@ -55,12 +56,14 @@ #ifdef HAVE_SJLJ_EXCEPTIONS extern void _Unwind_SjLj_Resume(void *); #else extern void _Unwind_Resume(void *); #endif +#ifdef OF_AMIGAOS_M68K extern void __register_frame_info(const void *, void *); extern void *__deregister_frame_info(const void *); +#endif struct Library *ObjFWRTBase; void *__objc_class_name_Protocol; static void __attribute__((__used__)) @@ -93,25 +96,38 @@ #ifdef HAVE_SJLJ_EXCEPTIONS ._Unwind_SjLj_Resume = _Unwind_SjLj_Resume, #else ._Unwind_Resume = _Unwind_Resume, #endif +#ifdef OF_AMIGAOS_M68K .__register_frame_info = __register_frame_info, .__deregister_frame_info = __deregister_frame_info, +#endif }; if (initialized) return; if ((ObjFWRTBase = OpenLibrary(OBJFWRT_AMIGA_LIB, OBJFWRT_LIB_MINOR)) == NULL) { - fputs("Failed to open " OBJFWRT_AMIGA_LIB "!\n", stderr); + /* + * The linklib is used by objfw(68k).library as well, so we + * can't have the compiler optimize this to another function, + * hence the use of an unnecessary format specifier. + */ + fprintf(stderr, "Failed to open %s!\n", OBJFWRT_AMIGA_LIB); abort(); } - if (!glue_objc_init(1, &libc, stdout, stderr)) { - fputs("Failed to initialize " OBJFWRT_AMIGA_LIB "!\n", stderr); + if (!glue_objc_init(1, &libc, __sF)) { + /* + * The linklib is used by objfw(68k).library as well, so we + * can't have the compiler optimize this to another function, + * hence the use of an unnecessary format specifier. + */ + fprintf(stderr, "Failed to initialize %s!\n", + OBJFWRT_AMIGA_LIB); abort(); } initialized = true; } Index: src/runtime/lookup-asm/Makefile ================================================================== --- src/runtime/lookup-asm/Makefile +++ src/runtime/lookup-asm/Makefile @@ -1,9 +1,10 @@ include ../../../extra.mk STATIC_PIC_LIB_NOINST = ${LOOKUP_ASM_LIB_A} STATIC_LIB_NOINST = ${LOOKUP_ASM_A} +STATIC_AMIGA_LIB_NOINST = ${LOOKUP_ASM_AMIGALIB_A} SRCS = lookup-asm.S include ../../../buildsys.mk Index: src/runtime/morphos-clib.h ================================================================== --- src/runtime/morphos-clib.h +++ src/runtime/morphos-clib.h @@ -1,7 +1,7 @@ /* The following function is only for the linklib. */ -bool glue_objc_init(unsigned int, struct objc_libc *, FILE *, FILE *); +bool glue_objc_init(unsigned int, struct objc_libc *, FILE **); void glue___objc_exec_class(struct objc_module *); IMP glue_objc_msg_lookup(id, SEL); IMP glue_objc_msg_lookup_stret(id, SEL); IMP glue_objc_msg_lookup_super(struct objc_super *, SEL); IMP glue_objc_msg_lookup_super_stret(struct objc_super *, SEL); Index: src/runtime/morphos.fd ================================================================== --- src/runtime/morphos.fd +++ src/runtime/morphos.fd @@ -1,10 +1,10 @@ ##base _ObjFWRTBase ##bias 30 ##public * The following function is only for the linklib. -glue_objc_init(version,libc,stdout,stderr)(sysv,r12base) +glue_objc_init(version,libc,sF)(sysv,r12base) glue___objc_exec_class(module)(sysv,r12base) glue_objc_msg_lookup(object,selector)(sysv,r12base) glue_objc_msg_lookup_stret(object,selector)(sysv,r12base) glue_objc_msg_lookup_super(super,selector)(sysv,r12base) glue_objc_msg_lookup_super_stret(super,selector)(sysv,r12base) Index: src/runtime/private.h ================================================================== --- src/runtime/private.h +++ src/runtime/private.h @@ -13,12 +13,10 @@ * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ -#include "config.h" - #import "macros.h" #import "platform.h" #if !defined(__has_feature) || !__has_feature(nullability) # ifndef _Nonnull @@ -216,60 +214,10 @@ IMP _Nullable buckets[256]; #endif } *_Nonnull buckets[256]; }; -#if defined(OBJC_COMPILING_AMIGA_LIBRARY) || \ - defined(OBJC_COMPILING_AMIGA_LINKLIB) -struct objc_libc { - void *_Nullable (*_Nonnull malloc)(size_t); - void *_Nullable (*_Nonnull calloc)(size_t, size_t); - void *_Nullable (*_Nonnull realloc)(void *_Nullable, size_t); - void (*_Nonnull free)(void *_Nullable); - int (*_Nonnull vfprintf)(FILE *_Nonnull, const char *_Nonnull, va_list); - int (*_Nonnull fflush)(FILE *_Nonnull); - void (*_Nonnull abort)(void); -# ifdef HAVE_SJLJ_EXCEPTIONS - int (*_Nonnull _Unwind_SjLj_RaiseException)(void *_Nonnull); -# else - int (*_Nonnull _Unwind_RaiseException)(void *_Nonnull); -# endif - void (*_Nonnull _Unwind_DeleteException)(void *_Nonnull); - void *_Nullable (*_Nonnull _Unwind_GetLanguageSpecificData)( - void *_Nonnull); - uintptr_t (*_Nonnull _Unwind_GetRegionStart)(void *_Nonnull); - uintptr_t (*_Nonnull _Unwind_GetDataRelBase)(void *_Nonnull); - uintptr_t (*_Nonnull _Unwind_GetTextRelBase)(void *_Nonnull); - uintptr_t (*_Nonnull _Unwind_GetIP)(void *_Nonnull); - uintptr_t (*_Nonnull _Unwind_GetGR)(void *_Nonnull, int); - void (*_Nonnull _Unwind_SetIP)(void *_Nonnull, uintptr_t); - void (*_Nonnull _Unwind_SetGR)(void *_Nonnull, int, uintptr_t); -# ifdef HAVE_SJLJ_EXCEPTIONS - void (*_Nonnull _Unwind_SjLj_Resume)(void *_Nonnull); -# else - void (*_Nonnull _Unwind_Resume)(void *_Nonnull); -# endif - void (*_Nonnull __register_frame_info)(const void *_Nonnull, - void *_Nonnull); - void *(*_Nonnull __deregister_frame_info)(const void *_Nonnull); -}; -#endif - -#ifdef OBJC_COMPILING_AMIGA_LIBRARY -# if defined(__MORPHOS__) -# include -# define OBJC_M68K_ARG(type, name, reg) type name = (type)REG_##reg; -# else -# define OBJC_M68K_ARG(type, name, reg) \ - register type reg_##name __asm__(#reg); \ - type name = reg_##name; -# endif -# undef stdout -# undef stderr -extern FILE *stdout, *stderr; -#endif - extern void objc_register_all_categories(struct objc_symtab *_Nonnull); extern struct objc_category *_Nullable *_Nullable objc_categories_for_class(Class _Nonnull); extern void objc_unregister_all_categories(void); extern void objc_initialize_class(Class _Nonnull);