make embedding wrapper executable less sensitive to argv[0]
Running a `starter`-based executable with an argv[0] different than the executable's path can make sense in various situations, but it doesn't work for finding code embedded in the enxecutable. On platforms where it's possible to get the current process's executable (not looking at you, OpenBSD), then use that instead of argv[0] for the purposes of loading embedded code. Related to #3685
This commit is contained in:
parent
4a06e4a1e3
commit
6f58ef5458
|
@ -201,6 +201,11 @@ flags:
|
|||
@racket[module-predefined?]. This option is normally embedded
|
||||
in a stand-alone binary that also embeds Racket code.}
|
||||
|
||||
@item{@FlagFirst{Y} @nonterm{file} @nonterm{n} @nonterm{m} @nonterm{p} :
|
||||
Like @Flag{k} @nonterm{n} @nonterm{m} @nonterm{p}, but reading
|
||||
from @nonterm{file} (without any adjustment on Mac OS or Windows
|
||||
for a segment or resource offset).}
|
||||
|
||||
@item{@FlagFirst{m} or @DFlagFirst{main} : Evaluates a call to
|
||||
@racketidfont{main} as bound in the top-level environment. All
|
||||
of the command-line arguments that are not processed as
|
||||
|
@ -473,7 +478,8 @@ Extra arguments following the last option are available from the
|
|||
@history[#:changed "6.90.0.17" @elem{Added @Flag{O}/@DFlag{stdout}.}
|
||||
#:changed "7.1.0.5" @elem{Added @Flag{M}/@DFlag{compile-any}.}
|
||||
#:changed "7.8.0.6" @elem{Added @Flag{Z}.}
|
||||
#:changed "8.0.0.10" @elem{Added @Flag{E}.}]
|
||||
#:changed "8.0.0.10" @elem{Added @Flag{E}.}
|
||||
#:changed "8.0.0.11" @elem{Added @Flag{Y}.}]
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -53,13 +53,13 @@ char *add_to_str(const char *addr, long amt)
|
|||
}
|
||||
#endif
|
||||
|
||||
static char *make_embedded_load(const char *start, const char *end)
|
||||
static char *make_embedded_load(const char *file, const char *start, const char *end)
|
||||
{
|
||||
char *s;
|
||||
int slen, elen;
|
||||
int slen, elen, flen;
|
||||
|
||||
#if defined(OS_X) || defined(DOS_FILE_SYSTEM)
|
||||
{
|
||||
if (file == NULL) {
|
||||
long fileoff;
|
||||
fileoff = get_segment_offset();
|
||||
start = add_to_str(start, fileoff);
|
||||
|
@ -67,12 +67,16 @@ static char *make_embedded_load(const char *start, const char *end)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!file) file = "";
|
||||
|
||||
slen = strlen(start);
|
||||
elen = strlen(end);
|
||||
flen = strlen(file);
|
||||
|
||||
s = (char *)malloc(slen + elen + 2);
|
||||
s = (char *)malloc(slen + elen + flen + 3);
|
||||
memcpy(s, start, slen + 1);
|
||||
memcpy(s + slen + 1, end, elen + 1);
|
||||
memcpy(s + slen + elen + 2, file, flen + 1);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -701,6 +705,7 @@ static int run_from_cmd_line(int argc, char *_argv[],
|
|||
int *eval_kind, num_enl;
|
||||
int no_more_switches = 0;
|
||||
int show_vers = 0;
|
||||
char *embedding_file;
|
||||
#endif
|
||||
#if !defined(DONT_RUN_REP) || !defined(DONT_PARSE_COMMAND_LINE)
|
||||
int use_repl = 0;
|
||||
|
@ -998,6 +1003,18 @@ static int run_from_cmd_line(int argc, char *_argv[],
|
|||
no_init_ns = 1;
|
||||
break;
|
||||
case 'k':
|
||||
case 'Y':
|
||||
if (*str == 'Y') {
|
||||
if (argc < 2) {
|
||||
PRINTF("%s: missing file name after %s switch\n",
|
||||
prog, real_switch);
|
||||
goto show_need_help;
|
||||
}
|
||||
argv++;
|
||||
--argc;
|
||||
embedding_file = argv[0];
|
||||
} else
|
||||
embedding_file = NULL;
|
||||
if (argc < 4) {
|
||||
PRINTF("%s: missing %s after %s switch\n",
|
||||
prog,
|
||||
|
@ -1007,12 +1024,12 @@ static int run_from_cmd_line(int argc, char *_argv[],
|
|||
}
|
||||
argv++;
|
||||
--argc;
|
||||
se = make_embedded_load(argv[0], argv[1]);
|
||||
se = make_embedded_load(embedding_file, argv[0], argv[1]);
|
||||
evals_and_loads[num_enl] = se;
|
||||
argv++;
|
||||
--argc;
|
||||
eval_kind[num_enl++] = mzcmd_EMBEDDED_REG;
|
||||
se = make_embedded_load(argv[0], argv[1]);
|
||||
se = make_embedded_load(embedding_file, argv[0], argv[1]);
|
||||
evals_and_loads[num_enl] = se;
|
||||
argv++;
|
||||
--argc;
|
||||
|
@ -1418,6 +1435,7 @@ static int run_from_cmd_line(int argc, char *_argv[],
|
|||
" -r <file>, --script <file> : Same as -f <file> -N <file> --\n"
|
||||
" -u <file>, --require-script <file> : Same as -t <file> -N <file> --\n"
|
||||
" -k <n> <m> <p> : Load executable-embedded code from offset <n> to <p>\n"
|
||||
" -Y <file> <n> <m> <p> : Like -k <n> <m> <p>, but from <file>\n"
|
||||
" -m, --main : Call `main' with command-line arguments, print results\n"
|
||||
" [*] Also `require's a `main' submodule, if any\n"
|
||||
" Interaction options:\n"
|
||||
|
|
|
@ -60,7 +60,7 @@ MZDYNDEP = ../mzdyn.o $(srcdir)/../include/ext.exp $(srcdir)/../include/racket.e
|
|||
dynexmpl.o: $(srcdir)/dynexmpl.c $(HEADERS)
|
||||
$(PLAIN_CC) $(ALL_CFLAGS) -c $(srcdir)/dynexmpl.c -o dynexmpl.o
|
||||
|
||||
../starter@NOT_MINGW@@EXE_SUFFIX@: $(srcdir)/../../start/ustart.c
|
||||
../starter@NOT_MINGW@@EXE_SUFFIX@: $(srcdir)/../../start/ustart.c $(srcdir)/../../start/unix_self.inc
|
||||
$(PLAIN_CC) $(ALL_CFLAGS) -o ../starter@EXE_SUFFIX@ $(srcdir)/../../start/ustart.c
|
||||
|
||||
PARSE_CMDL = $(srcdir)/../../start/parse_cmdl.inc
|
||||
|
|
|
@ -3756,15 +3756,28 @@ Scheme_Object *scheme_eval_string_multi_with_prompt(const char *str, Scheme_Env
|
|||
|
||||
void scheme_embedded_load(intptr_t len, const char *desc, int predefined)
|
||||
{
|
||||
Scheme_Object *s, *e, *a[4], *eload;
|
||||
Scheme_Object *s, *e, *f, *a[5], *eload;
|
||||
int argc = 4;
|
||||
eload = scheme_get_startup_export("embedded-load");
|
||||
if (len < 0) {
|
||||
/* description mode */
|
||||
/* description mode: string embeds start, end, and filename, where
|
||||
a 0-length filename means to find the executable via
|
||||
`(system-path 'exec-file)`. */
|
||||
int slen, elen, foff;
|
||||
slen = strlen(desc);
|
||||
elen = strlen(desc XFORM_OK_PLUS (slen + 1));
|
||||
foff = slen + 1 + elen + 1;
|
||||
s = scheme_make_utf8_string(desc);
|
||||
e = scheme_make_utf8_string(desc XFORM_OK_PLUS strlen(desc) XFORM_OK_PLUS 1);
|
||||
e = scheme_make_utf8_string(desc XFORM_OK_PLUS (slen + 1));
|
||||
if (desc[foff] != 0) {
|
||||
f = scheme_make_byte_string(desc XFORM_OK_PLUS foff);
|
||||
argc = 5;
|
||||
} else
|
||||
f = scheme_false;
|
||||
a[0] = s;
|
||||
a[1] = e;
|
||||
a[2] = scheme_false;
|
||||
a[4] = f;
|
||||
} else {
|
||||
/* content mode */
|
||||
a[0] = scheme_false;
|
||||
|
@ -3773,7 +3786,7 @@ void scheme_embedded_load(intptr_t len, const char *desc, int predefined)
|
|||
a[2] = s;
|
||||
}
|
||||
a[3] = (predefined ? scheme_true : scheme_false);
|
||||
(void)scheme_apply(eload, 4, a);
|
||||
(void)scheme_apply(eload, argc, a);
|
||||
}
|
||||
|
||||
int scheme_is_predefined_module_path(Scheme_Object *m)
|
||||
|
|
|
@ -421,7 +421,9 @@ DEF_COLLECTS_DIR@MINGW@ =
|
|||
DEF_CONFIG_DIR@MINGW@ =
|
||||
DEF_C_DIRS = $(DEF_COLLECTS_DIR) $(DEF_CONFIG_DIR)
|
||||
|
||||
MAIN_DEPS = $(srcdir)/main.c $(srcdir)/boot.h $(srcdir)/../../start/config.inc cs_config.h
|
||||
MAIN_DEPS = $(srcdir)/main.c $(srcdir)/boot.h cs_config.h \
|
||||
$(srcdir)/../../start/config.inc \
|
||||
$(srcdir)/../../start/unix_self.inc
|
||||
|
||||
main.o: $(MAIN_DEPS)
|
||||
$(CC) $(CFLAGS) $(DEF_C_DIRS) -c -o main.o $(srcdir)/main.c
|
||||
|
@ -432,7 +434,7 @@ grmain.o: $(srcdir)/grmain.c $(MAIN_DEPS) $(srcdir)/../../start/gui_filter.inc
|
|||
boot.o: $(srcdir)/boot.c $(srcdir)/../../rktio/rktio.inc $(srcdir)/boot.h
|
||||
$(CC) $(CFLAGS) -c -o boot.o $(srcdir)/boot.c
|
||||
|
||||
starter@NOT_MINGW@: $(srcdir)/../../start/ustart.c
|
||||
starter@NOT_MINGW@: $(srcdir)/../../start/ustart.c $(srcdir)/../../start/unix_self.inc
|
||||
$(CC) $(CFLAGS) -o starter $(srcdir)/../../start/ustart.c
|
||||
|
||||
|
||||
|
|
|
@ -57,30 +57,10 @@ PRESERVE_IN_EXECUTABLE
|
|||
char *boot_file_data = "BooT FilE OffsetS:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
||||
static int boot_file_offset = 18;
|
||||
|
||||
#define USE_GENERIC_GET_SELF_PATH
|
||||
#include "../../start/unix_self.inc"
|
||||
|
||||
#ifdef OS_X
|
||||
# include <mach-o/dyld.h>
|
||||
static char *get_self_path(char *exec_file)
|
||||
{
|
||||
char buf[1024], *s;
|
||||
uint32_t size = sizeof(buf);
|
||||
int r;
|
||||
|
||||
r = _NSGetExecutablePath(buf, &size);
|
||||
if (!r)
|
||||
return strdup(buf);
|
||||
else {
|
||||
s = malloc(size);
|
||||
r = _NSGetExecutablePath(s, &size);
|
||||
if (!r)
|
||||
return s;
|
||||
fprintf(stderr, "failed to get self\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
# undef USE_GENERIC_GET_SELF_PATH
|
||||
|
||||
static long find_rktboot_section(char *me)
|
||||
{
|
||||
const struct mach_header *mh;
|
||||
|
@ -147,68 +127,6 @@ static char *path_append(const char *p1, char *p2) {
|
|||
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
# include <errno.h>
|
||||
static char *get_self_path(char *exec_file)
|
||||
{
|
||||
char buf[256], *s = buf;
|
||||
ssize_t len, blen = sizeof(buf);
|
||||
|
||||
while (1) {
|
||||
len = readlink("/proc/self/exe", s, blen-1);
|
||||
if (len == (blen-1)) {
|
||||
if (s != buf) free(s);
|
||||
blen *= 2;
|
||||
s = malloc(blen);
|
||||
} else if (len < 0) {
|
||||
fprintf(stderr, "failed to get self (%d)\n", errno);
|
||||
exit(1);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
buf[len] = 0;
|
||||
return strdup(buf);
|
||||
}
|
||||
# undef USE_GENERIC_GET_SELF_PATH
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
# include <sys/sysctl.h>
|
||||
# include <errno.h>
|
||||
static char *get_self_path(char *exec_file)
|
||||
{
|
||||
int mib[4];
|
||||
char *s;
|
||||
size_t len;
|
||||
int r;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
#if defined(__NetBSD__)
|
||||
mib[1] = KERN_PROC_ARGS;
|
||||
mib[2] = getpid();
|
||||
mib[3] = KERN_PROC_PATHNAME;
|
||||
#else
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_PATHNAME;
|
||||
mib[3] = -1;
|
||||
#endif
|
||||
|
||||
r = sysctl(mib, 4, NULL, &len, NULL, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "failed to get self (%d)\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
s = malloc(len);
|
||||
r = sysctl(mib, 4, s, &len, NULL, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "failed to get self (%d)\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
# undef USE_GENERIC_GET_SELF_PATH
|
||||
#endif
|
||||
|
||||
#ifdef ELF_FIND_BOOT_SECTION
|
||||
# include <elf.h>
|
||||
# include <fcntl.h>
|
||||
|
@ -289,7 +207,7 @@ static int scheme_utf8_encode(unsigned int *path, int zero_offset, int len,
|
|||
#endif
|
||||
|
||||
#ifdef USE_GENERIC_GET_SELF_PATH
|
||||
/* Get executable path via argv[0] and the `PATH` encironment variable */
|
||||
/* Get executable path via argv[0] and the `PATH` environment variable */
|
||||
|
||||
static int has_slash(char *s)
|
||||
{
|
||||
|
|
|
@ -403,10 +403,13 @@
|
|||
(loop))))
|
||||
loads))
|
||||
(flags-loop rest-args (see saw 'non-config 'top)))]
|
||||
[("-k")
|
||||
(let*-values ([(n rest-args) (next-arg "starting and ending offsets" arg within-arg args)]
|
||||
[(m rest-args) (next-arg "first ending offset" arg within-arg (cons "-k" rest-args))]
|
||||
[(p rest-args) (next-arg "second ending offset" arg within-arg (cons "-k" rest-args))])
|
||||
[("-k" "-Y")
|
||||
(let*-values ([(f rest-args) (if (equal? arg "-Y")
|
||||
(next-arg "file" arg within-arg args)
|
||||
(values #f (cdr args)))]
|
||||
[(n rest-args) (next-arg "starting and ending offsets" arg within-arg (cons arg rest-args))]
|
||||
[(m rest-args) (next-arg "first ending offset" arg within-arg (cons arg rest-args))]
|
||||
[(p rest-args) (next-arg "second ending offset" arg within-arg (cons arg rest-args))])
|
||||
(let* ([add-segment-offset
|
||||
(lambda (s what)
|
||||
(let ([n (#%string->number s)])
|
||||
|
@ -419,9 +422,9 @@
|
|||
(set! loads
|
||||
(cons
|
||||
(lambda ()
|
||||
(set! embedded-load-in-places (cons (list #f n m #f) embedded-load-in-places))
|
||||
(embedded-load n m #f #t)
|
||||
(embedded-load m p #f #f))
|
||||
(set! embedded-load-in-places (cons (list f n m #f) embedded-load-in-places))
|
||||
(embedded-load n m #f #t f)
|
||||
(embedded-load m p #f #f f))
|
||||
loads)))
|
||||
(no-init! saw)
|
||||
(flags-loop rest-args (see saw 'non-config)))]
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
" -r <file>, --script <file> : Same as -f <file> -N <file> --\n"
|
||||
" -u <file>, --require-script <file> : Same as -t <file> -N <file> --\n"
|
||||
" -k <n> <m> <p> : Load executable-embedded code from offset <n> to <p>\n"
|
||||
" -Y <file> <n> <m> <p> : Like -k <n> <m> <p>, but from <file>\n"
|
||||
" -m, --main : Call `main' with command-line arguments, print results\n"
|
||||
" [*] Also `require's a `main' submodule, if any\n"
|
||||
" Interaction options:\n"
|
||||
|
@ -70,6 +71,7 @@
|
|||
" --cross-server <mach> <comp> <lib> : Drive cross-compiler (as only option)\n"
|
||||
" Meta options:\n"
|
||||
" -- : No argument following this switch is used as a switch\n"
|
||||
" -Z : Ignore the argument following this switch\n"
|
||||
" -h, --help : Show this information and exits, ignoring other options\n"
|
||||
"Default options:\n"
|
||||
" If only configuration options are provided, -i is added\n"
|
||||
|
|
86
racket/src/start/unix_self.inc
Normal file
86
racket/src/start/unix_self.inc
Normal file
|
@ -0,0 +1,86 @@
|
|||
#define USE_GENERIC_GET_SELF_PATH
|
||||
|
||||
#if defined(__linux__)
|
||||
# include <errno.h>
|
||||
static char *get_self_path(char *exec_file)
|
||||
{
|
||||
char buf[256], *s = buf;
|
||||
ssize_t len, blen = sizeof(buf);
|
||||
|
||||
while (1) {
|
||||
len = readlink("/proc/self/exe", s, blen-1);
|
||||
if (len == (blen-1)) {
|
||||
if (s != buf) free(s);
|
||||
blen *= 2;
|
||||
s = malloc(blen);
|
||||
} else if (len < 0) {
|
||||
fprintf(stderr, "failed to get self (%d)\n", errno);
|
||||
exit(1);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
buf[len] = 0;
|
||||
return strdup(buf);
|
||||
}
|
||||
# undef USE_GENERIC_GET_SELF_PATH
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
# include <sys/sysctl.h>
|
||||
# include <errno.h>
|
||||
static char *get_self_path(char *exec_file)
|
||||
{
|
||||
int mib[4];
|
||||
char *s;
|
||||
size_t len;
|
||||
int r;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
#if defined(__NetBSD__)
|
||||
mib[1] = KERN_PROC_ARGS;
|
||||
mib[2] = getpid();
|
||||
mib[3] = KERN_PROC_PATHNAME;
|
||||
#else
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_PATHNAME;
|
||||
mib[3] = -1;
|
||||
#endif
|
||||
|
||||
r = sysctl(mib, 4, NULL, &len, NULL, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "failed to get self (%d)\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
s = malloc(len);
|
||||
r = sysctl(mib, 4, s, &len, NULL, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "failed to get self (%d)\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
# undef USE_GENERIC_GET_SELF_PATH
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
# include <mach-o/dyld.h>
|
||||
static char *get_self_path(char *exec_file)
|
||||
{
|
||||
char buf[1024], *s;
|
||||
uint32_t size = sizeof(buf);
|
||||
int r;
|
||||
|
||||
r = _NSGetExecutablePath(buf, &size);
|
||||
if (!r)
|
||||
return strdup(buf);
|
||||
else {
|
||||
s = malloc(size);
|
||||
r = _NSGetExecutablePath(s, &size);
|
||||
if (!r)
|
||||
return s;
|
||||
fprintf(stderr, "failed to get self\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
# undef USE_GENERIC_GET_SELF_PATH
|
||||
#endif
|
|
@ -262,6 +262,20 @@ static char *next_string(char *s)
|
|||
return s + strlen(s) + 1;
|
||||
}
|
||||
|
||||
#include "unix_self.inc"
|
||||
|
||||
#ifdef USE_GENERIC_GET_SELF_PATH
|
||||
static char *adjust_self_reference(char *me)
|
||||
{
|
||||
return me;
|
||||
}
|
||||
#else
|
||||
static char *adjust_self_reference(char *me)
|
||||
{
|
||||
return get_self_path(me);
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef unsigned short ELF__Half;
|
||||
typedef unsigned int ELF__Word;
|
||||
typedef unsigned long ELF__Xword;
|
||||
|
@ -353,7 +367,7 @@ static int try_elf_section(const char *me, int *_start, int *_decl_end, int *_pr
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *me = argv[0], *data, **new_argv;
|
||||
char *me = argv[0], *embedding_me, *data, **new_argv;
|
||||
char *exe_path, *lib_path, *dll_path;
|
||||
int start, decl_end, prog_end, end, count, fd, v, en, x11;
|
||||
int argpos, inpos, collcount = 1, fix_argv;
|
||||
|
@ -434,6 +448,11 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
/* use `me` for `-k`, unless we have a way to more directly get the
|
||||
executable file that contains embedded code; if we do, then
|
||||
argv[0] doesn't have to match the executable */
|
||||
embedding_me = adjust_self_reference(me);
|
||||
|
||||
start = as_int(config + 8);
|
||||
decl_end = as_int(config + 12);
|
||||
prog_end = as_int(config + 16);
|
||||
|
@ -441,7 +460,7 @@ int main(int argc, char **argv)
|
|||
count = as_int(config + 24);
|
||||
x11 = as_int(config + 28);
|
||||
|
||||
fix_argv = try_elf_section(me, &start, &decl_end, &prog_end, &end);
|
||||
fix_argv = try_elf_section(embedding_me, &start, &decl_end, &prog_end, &end);
|
||||
|
||||
{
|
||||
int offset, len;
|
||||
|
@ -456,14 +475,14 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
data = (char *)malloc(end - prog_end);
|
||||
new_argv = (char **)malloc((count + argc + (2 * collcount) + 12) * sizeof(char*));
|
||||
new_argv = (char **)malloc((count + argc + (2 * collcount) + 13) * sizeof(char*));
|
||||
|
||||
fd = open(me, O_RDONLY, 0);
|
||||
fd = open(embedding_me, O_RDONLY, 0);
|
||||
lseek(fd, prog_end, SEEK_SET);
|
||||
{
|
||||
int expected_length = end - prog_end;
|
||||
if (expected_length != read(fd, data, expected_length)) {
|
||||
printf("read failed to read all %i bytes from file %s\n", expected_length, me);
|
||||
printf("read failed to read all %i bytes from file %s\n", expected_length, embedding_me);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
@ -548,9 +567,11 @@ int main(int argc, char **argv)
|
|||
new_argv[argpos++] = absolutize(_configdir + _configdir_offset, me);
|
||||
|
||||
if (fix_argv) {
|
||||
/* next three args are "-k" and numbers; fix
|
||||
the numbers to match start, decl_end, and prog_end */
|
||||
fix_argv = argpos + 1;
|
||||
/* next four args are "-k" and numbers; leave room to insert the
|
||||
filename in place of "-k", and fix the numbers to match start,
|
||||
decl_end, and prog_end */
|
||||
new_argv[argpos++] = "-Y";
|
||||
fix_argv = argpos;
|
||||
}
|
||||
|
||||
/* Add built-in flags: */
|
||||
|
@ -567,9 +588,10 @@ int main(int argc, char **argv)
|
|||
new_argv[argpos] = NULL;
|
||||
|
||||
if (fix_argv) {
|
||||
new_argv[fix_argv] = num_to_string(start);
|
||||
new_argv[fix_argv+1] = num_to_string(decl_end);
|
||||
new_argv[fix_argv+2] = num_to_string(prog_end);
|
||||
new_argv[fix_argv] = embedding_me;
|
||||
new_argv[fix_argv+1] = num_to_string(start);
|
||||
new_argv[fix_argv+2] = num_to_string(decl_end);
|
||||
new_argv[fix_argv+3] = num_to_string(prog_end);
|
||||
}
|
||||
|
||||
/* Execute the original binary: */
|
||||
|
|
Loading…
Reference in New Issue
Block a user