Skip to content

Commit a94db68

Browse files
committed
asmatt
1 parent 1c78b28 commit a94db68

File tree

6 files changed

+486
-10
lines changed

6 files changed

+486
-10
lines changed

libr/arch/p/x86_nz/att2intel.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
#include <r_asm.h>
44

55
// x86-specific AT&T to Intel parser plugin
6-
// Uses the generic r_str_att2intel() from libr/util/str_att.c
6+
// Uses the x86-specific r_str_att2intel() from libr/util/str_att.c
7+
// This plugin is used as a pseudo-disassembler parser to convert AT&T output to Intel
78

89
static char *parse(RAsmPluginSession *aps, const char *data) {
910
return r_str_att2intel (data);

libr/asm/asm.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -619,13 +619,26 @@ static int r_asm_assemble_single(RAsm *a, RAnalOp *op, const char *buf) {
619619
if (!b) {
620620
return 0;
621621
}
622-
// convert AT&T syntax to Intel if needed
623-
const char *arch = R_UNWRAP3 (a, config, arch);
624-
if (a->config->syntax == R_ARCH_SYNTAX_ATT && arch && r_str_startswith (arch, "x86")) {
625-
char *intel = r_str_att2intel (b);
626-
if (intel) {
627-
free (b);
628-
b = intel;
622+
// convert AT&T syntax to Intel if needed, but only if the encoder doesn't support ATT natively
623+
// The r_str_att2intel function is x86-specific, so only use it for x86 architectures
624+
if (a->config->syntax == R_ARCH_SYNTAX_ATT) {
625+
const char *arch = R_UNWRAP3 (a, config, arch);
626+
// Get the encoder plugin to check its syntax support
627+
RArchSession *as = R_UNWRAP4 (a, analb.anal, arch, session);
628+
RArchPlugin *encoder_plugin = NULL;
629+
if (as) {
630+
// If encoder is separate, use that
631+
encoder_plugin = as->encoder ? as->encoder->plugin : as->plugin;
632+
}
633+
// Check if encoder supports ATT syntax natively
634+
bool encoder_supports_att = encoder_plugin && (encoder_plugin->encode_syntax & R_ARCH_SYNTAX_MASK_ATT);
635+
// Only convert for x86 if encoder doesn't support ATT natively
636+
if (!encoder_supports_att && arch && r_str_startswith (arch, "x86")) {
637+
char *intel = r_str_att2intel (b);
638+
if (intel) {
639+
free (b);
640+
b = intel;
641+
}
629642
}
630643
}
631644
r_str_case (b, false); // to-lower

libr/include/r_arch.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ typedef bool (*RArchPluginInitCallback)(RArchSession *s);
151151
typedef bool (*RArchPluginFiniCallback)(RArchSession *s);
152152
typedef bool (*RArchPluginEsilCallback)(RArchSession *s, RArchEsilAction action);
153153

154+
// Bitmask for supported syntax modes in arch plugins
155+
#define R_ARCH_SYNTAX_MASK_INTEL (1 << R_ARCH_SYNTAX_INTEL)
156+
#define R_ARCH_SYNTAX_MASK_ATT (1 << R_ARCH_SYNTAX_ATT)
157+
#define R_ARCH_SYNTAX_MASK_MASM (1 << R_ARCH_SYNTAX_MASM)
158+
154159
// TODO: use `const char *const` instead of `char*`
155160
typedef struct r_arch_plugin_t {
156161
RPluginMeta meta;
@@ -161,6 +166,7 @@ typedef struct r_arch_plugin_t {
161166
ut32 endian;
162167
RSysBits bits;
163168
RSysBits addr_bits;
169+
ut32 encode_syntax; // bitmask of R_ARCH_SYNTAX_MASK_* for encoder-supported syntaxes (0 = Intel only, default)
164170

165171
const RArchPluginInitCallback init;
166172
const RArchPluginFiniCallback fini;

libr/util/str_att.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@
22

33
#include <r_util.h>
44

5-
// Generic AT&T to Intel syntax conversion
6-
// This handles the common cases that work across architectures:
5+
// x86-specific AT&T to Intel syntax conversion
6+
// This handles x86 AT&T syntax conversion to Intel syntax for assemblers that
7+
// only support Intel syntax. The conversion includes:
78
// - Remove % prefix from registers
89
// - Remove $ prefix from immediates
910
// - Swap operand order (AT&T: src, dst -> Intel: dst, src)
1011
// - Convert memory addressing ( ) to [ ]
12+
// - Strip AT&T size suffixes (l, q, b, w) from instructions
13+
//
14+
// Note: This is NOT generic across architectures. Most non-x86 architectures
15+
// use their own syntax and don't have AT&T/Intel distinction. The encoder
16+
// plugin's encode_syntax field should indicate if it supports ATT natively.
1117

1218
// instructions that take 2 operands and need swap (src, dst -> dst, src)
1319
static const char *ops_2swap[] = {

0 commit comments

Comments
 (0)