From 332315fba92d38c1c1edb0b34320d8cd7a2abb52 Mon Sep 17 00:00:00 2001 From: Robert Pengelly Date: Thu, 17 Apr 2025 08:09:31 +0100 Subject: [PATCH] Allow MZ stack to be set using command line --- lib.c | 34 +++++++++++++------ mz.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- mz.h | 7 +++- 3 files changed, 132 insertions(+), 14 deletions(-) diff --git a/lib.c b/lib.c index 7edc8bc..fcb1971 100644 --- a/lib.c +++ b/lib.c @@ -10,24 +10,27 @@ #include "ld.h" #include "lib.h" +#include "mz.h" #include "pe.h" #include "report.h" struct options_with_use { + void (*print_help) (void); + int (*check_option) (const char *cmd_arg, int argc, char **argv, int *optind, const char **optarg); void (*use_option) (const char *cmd_arg, int idx, const char *optarg); }; -static struct options_with_use fmt_tbl[] = { +static struct options_with_use emulation_table[] = { - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { &pe_check_option, &pe_use_option } + { 0, 0, 0 }, + { &mz_print_help, &mz_check_option, &mz_use_option }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { &pe_print_help, &pe_check_option, &pe_use_option } }; @@ -77,6 +80,8 @@ static void print_usage (void) { if (program_name) { + struct options_with_use *options_with_use; + fprintf (stderr, "Usage: %s [options] file...\n\n", program_name); fprintf (stderr, "Options:\n\n"); @@ -107,8 +112,17 @@ static void print_usage (void) { fprintf (stderr, " --image-base
Set base address of the executable.\n"); fprintf (stderr, "\n"); - pe_print_help (); - fprintf (stderr, "\n"); + + for (options_with_use = emulation_table; ; options_with_use++) { + + if (options_with_use->print_help) { + + options_with_use->print_help (); + fprintf (stderr, "\n"); + + } + + } } @@ -571,7 +585,7 @@ void parse_args (int argc, char **argv, int optind) { if (state->emulation != LD_EMULATION_NONE) { - options_with_use = &fmt_tbl[state->emulation - 1]; + options_with_use = &emulation_table[state->emulation - 1]; if (options_with_use->check_option && options_with_use->use_option) { diff --git a/mz.c b/mz.c index e9e43f1..b849a69 100644 --- a/mz.c +++ b/mz.c @@ -1,6 +1,8 @@ /****************************************************************************** * @file mz.c *****************************************************************************/ +#include +#include #include #include #include @@ -13,6 +15,105 @@ #include "symbol.h" #include "write7x.h" +unsigned long stack_size = 0x1000; +#define LD_OPTION_STACK 1 + +static struct ld_option opts[] = { + + { "--stack", LD_OPTION_STACK, LD_OPTION_HAS_ARG }, + { 0, 0, 0 } + +}; + +int mz_check_option (const char *cmd_arg, int argc, char **argv, int *optind, const char **optarg) { + + struct ld_option *popt; + + for (popt = opts; ; popt++) { + + const char *p1 = popt->name; + const char *r1 = cmd_arg; + + if (!p1) { + break; + } + + if (!strstart (p1, &r1)) { + continue; + } + + (*optarg) = r1; + + if (popt->flgs & LD_OPTION_HAS_ARG) { + + if (*r1 == '\0') { + + if ((*optind) >= argc) { + + report_at (program_name, 0, REPORT_ERROR, "argument to '%s' is missing", cmd_arg); + exit (EXIT_FAILURE); + + } + + (*optarg) = argv[(*optind)++]; + + } + + } else if (*r1 != '\0') { + continue; + } + + return popt->idx; + + } + + return -1; + +} + +void mz_use_option (const char *cmd_arg, int idx, const char *optarg) { + + switch (idx) { + + case LD_OPTION_STACK: { + + long conversion; + char *temp; + + errno = 0; + conversion = strtol (optarg, &temp, 0); + + if (!*optarg || isspace ((int) *optarg) || errno || *temp) { + + report_at (program_name, 0, REPORT_ERROR, "invalid stack number '%s'", optarg); + exit (EXIT_FAILURE); + + } + + stack_size = (unsigned long) conversion; + break; + + } + + default: { + + report_at (program_name, 0, REPORT_ERROR, "unsupported option '%s'", cmd_arg); + exit (EXIT_FAILURE); + + } + + } + +} + +void mz_print_help (void) { + + fprintf (stderr, "ia16_mz:\n\n"); + fprintf (stderr, " --stack Set size of the initial stack.\n"); + +} + + static unsigned long section_get_num_relocs (struct section *section) { unsigned long num_relocs = 0, i; @@ -78,8 +179,7 @@ void mz_write (const char *filename) { unsigned long header_size; unsigned long reloc_size = 0, reloc_count = 0; - unsigned long ibss_addr = 0, ibss_size = 0; - unsigned long stack_addr = 0, stack_size = 0; + unsigned long stack_addr = 0, ibss_addr = 0, ibss_size = 0; struct mz_exec exec; memset (&exec, 0, sizeof (exec)); @@ -132,7 +232,6 @@ void mz_write (const char *filename) { } stack_addr = ALIGN (ibss_addr + ibss_size, 16); - stack_size = 0x2000; /* Maybe get this from command line in the future. */ exec.e_magic[0] = 'M'; diff --git a/mz.h b/mz.h index 309a10b..dbf2fa5 100644 --- a/mz.h +++ b/mz.h @@ -1,5 +1,5 @@ /****************************************************************************** - * @file pe.h + * @file mz.h *****************************************************************************/ #ifndef _MZ_H #define _MZ_H @@ -26,6 +26,11 @@ struct mz_exec { }; +int mz_check_option (const char *cmd_arg, int argc, char **argv, int *optind, const char **optarg); + +void mz_print_help (void); +void mz_use_option (const char *cmd_arg, int idx, const char *optarg); + void mz_write (const char *filename); #endif /* _MZ_H */ -- 2.34.1