Implement XIP feature and enable ARC target support (#694)

Implement XIP (Execution In Place) feature for AOT mode to enable running the AOT code inside AOT file directly, without memory mapping the executable memory for AOT code and applying relocations for text section. Developer can use wamrc with "--enable-indirect-mode --disable-llvm-intrinsics" flags to generate the AOT file and run iwasm with "--xip" flag. Known issues: there might still be some relocations in the text section which access the ".rodata" like sections.

And also enable ARC target support for both interpreter mode and AOT mode.

Signed-off-by: Wenyong Huang <wenyong.huang@intel.com>
This commit is contained in:
Wenyong Huang
2021-08-12 17:44:39 +08:00
committed by GitHub
parent 8fd89bd415
commit db695fada4
44 changed files with 2613 additions and 263 deletions

View File

@ -32,29 +32,44 @@
#define REQUES_PACKET_VER 1
#define REQUEST_PACKET_FIX_PART_LEN 18
#define REQUEST_PACKET_URL_OFFSET REQUEST_PACKET_FIX_PART_LEN
#define REQUEST_PACKET_URL_LEN *((uint16*)( (char*) buffer + 12))) //!!! to ensure little endian
#define REQUEST_PACKET_PAYLOAD_LEN *((uint32*)( (char*) buffer + 14))) //!!! to ensure little endian
#define REQUEST_PACKET_URL_LEN *((uint16*)((char*) buffer + 12)) /* to ensure little endian */
#define REQUEST_PACKET_PAYLOAD_LEN *((uint32*)((char*) buffer + 14)) /* to ensure little endian */
#define REQUEST_PACKET_URL(buffer) ((char*) buffer + REQUEST_PACKET_URL_OFFSET)
#define REQUEST_PACKET_PAYLOAD(buffer) ((char*) buffer + REQUEST_PACKET_URL_OFFSET + REQUEST_PACKET_URL_LEN(buffer))
#define RESPONSE_PACKET_FIX_PART_LEN 16
char * pack_request(request_t *request, int * size)
char *
pack_request(request_t *request, int *size)
{
int url_len = strlen(request->url) + 1;
int len = REQUEST_PACKET_FIX_PART_LEN + url_len + request->payload_len;
char * packet = (char*) WA_MALLOC(len);
if (packet == NULL)
uint16 u16;
uint32 u32;
char *packet;
if ((packet = (char*) WA_MALLOC(len)) == NULL)
return NULL;
// TODO: ensure little endian for words and dwords
/* TODO: ensure little endian for words and dwords */
*packet = REQUES_PACKET_VER;
*((uint8*) (packet + 1)) = request->action;
*((uint16*) (packet + 2)) = htons(request->fmt);
*((uint32*) (packet + 4)) = htonl(request->mid);
*((uint32*) (packet + 8)) = htonl(request->sender);
*((uint16*) (packet + 12)) = htons(url_len);
*((uint32*) (packet + 14)) = htonl(request->payload_len);
u16 = htons(request->fmt);
memcpy(packet + 2, &u16, 2);
u32 = htonl(request->mid);
memcpy(packet + 4, &u32, 4);
u32 = htonl(request->sender);
memcpy(packet + 8, &u32, 4);
u16 = htons(url_len);
memcpy(packet + 12, &u16, 2);
u32 = htonl(request->payload_len);
memcpy(packet + 14, &u32, 4);
strcpy(packet + REQUEST_PACKET_URL_OFFSET, request->url);
memcpy(packet + REQUEST_PACKET_URL_OFFSET + url_len, request->payload,
request->payload_len);
@ -63,35 +78,53 @@ char * pack_request(request_t *request, int * size)
return packet;
}
void free_req_resp_packet(char * packet)
void
free_req_resp_packet(char *packet)
{
WA_FREE(packet);
}
request_t * unpack_request(char * packet, int size, request_t * request)
request_t *
unpack_request(char *packet, int size, request_t *request)
{
uint16 url_len, u16;
uint32 payload_len, u32;
if (*packet != REQUES_PACKET_VER) {
return NULL;
}
if (size < REQUEST_PACKET_FIX_PART_LEN) {
return NULL;
}
uint16 url_len = ntohs(*((uint16*) (packet + 12)));
uint32 payload_len = ntohl(*((uint32*) (packet + 14)));
if (size != ( REQUEST_PACKET_FIX_PART_LEN + url_len + payload_len)) {
memcpy(&u16, packet + 12, 2);
url_len = ntohs(u16);
memcpy(&u32, packet + 14, 4);
payload_len = ntohl(u32);
if (size != (REQUEST_PACKET_FIX_PART_LEN + url_len + payload_len)) {
return NULL;
}
if (*(packet + REQUEST_PACKET_FIX_PART_LEN + url_len - 1) != 0) {
return NULL;
}
request->action = *((uint8*) (packet + 1));
request->fmt = ntohs(*((uint16*) (packet + 2)));
request->mid = ntohl(*((uint32*) (packet + 4)));
request->sender = ntohl(*((uint32*) (packet + 8)));
memcpy(&u16, packet + 2, 2);
request->fmt = ntohs(u16);
memcpy(&u32, packet + 4, 4);
request->mid = ntohl(u32);
memcpy(&u32, packet + 8, 4);
request->sender = ntohl(u32);
request->payload_len = payload_len;
request->url = REQUEST_PACKET_URL(packet);
if (payload_len > 0)
request->payload = packet + REQUEST_PACKET_URL_OFFSET + url_len;
else
@ -100,20 +133,33 @@ request_t * unpack_request(char * packet, int size, request_t * request)
return request;
}
char * pack_response(response_t *response, int * size)
char *
pack_response(response_t *response, int *size)
{
int len = RESPONSE_PACKET_FIX_PART_LEN + response->payload_len;
char * packet = (char*) WA_MALLOC(len);
if (packet == NULL)
uint16 u16;
uint32 u32;
char *packet;
if ((packet = (char*) WA_MALLOC(len)) == NULL)
return NULL;
// TODO: ensure little endian for words and dwords
/* TODO: ensure little endian for words and dwords */
*packet = REQUES_PACKET_VER;
*((uint8*) (packet + 1)) = response->status;
*((uint16*) (packet + 2)) = htons(response->fmt);
*((uint32*) (packet + 4)) = htonl(response->mid);
*((uint32*) (packet + 8)) = htonl(response->reciever);
*((uint32*) (packet + 12)) = htonl(response->payload_len);
u16 = htons(response->fmt);
memcpy(packet + 2, &u16, 2);
u32 = htonl(response->mid);
memcpy(packet + 4, &u32, 4);
u32 = htonl(response->reciever);
memcpy(packet + 8, &u32, 4);
u32 = htonl(response->payload_len);
memcpy(packet + 12, &u32, 4);
memcpy(packet + RESPONSE_PACKET_FIX_PART_LEN, response->payload,
response->payload_len);
@ -121,20 +167,34 @@ char * pack_response(response_t *response, int * size)
return packet;
}
response_t * unpack_response(char * packet, int size, response_t * response)
response_t *
unpack_response(char *packet, int size, response_t *response)
{
uint16 u16;
uint32 payload_len, u32;
if (*packet != REQUES_PACKET_VER)
return NULL;
if (size < RESPONSE_PACKET_FIX_PART_LEN)
return NULL;
uint32 payload_len = ntohl(*((uint32*) (packet + 12)));
if (size != ( RESPONSE_PACKET_FIX_PART_LEN + payload_len))
memcpy(&u32, packet + 12, 4);
payload_len = ntohl(u32);
if (size != (RESPONSE_PACKET_FIX_PART_LEN + payload_len))
return NULL;
response->status = *((uint8*) (packet + 1));
response->fmt = ntohs(*((uint16*) (packet + 2)));
response->mid = ntohl(*((uint32*) (packet + 4)));
response->reciever = ntohl(*((uint32*) (packet + 8)));
memcpy(&u16, packet + 2, 2);
response->fmt = ntohs(u16);
memcpy(&u32, packet + 4, 4);
response->mid = ntohl(u32);
memcpy(&u32, packet + 8, 4);
response->reciever = ntohl(u32);
response->payload_len = payload_len;
if (payload_len > 0)
response->payload = packet + RESPONSE_PACKET_FIX_PART_LEN;
@ -144,7 +204,8 @@ response_t * unpack_response(char * packet, int size, response_t * response)
return response;
}
request_t *clone_request(request_t *request)
request_t *
clone_request(request_t *request)
{
/* deep clone */
request_t *req = (request_t *) WA_MALLOC(sizeof(request_t));
@ -164,12 +225,14 @@ request_t *clone_request(request_t *request)
req->payload_len = request->payload_len;
if (request->payload_len) {
req->payload = (char *) WA_MALLOC(request->payload_len);
req->payload = (char *)WA_MALLOC(request->payload_len);
if (!req->payload)
goto fail;
memcpy(req->payload, request->payload, request->payload_len);
} else {
// when payload_len is 0, the payload may be used for carrying some handle or integer
}
else {
/* when payload_len is 0, the payload may be used for
carrying some handle or integer */
req->payload = request->payload;
}
@ -180,7 +243,8 @@ fail:
return NULL;
}
void request_cleaner(request_t *request)
void
request_cleaner(request_t *request)
{
if (request->url != NULL)
WA_FREE(request->url);
@ -190,7 +254,8 @@ void request_cleaner(request_t *request)
WA_FREE(request);
}
void response_cleaner(response_t * response)
void
response_cleaner(response_t *response)
{
if (response->payload != NULL && response->payload_len > 0)
WA_FREE(response->payload);
@ -198,9 +263,11 @@ void response_cleaner(response_t * response)
WA_FREE(response);
}
response_t * clone_response(response_t * response)
response_t *
clone_response(response_t *response)
{
response_t *clone = (response_t *) WA_MALLOC(sizeof(response_t));
response_t *clone = (response_t *)WA_MALLOC(sizeof(response_t));
if (clone == NULL)
return NULL;
@ -215,8 +282,10 @@ response_t * clone_response(response_t * response)
if (!clone->payload)
goto fail;
memcpy(clone->payload, response->payload, response->payload_len);
} else {
// when payload_len is 0, the payload may be used for carrying some handle or integer
}
else {
/* when payload_len is 0, the payload may be used for
carrying some handle or integer */
clone->payload = response->payload;
}
return clone;
@ -226,8 +295,9 @@ fail:
return NULL;
}
response_t * set_response(response_t * response, int status, int fmt,
const char *payload, int payload_len)
response_t *
set_response(response_t *response, int status, int fmt,
const char *payload, int payload_len)
{
response->payload = (void *)payload;
response->payload_len = payload_len;
@ -236,8 +306,9 @@ response_t * set_response(response_t * response, int status, int fmt,
return response;
}
response_t * make_response_for_request(request_t * request,
response_t * response)
response_t *
make_response_for_request(request_t *request,
response_t *response)
{
response->mid = request->mid;
response->reciever = request->sender;
@ -245,10 +316,12 @@ response_t * make_response_for_request(request_t * request,
return response;
}
request_t * init_request(request_t * request, char *url, int action, int fmt,
void *payload, int payload_len)
static unsigned int mid = 0;
request_t *
init_request(request_t *request, char *url, int action, int fmt,
void *payload, int payload_len)
{
static unsigned int mid = 0;
request->url = url;
request->action = action;
request->fmt = fmt;
@ -269,7 +342,8 @@ request_t * init_request(request_t * request, char *url, int action, int fmt,
3. it ensure the leading_str "/abc" can pass "/abc?cde
*/
int check_url_start(const char* url, int url_len, const char * leading_str)
int
check_url_start(const char *url, int url_len, const char *leading_str)
{
int offset = 0;
if (*leading_str == '/')
@ -284,28 +358,27 @@ int check_url_start(const char* url, int url_len, const char * leading_str)
if (len == 0)
return 0;
// ensure leading_str not end with "/"
/* ensure leading_str not end with "/" */
if (leading_str[len - 1] == '/') {
len--;
if (len == 0)
return 0;
}
// equal length
/* equal length */
if (url_len == len) {
if (memcmp(url, leading_str, url_len) == 0) {
return (offset + len);
} else {
}
else {
return 0;
}
}
if (url_len < len)
return 0;
else if (memcmp(url, leading_str, len) != 0)
return 0;
else if (url[len] != '/' && url[len] != '?')
return 0;
else
@ -318,7 +391,8 @@ int check_url_start(const char* url, int url_len, const char * leading_str)
// * sample 3: /abcd*, match any url started with "/abcd"
// * sample 4: /abcd/*, exclude "/abcd"
bool match_url(char * pattern, char * matched)
bool
match_url(char *pattern, char *matched)
{
if (*pattern == '/')
pattern++;
@ -352,17 +426,19 @@ bool match_url(char * pattern, char * matched)
return false;
} else if (pattern[len - 1] == '*') {
}
else if (pattern[len - 1] == '*') {
if (pattern[len - 2] == '/') {
if (strncmp(pattern, matched, len - 1) == 0)
return true;
else
return false;
} else {
}
else {
return (strncmp(pattern, matched, len - 1) == 0);
}
} else {
}
else {
return (strcmp(pattern, matched) == 0);
}
}
@ -371,10 +447,11 @@ bool match_url(char * pattern, char * matched)
* get the value of the key from following format buffer:
* key1=value1;key2=value2;key3=value3
*/
char * find_key_value(char * buffer, int buffer_len, char * key, char * value,
int value_len, char delimiter)
char *
find_key_value(char *buffer, int buffer_len, char *key, char *value,
int value_len, char delimiter)
{
char * p = buffer;
char *p = buffer;
int remaining = buffer_len;
int key_len = strlen(key);
@ -387,13 +464,13 @@ char * find_key_value(char * buffer, int buffer_len, char * key, char * value,
if (remaining <= key_len)
return NULL;
// find the key
/* find the key */
if (0 == strncmp(p, key, key_len) && p[key_len] == '=') {
p += (key_len + 1);
remaining -= (key_len + 1);
char * v = value;
memset(value, 0, value_len);
value_len--; // ensure last char is 0
value_len--; /* ensure last char is 0 */
while (*p != delimiter && remaining > 0 && value_len > 0) {
*v++ = *p++;
remaining--;
@ -402,7 +479,7 @@ char * find_key_value(char * buffer, int buffer_len, char * key, char * value,
return value;
}
// goto next key
/* goto next key */
while (*p != delimiter && remaining > 0) {
p++;
remaining--;