public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* gas local label and dollar label handling
@ 2022-02-16 11:34 Alan Modra
  0 siblings, 0 replies; only message in thread
From: Alan Modra @ 2022-02-16 11:34 UTC (permalink / raw)
  To: binutils

Much of the gas source and older BFD source use "long" for function
parameters and variables, when other types would be more appropriate.
This patch fixes one of those cases.  Dollar labels and numeric local
labels do not need large numbers.  Small positive itegers are usually
all that is required.  Due to allowing longs, it was possible for
fb_label_name and dollar_label_name to overflow their buffers.

	* symbols.c: Delete unnecessary forward declarations.
	(dollar_labels, dollar_label_instances): Use unsigned int.
	(dollar_label_defined, dollar_label_instance): Likewise.
	(define_dollar_label): Likewise.
	(fb_low_counter, fb_labels, fb_label_instances): Likewise.
	(fb_label_instance_inc, fb_label_instance): Likewise.
	(fb_label_count, fb_label_max): Make them size_t.
	(dollar_label_name, fb_label_name): Rewrite using sprintf.
	* symbols.h (dollar_label_defined): Update prototype.
	(define_dollar_label, dollar_label_name): Likewise.
	(fb_label_instance_inc, fb_label_name): Likewise.
	* config/bfin-lex.l (yylex): Remove unnecessary casts.
	* expr.c (integer_constant): Likewise.
	* read.c (read_a_source_file): Limit numeric label range to int.

