[binutils-gdb] base64: Add support for targets with byte size > octet size.
Nick Clifton
nickc@sourceware.org
Thu Jul 11 11:52:41 GMT 2024
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a79094915578872a0360c78a54accff994b883b1
commit a79094915578872a0360c78a54accff994b883b1
Author: Nick Clifton <nickc@redhat.com>
Date: Thu Jul 11 12:51:16 2024 +0100
base64: Add support for targets with byte size > octet size.
PR 31964
Diff:
---
gas/doc/as.texi | 7 ++-
gas/read.c | 96 +++++++++++++++++++++++++-----------------
gas/read.h | 69 +++++++++++++++---------------
gas/testsuite/gas/all/base64.d | 16 +++----
gas/testsuite/gas/all/base64.s | 2 +-
5 files changed, 107 insertions(+), 83 deletions(-)
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index 02db6cb3496..6d927eaefe9 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -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
diff --git a/gas/read.c b/gas/read.c
index e6bbb89d4cf..9a26a9a5b7a 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -5413,42 +5413,6 @@ s_leb128 (int sign)
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);
-}
-
/* 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.
diff --git a/gas/read.h b/gas/read.h
index 9908d44948d..2441d560bbd 100644
--- a/gas/read.h
+++ b/gas/read.h
@@ -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);
diff --git a/gas/testsuite/gas/all/base64.d b/gas/testsuite/gas/all/base64.d
index ad3cd9c6fca..a35382d16a5 100644
--- a/gas/testsuite/gas/all/base64.d
+++ b/gas/testsuite/gas/all/base64.d
@@ -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) .*
diff --git a/gas/testsuite/gas/all/base64.s b/gas/testsuite/gas/all/base64.s
index d176467aae4..7d1350d42e7 100644
--- a/gas/testsuite/gas/all/base64.s
+++ b/gas/testsuite/gas/all/base64.s
@@ -1,7 +1,7 @@
.data
.global hello
hello:
- .base64 "aGVsbG8gd29ybGQK", "cGFkZGluZyBoZXJlCg=="
+ .base64 "aGVsbG8gd29ybGQK", "cGFkZGluZyBoZXJlCg==" , "ABCD"
.global very_long
very_long:
More information about the Binutils-cvs
mailing list