x86: Fix do_go_exec() - const argv[]

Commit 54841ab50c made the argv parameter
to do_go_exec() const but did not allow for the fact that argv[-1] is
set to point to the global data structure and relies on argv being non-
const.

With this patch, do_go_exec() creates a new copy of the argv array with
an extra element to store global data pointer rather than simply
clobbering an arbitrary memory location.
master
Graeme Russ 14 years ago
parent 93ceb4790d
commit e69c0cba8f
  1. 25
      arch/i386/lib/board.c

@ -431,15 +431,30 @@ void hang (void)
for (;;); for (;;);
} }
unsigned long do_go_exec (ulong (*entry)(int, char *[]), int argc, char * const argv[]) unsigned long do_go_exec (ulong (*entry)(int, char * const []), int argc, char * const argv[])
{ {
unsigned long ret = 0;
char **argv_tmp;
/* /*
* x86 does not use a dedicated register to pass the pointer * x86 does not use a dedicated register to pass the pointer to
* to the global_data * the global_data, so it is instead passed as argv[-1]. By using
* argv[-1], the called 'Application' can use the contents of
* argv natively. However, to safely use argv[-1] a new copy of
* argv is needed with the extra element
*/ */
argv[-1] = (char *)gd; argv_tmp = malloc(sizeof(char *) * (argc + 1));
if (argv_tmp) {
argv_tmp[0] = (char *)gd;
memcpy(&argv_tmp[1], argv, (size_t)(sizeof(char *) * argc));
ret = (entry) (argc, &argv_tmp[1]);
free(argv_tmp);
}
return (entry) (argc, argv); return ret;
} }
void setup_pcat_compatibility(void) void setup_pcat_compatibility(void)

Loading…
Cancel
Save