This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH]: Support control of ELF ABI flags in gas HC11/HC12
- From: Stephane Carrez <stcarrez at nerim dot fr>
- To: binutils at sources dot redhat dot com
- Date: Wed, 14 Aug 2002 01:53:45 +0200
- Subject: [PATCH]: Support control of ELF ABI flags in gas HC11/HC12
Hi!
This patch adds the support in GAS to set the ELF ABI flags for HC11/HC12.
It adds pseudo ops that allow control of these flags (followed Mips mostly).
Committed on mainline.
Stephane
2002-08-13 Stephane Carrez <stcarrez@nerim.fr>
* config/tc-m68hc11.c (m68hc11_elf_final_processing): New function.
(md_pseudo_table): Add .mode, .far and .interrupt pseudo op.
(s_m68hc11_mode): New function for .mode pseudo op.
(s_m68hc11_mark_symbol): New function for .far and .interrupt
pseudo op.
* config/tc-m68hc11.h (elf_tc_final_processing): Define.
(m68hc11_elf_final_processing): Declare.
Index: config/tc-m68hc11.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-m68hc11.h,v
retrieving revision 1.7
diff -u -p -r1.7 tc-m68hc11.h
--- config/tc-m68hc11.h 29 Jun 2002 15:52:31 -0000 1.7
+++ config/tc-m68hc11.h 13 Aug 2002 21:49:17 -0000
@@ -104,5 +104,8 @@ extern struct relax_type md_relax_table[
S_SET_VALUE (sym, (valueT) frag_now_fix ()); \
} while (0)
+#define elf_tc_final_processing m68hc11_elf_final_processing
+extern void m68hc11_elf_final_processing PARAMS ((void));
+
#define tc_print_statistics(FILE) m68hc11_print_statistics (FILE)
extern void m68hc11_print_statistics PARAMS ((FILE *));
Index: config/tc-m68hc11.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-m68hc11.c,v
retrieving revision 1.25
diff -u -p -r1.25 tc-m68hc11.c
--- config/tc-m68hc11.c 13 Aug 2002 21:38:15 -0000 1.25
+++ config/tc-m68hc11.c 13 Aug 2002 21:49:18 -0000
@@ -182,6 +182,15 @@ static void build_insn
PARAMS ((struct m68hc11_opcode *, operand *, int));
static int relaxable_symbol PARAMS ((symbolS *));
+/* Pseudo op to control the ELF flags. */
+static void s_m68hc11_mode PARAMS ((int));
+
+/* Mark the symbols with STO_M68HC12_FAR to indicate the functions
+ are using 'rtc' for returning. It is necessary to use 'call'
+ to invoke them. This is also used by the debugger to correctly
+ find the stack frame. */
+static void s_m68hc11_mark_symbol PARAMS ((int));
+
/* Controls whether relative branches can be turned into long branches.
When the relative offset is too large, the insn are changed:
bra -> jmp
@@ -229,6 +238,9 @@ static int num_opcodes;
/* The opcodes sorted by name and filtered by current cpu. */
static struct m68hc11_opcode *m68hc11_sorted_opcodes;
+/* ELF flags to set in the output file header. */
+static int elf_flags = 0;
+
/* These are the machine dependent pseudo-ops. These are included so
the assembler can work on the output from the SUN C compiler, which
generates these. */
@@ -252,6 +264,15 @@ const pseudo_typeS md_pseudo_table[] = {
/* Motorola ALIS. */
{"xrefb", s_ignore, 0}, /* Same as xref */
+ /* .mode instruction (ala SH). */
+ {"mode", s_m68hc11_mode, 0},
+
+ /* .far instruction. */
+ {"far", s_m68hc11_mark_symbol, STO_M68HC12_FAR},
+
+ /* .interrupt instruction. */
+ {"interrupt", s_m68hc11_mark_symbol, STO_M68HC12_INTERRUPT},
+
{0, 0, 0}
};
@@ -2488,6 +2509,89 @@ md_assemble (str)
else
build_insn (opcode, operands, nb_operands);
}
+
+
+/* Pseudo op to control the ELF flags. */
+static void
+s_m68hc11_mode (x)
+ int x ATTRIBUTE_UNUSED;
+{
+ char *name = input_line_pointer, ch;
+
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ input_line_pointer++;
+ ch = *input_line_pointer;
+ *input_line_pointer = '\0';
+
+ if (strcmp (name, "mshort") == 0)
+ {
+ elf_flags &= ~E_M68HC11_I32;
+ }
+ else if (strcmp (name, "mlong") == 0)
+ {
+ elf_flags |= E_M68HC11_I32;
+ }
+ else if (strcmp (name, "mshort-double") == 0)
+ {
+ elf_flags &= ~E_M68HC11_F64;
+ }
+ else if (strcmp (name, "mlong-double") == 0)
+ {
+ elf_flags |= E_M68HC11_F64;
+ }
+ else
+ {
+ as_warn (_("Invalid mode: %s\n"), name);
+ }
+ *input_line_pointer = ch;
+ demand_empty_rest_of_line ();
+}
+
+/* Mark the symbols with STO_M68HC12_FAR to indicate the functions
+ are using 'rtc' for returning. It is necessary to use 'call'
+ to invoke them. This is also used by the debugger to correctly
+ find the stack frame. */
+static void
+s_m68hc11_mark_symbol (mark)
+ int mark;
+{
+ char *name;
+ int c;
+ symbolS *symbolP;
+ asymbol *bfdsym;
+ elf_symbol_type *elfsym;
+
+ do
+ {
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ symbolP = symbol_find_or_make (name);
+ *input_line_pointer = c;
+
+ SKIP_WHITESPACE ();
+
+ bfdsym = symbol_get_bfdsym (symbolP);
+ elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
+
+ assert (elfsym);
+
+ /* Mark the symbol far (using rtc for function return). */
+ elfsym->internal_elf_sym.st_other |= mark;
+
+ if (c == ',')
+ {
+ input_line_pointer ++;
+
+ SKIP_WHITESPACE ();
+
+ if (*input_line_pointer == '\n')
+ c = '\n';
+ }
+ }
+ while (c == ',');
+
+ demand_empty_rest_of_line ();
+}
/* Relocation, relaxation and frag conversions. */
long
@@ -2937,4 +3041,12 @@ md_apply_fix3 (fixP, valP, seg)
as_fatal (_("Line %d: unknown relocation type: 0x%x."),
fixP->fx_line, fixP->fx_r_type);
}
+}
+
+/* Set the ELF specific flags. */
+void
+m68hc11_elf_final_processing ()
+{
+ elf_elfheader (stdoutput)->e_flags &= ~EF_M68HC11_ABI;
+ elf_elfheader (stdoutput)->e_flags |= elf_flags;
}