diff --git a/gas/config/bfin-lex.l b/gas/config/bfin-lex.l
index 7af47b12954..f0a685b710b 100644
--- a/gas/config/bfin-lex.l
+++ b/gas/config/bfin-lex.l
@@ -311,7 +311,7 @@ int yylex (void);
     char *ref = strdup (yytext);
     if (ref[1] == 'b' || ref[1] == 'B')
       {
-        name = fb_label_name ((int) (ref[0] - '0'), 0);
+        name = fb_label_name (ref[0] - '0', 0);
 	yylval.symbol = symbol_find (name);
 
 	if ((yylval.symbol != NULL)
@@ -329,7 +329,7 @@ int yylex (void);
            Construct a local label name, then an undefined symbol.
            Just return it as never seen before.  */
 
-        name = fb_label_name ((int) (ref[0] - '0'), 1);
+        name = fb_label_name (ref[0] - '0', 1);
 	yylval.symbol = symbol_find_or_make (name);
 	/* We have no need to check symbol properties.  */
 	return SYMBOL;
diff --git a/gas/expr.c b/gas/expr.c
index 1e97a83f27b..bd5b9e70a4a 100644
--- a/gas/expr.c
+++ b/gas/expr.c
@@ -567,7 +567,7 @@ integer_constant (int radix, expressionS *expressionP)
 	  /* Backward ref to local label.
 	     Because it is backward, expect it to be defined.  */
 	  /* Construct a local label.  */
-	  name = fb_label_name ((int) number, 0);
+	  name = fb_label_name (number, 0);
 
 	  /* Seen before, or symbol is defined: OK.  */
 	  symbolP = symbol_find (name);
@@ -601,7 +601,7 @@ integer_constant (int radix, expressionS *expressionP)
 	     Construct a local label name, then an undefined symbol.
 	     Don't create a xseg frag for it: caller may do that.
 	     Just return it as never seen before.  */
-	  name = fb_label_name ((int) number, 1);
+	  name = fb_label_name (number, 1);
 	  symbolP = symbol_find_or_make (name);
 	  /* We have no need to check symbol properties.  */
 #ifndef many_segments
@@ -620,15 +620,15 @@ integer_constant (int radix, expressionS *expressionP)
 	     then this is a fresh instantiation of that number, so create
 	     it.  */
 
-	  if (dollar_label_defined ((long) number))
+	  if (dollar_label_defined (number))
 	    {
-	      name = dollar_label_name ((long) number, 0);
+	      name = dollar_label_name (number, 0);
 	      symbolP = symbol_find (name);
 	      know (symbolP != NULL);
 	    }
 	  else
 	    {
-	      name = dollar_label_name ((long) number, 1);
+	      name = dollar_label_name (number, 1);
 	      symbolP = symbol_find_or_make (name);
 	    }
 
diff --git a/gas/read.c b/gas/read.c
index f3635626649..fe0aff26175 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -1266,7 +1266,7 @@ read_a_source_file (const char *name)
 	      while (ISDIGIT (*input_line_pointer))
 		{
 		  const long digit = *input_line_pointer - '0';
-		  if (temp > (LONG_MAX - digit) / 10)
+		  if (temp > (INT_MAX - digit) / 10)
 		    {
 		      as_bad (_("local label too large near %s"), backup);
 		      temp = -1;
diff --git a/gas/symbols.c b/gas/symbols.c
index 8598792176a..2a0ee7783c0 100644
--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -246,13 +246,6 @@ struct obstack notes;
 const char * an_external_name;
 #endif
 
-static const char *save_symbol_name (const char *);
-static void fb_label_init (void);
-static long dollar_label_instance (long);
-static long fb_label_instance (long);
-
-static void print_binary (FILE *, const char *, expressionS *);
-
 /* Return a pointer to a new symbol.  Die if we can't make a new
    symbol.  Fill in the symbol's values.  Add symbol to end of symbol
    chain.
@@ -1804,16 +1797,17 @@ snapshot_symbol (symbolS **symbolPP, valueT *valueP, segT *segP, fragS **fragPP)
    the instance number, keep a list of defined symbols separate from the real
    symbol table, and we treat these buggers as a sparse array.  */
 
-static long *dollar_labels;
-static long *dollar_label_instances;
+typedef unsigned int dollar_ent;
+static dollar_ent *dollar_labels;
+static dollar_ent *dollar_label_instances;
 static char *dollar_label_defines;
 static size_t dollar_label_count;
 static size_t dollar_label_max;
 
 int
-dollar_label_defined (long label)
+dollar_label_defined (unsigned int label)
 {
-  long *i;
+  dollar_ent *i;
 
   know ((dollar_labels != NULL) || (dollar_label_count == 0));
 
@@ -1825,10 +1819,10 @@ dollar_label_defined (long label)
   return 0;
 }
 
-static long
-dollar_label_instance (long label)
+static unsigned int
+dollar_label_instance (unsigned int label)
 {
-  long *i;
+  dollar_ent *i;
 
   know ((dollar_labels != NULL) || (dollar_label_count == 0));
 
@@ -1851,9 +1845,9 @@ dollar_label_clear (void)
 #define DOLLAR_LABEL_BUMP_BY 10
 
 void
-define_dollar_label (long label)
+define_dollar_label (unsigned int label)
 {
-  long *i;
+  dollar_ent *i;
 
   for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
     if (*i == label)
@@ -1867,8 +1861,8 @@ define_dollar_label (long label)
 
   if (dollar_labels == NULL)
     {
-      dollar_labels = XNEWVEC (long, DOLLAR_LABEL_BUMP_BY);
-      dollar_label_instances = XNEWVEC (long, DOLLAR_LABEL_BUMP_BY);
+      dollar_labels = XNEWVEC (dollar_ent, DOLLAR_LABEL_BUMP_BY);
+      dollar_label_instances = XNEWVEC (dollar_ent, DOLLAR_LABEL_BUMP_BY);
       dollar_label_defines = XNEWVEC (char, DOLLAR_LABEL_BUMP_BY);
       dollar_label_max = DOLLAR_LABEL_BUMP_BY;
       dollar_label_count = 0;
@@ -1876,9 +1870,11 @@ define_dollar_label (long label)
   else if (dollar_label_count == dollar_label_max)
     {
       dollar_label_max += DOLLAR_LABEL_BUMP_BY;
-      dollar_labels = XRESIZEVEC (long, dollar_labels, dollar_label_max);
-      dollar_label_instances = XRESIZEVEC (long, dollar_label_instances,
-					  dollar_label_max);
+      dollar_labels = XRESIZEVEC (dollar_ent, dollar_labels,
+				  dollar_label_max);
+      dollar_label_instances = XRESIZEVEC (dollar_ent,
+					   dollar_label_instances,
+					   dollar_label_max);
       dollar_label_defines = XRESIZEVEC (char, dollar_label_defines,
 					 dollar_label_max);
     }				/* if we needed to grow  */
@@ -1898,50 +1894,22 @@ define_dollar_label (long label)
    symbol. The first "4:" is "L4^A1" - the m numbers begin at 1.
 
    fb labels get the same treatment, except that ^B is used in place
-   of ^A.  */
+   of ^A.
 
-char *				/* Return local label name.  */
-dollar_label_name (long n,	/* we just saw "n$:" : n a number.  */
-		   int augend	/* 0 for current instance, 1 for new instance.  */)
+   AUGEND is 0 for current instance, 1 for new instance.  */
+
+char *
+dollar_label_name (unsigned int n, unsigned int augend)
 {
-  long i;
   /* Returned to caller, then copied.  Used for created names ("4f").  */
   static char symbol_name_build[24];
-  char *p;
-  char *q;
-  char symbol_name_temporary[20];	/* Build up a number, BACKWARDS.  */
+  char *p = symbol_name_build;
 
-  know (n >= 0);
-  know (augend == 0 || augend == 1);
-  p = symbol_name_build;
 #ifdef LOCAL_LABEL_PREFIX
   *p++ = LOCAL_LABEL_PREFIX;
 #endif
-  *p++ = 'L';
-
-  /* Next code just does sprintf( {}, "%d", n);  */
-  /* Label number.  */
-  q = symbol_name_temporary;
-  for (*q++ = 0, i = n; i; ++q)
-    {
-      *q = i % 10 + '0';
-      i /= 10;
-    }
-  while ((*p = *--q) != '\0')
-    ++p;
-
-  *p++ = DOLLAR_LABEL_CHAR;		/* ^A  */
-
-  /* Instance number.  */
-  q = symbol_name_temporary;
-  for (*q++ = 0, i = dollar_label_instance (n) + augend; i; ++q)
-    {
-      *q = i % 10 + '0';
-      i /= 10;
-    }
-  while ((*p++ = *--q) != '\0');
-
-  /* The label, as a '\0' ended string, starts at symbol_name_build.  */
+  sprintf (p, "L%u%c%u",
+	   n, DOLLAR_LABEL_CHAR, dollar_label_instance (n) + augend);
   return symbol_name_build;
 }
 
@@ -1964,11 +1932,12 @@ dollar_label_name (long n,	/* we just saw "n$:" : n a number.  */
 
 #define FB_LABEL_SPECIAL (10)
 
-static long fb_low_counter[FB_LABEL_SPECIAL];
-static long *fb_labels;
-static long *fb_label_instances;
-static long fb_label_count;
-static long fb_label_max;
+typedef unsigned int fb_ent;
+static fb_ent fb_low_counter[FB_LABEL_SPECIAL];
+static fb_ent *fb_labels;
+static fb_ent *fb_label_instances;
+static size_t fb_label_count;
+static size_t fb_label_max;
 
 /* This must be more than FB_LABEL_SPECIAL.  */
 #define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6)
@@ -1982,11 +1951,11 @@ fb_label_init (void)
 /* Add one to the instance number of this fb label.  */
 
 void
-fb_label_instance_inc (long label)
+fb_label_instance_inc (unsigned int label)
 {
-  long *i;
+  fb_ent *i;
 
-  if ((unsigned long) label < FB_LABEL_SPECIAL)
+  if (label < FB_LABEL_SPECIAL)
     {
       ++fb_low_counter[label];
       return;
@@ -2009,8 +1978,8 @@ fb_label_instance_inc (long label)
 
   if (fb_labels == NULL)
     {
-      fb_labels = XNEWVEC (long, FB_LABEL_BUMP_BY);
-      fb_label_instances = XNEWVEC (long, FB_LABEL_BUMP_BY);
+      fb_labels = XNEWVEC (fb_ent, FB_LABEL_BUMP_BY);
+      fb_label_instances = XNEWVEC (fb_ent, FB_LABEL_BUMP_BY);
       fb_label_max = FB_LABEL_BUMP_BY;
       fb_label_count = FB_LABEL_SPECIAL;
 
@@ -2018,8 +1987,9 @@ fb_label_instance_inc (long label)
   else if (fb_label_count == fb_label_max)
     {
       fb_label_max += FB_LABEL_BUMP_BY;
-      fb_labels = XRESIZEVEC (long, fb_labels, fb_label_max);
-      fb_label_instances = XRESIZEVEC (long, fb_label_instances, fb_label_max);
+      fb_labels = XRESIZEVEC (fb_ent, fb_labels, fb_label_max);
+      fb_label_instances = XRESIZEVEC (fb_ent, fb_label_instances,
+				       fb_label_max);
     }				/* if we needed to grow  */
 
   fb_labels[fb_label_count] = label;
@@ -2027,15 +1997,13 @@ fb_label_instance_inc (long label)
   ++fb_label_count;
 }
 
-static long
-fb_label_instance (long label)
+static unsigned int
+fb_label_instance (unsigned int label)
 {
-  long *i;
+  fb_ent *i;
 
-  if ((unsigned long) label < FB_LABEL_SPECIAL)
-    {
-      return (fb_low_counter[label]);
-    }
+  if (label < FB_LABEL_SPECIAL)
+    return (fb_low_counter[label]);
 
   if (fb_labels != NULL)
     {
@@ -2043,10 +2011,8 @@ fb_label_instance (long label)
 	   i < fb_labels + fb_label_count; ++i)
 	{
 	  if (*i == label)
-	    {
-	      return (fb_label_instances[i - fb_labels]);
-	    }			/* if we find it  */
-	}			/* for each existing label  */
+	    return (fb_label_instances[i - fb_labels]);
+	}
     }
 
   /* We didn't find the label, so this must be a reference to the
@@ -2063,55 +2029,29 @@ fb_label_instance (long label)
    symbol. The first "4:" is "L4^B1" - the m numbers begin at 1.
 
    dollar labels get the same treatment, except that ^A is used in
-   place of ^B.  */
+   place of ^B.
+
+   AUGEND is 0 for nb, 1 for n:, nf.  */
 
-char *				/* Return local label name.  */
-fb_label_name (long n,	/* We just saw "n:", "nf" or "nb" : n a number.  */
-	       long augend	/* 0 for nb, 1 for n:, nf.  */)
+char *
+fb_label_name (unsigned int n, unsigned int augend)
 {
-  long i;
   /* Returned to caller, then copied.  Used for created names ("4f").  */
   static char symbol_name_build[24];
-  char *p;
-  char *q;
-  char symbol_name_temporary[20];	/* Build up a number, BACKWARDS.  */
+  char *p = symbol_name_build;
 
-  know (n >= 0);
 #ifdef TC_MMIX
-  know ((unsigned long) augend <= 2 /* See mmix_fb_label.  */);
+  know (augend <= 2 /* See mmix_fb_label.  */);
 #else
-  know ((unsigned long) augend <= 1);
+  know (augend <= 1);
 #endif
-  p = symbol_name_build;
+
 #ifdef LOCAL_LABEL_PREFIX
   *p++ = LOCAL_LABEL_PREFIX;
 #endif
-  *p++ = 'L';
-
-  /* Next code just does sprintf( {}, "%d", n);  */
-  /* Label number.  */
-  q = symbol_name_temporary;
-  for (*q++ = 0, i = n; i; ++q)
-    {
-      *q = i % 10 + '0';
-      i /= 10;
-    }
-  while ((*p = *--q) != '\0')
-    ++p;
-
-  *p++ = LOCAL_LABEL_CHAR;		/* ^B  */
-
-  /* Instance number.  */
-  q = symbol_name_temporary;
-  for (*q++ = 0, i = fb_label_instance (n) + augend; i; ++q)
-    {
-      *q = i % 10 + '0';
-      i /= 10;
-    }
-  while ((*p++ = *--q) != '\0');
-
-  /* The label, as a '\0' ended string, starts at symbol_name_build.  */
-  return (symbol_name_build);
+  sprintf (p, "L%u%c%u",
+	   n, LOCAL_LABEL_CHAR, fb_label_instance (n) + augend);
+  return symbol_name_build;
 }
 
 /* Decode name that may have been generated by foo_label_name() above.
diff --git a/gas/symbols.h b/gas/symbols.h
index a6068cba07d..19eb658ca68 100644
--- a/gas/symbols.h
+++ b/gas/symbols.h
@@ -72,13 +72,13 @@ void print_expr (expressionS *);
 void print_expr_1 (FILE *, expressionS *);
 void print_symbol_value_1 (FILE *, symbolS *);
 
-int dollar_label_defined (long l);
+int dollar_label_defined (unsigned int);
 void dollar_label_clear (void);
-void define_dollar_label (long l);
-char *dollar_label_name (long l, int augend);
+void define_dollar_label (unsigned int);
+char *dollar_label_name (unsigned int, unsigned int);
 
-void fb_label_instance_inc (long label);
-char *fb_label_name (long n, long augend);
+void fb_label_instance_inc (unsigned int);
+char *fb_label_name (unsigned int, unsigned int);
 
 extern void copy_symbol_attributes (symbolS *, symbolS *);
 

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-02-16 11:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-16 11:34 gas local label and dollar label handling Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).