#define LD_OPTION_IGNORED 0
#define LD_OPTION_EMIT_RELOCS 1
-#define LD_OPTION_ENTRY 2
-#define LD_OPTION_FORMAT 3
-#define LD_OPTION_GENERATE_SYMBOLS_TABLE 4
-#define LD_OPTION_HELP 5
-#define LD_OPTION_IMAGE_BASE 6
-#define LD_OPTION_MAP 7
-#define LD_OPTION_MAP_FILE 8
-#define LD_OPTION_OUTFILE 9
+#define LD_OPTION_EMULATION 2
+#define LD_OPTION_ENTRY 3
+#define LD_OPTION_FORMAT 4
+#define LD_OPTION_GENERATE_SYMBOLS_TABLE 5
+#define LD_OPTION_HELP 6
+#define LD_OPTION_IMAGE_BASE 7
+#define LD_OPTION_MAP 8
+#define LD_OPTION_MAP_FILE 9
+#define LD_OPTION_OUTFILE 10
static struct ld_option opts[] = {
{ "-N", LD_OPTION_IGNORED, LD_OPTION_NO_ARG },
{ "-e", LD_OPTION_ENTRY, LD_OPTION_HAS_ARG },
+ { "-m", LD_OPTION_EMULATION, LD_OPTION_HAS_ARG },
{ "-o", LD_OPTION_OUTFILE, LD_OPTION_HAS_ARG },
{ "-s", LD_OPTION_IGNORED, LD_OPTION_NO_ARG },
{ "-q", LD_OPTION_EMIT_RELOCS, LD_OPTION_NO_ARG },
fprintf (stderr, "Options:\n\n");
fprintf (stderr, " -e ADDRESS, --entry ADDRESS Set start address.\n");
+ fprintf (stderr, " -m EMULATION Set emulation. (default none)\n");
+ fprintf (stderr, " Supported emualtions are:\n");
+ fprintf (stderr, " i386aout, i386coff, i386elks, i386pe\n");
+ fprintf (stderr, " ia16_elks, ia16_mz\n");
fprintf (stderr, " -q, --emit-relocs Generate relocations in final output.\n");
fprintf (stderr, " -s, --strip-all Ignored.\n");
fprintf (stderr, " --generate-symbols-table Generate a symbols table from global symbols.\n");
fprintf (stderr, " --help Print option help.\n");
- fprintf (stderr, " --oformat FORMAT Specify the format of output file (default msdos)\n");
+ fprintf (stderr, " --oformat FORMAT Specify the format of output file (default msdos).\n");
fprintf (stderr, " Supported formats are:\n");
fprintf (stderr, " a.out-i386, elks-ia16, elks-i386, pe-i386\n");
fprintf (stderr, " binary, msdos\n");
}
+ case LD_OPTION_EMULATION: {
+
+ if (xstrcasecmp (optarg, "ia16_elks") == 0) {
+
+ state->emulation = LD_EMULATION_IA16_ELKS;
+ break;
+
+ }
+
+ if (xstrcasecmp (optarg, "ia16_mz") == 0) {
+
+ state->emulation = LD_EMULATION_IA16_MZ;
+ break;
+
+ }
+
+ if (xstrcasecmp (optarg, "i386aout") == 0) {
+
+ state->emulation = LD_EMULATION_I386_AOUT;
+ break;
+
+ }
+
+ if (xstrcasecmp (optarg, "i386coff") == 0) {
+
+ state->emulation = LD_EMULATION_I386_COFF;
+ break;
+
+ }
+
+ if (xstrcasecmp (optarg, "i386elks") == 0) {
+
+ state->emulation = LD_EMULATION_I386_ELKS;
+ break;
+
+ }
+
+ if (xstrcasecmp (optarg, "i386pe") == 0) {
+
+ state->emulation = LD_EMULATION_I386_PE;
+ break;
+
+ }
+
+ report_at (program_name, 0, REPORT_ERROR, "unrecognised emulation mode '%s'", optarg);
+ exit (EXIT_FAILURE);
+
+ }
+
case LD_OPTION_ENTRY: {
char *p;
if (xstrcasecmp (optarg, "msdos-mz") == 0) {
state->format = LD_FORMAT_MZ;
+
+ if (state->emulation == LD_EMULATION_NONE) {
+ state->emulation = LD_EMULATION_IA16_MZ;
+ }
+
break;
}
if (xstrcasecmp (optarg, "elks-ia16") == 0) {
state->format = LD_FORMAT_IA16_ELKS;
+
+ if (state->emulation == LD_EMULATION_NONE) {
+ state->emulation = LD_EMULATION_IA16_ELKS;
+ }
+
break;
}
if (xstrcasecmp (optarg, "elks-i386") == 0) {
state->format = LD_FORMAT_I386_ELKS;
+
+ if (state->emulation == LD_EMULATION_NONE) {
+ state->emulation = LD_EMULATION_I386_ELKS;
+ }
+
break;
}
if (xstrcasecmp (optarg, "a.out-i386") == 0) {
state->format = LD_FORMAT_I386_AOUT;
+
+ if (state->emulation == LD_EMULATION_NONE) {
+ state->emulation = LD_EMULATION_I386_AOUT;
+ }
+
break;
}
if (xstrcasecmp (optarg, "pe-i386") == 0) {
state->format = LD_FORMAT_I386_PE;
+
+ if (state->emulation == LD_EMULATION_NONE) {
+ state->emulation = LD_EMULATION_I386_PE;
+ }
+
break;
}
if (xstrcasecmp (optarg, "coff-i386") == 0) {
state->format = LD_FORMAT_I386_COFF;
+
+ if (state->emulation == LD_EMULATION_NONE) {
+ state->emulation = LD_EMULATION_I386_COFF;
+ }
+
break;
}
}
- options_with_use = &fmt_tbl[state->format];
-
- if (options_with_use->check_option && options_with_use->use_option) {
+ if (state->emulation != LD_EMULATION_NONE) {
- int idx;
+ options_with_use = &fmt_tbl[state->emulation - 1];
- if ((idx = options_with_use->check_option (r, argc, argv, &optind, &optarg)) >= 0) {
+ if (options_with_use->check_option && options_with_use->use_option) {
- options_with_use->use_option (r, idx, optarg);
- continue;
+ int idx;
+
+ if ((idx = options_with_use->check_option (r, argc, argv, &optind, &optarg)) >= 0) {
+
+ options_with_use->use_option (r, idx, optarg);
+ continue;
+
+ }
}
/*printf ("%lx\n", n_type);*/
- if (state->format == LD_FORMAT_MZ || state->format == LD_FORMAT_IA16_ELKS) {
+ if (state->emulation == LD_EMULATION_IA16_ELKS || state->format == LD_EMULATION_IA16_MZ) {
if (opcode == 0x9A || opcode == 0xFF || rel->n_type == 4) {
}
- value = 0;
-
- if ((symbol = symbol_find ("DGROUP")) && symbol_is_undefined (symbol)) {
+ if (state->emulation == LD_EMULATION_IA16_ELKS || state->format == LD_EMULATION_IA16_MZ) {
- if ((section = section_find (".data"))) {
- value += align_section_if_needed (section->rva);
- } else if ((section = section_find (".bss"))) {
- value += align_section_if_needed (section->rva);
- }
+ value = 0;
- dgroup_start = value;
- has_dgroup = 1;
+ if ((symbol = symbol_find ("DGROUP")) && symbol_is_undefined (symbol)) {
- of = object_file_make (FAKE_LD_FILENAME, 1);
-
- symbol = of->symbol_arr;
- symbol->name = xstrdup ("DGROUP");
-
- symbol->section_number = ABSOLUTE_SECTION_NUMBER;
- symbol->value = value / 16;
+ if ((section = section_find (".data"))) {
+ value += align_section_if_needed (section->rva);
+ } else if ((section = section_find (".bss"))) {
+ value += align_section_if_needed (section->rva);
+ }
+
+ dgroup_start = value;
+ has_dgroup = 1;
+
+ of = object_file_make (FAKE_LD_FILENAME, 1);
+
+ symbol = of->symbol_arr;
+ symbol->name = xstrdup ("DGROUP");
+
+ symbol->section_number = ABSOLUTE_SECTION_NUMBER;
+ symbol->value = value / 16;
+
+ symbol_record_external_symbol (symbol);
- symbol_record_external_symbol (symbol);
-
- }
-
- value = 0;
-
- if ((symbol = symbol_find ("DGROUP__edata")) && symbol_is_undefined (symbol)) {
-
- if ((section = section_find (".data"))) {
- value += align_section_if_needed (section->rva + section->total_size);
}
- of = object_file_make (FAKE_LD_FILENAME, 1);
- value -= (dgroup_start & 0xfffffff0);
+ value = 0;
- symbol = of->symbol_arr;
- symbol->name = xstrdup ("DGROUP__edata");
+ if ((symbol = symbol_find ("DGROUP__edata")) && symbol_is_undefined (symbol)) {
- symbol->section_number = ABSOLUTE_SECTION_NUMBER;
- symbol->value = value;
+ if ((section = section_find (".data"))) {
+ value += align_section_if_needed (section->rva + section->total_size);
+ }
+
+ of = object_file_make (FAKE_LD_FILENAME, 1);
+ value -= (dgroup_start & 0xfffffff0);
+
+ symbol = of->symbol_arr;
+ symbol->name = xstrdup ("DGROUP__edata");
+
+ symbol->section_number = ABSOLUTE_SECTION_NUMBER;
+ symbol->value = value;
+
+ symbol_record_external_symbol (symbol);
- symbol_record_external_symbol (symbol);
-
- }
-
- value = 0;
-
- if ((symbol = symbol_find ("DGROUP__end")) && symbol_is_undefined (symbol)) {
-
- if ((section = section_find (".bss"))) {
- value += align_section_if_needed (section->rva + section->total_size);
- } else if ((section = section_find (".data"))) {
- value += align_section_if_needed (section->rva + section->total_size);
}
- of = object_file_make (FAKE_LD_FILENAME, 1);
- value -= (dgroup_start & 0xfffffff0);
+ value = 0;
- symbol = of->symbol_arr;
- symbol->name = xstrdup ("DGROUP__end");
+ if ((symbol = symbol_find ("DGROUP__end")) && symbol_is_undefined (symbol)) {
- symbol->section_number = ABSOLUTE_SECTION_NUMBER;
- symbol->value = value;
+ if ((section = section_find (".bss"))) {
+ value += align_section_if_needed (section->rva + section->total_size);
+ } else if ((section = section_find (".data"))) {
+ value += align_section_if_needed (section->rva + section->total_size);
+ }
+
+ of = object_file_make (FAKE_LD_FILENAME, 1);
+ value -= (dgroup_start & 0xfffffff0);
+
+ symbol = of->symbol_arr;
+ symbol->name = xstrdup ("DGROUP__end");
+
+ symbol->section_number = ABSOLUTE_SECTION_NUMBER;
+ symbol->value = value;
+
+ symbol_record_external_symbol (symbol);
- symbol_record_external_symbol (symbol);
+ }
}