[LibOS] Reorder argv in initial user stack

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. This commit reorders argv strings in the
initial user stack in this way.
This commit is contained in:
Yunjong Jeong
2019-10-17 03:02:06 -07:00
committed by Dmitrii Kuvaiskii
parent 560da76252
commit 5c3b6929df
2 changed files with 25 additions and 1 deletions
+11 -1
View File
@@ -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;
}
+14
View File
@@ -1,4 +1,5 @@
#include <stdio.h>
#include <string.h>
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;
}