Skip to content

Commit 10bcb0a

Browse files
committed
[Rust] Fix missing operand field when round tripping text tokens
Fixes #8028
1 parent 64aae45 commit 10bcb0a

4 files changed

Lines changed: 75 additions & 5 deletions

File tree

arch/msp430/src/architecture.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ fn generate_jxx_tokens(inst: &impl Jxx, addr: u64) -> Vec<InstructionTextToken>
464464
InstructionTextTokenKind::CodeRelativeAddress {
465465
value: fixed_addr,
466466
size: None,
467+
operand: None,
467468
},
468469
));
469470

@@ -560,6 +561,7 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
560561
InstructionTextTokenKind::Integer {
561562
value: *i as u64,
562563
size: None,
564+
operand: None,
563565
},
564566
),
565567
InstructionTextToken::new("(", InstructionTextTokenKind::Text),
@@ -579,6 +581,7 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
579581
InstructionTextTokenKind::Integer {
580582
value: *i as u64,
581583
size: None,
584+
operand: None,
582585
},
583586
),
584587
InstructionTextToken::new("(", InstructionTextTokenKind::Text),
@@ -598,6 +601,7 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
598601
InstructionTextTokenKind::Integer {
599602
value: *i as u64,
600603
size: None,
604+
operand: None,
601605
},
602606
),
603607
InstructionTextToken::new("(", InstructionTextTokenKind::Text),
@@ -617,6 +621,7 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
617621
InstructionTextTokenKind::Integer {
618622
value: *i as u64,
619623
size: None,
624+
operand: None,
620625
},
621626
),
622627
InstructionTextToken::new("(", InstructionTextTokenKind::Text),
@@ -636,6 +641,7 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
636641
InstructionTextTokenKind::Integer {
637642
value: *i as u64,
638643
size: None,
644+
operand: None,
639645
},
640646
),
641647
InstructionTextToken::new("(", InstructionTextTokenKind::Text),
@@ -673,7 +679,11 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
673679
let value = (addr as i64 + *i as i64) as u64;
674680
vec![InstructionTextToken::new(
675681
format!("{value:#x}"),
676-
InstructionTextTokenKind::CodeRelativeAddress { value, size: None },
682+
InstructionTextTokenKind::CodeRelativeAddress {
683+
value,
684+
size: None,
685+
operand: None,
686+
},
677687
)]
678688
}
679689
Operand::Immediate(i) => {
@@ -683,6 +693,7 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
683693
InstructionTextTokenKind::CodeRelativeAddress {
684694
value: *i as u64,
685695
size: None,
696+
operand: None,
686697
},
687698
)]
688699
} else {
@@ -691,6 +702,7 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
691702
InstructionTextTokenKind::PossibleAddress {
692703
value: *i as u64,
693704
size: None,
705+
operand: None,
694706
},
695707
)]
696708
}
@@ -702,6 +714,7 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
702714
InstructionTextTokenKind::CodeRelativeAddress {
703715
value: *a as u64,
704716
size: None,
717+
operand: None,
705718
},
706719
)]
707720
} else {
@@ -710,6 +723,7 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
710723
InstructionTextTokenKind::PossibleAddress {
711724
value: *a as u64,
712725
size: None,
726+
operand: None,
713727
},
714728
)]
715729
}
@@ -728,6 +742,7 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
728742
InstructionTextTokenKind::Integer {
729743
value: *i as u64,
730744
size: None,
745+
operand: None,
731746
},
732747
),
733748
]

arch/riscv/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,7 @@ impl<D: RiscVDisassembler> Architecture for RiscVArch<D> {
11251125
CodeRelativeAddress {
11261126
value: target,
11271127
size: Some(self.address_size()),
1128+
operand: None,
11281129
},
11291130
));
11301131
}
@@ -1137,6 +1138,7 @@ impl<D: RiscVDisassembler> Architecture for RiscVArch<D> {
11371138
Integer {
11381139
value: i as u64,
11391140
size: None,
1141+
operand: None,
11401142
},
11411143
));
11421144
}
@@ -1155,6 +1157,7 @@ impl<D: RiscVDisassembler> Architecture for RiscVArch<D> {
11551157
Integer {
11561158
value: i as u64,
11571159
size: None,
1160+
operand: None,
11581161
},
11591162
));
11601163

