]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
base64: Add support for targets with byte size > octet size.
authorNick Clifton <nickc@redhat.com>
Thu, 11 Jul 2024 11:51:16 +0000 (12:51 +0100)
committerNick Clifton <nickc@redhat.com>
Thu, 11 Jul 2024 11:52:32 +0000 (12:52 +0100)
PR 31964

gas/doc/as.texi
gas/read.c
gas/read.h
gas/testsuite/gas/all/base64.d
gas/testsuite/gas/all/base64.s

index 02db6cb34961e090106bfb50b1685bdb3c093bf2..6d927eaefe91b136dfa6fe0b9070521b73dbf411 100644 (file)
@@ -4863,7 +4863,12 @@ characters.  Multiple strings are allowed, but they must be separated by
 commas.
 
 As an example of how to create a base64 encoded string, see the
-@command{base64} program (with its @option{-w0} option to disable line breaks.
+@command{base64} program (with its @option{-w0} option to disable line breaks).
+
+Note: for targets where the size of a byte is larger than the size of an octet
+the @code{.base64} directive will, if necessary, pad the end of the @emph{last}
+string so that the total number of octets generated are a multiple the number
+of octets in a byte.
 
 @ifset ELF
 @node Bss
index e6bbb89d4cffc2104540c126f6405812262e4a5c..9a26a9a5b7a5a7329a6159631d7fafa88995773d 100644 (file)
@@ -5413,42 +5413,6 @@ s_leb128 (int sign)
   demand_empty_rest_of_line ();
 }
 \f
-static void
-stringer_append_char (int c, int bitsize)
-{
-  if (c && in_bss ())
-    as_bad (_("attempt to store non-empty string in section `%s'"),
-           segment_name (now_seg));
-
-  if (!target_big_endian)
-    FRAG_APPEND_1_CHAR (c);
-
-  switch (bitsize)
-    {
-    case 64:
-      FRAG_APPEND_1_CHAR (0);
-      FRAG_APPEND_1_CHAR (0);
-      FRAG_APPEND_1_CHAR (0);
-      FRAG_APPEND_1_CHAR (0);
-      /* Fall through.  */
-    case 32:
-      FRAG_APPEND_1_CHAR (0);
-      FRAG_APPEND_1_CHAR (0);
-      /* Fall through.  */
-    case 16:
-      FRAG_APPEND_1_CHAR (0);
-      /* Fall through.  */
-    case 8:
-      break;
-    default:
-      /* Called with invalid bitsize argument.  */
-      abort ();
-      break;
-    }
-  if (target_big_endian)
-    FRAG_APPEND_1_CHAR (c);
-}
-
 /* Code for handling base64 encoded strings.
    Based upon code in sharutils' lib/base64.c source file, written by
    Simon Josefsson.  Which was partially adapted from GNU MailUtils
@@ -5602,9 +5566,15 @@ decode_base64_and_append (unsigned int b[4], int len)
   gas_assert (len > 1);
 
   FRAG_APPEND_1_CHAR ((b64[b[0]] << 2) | (b64[b[1]] >> 4));
-  if (len == 2) return;
+
+  if (len == 2)
+    return; /* FIXME: Check for unused bits in b[1] ?  */
+
   FRAG_APPEND_1_CHAR (((b64[b[1]] << 4) & 0xf0) | (b64[b[2]] >> 2));
-  if (len == 3) return;
+
+  if (len == 3)
+    return; /* FIXME: Check for unused bits in b[2] ?  */
+
   FRAG_APPEND_1_CHAR (((b64[b[2]] << 6) & 0xc0) | b64[b[3]]);
 }
 
@@ -5620,6 +5590,7 @@ void
 s_base64 (int dummy ATTRIBUTE_UNUSED)
 {
   unsigned int c;
+  unsigned long num_octets = 0;
 
   /* If we have been switched into the abs_section then we
      will not have an obstack onto which we can hang strings.  */
@@ -5736,6 +5707,7 @@ s_base64 (int dummy ATTRIBUTE_UNUSED)
 
       /* We have a block of up to four valid base64 encoded bytes.  */
       decode_base64_and_append (b, i);
+      num_octets += (i - 1);
 
       /* Check the next character.  */
       c = * input_line_pointer ++;
@@ -5765,11 +5737,59 @@ s_base64 (int dummy ATTRIBUTE_UNUSED)
     }
   while (c == ',');
 
