From: Robert Pengelly Date: Mon, 16 Sep 2024 14:35:02 +0000 (+0100) Subject: Support MASM segments X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=6d9cd8ff9e955a89b83f3e5fdd0605b6b00a1f26;p=sasm.git Support MASM segments --- diff --git a/as.h b/as.h index d33151c..2431e45 100644 --- a/as.h +++ b/as.h @@ -20,6 +20,16 @@ struct proc { }; +struct segment { + + char *name, *old_section, *old_cpu; + int old_bits; + + char *filename; + unsigned long line_number; + +}; + #define AS_OUTPUT_OBJ 0x00 #define AS_OUTPUT_BIN 0x01 @@ -32,6 +42,8 @@ struct as_state { int model, data_size; struct vector procs; + struct vector segs; + char *ext; struct symbol *end_symbol; diff --git a/intel.c b/intel.c index 31644ec..45b6a6e 100644 --- a/intel.c +++ b/intel.c @@ -1524,13 +1524,119 @@ void machine_dependent_handle_proc (char *start, char **pp, char *name) { } -void machine_dependent_handle_endp (char *start, char **pp, char *name) { +void machine_dependent_handle_segment (char *start, char **pp, char *name) { + + struct segment *seg; + char *caret, *arg, saved_ch; + + seg = xmalloc (sizeof (*seg)); + seg->name = xstrdup (name); + + seg->filename = xstrdup (get_filename ()); + seg->line_number = get_line_number (); + + vec_push (&state->segs, (void *) seg); + + seg->old_bits = bits; + seg->old_section = xstrdup (section_get_name (current_section)); + + if (cpu_arch_name) { + + seg->old_cpu = xmalloc (strlen (cpu_arch_name) + 1); + strcpy (seg->old_cpu, cpu_arch_name); + + } + + if (cpu_extensions_name && strcmp (cpu_extensions_name, "")) { + + if (cpu_arch_name) { + + seg->old_cpu = xrealloc (seg->old_cpu, strlen (cpu_arch_name) + 1 + strlen (cpu_extensions_name) + 1); + sprintf (seg->old_cpu, "%s+%s", cpu_arch_name, cpu_extensions_name + 1); + + } else { + + seg->old_cpu = xmalloc (strlen (cpu_extensions_name) + 1); + strcpy (seg->old_cpu, cpu_extensions_name + 1); + + } + + } + + caret = (*pp = skip_whitespace (*pp)); + + while (!is_end_of_line[(int) *caret]) { + + if (**pp == '\'') { + + arg = ++(*pp); + + while (!is_end_of_line[(int) **pp] && **pp != '\'') { + (*pp)++; + } + + saved_ch = **pp; + **pp = '\0'; + + } else { + + arg = symname (pp); + saved_ch = 0; + + } + + if (!arg) { + break; + } + + if (xstrcasecmp (arg, "use16") == 0) { + + machine_dependent_set_march ("i8086+8087"); + bits = 16; + + } else if (xstrcasecmp (arg, "use32") == 0) { + + machine_dependent_set_march ("i386+387"); + bits = 32; + + } else if (xstrcasecmp (arg, "code")) { + section_set_by_name (".text"); + } else if (xstrcasecmp (arg, "data")) { + section_set_by_name (".data"); + } else if (xstrcasecmp (arg, "bss")) { + section_set_by_name (".bss"); + } else { + + **pp = saved_ch; + + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, start, caret, "invalid option passed to segment"); + ignore_rest_of_line (pp); + + return; + + } + + if (saved_ch) { **pp = saved_ch; }; + + if (**pp == '\'') { (*pp)++; } + caret = (*pp = skip_whitespace (*pp)); + + } + + if (!is_end_of_line[(int) **pp]) { + + report_at (get_filename (), get_line_number (), REPORT_ERROR, "invalid option passed to segment"); + ignore_rest_of_line (pp); + + } + +} + +void machine_dependent_handle_endp (char *start, char *name) { struct proc *proc; int last; - (void) pp; - if (state->procs.length == 0) { report_at (get_filename (), get_line_number (), REPORT_ERROR, "block nesting error"); @@ -1550,8 +1656,47 @@ void machine_dependent_handle_endp (char *start, char **pp, char *name) { free (proc->name); free (proc->filename); + free (vec_pop (&state->procs)); + +} + +void machine_dependent_handle_ends (char *start, char *name) { + + struct segment *seg; + int last; + + if (state->segs.length == 0) { + + report_at (get_filename (), get_line_number (), REPORT_ERROR, "block nesting error"); + return; + + } + + last = state->segs.length - 1; + seg = state->segs.data[last]; + + if (strcmp (seg->name, name)) { + + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, start, skip_whitespace (start), "segment name does not match"); + return; + + } + + section_set_by_name (seg->old_section); + free (seg->old_section); + + bits = seg->old_bits; + + if (seg->old_cpu) { + + machine_dependent_set_march (seg->old_cpu); + free (seg->old_cpu); + + } - vec_pop (&state->procs); + free (seg->name); + free (seg->filename); + free (vec_pop (&state->segs)); } diff --git a/process.c b/process.c index 8922628..2e329e4 100644 --- a/process.c +++ b/process.c @@ -1067,8 +1067,12 @@ static void handle_org (char *start, char **pp) { } extern void machine_dependent_assemble_line (char *start, char *line); + extern void machine_dependent_handle_proc (char *start, char **pp, char *name); -extern void machine_dependent_handle_endp (char *start, char **pp, char *name); +extern void machine_dependent_handle_endp (char *start, char *name); + +extern void machine_dependent_handle_segment (char *start, char **pp, char *name); +extern void machine_dependent_handle_ends (char *start, char *name); static char *find_end_of_line (char *line) { @@ -1148,6 +1152,15 @@ static void process_line (char *line, char *line_end) { } + if (xstrcasecmp (arg, "segment") == 0 || xstrcasecmp (arg, "ends") == 0) { + + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, start, caret, "segment must have a name"); + + ignore_rest_of_line (&line); + goto check; + + } + line = skip_whitespace (line); if ((poe = find_poe (arg))) { @@ -1247,7 +1260,25 @@ static void process_line (char *line, char *line_end) { if (xstrcasecmp (directive, "endp") == 0) { - machine_dependent_handle_endp (start, &line, arg); + machine_dependent_handle_endp (start, arg); + + free (directive); + goto check; + + } + + if (xstrcasecmp (directive, "segment") == 0) { + + machine_dependent_handle_segment (start, &line, arg); + + free (directive); + goto check; + + } + + if (xstrcasecmp (directive, "ends") == 0) { + + machine_dependent_handle_ends (start, arg); free (directive); goto check; @@ -1299,7 +1330,7 @@ void process_file (const char *ifile) { void *load_line_internal_data = NULL; struct cond *cond; - int cond_idx, proc_idx; + int cond_idx, proc_idx, seg_idx; struct hashtab_name *key; struct macro *m; @@ -1486,6 +1517,13 @@ void process_file (const char *ifile) { report_at (proc->filename, proc->line_number, REPORT_ERROR, "procedure %s is not closed", proc->name); } + + for (seg_idx = 0; seg_idx < state->segs.length; seg_idx++) { + + struct segment *seg = (struct segment *) state->segs.data[seg_idx]; + report_at (seg->filename, seg->line_number, REPORT_ERROR, "segment %s is not closed", seg->name); + + } }