Enable source debugging feature for windows platform (#910)
- use platform independent data types in debug-engine library - add os_socket APIs and provide windows and posix implementation - avoid using platform related header files in non-platform layer - use format specifiers macros for sprintf and sscanf - change thread handle type from uint64 to korp_tid - add lock when sending socket packet to avoid thread racing
This commit is contained in:
@ -58,6 +58,8 @@ typedef pthread_t korp_thread;
|
||||
|
||||
#define os_thread_local_attribute __thread
|
||||
|
||||
#define bh_socket_t int
|
||||
|
||||
#if WASM_DISABLE_HW_BOUND_CHECK == 0
|
||||
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|
||||
|| defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
|
||||
|
||||
124
core/shared/platform/common/posix/posix_socket.c
Normal file
124
core/shared/platform/common/posix/posix_socket.c
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "platform_api_vmcore.h"
|
||||
#include "platform_api_extension.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
int
|
||||
os_socket_create(bh_socket_t *sock, int tcp_or_udp)
|
||||
{
|
||||
if (!sock) {
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
if (1 == tcp_or_udp) {
|
||||
*sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
}
|
||||
else if (0 == tcp_or_udp) {
|
||||
*sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
}
|
||||
|
||||
return (*sock == -1) ? BHT_ERROR : BHT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_bind(bh_socket_t socket, const char *host, int *port)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
struct linger ling;
|
||||
socklen_t socklen;
|
||||
int ret;
|
||||
|
||||
assert(host);
|
||||
assert(port);
|
||||
|
||||
ling.l_onoff = 1;
|
||||
ling.l_linger = 0;
|
||||
|
||||
ret = fcntl(socket, F_SETFD, FD_CLOEXEC);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = setsockopt(socket, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
addr.sin_addr.s_addr = inet_addr(host);
|
||||
addr.sin_port = htons(*port);
|
||||
addr.sin_family = AF_INET;
|
||||
|
||||
ret = bind(socket, (struct sockaddr *)&addr, sizeof(addr));
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
socklen = sizeof(addr);
|
||||
if (getsockname(socket, (void *)&addr, &socklen) == -1) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*port = ntohs(addr.sin_port);
|
||||
|
||||
return BHT_OK;
|
||||
|
||||
fail:
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_listen(bh_socket_t socket, int max_client)
|
||||
{
|
||||
if (listen(socket, max_client) != 0) {
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
|
||||
unsigned int *addrlen)
|
||||
{
|
||||
struct sockaddr addr_tmp;
|
||||
unsigned int len = sizeof(struct sockaddr);
|
||||
|
||||
*sock = accept(server_sock, (struct sockaddr *)&addr_tmp, &len);
|
||||
|
||||
if (*sock < 0) {
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
|
||||
{
|
||||
return recv(socket, buf, len, 0);
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
|
||||
{
|
||||
return send(socket, buf, len, 0);
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_close(bh_socket_t socket)
|
||||
{
|
||||
close(socket);
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_shutdown(bh_socket_t socket)
|
||||
{
|
||||
shutdown(socket, O_RDWR);
|
||||
return BHT_OK;
|
||||
}
|
||||
@ -59,6 +59,8 @@ typedef pthread_t korp_thread;
|
||||
|
||||
#define os_thread_local_attribute __thread
|
||||
|
||||
#define bh_socket_t int
|
||||
|
||||
#if WASM_DISABLE_HW_BOUND_CHECK == 0
|
||||
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|
||||
|| defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
|
||||
|
||||
@ -23,6 +23,11 @@ extern "C" {
|
||||
* *
|
||||
***************************************************/
|
||||
|
||||
/****************************************************
|
||||
* Section 1 *
|
||||
* Multi thread support *
|
||||
****************************************************/
|
||||
|
||||
/**
|
||||
* NOTES:
|
||||
* 1. If you are building VM core only, it must be implemented to
|
||||
@ -174,6 +179,116 @@ os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, uint64 useconds);
|
||||
int
|
||||
os_cond_signal(korp_cond *cond);
|
||||
|
||||
/****************************************************
|
||||
* Section 2 *
|
||||
* Socket support *
|
||||
****************************************************/
|
||||
|
||||
/**
|
||||
* NOTES:
|
||||
* Socket APIs are required by source debugging feature.
|
||||
* If you don't need source debugging feature, then no
|
||||
* need to implement these APIs
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a socket
|
||||
*
|
||||
* @param sock [OUTPUT] the pointer of socket
|
||||
* @param tcp_or_udp 1 for tcp, 0 for udp
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_create(bh_socket_t *sock, int tcp_or_udp);
|
||||
|
||||
/**
|
||||
* Assign the address and port to the socket
|
||||
*
|
||||
* @param socket the socket to bind
|
||||
* @param addr the ip address, only IPv4 supported currently
|
||||
* @param port [INPUT/OUTPUT] the port number, if the value is 0,
|
||||
* it will use a port assigned by OS. On return it will
|
||||
* contain the actual bound port number
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_bind(bh_socket_t socket, const char *addr, int *port);
|
||||
|
||||
/**
|
||||
* Make the socket as a passive socket to accept incoming connection requests
|
||||
*
|
||||
* @param socket the socket to listen
|
||||
* @param max_client maximum clients
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_listen(bh_socket_t socket, int max_client);
|
||||
|
||||
/**
|
||||
* Accept an incoming connection
|
||||
*
|
||||
* @param server_sock the socket to accept new connections
|
||||
* @param sock [OUTPUT] the connected socket
|
||||
* @param addr [OUTPUT] the address of the peer socket. If addr is NULL,
|
||||
* nothing is filled in, and addrlen will not be used
|
||||
* @param addrlen [INPUT/OUTPUT] the size (in bytes) of the structure
|
||||
* pointed to by addr, on return it will contain the actual
|
||||
* size of the peer address
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
|
||||
unsigned int *addrlen);
|
||||
|
||||
/**
|
||||
* Blocking receive message from a socket.
|
||||
*
|
||||
* @param socket the socket to receive message from
|
||||
* @param buf the buffer to store the data
|
||||
* @param len length of the buffer, this API does not guarantee that
|
||||
* [len] bytes are received
|
||||
*
|
||||
* @return number of bytes received if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_recv(bh_socket_t socket, void *buf, unsigned int len);
|
||||
|
||||
/**
|
||||
* Blocking send message on a socket
|
||||
*
|
||||
* @param socket the socket to send message
|
||||
* @param buf the buffer of data to be sent
|
||||
* @param len length of the buffer
|
||||
*
|
||||
* @return number of bytes sent if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_send(bh_socket_t socket, const void *buf, unsigned int len);
|
||||
|
||||
/**
|
||||
* Close a socket
|
||||
*
|
||||
* @param socket the socket to be closed
|
||||
*
|
||||
* @return always return 0
|
||||
*/
|
||||
int
|
||||
os_socket_close(bh_socket_t socket);
|
||||
|
||||
/**
|
||||
* Shutdown a socket
|
||||
*
|
||||
* @param socket the socket to be shutdown
|
||||
*
|
||||
* @return always return 0
|
||||
*/
|
||||
int
|
||||
os_socket_shutdown(bh_socket_t socket);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -104,6 +104,25 @@ typedef int64_t int64;
|
||||
|
||||
typedef void *(*thread_start_routine_t)(void *);
|
||||
|
||||
#ifndef bh_socket_t
|
||||
/* If no socket defined on current platform,
|
||||
give a fake definition to make the compiler happy */
|
||||
#define bh_socket_t int
|
||||
#endif
|
||||
|
||||
/* Format specifiers macros in case
|
||||
they are not provided by compiler */
|
||||
#ifndef __PRI64_PREFIX
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
#define __PRI64_PREFIX "l"
|
||||
#define __PRIPTR_PREFIX "l"
|
||||
#else
|
||||
#define __PRI64_PREFIX "ll"
|
||||
#define __PRIPTR_PREFIX
|
||||
#endif
|
||||
#endif /* #ifndef __PRI64_PREFIX */
|
||||
|
||||
/* Macros for printing format specifiers */
|
||||
#ifndef PRId32
|
||||
#define PRId32 "d"
|
||||
#endif
|
||||
@ -120,16 +139,6 @@ typedef void *(*thread_start_routine_t)(void *);
|
||||
#define PRIX32 "X"
|
||||
#endif
|
||||
|
||||
#ifndef __PRI64_PREFIX
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
#define __PRI64_PREFIX "l"
|
||||
#define __PRIPTR_PREFIX "l"
|
||||
#else
|
||||
#define __PRI64_PREFIX "ll"
|
||||
#define __PRIPTR_PREFIX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef PRId64
|
||||
#define PRId64 __PRI64_PREFIX "d"
|
||||
#endif
|
||||
@ -142,10 +151,40 @@ typedef void *(*thread_start_routine_t)(void *);
|
||||
#ifndef PRIX64
|
||||
#define PRIX64 __PRI64_PREFIX "X"
|
||||
#endif
|
||||
#ifndef PRIxPTR
|
||||
#define PRIxPTR __PRIPTR_PREFIX "x"
|
||||
#endif
|
||||
#ifndef PRIXPTR
|
||||
#define PRIXPTR __PRIPTR_PREFIX "X"
|
||||
#endif
|
||||
|
||||
/* Macros for scanning format specifiers */
|
||||
#ifndef SCNd32
|
||||
#define SCNd32 "d"
|
||||
#endif
|
||||
#ifndef SCNi32
|
||||
#define SCNi32 "i"
|
||||
#endif
|
||||
#ifndef SCNu32
|
||||
#define SCNu32 "u"
|
||||
#endif
|
||||
#ifndef SCNx32
|
||||
#define SCNx32 "x"
|
||||
#endif
|
||||
|
||||
#ifndef SCNd64
|
||||
#define SCNd64 __PRI64_PREFIX "d"
|
||||
#endif
|
||||
#ifndef SCNu64
|
||||
#define SCNu64 __PRI64_PREFIX "u"
|
||||
#endif
|
||||
#ifndef SCNx64
|
||||
#define SCNx64 __PRI64_PREFIX "x"
|
||||
#endif
|
||||
#ifndef SCNxPTR
|
||||
#define SCNxPTR __PRIPTR_PREFIX "x"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -58,6 +58,8 @@ typedef pthread_t korp_thread;
|
||||
|
||||
#define os_thread_local_attribute __thread
|
||||
|
||||
#define bh_socket_t int
|
||||
|
||||
#if WASM_DISABLE_HW_BOUND_CHECK == 0
|
||||
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|
||||
|| defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
|
||||
|
||||
@ -11,15 +11,27 @@ os_thread_sys_init();
|
||||
void
|
||||
os_thread_sys_destroy();
|
||||
|
||||
int
|
||||
init_winsock();
|
||||
|
||||
void
|
||||
deinit_winsock();
|
||||
|
||||
int
|
||||
bh_platform_init()
|
||||
{
|
||||
if (init_winsock() != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return os_thread_sys_init();
|
||||
}
|
||||
|
||||
void
|
||||
bh_platform_destroy()
|
||||
{
|
||||
deinit_winsock();
|
||||
|
||||
os_thread_sys_destroy();
|
||||
}
|
||||
|
||||
|
||||
@ -26,6 +26,8 @@
|
||||
#include <malloc.h>
|
||||
#include <process.h>
|
||||
#include <Windows.h>
|
||||
#include <BaseTsd.h>
|
||||
#include <winsock2.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -35,12 +37,20 @@ extern "C" {
|
||||
#define BH_PLATFORM_WINDOWS
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX MAX_PATH
|
||||
#endif
|
||||
#endif /* #ifdef _MSC_VER */
|
||||
|
||||
/* Stack size of applet threads's native part. */
|
||||
#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024)
|
||||
|
||||
/* Default thread priority */
|
||||
#define BH_THREAD_DEFAULT_PRIORITY 0
|
||||
|
||||
typedef SSIZE_T ssize_t;
|
||||
|
||||
typedef void *korp_thread;
|
||||
typedef void *korp_tid;
|
||||
typedef void *korp_mutex;
|
||||
@ -53,6 +63,8 @@ typedef struct korp_cond {
|
||||
os_thread_wait_list thread_wait_list;
|
||||
} korp_cond;
|
||||
|
||||
#define bh_socket_t SOCKET
|
||||
|
||||
unsigned
|
||||
os_getpagesize();
|
||||
void *
|
||||
|
||||
140
core/shared/platform/windows/win_socket.c
Normal file
140
core/shared/platform/windows/win_socket.c
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "platform_api_vmcore.h"
|
||||
#include "platform_api_extension.h"
|
||||
|
||||
/* link with Ws2_32.lib */
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
static bool is_winsock_inited = false;
|
||||
|
||||
int
|
||||
init_winsock()
|
||||
{
|
||||
WSADATA wsaData;
|
||||
|
||||
if (!is_winsock_inited) {
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||||
os_printf("winsock init failed");
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
is_winsock_inited = true;
|
||||
}
|
||||
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
void
|
||||
deinit_winsock()
|
||||
{
|
||||
if (is_winsock_inited) {
|
||||
WSACleanup();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_create(bh_socket_t *sock, int tcp_or_udp)
|
||||
{
|
||||
if (!sock) {
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
if (1 == tcp_or_udp) {
|
||||
*sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
}
|
||||
else if (0 == tcp_or_udp) {
|
||||
*sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
}
|
||||
|
||||
return (*sock == -1) ? BHT_ERROR : BHT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_bind(bh_socket_t socket, const char *host, int *port)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
int socklen, ret;
|
||||
|
||||
assert(host);
|
||||
assert(port);
|
||||
|
||||
addr.sin_addr.s_addr = inet_addr(host);
|
||||
addr.sin_port = htons(*port);
|
||||
addr.sin_family = AF_INET;
|
||||
|
||||
ret = bind(socket, (struct sockaddr *)&addr, sizeof(addr));
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
socklen = sizeof(addr);
|
||||
if (getsockname(socket, (void *)&addr, &socklen) == -1) {
|
||||
os_printf("getsockname failed with error %d\n", WSAGetLastError());
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*port = ntohs(addr.sin_port);
|
||||
|
||||
return BHT_OK;
|
||||
|
||||
fail:
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_listen(bh_socket_t socket, int max_client)
|
||||
{
|
||||
if (listen(socket, max_client) != 0) {
|
||||
os_printf("socket listen failed with error %d\n", WSAGetLastError());
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
|
||||
unsigned int *addrlen)
|
||||
{
|
||||
struct sockaddr addr_tmp;
|
||||
unsigned int len = sizeof(struct sockaddr);
|
||||
|
||||
*sock = accept(server_sock, (struct sockaddr *)&addr_tmp, &len);
|
||||
|
||||
if (*sock < 0) {
|
||||
os_printf("socket accept failed with error %d\n", WSAGetLastError());
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
|
||||
{
|
||||
return recv(socket, buf, len, 0);
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
|
||||
{
|
||||
return send(socket, buf, len, 0);
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_close(bh_socket_t socket)
|
||||
{
|
||||
closesocket(socket);
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_shutdown(bh_socket_t socket)
|
||||
{
|
||||
shutdown(socket, SD_BOTH);
|
||||
return BHT_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user