+  /* Make sure that we have not skipped the EOL marker.  */
   -- input_line_pointer;
 
+  while (num_octets % OCTETS_PER_BYTE)
+    {
+      /* We have finished emiting the octets for this .base64 pseudo-op, but
+        we have not filled up enough bytes for the target architecture.  So
+        we emit padding octets here.  This is done after all of the arguments
+        to the pseudo-op have been processed, rather than at the end of each
+        argument, as it is likely that the user wants the arguments to be
+        contiguous.  */
+      FRAG_APPEND_1_CHAR (0);
+      ++ num_octets;
+    }
+
   demand_empty_rest_of_line ();
 }
 
+static void
+stringer_append_char (int c, int bitsize)
+{
+  if (c && in_bss ())
+    as_bad (_("attempt to store non-empty string in section `%s'"),
+           segment_name (now_seg));
+
+  if (!target_big_endian)
+    FRAG_APPEND_1_CHAR (c);
+
+  switch (bitsize)
+    {
+    case 64:
+      FRAG_APPEND_1_CHAR (0);
+      FRAG_APPEND_1_CHAR (0);
+      FRAG_APPEND_1_CHAR (0);
+      FRAG_APPEND_1_CHAR (0);
+      /* Fall through.  */
+    case 32:
+      FRAG_APPEND_1_CHAR (0);
+      FRAG_APPEND_1_CHAR (0);
+      /* Fall through.  */
+    case 16:
+      FRAG_APPEND_1_CHAR (0);
+      /* Fall through.  */
+    case 8:
+      break;
+    default:
+      /* Called with invalid bitsize argument.  */
+      abort ();
+      break;
+    }
+  if (target_big_endian)
+    FRAG_APPEND_1_CHAR (c);
+}
 
 /* Worker to do .ascii etc statements.
    Reads 0 or more ',' separated, double-quoted strings.
index 9908d44948dcea3c202da0d70994bb970c530b1d..2441d560bbd8a2836d9a20da281bb08b3fd974cb 100644 (file)
@@ -155,71 +155,70 @@ extern void stabs_end (void);
 extern void do_repeat (size_t, const char *, const char *, const char *);
 extern void end_repeat (int);
 extern void do_parse_cons_expression (expressionS *, int);
-
 extern void generate_lineno_debug (void);
-
-extern void s_abort (int) ATTRIBUTE_NORETURN;
-extern void s_align_bytes (int arg);
-extern void s_align_ptwo (int);
 extern void do_align (unsigned int align, char *fill, unsigned int length,
                      unsigned int max);
 extern void bss_alloc (symbolS *, addressT, unsigned);
 extern offsetT parse_align (int);
 extern symbolS *s_comm_internal (int, symbolS *(*) (int, symbolS *, addressT));
 extern symbolS *s_lcomm_internal (int, symbolS *, addressT);
+extern void temp_ilp (char *);
+extern void restore_ilp (void);
 extern void s_file_string (char *);
-extern void s_file (int);
-extern void s_linefile (int);
+
+extern void s_abort (int) ATTRIBUTE_NORETURN;
+extern void s_align_bytes (int);
+extern void s_align_ptwo (int);
+extern void s_base64 (int);
 extern void s_bundle_align_mode (int);
 extern void s_bundle_lock (int);
 extern void s_bundle_unlock (int);
 extern void s_comm (int);
 extern void s_data (int);
 extern void s_desc (int);
-extern void s_else (int arg);
-extern void s_elseif (int arg);
-extern void s_end (int arg);
-extern void s_endif (int arg);
+extern void s_else (int);
+extern void s_elseif (int);
+extern void s_end (int);
+extern void s_endif (int);
 extern void s_err (int);
 extern void s_errwarn (int);
 extern void s_fail (int);
+extern void s_file (int);
 extern void s_fill (int);
-extern void s_float_space (int mult);
+extern void s_float_space (int);
 extern void s_func (int);
-extern void s_globl (int arg);
-extern void s_if (int arg);
-extern void s_ifb (int arg);
-extern void s_ifc (int arg);
-extern void s_ifdef (int arg);
-extern void s_ifeqs (int arg);
-extern void s_ignore (int arg);
-extern void s_include (int arg);
-extern void s_irp (int arg);
-extern void s_lcomm (int needs_align);
-extern void s_lcomm_bytes (int needs_align);
-extern void s_leb128 (int sign);
+extern void s_globl (int);
+extern void s_if (int);
+extern void s_ifb (int);
+extern void s_ifc (int);
+extern void s_ifdef (int);
+extern void s_ifeqs (int);
+extern void s_ignore (int);
+extern void s_incbin (int);
+extern void s_include (int);
+extern void s_irp (int);
+extern void s_lcomm (int);
+extern void s_lcomm_bytes (int);
+extern void s_leb128 (int);
+extern void s_linefile (int);
 extern void s_linkonce (int);
 extern void s_lsym (int);
 extern void s_macro (int);
 extern void s_mexit (int);
 extern void s_mri (int);
 extern void s_mri_common (int);
+extern void s_nop (int);
+extern void s_nops (int);
 extern void s_org (int);
 extern void s_print (int);
 extern void s_purgem (int);
 extern void s_rept (int);
+extern void s_rva (int);
 extern void s_set (int);
-extern void s_space (int mult);
-extern void s_nop (int);
-extern void s_nops (int);
-extern void s_stab (int what);
+extern void s_space (int);
+extern void s_stab (int);
 extern void s_struct (int);
 extern void s_text (int);
-extern void s_base64 (int);
-extern void stringer (int append_zero);
-extern void s_xstab (int what);
-extern void s_rva (int);
-extern void s_incbin (int);
 extern void s_weakref (int);
-extern void temp_ilp (char *);
-extern void restore_ilp (void);
+extern void s_xstab (int);
+extern void stringer (int);
index ad3cd9c6fca47de2c5b42aa02da6060092925200..a35382d16a50f94933c4d7b6ae9dd247653a0141 100644 (file)
@@ -5,12 +5,12 @@
 
 Contents of section \.data:
 .* 68656c6c 6f20776f 726c640a 70616464 .*
-.* 696e6720 68657265 0a454c46 02010103 .*
-.* 00000000 00000000 02003e00 01000000 .*
-.* 50d34000 00000000 40000000 00000000 .*
-.* d8204b10 00000000 00000000 40003800 .*
-.* 0e004000 2c002b00 06000000 04000000 .*
-.* 40000000 00000000 40004000 00000000 .*
-.* 40004000 00000000 10030000 00000000 .*
-.* 10030000 00000000 08000000 00000000 .*
+.* 696e6720 68657265 0a001083 454c4602 .*
+.* 01010300 00000000 00000002 003e0001 .*
+.* 00000050 d3400000 00000040 00000000 .*
+.* 000000d8 204b1000 00000000 00000040 .*
+.* 0038000e 0040002c 002b0006 00000004 .*
+.* 00000040 00000000 00000040 00400000 .*
+.* 00000040 00400000 00000010 03000000 .*
+.* 00000010 03000000 00000008 00000000 .*
 .* 00000000 00000000 00(      |00    |000000) (        |00000000) .*
index d176467aae436a20b79cf79feabf3bf2f2141aae..7d1350d42e7289133e3303fe6976f945dbe89bac 100644 (file)
@@ -1,7 +1,7 @@
        .data
        .global hello
 hello:
-       .base64 "aGVsbG8gd29ybGQK", "cGFkZGluZyBoZXJlCg==" 
+       .base64 "aGVsbG8gd29ybGQK", "cGFkZGluZyBoZXJlCg==" , "ABCD" 
 
        .global very_long
 very_long: