Patches for eCos: Dump literal pool on section change. Mark thumb function
authorNick Clifton <nickc@redhat.com>
Fri, 18 Jun 1999 01:38:26 +0000 (01:38 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 18 Jun 1999 01:38:26 +0000 (01:38 +0000)
aliases as being thumb functions as well.

gas/ChangeLog
gas/config/tc-arm.c

index e0f1547..708e1a7 100644 (file)
@@ -1,3 +1,23 @@
+1999-06-16  Nick Clifton  <nickc@cygnus.com>
+
+       * config/tc-arm.c (thumb_set): New pseudo op.
+       (text, data, section): Override these pseudo ops with ARM
+       specific versions.
+       (s_thumb_set): New function: Perform the same as a .set pseudo
+       op, but also mark the alias'ed symbol as being a Thumb
+       function.
+       (arm_s_text): New function: Perform the same as the .text
+       pseudo op, but dump the literal pool before changing
+       sections. 
+       (arm_s_data): New function: Perform the same as the .data
+       pseudo op, but dump the literal pool before changing
+       sections. 
+       (arm_s_section): New function: Perform the same as the
+       .section pseudo op, but dump the literal pool before changing 
+       sections. 
+       (arm_cleanup): Do not reset the current section before dumping
+       the literal pool.
+
 1999-06-17  Nick Clifton  <nickc@cygnus.com>
 
        * config/tc-m32r.c (md_longopts): Fix OPTION_WARN_UNMATCHED and
index eb39c78..9399a7b 100644 (file)
@@ -897,7 +897,11 @@ static void s_thumb PARAMS ((int));
 static void s_code PARAMS ((int));
 static void s_force_thumb PARAMS ((int));
 static void s_thumb_func PARAMS ((int));
+static void s_thumb_set PARAMS ((int));
+static void arm_s_text PARAMS ((int));
+static void arm_s_data PARAMS ((int));
 #ifdef OBJ_ELF
+static void arm_s_section PARAMS ((int));
 static void s_arm_elf_cons PARAMS ((int));
 #endif
 
@@ -905,27 +909,35 @@ static int my_get_expression PARAMS ((expressionS *, char **));
 
 CONST pseudo_typeS md_pseudo_table[] =
 {
-  {"req",         s_req, 0},   /* Never called becasue '.req' does not start line */
-  {"bss",         s_bss, 0},
-  {"align",       s_align, 0},
-  {"arm",         s_arm, 0},
-  {"thumb",       s_thumb, 0},
-  {"code",        s_code, 0},
-  {"force_thumb", s_force_thumb, 0},
-  {"thumb_func",  s_thumb_func, 0},
-  {"even",        s_even, 0},
-  {"ltorg",       s_ltorg, 0},
-  {"pool",        s_ltorg, 0},
+  { "req",         s_req,         0 }, /* Never called becasue '.req' does not start line */
+  { "bss",         s_bss,         0 },
+  { "align",       s_align,       0 },
+  { "arm",         s_arm,         0 },
+  { "thumb",       s_thumb,       0 },
+  { "code",        s_code,        0 },
+  { "force_thumb", s_force_thumb, 0 },
+  { "thumb_func",  s_thumb_func,  0 },
+  { "thumb_set",   s_thumb_set,   0 },
+  { "even",        s_even,        0 },
+  { "ltorg",       s_ltorg,       0 },
+  { "pool",        s_ltorg,       0 },
+  /* Allow for the effect of section changes.  */
+  { "text",        arm_s_text,    0 },
+  { "data",        arm_s_data,    0 },
 #ifdef OBJ_ELF  
-  {"word",        s_arm_elf_cons, 4},
-  {"long",        s_arm_elf_cons, 4},
+  { "section",     arm_s_section, 0 },
+  { "section.s",   arm_s_section, 0 },
+  { "sect",        arm_s_section, 0 },
+  { "sect.s",      arm_s_section, 0 },
+  { "word",        s_arm_elf_cons, 4 },
+  { "long",        s_arm_elf_cons, 4 },
 #else
-  {"word",        cons, 4},
+  { "word",        cons, 4},
 #endif
-  {"extend",      float_cons, 'x'},
-  {"ldouble",     float_cons, 'x'},
-  {"packed",      float_cons, 'p'},
-  {0, 0, 0}
+  { "extend",      float_cons, 'x' },
+  { "ldouble",     float_cons, 'x' },
+  { "packed",      float_cons, 'p' },
+  { 0, 0, 0 }
 };
 
 /* Stuff needed to resolve the label ambiguity
@@ -1109,19 +1121,14 @@ s_even (ignore)
 }
 
 static void
-s_ltorg (internal)
-     int internal;
+s_ltorg (ignored)
+     int ignored;
 {
   int lit_count = 0;
   char sym_name[20];
 
   if (current_poolP == NULL)
-    {
-      /* Nothing to do */
-      if (!internal)
-       as_tsktsk (_("Nothing to put in the pool\n"));
-      return;
-    }
+    return;
 
   /* Align pool as you have word accesses */
   /* Only make a frag if we have to ... */
@@ -1130,9 +1137,6 @@ s_ltorg (internal)
 
   record_alignment (now_seg, 2);
 
-  if (internal)
-    as_tsktsk (_("Inserting implicit pool at change of section"));
-
   sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
 
   symbol_locate (current_poolP, sym_name, now_seg,
@@ -1221,6 +1225,135 @@ s_thumb_func (ignore)
   demand_empty_rest_of_line ();
 }
 
+/* Perform a .set directive, but also mark the alias as
+   being a thumb function.  */
+
+static void
+s_thumb_set (equiv)
+     int equiv;
+{
+  /* XXX the following is a duplicate of the code for s_set() in read.c
+     We cannot just call that code as we need to get at the symbol that
+     is created.  */
+  register char *    name;
+  register char      delim;
+  register char *    end_name;
+  register symbolS * symbolP;
+
+  /*
+   * Especial apologies for the random logic:
+   * this just grew, and could be parsed much more simply!
+   * Dean in haste.
+   */
+  name      = input_line_pointer;
+  delim     = get_symbol_end ();
+  end_name  = input_line_pointer;
+  *end_name = delim;
+  
+  SKIP_WHITESPACE ();
+
+  if (*input_line_pointer != ',')
+    {
+      *end_name = 0;
+      as_bad (_("Expected comma after name \"%s\""), name);
+      *end_name = delim;
+      ignore_rest_of_line ();
+      return;
+    }
+
+  input_line_pointer++;
+  *end_name = 0;
+
+  if (name[0] == '.' && name[1] == '\0')
+    {
+      /* XXX - this should not happen to .thumb_set  */
+      abort ();
+    }
+
+  if ((symbolP = symbol_find (name)) == NULL
+      && (symbolP = md_undefined_symbol (name)) == NULL)
+    {
+#ifndef NO_LISTING
+      /* When doing symbol listings, play games with dummy fragments living
+        outside the normal fragment chain to record the file and line info
+         for this symbol.  */
+      if (listing & LISTING_SYMBOLS)
+       {
+         extern struct list_info_struct * listing_tail;
+         fragS * dummy_frag = (fragS *) xmalloc (sizeof(fragS));
+         memset (dummy_frag, 0, sizeof(fragS));
+         dummy_frag->fr_type = rs_fill;
+         dummy_frag->line = listing_tail;
+         symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
+         dummy_frag->fr_symbol = symbolP;
+       }
+      else
+#endif
+        symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
+                           
+#ifdef OBJ_COFF
+      /* "set" symbols are local unless otherwise specified. */
+      SF_SET_LOCAL (symbolP);
+#endif /* OBJ_COFF */
+    }                          /* make a new symbol */
+
+  symbol_table_insert (symbolP);
+
+  * end_name = delim;
+
+  if (equiv
+      && S_IS_DEFINED (symbolP)
+      && S_GET_SEGMENT (symbolP) != reg_section)
+    as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
+
+  pseudo_set (symbolP);
+  
+  demand_empty_rest_of_line ();
+
+  /* XXX now we come to the Thumb specific bit of code.  */
+  
+  THUMB_SET_FUNC (symbolP, 1);
+  ARM_SET_THUMB (symbolP, 1);
+  ARM_SET_INTERWORK (symbolP, support_interwork);
+}
+
+/* If we change section we must dump the literal pool first.  */
+static void
+arm_s_text (ignore)
+     int ignore;
+{
+  if (now_seg != text_section)
+    s_ltorg (0);
+  
+  s_text (ignore);
+}
+
+static void
+arm_s_data (ignore)
+     int ignore;
+{
+  if (flag_readonly_data_in_text)
+    {
+      if (now_seg != text_section)
+       s_ltorg (0);
+    }
+  else if (now_seg != data_section)
+    s_ltorg (0);
+  
+  s_data (ignore);
+}
+
+#ifdef OBJ_ELF
+static void
+arm_s_section (ignore)
+     int ignore;
+{
+  s_ltorg (0);
+
+  obj_elf_section (ignore);
+}
+#endif
+
 static void
 opcode_select (width)
      int width;
@@ -6845,4 +6978,3 @@ s_arm_elf_cons (nbytes)
 }
 
 #endif /* OBJ_ELF */
-