plugins/dwarf/dwarfdump/src/lib.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ fn get_info_string<R: Reader>(
142142
InstructionTextTokenKind::Integer {
143143
value: addr,
144144
size: None,
145+
operand: None,
145146
},
146147
));
147148
} else if let Ok(attr_reader) = dwarf.attr_string(unit, attr.value()) {
@@ -180,6 +181,7 @@ fn get_info_string<R: Reader>(
180181
InstructionTextTokenKind::Integer {
181182
value: 1,
182183
size: None,
184+
operand: None,
183185
},
184186
));
185187
} else if let Flag(false) = attr.value() {
@@ -188,6 +190,7 @@ fn get_info_string<R: Reader>(
188190
InstructionTextTokenKind::Integer {
189191
value: 0,
190192
size: None,
193+
operand: None,
191194
},
192195
));
193196

@@ -199,6 +202,7 @@ fn get_info_string<R: Reader>(
199202
InstructionTextTokenKind::Integer {
200203
value: value as u64,
201204
size: None,
205+
operand: None,
202206
},
203207
));
204208
} else if let Some(value) = attr.u16_value() {
@@ -208,13 +212,18 @@ fn get_info_string<R: Reader>(
208212
InstructionTextTokenKind::Integer {
209213
value: value as u64,
210214
size: None,
215+
operand: None,
211216
},
212217
));
213218
} else if let Some(value) = attr.udata_value() {
214219
let value_string = format!("{}", value);
215220
attr_line.push(InstructionTextToken::new(
216221
&value_string,
217-
InstructionTextTokenKind::Integer { value, size: None },
222+
InstructionTextTokenKind::Integer {
223+
value,
224+
size: None,
225+
operand: None,
226+
},
218227
));
219228
} else if let Some(value) = attr.sdata_value() {
220229
let value_string = format!("{}", value);
@@ -223,6 +232,7 @@ fn get_info_string<R: Reader>(
223232
InstructionTextTokenKind::Integer {
224233
value: value as u64,
225234
size: None,
235+
operand: None,
226236
},
227237
));
228238
} else {

rust/src/disassembly.rs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -394,17 +394,34 @@ unsafe impl CoreArrayProviderInner for Array<InstructionTextToken> {
394394
pub enum InstructionTextTokenKind {
395395
Text,
396396
Instruction,
397+
/// Separator between operands, such as `,` or `+`.
398+
///
399+
/// This is primarily used to identify the tokens associated with a given operand.
397400
OperandSeparator,
398401
Register,
399402
Integer {
400403
value: u64,
401404
/// Size of the integer
402405
size: Option<usize>,
406+
/// The operand this integer is associated with.
407+
///
408+
/// This is primarily used to change the display type of the integer.
409+
///
410+
/// NOTE: This will be populated by a post-processing step when rendering, so you can leave this
411+
/// as `None` when emitting in [`Architecture::instruction_text`] and other similar methods.
412+
operand: Option<usize>,
403413
},
404414
PossibleAddress {
405415
value: u64,
406416
/// Size of the address
407417
size: Option<usize>,
418+
/// The operand this integer is associated with.
419+
///
420+
/// This is primarily used to change the display type of the integer.
421+
///
422+
/// NOTE: This will be populated by a post-processing step when rendering, so you can leave this
423+
/// as `None` when emitting in [`Architecture::instruction_text`] and other similar methods.
424+
operand: Option<usize>,
408425
},
409426
BeginMemoryOperand,
410427
EndMemoryOperand,
@@ -416,7 +433,15 @@ pub enum InstructionTextTokenKind {
416433
Annotation,
417434
CodeRelativeAddress {
418435
value: u64,
436+
/// Size of the address
419437
size: Option<usize>,
438+
/// The operand this integer is associated with.
439+
///
440+
/// This is primarily used to change the display type of the integer.
441+
///
442+
/// NOTE: This will be populated by a post-processing step when rendering, so you can leave this
443+
/// as `None` when emitting in [`Architecture::instruction_text`] and other similar methods.
444+
operand: Option<usize>,
420445
},
421446
ArgumentName {
422447
// TODO: The argument index?
@@ -443,7 +468,15 @@ pub enum InstructionTextTokenKind {
443468
StringContent {
444469
ty: StringType,
445470
},
446-
CharacterConstant,
471+
CharacterConstant {
472+
/// The operand this character is associated with.
473+
///
474+
/// This is primarily used to change the display type of the character.
475+
///
476+
/// NOTE: This will be populated by a post-processing step when rendering, so you can leave this
477+
/// as `None` when emitting in [`Architecture::instruction_text`] and other similar methods.
478+
operand: Option<usize>,
479+
},
447480
Keyword {
448481
// Example usage can be found for `BNAnalysisWarningActionType`.
449482
value: u64,
@@ -579,13 +612,15 @@ impl InstructionTextTokenKind {
579612
0 => None,
580613
size => Some(size),
581614
},
615+
operand: Some(value.operand),
582616
},
583617
BNInstructionTextTokenType::PossibleAddressToken => Self::PossibleAddress {
584618
value: value.value,
585619
size: match value.size {
586620
0 => None,
587621
size => Some(size),
588622
},
623+
operand: Some(value.operand),
589624
},
590625
BNInstructionTextTokenType::BeginMemoryOperandToken => Self::BeginMemoryOperand,
591626
BNInstructionTextTokenType::EndMemoryOperandToken => Self::EndMemoryOperand,
@@ -603,6 +638,7 @@ impl InstructionTextTokenKind {
603638
0 => None,
604639
size => Some(size),
605640
},
641+
operand: Some(value.operand),
606642
},
607643
BNInstructionTextTokenType::ArgumentNameToken => {
608644
Self::ArgumentName { value: value.value }
@@ -640,7 +676,9 @@ impl InstructionTextTokenKind {
640676
}
641677
_ => Self::String { value: value.value },
642678
},
643-
BNInstructionTextTokenType::CharacterConstantToken => Self::CharacterConstant,
679+
BNInstructionTextTokenType::CharacterConstantToken => Self::CharacterConstant {
680+
operand: Some(value.operand),
681+
},
644682
BNInstructionTextTokenType::KeywordToken => Self::Keyword { value: value.value },
645683
BNInstructionTextTokenType::TypeNameToken => Self::TypeName,
646684
BNInstructionTextTokenType::FieldNameToken => Self::FieldName {
@@ -799,6 +837,10 @@ impl InstructionTextTokenKind {
799837
/// Mapping to the [`BNInstructionTextTokenType::operand`] field.
800838
fn try_operand(&self) -> Option<usize> {
801839
match self {
840+
InstructionTextTokenKind::Integer { operand, .. } => *operand,
841+
InstructionTextTokenKind::PossibleAddress { operand, .. } => *operand,
842+
InstructionTextTokenKind::CodeRelativeAddress { operand, .. } => *operand,
843+
InstructionTextTokenKind::CharacterConstant { operand, .. } => *operand,
802844
InstructionTextTokenKind::LocalVariable { ssa_version, .. } => Some(*ssa_version),
803845
InstructionTextTokenKind::IndirectImport { source_operand, .. } => {
804846
Some(*source_operand)
@@ -866,7 +908,7 @@ impl From<InstructionTextTokenKind> for BNInstructionTextTokenType {
866908
InstructionTextTokenKind::StringContent { .. } => {
867909
BNInstructionTextTokenType::StringToken
868910
}
869-
InstructionTextTokenKind::CharacterConstant => {
911+
InstructionTextTokenKind::CharacterConstant { .. } => {
870912
BNInstructionTextTokenType::CharacterConstantToken
871913
}
872914
InstructionTextTokenKind::Keyword { .. } => BNInstructionTextTokenType::KeywordToken,

0 commit comments

Comments
 (0)