passing argc, argv and envp to main()
This commit is contained in:
@@ -191,12 +191,88 @@ void print_desc(struct program_load_desc *desc)
|
||||
|
||||
unsigned long dma_buf_pa;
|
||||
|
||||
|
||||
void print_flat(char *flat)
|
||||
{
|
||||
char **string;
|
||||
|
||||
printf("counter: %d\n", *((int *)flat));
|
||||
|
||||
string = (char **)(flat + sizeof(int));
|
||||
while (*string) {
|
||||
|
||||
printf("%s\n", (flat + (unsigned long)(*string)));
|
||||
|
||||
++string;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Flatten out a (char **) string array into the following format:
|
||||
* [nr_strings][char *offset of string_0]...[char *offset of string_n-1][NULL][string0]...[stringn_1]
|
||||
* if nr_strings == -1, we assume the last item is NULL
|
||||
*
|
||||
* NOTE: copy this string somewhere, add the address of the string to each offset
|
||||
* and we get back a valid argv or envp array.
|
||||
*
|
||||
* returns the total length of the flat string and updates flat to
|
||||
* point to the beginning.
|
||||
*/
|
||||
int flatten_strings(int nr_strings, char **strings, char **flat)
|
||||
{
|
||||
int full_len, string_i;
|
||||
unsigned int flat_offset;
|
||||
char *string;
|
||||
char *_flat;
|
||||
|
||||
/* How many strings do we have? */
|
||||
if (nr_strings == -1) {
|
||||
for (nr_strings = 0; strings[nr_strings]; ++nr_strings);
|
||||
}
|
||||
|
||||
/* Count full length */
|
||||
full_len = sizeof(int) + sizeof(char *); // Counter and terminating NULL
|
||||
for (string_i = 0; string_i < nr_strings; ++string_i) {
|
||||
// Pointer + actual value
|
||||
full_len += sizeof(char *) + strlen(strings[string_i]) + 1;
|
||||
}
|
||||
|
||||
_flat = (char *)malloc(full_len);
|
||||
if (!_flat) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(_flat, 0, full_len);
|
||||
|
||||
/* Number of strings */
|
||||
*((int*)_flat) = nr_strings;
|
||||
|
||||
// Actual offset
|
||||
flat_offset = sizeof(int) + sizeof(char *) * (nr_strings + 1);
|
||||
|
||||
for (string_i = 0; string_i < nr_strings; ++string_i) {
|
||||
|
||||
/* Fabricate the string */
|
||||
*((char **)(_flat + sizeof(int) + string_i * sizeof(char *))) = (void *)flat_offset;
|
||||
memcpy(_flat + flat_offset, strings[string_i], strlen(strings[string_i]) + 1);
|
||||
flat_offset += strlen(strings[string_i]) + 1;
|
||||
|
||||
}
|
||||
|
||||
*flat = _flat;
|
||||
return full_len;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int fd, fdm;
|
||||
FILE *fp;
|
||||
struct program_load_desc *desc;
|
||||
long r;
|
||||
char *envs;
|
||||
char *args;
|
||||
int len;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s (program) [args...]\n",
|
||||
@@ -217,6 +293,14 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
__dprintf("# of sections: %d\n", desc->num_sections);
|
||||
|
||||
desc->envs_len = flatten_strings(-1, environ, &envs);
|
||||
desc->envs = envs;
|
||||
//print_flat(envs);
|
||||
|
||||
desc->args_len = flatten_strings(-1, argv + 1, &args);
|
||||
desc->args = args;
|
||||
//print_flat(args);
|
||||
|
||||
fd = open("/dev/mcos0", O_RDWR);
|
||||
if (fd < 0) {
|
||||
|
||||
@@ -31,6 +31,10 @@ struct program_load_desc {
|
||||
int pid;
|
||||
unsigned long entry;
|
||||
unsigned long rprocess;
|
||||
char *args;
|
||||
unsigned long args_len;
|
||||
char *envs;
|
||||
unsigned long envs_len;
|
||||
struct program_image_section sections[0];
|
||||
};
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ static long mcexec_prepare_image(aal_os_t os,
|
||||
{
|
||||
struct program_load_desc desc, *pdesc;
|
||||
struct ikc_scd_packet isp;
|
||||
void *args, *envs;
|
||||
|
||||
if (copy_from_user(&desc, udesc,
|
||||
sizeof(struct program_load_desc))) {
|
||||
@@ -46,6 +47,28 @@ static long mcexec_prepare_image(aal_os_t os,
|
||||
|
||||
pdesc->pid = task_tgid_vnr(current);
|
||||
|
||||
args = kmalloc(pdesc->args_len, GFP_KERNEL);
|
||||
if (copy_from_user(args, pdesc->args, pdesc->args_len)) {
|
||||
kfree(args);
|
||||
kfree(pdesc);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
envs = kmalloc(pdesc->envs_len, GFP_KERNEL);
|
||||
if (copy_from_user(envs, pdesc->envs, pdesc->envs_len)) {
|
||||
kfree(envs);
|
||||
kfree(args);
|
||||
kfree(pdesc);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
pdesc->args = virt_to_phys(args);
|
||||
printk("args: 0x%lX\n", pdesc->args);
|
||||
printk("argc: %d\n", *(int*)args);
|
||||
pdesc->envs = virt_to_phys(envs);
|
||||
printk("envs: 0x%lX\n", pdesc->envs);
|
||||
printk("envc: %d\n", *(int*)envs);
|
||||
|
||||
isp.msg = SCD_MSG_PREPARE_PROCESS;
|
||||
isp.ref = pdesc->cpu;
|
||||
isp.arg = virt_to_phys(pdesc);
|
||||
@@ -62,6 +85,8 @@ static long mcexec_prepare_image(aal_os_t os,
|
||||
sizeof(struct program_image_section) * desc.num_sections);
|
||||
|
||||
kfree(pdesc);
|
||||
kfree(envs);
|
||||
kfree(args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user