diff --git a/LibOS/shim/src/shim_init.c b/LibOS/shim/src/shim_init.c index 94cca41a..4139b58c 100644 --- a/LibOS/shim/src/shim_init.c +++ b/LibOS/shim/src/shim_init.c @@ -326,10 +326,20 @@ static int populate_user_stack (void * stack, size_t stack_size, new_argv = stack_bottom; while (argv) { + /* Even though the SysV ABI does not specify the order of argv strings, + some applications (notably Node.js's libuv) assume the compact + encoding of argv where (1) all strings are located adjacently and + (2) in increasing order. */ + int argv_size = 0; + for (const char ** a = argv ; *a ; a++) + argv_size += strlen(*a) + 1; + char * argv_bottom = ALLOCATE_TOP(argv_size); + for (const char ** a = argv ; *a ; a++) { const char ** t = ALLOCATE_BOTTOM(sizeof(const char *)); int len = strlen(*a) + 1; - char * abuf = ALLOCATE_TOP(len); + char * abuf = argv_bottom; + argv_bottom += len; memcpy(abuf, *a, len); *t = abuf; } diff --git a/LibOS/shim/test/regression/bootstrap.c b/LibOS/shim/test/regression/bootstrap.c index 7c479277..6689a3ca 100644 --- a/LibOS/shim/test/regression/bootstrap.c +++ b/LibOS/shim/test/regression/bootstrap.c @@ -1,4 +1,5 @@ #include +#include int main(int argc, const char** argv, const char** envp) { printf("User Program Started\n"); @@ -9,5 +10,18 @@ int main(int argc, const char** argv, const char** envp) { printf("argv[%d] = %s\n", i, argv[i]); } + /* Make sure argv strings follow the compact encoding where (1) all strings + are located adjacently and (2) in increasing order. */ + size_t sum_len = 0; + for (int i = 0; i < argc; i++) { + sum_len += strlen(argv[i]) + 1; + } + + size_t chunk_len = argv[argc - 1] + strlen(argv[argc - 1]) - argv[0]; + if (sum_len != chunk_len + 1) { + printf("argv strings are not adjacent or not in increasing order\n"); + return 1; + } + return 0; }