[llvm] Add support for the .base64 directive (fixes #165499) (PR #165549)
Ben Kallus via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 4 06:33:25 PST 2025
https://github.com/kenballus updated https://github.com/llvm/llvm-project/pull/165549
>From 4ca5466ad319ade27c44903ab25f38e81efb5076 Mon Sep 17 00:00:00 2001
From: Ben Kallus <benjamin.p.kallus.gr at dartmouth.edu>
Date: Fri, 31 Oct 2025 09:06:05 -0400
Subject: [PATCH 1/2] MC/AsmParser: Add .base64 directive
---
llvm/lib/MC/MCParser/AsmParser.cpp | 25 +++++++++++++++++++++++
llvm/test/MC/AsmParser/directive_base64.s | 12 +++++++++++
2 files changed, 37 insertions(+)
create mode 100644 llvm/test/MC/AsmParser/directive_base64.s
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index dd1bc2be5feb4..357b114f0b1e3 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -46,6 +46,7 @@
#include "llvm/MC/MCSymbolMachO.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCValue.h"
+#include "llvm/Support/Base64.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
@@ -530,6 +531,7 @@ class AsmParser : public MCAsmParser {
DK_LTO_SET_CONDITIONAL,
DK_CFI_MTE_TAGGED_FRAME,
DK_MEMTAG,
+ DK_BASE64,
DK_END
};
@@ -552,6 +554,7 @@ class AsmParser : public MCAsmParser {
// ".ascii", ".asciz", ".string"
bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
+ bool parseDirectiveBase64(); // ".base64"
bool parseDirectiveReloc(SMLoc DirectiveLoc); // ".reloc"
bool parseDirectiveValue(StringRef IDVal,
unsigned Size); // ".byte", ".long", ...
@@ -1953,6 +1956,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
case DK_ASCIZ:
case DK_STRING:
return parseDirectiveAscii(IDVal, true);
+ case DK_BASE64:
+ return parseDirectiveBase64();
case DK_BYTE:
case DK_DC_B:
return parseDirectiveValue(IDVal, 1);
@@ -3076,6 +3081,25 @@ bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
return parseMany(parseOp);
}
+/// parseDirectiveBase64:
+// ::= .base64 "string"
+bool AsmParser::parseDirectiveBase64() {
+ if (checkForValidSection() ||
+ check(getTok().isNot(AsmToken::String), "expected string")) {
+ return true;
+ }
+
+ std::vector<char> Decoded;
+ std::string const str = getTok().getStringContents().str();
+ if (str.empty() || decodeBase64(str, Decoded)) {
+ return true;
+ }
+
+ getStreamer().emitBytes(std::string(Decoded.begin(), Decoded.end()));
+ Lex();
+ return false;
+}
+
/// parseDirectiveReloc
/// ::= .reloc expression , identifier [ , expression ]
bool AsmParser::parseDirectiveReloc(SMLoc DirectiveLoc) {
@@ -5345,6 +5369,7 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".asciz"] = DK_ASCIZ;
DirectiveKindMap[".string"] = DK_STRING;
DirectiveKindMap[".byte"] = DK_BYTE;
+ DirectiveKindMap[".base64"] = DK_BASE64;
DirectiveKindMap[".short"] = DK_SHORT;
DirectiveKindMap[".value"] = DK_VALUE;
DirectiveKindMap[".2byte"] = DK_2BYTE;
diff --git a/llvm/test/MC/AsmParser/directive_base64.s b/llvm/test/MC/AsmParser/directive_base64.s
new file mode 100644
index 0000000000000..947895caa171f
--- /dev/null
+++ b/llvm/test/MC/AsmParser/directive_base64.s
@@ -0,0 +1,12 @@
+# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
+
+ .data
+# CHECK: TEST0:
+# CHECK: .byte 0
+TEST0:
+ .base64 "AA=="
+
+# CHECK: TEST1:
+# CHECK: .ascii "abcxyz"
+TEST1:
+ .base64 "YWJjeHl6"
>From 0df7acd3b1f68bafb72bd2e2f12031960a9ff945 Mon Sep 17 00:00:00 2001
From: Ben Kallus <benjamin.p.kallus.gr at dartmouth.edu>
Date: Tue, 4 Nov 2025 09:33:07 -0500
Subject: [PATCH 2/2] Make base64 directive take multiple comma-separated
operands and improve tests.
---
llvm/lib/MC/MCParser/AsmParser.cpp | 38 +++++++++++++++--------
llvm/test/MC/AsmParser/directive_base64.s | 33 +++++++++++++++++---
2 files changed, 54 insertions(+), 17 deletions(-)
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 439dcbcddb456..c9cce7d69cc01 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -3080,22 +3080,34 @@ bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
}
/// parseDirectiveBase64:
-// ::= .base64 "string"
+// ::= .base64 "string" (, "string" )*
bool AsmParser::parseDirectiveBase64() {
- if (checkForValidSection() ||
- check(getTok().isNot(AsmToken::String), "expected string")) {
- return true;
- }
+ auto parseOp = [&]() -> bool {
+ if (checkForValidSection())
+ return true;
- std::vector<char> Decoded;
- std::string const str = getTok().getStringContents().str();
- if (str.empty() || decodeBase64(str, Decoded)) {
- return true;
- }
+ if (getTok().isNot(AsmToken::String)) {
+ return true;
+ }
- getStreamer().emitBytes(std::string(Decoded.begin(), Decoded.end()));
- Lex();
- return false;
+ std::vector<char> Decoded;
+ std::string const str = getTok().getStringContents().str();
+ if (check(str.empty(), "expected nonempty string")) {
+ return true;
+ }
+
+ llvm::Error e = decodeBase64(str, Decoded);
+ if (e) {
+ consumeError(std::move(e));
+ return Error(Lexer.getLoc(), "failed to base64 decode string data");
+ }
+
+ getStreamer().emitBytes(std::string(Decoded.begin(), Decoded.end()));
+ Lex();
+ return false;
+ };
+
+ return check(parseMany(parseOp), "expected string");
}
/// parseDirectiveReloc
diff --git a/llvm/test/MC/AsmParser/directive_base64.s b/llvm/test/MC/AsmParser/directive_base64.s
index 947895caa171f..46a477eef51dc 100644
--- a/llvm/test/MC/AsmParser/directive_base64.s
+++ b/llvm/test/MC/AsmParser/directive_base64.s
@@ -1,12 +1,37 @@
# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
+# RUN: not llvm-mc -triple i386-unknown-unknown -defsym=ERR=1 -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
.data
-# CHECK: TEST0:
-# CHECK: .byte 0
+# CHECK-LABEL: TEST0:
+# CHECK-NEXT: .byte 0
TEST0:
.base64 "AA=="
-# CHECK: TEST1:
-# CHECK: .ascii "abcxyz"
+# CHECK-LABEL: TEST1:
+# CHECK-NEXT: .ascii "abcxyz"
TEST1:
.base64 "YWJjeHl6"
+
+# CHECK-LABEL: TEST2:
+# CHECK-NEXT: .byte 1
+# CHECK-NEXT: .byte 2
+TEST2:
+ .base64 "AQ=="
+ .base64 "Ag=="
+
+# CHECK-LABEL: TEST3:
+# CHECK-NEXT: .byte 1
+# CHECK-NEXT: .byte 2
+TEST3:
+ .base64 "AQ==", "Ag=="
+
+.ifdef ERR
+# CHECK-ERROR: [[#@LINE+1]]:17: error: expected string
+ .base64 not-a-string
+
+# CHECK-ERROR: [[#@LINE+1]]:17: error: failed to base64 decode string data
+ .base64 "AA"
+
+# CHECK-ERROR: [[#@LINE+1]]:17: error: expected nonempty string
+ .base64 ""
+.endif
More information about the llvm-commits
mailing list