Artifact 35f4fabad7d1caf7182bf4a0a60579b7d583fbfa244ccad5eb84b49feacbb0aa:
- File
src/linklib/linklib.m
— part of check-in
[1ec05804b0]
at
2020-06-20 21:54:52
on branch amiga-library
— Add all functions to linklib
Also contains a workaround for Amiga library functions not being able to
return structs. (user: js, size: 8326) [annotate] [blame] [check-ins using]
/* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * 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 <proto/exec.h> struct ObjFWBase; #import "inline.h" #include <locale.h> #include <stdio.h> #include <stdlib.h> #if defined(OF_AMIGAOS_M68K) # include <stabs.h> # define SYM(name) __asm__("_" name) #elif defined(OF_MORPHOS) # include <constructor.h> # 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; 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 <OFApplicationDelegate> 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); } void of_logv(OFConstantString *format, va_list arguments) { glue_of_logv(format, arguments); } 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(OFHMAC *HMAC, size_t iterations, const unsigned char *salt, size_t saltLength, const char *password, size_t passwordLength, unsigned char *key, size_t keyLength, bool allowsSwappableMemory) { glue_of_pbkdf2(HMAC, iterations, salt, saltLength, password, passwordLength, key, keyLength, allowsSwappableMemory); } void of_scrypt(size_t blockSize, size_t costFactor, size_t parallelization, const unsigned char *salt, size_t saltLength, const char *password, size_t passwordLength, unsigned char *key, size_t keyLength, bool allowsSwappableMemory) { glue_of_scrypt(blockSize, costFactor, parallelization, salt, saltLength, password, passwordLength, key, keyLength, allowsSwappableMemory); } 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); }