|
@@ -6,7 +6,7 @@ use sbpf_assembler::opcode::Opcode;
|
|
|
use sbpf_assembler::parser::ParseResult;
|
|
use sbpf_assembler::parser::ParseResult;
|
|
|
|
|
|
|
|
use object::RelocationTarget::Symbol;
|
|
use object::RelocationTarget::Symbol;
|
|
|
-use object::{File, Object, ObjectSection, ObjectSymbol};
|
|
|
|
|
|
|
+use object::{File, Object as _, ObjectSection as _, ObjectSymbol as _};
|
|
|
|
|
|
|
|
use std::collections::HashMap;
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
@@ -21,16 +21,19 @@ pub fn parse_bytecode(bytes: &[u8]) -> Result<ParseResult, SbpfLinkerError> {
|
|
|
// only handle symbols in the .rodata section for now
|
|
// only handle symbols in the .rodata section for now
|
|
|
let mut rodata_offset = 0;
|
|
let mut rodata_offset = 0;
|
|
|
for symbol in obj.symbols() {
|
|
for symbol in obj.symbols() {
|
|
|
- if symbol.section_index() == Some(ro_section.index()) && symbol.size() > 0 {
|
|
|
|
|
|
|
+ if symbol.section_index() == Some(ro_section.index())
|
|
|
|
|
+ && symbol.size() > 0
|
|
|
|
|
+ {
|
|
|
let mut bytes = Vec::new();
|
|
let mut bytes = Vec::new();
|
|
|
for i in 0..symbol.size() {
|
|
for i in 0..symbol.size() {
|
|
|
- bytes.push(ImmediateValue::Int(
|
|
|
|
|
- ro_section.data().unwrap()[(symbol.address() + i) as usize] as i64,
|
|
|
|
|
- ));
|
|
|
|
|
|
|
+ bytes.push(ImmediateValue::Int(i64::from(
|
|
|
|
|
+ ro_section.data().unwrap()
|
|
|
|
|
+ [(symbol.address() + i) as usize],
|
|
|
|
|
+ )));
|
|
|
}
|
|
}
|
|
|
ast.rodata_nodes.push(ASTNode::ROData {
|
|
ast.rodata_nodes.push(ASTNode::ROData {
|
|
|
rodata: ROData {
|
|
rodata: ROData {
|
|
|
- name: symbol.name().unwrap().to_string(),
|
|
|
|
|
|
|
+ name: symbol.name().unwrap().to_owned(),
|
|
|
args: vec![
|
|
args: vec![
|
|
|
Token::Directive(String::from("byte"), 0..1), //
|
|
Token::Directive(String::from("byte"), 0..1), //
|
|
|
Token::VectorLiteral(bytes.clone(), 0..1),
|
|
Token::VectorLiteral(bytes.clone(), 0..1),
|
|
@@ -39,7 +42,10 @@ pub fn parse_bytecode(bytes: &[u8]) -> Result<ParseResult, SbpfLinkerError> {
|
|
|
},
|
|
},
|
|
|
offset: rodata_offset,
|
|
offset: rodata_offset,
|
|
|
});
|
|
});
|
|
|
- rodata_table.insert(symbol.address(), symbol.name().unwrap().to_string());
|
|
|
|
|
|
|
+ rodata_table.insert(
|
|
|
|
|
+ symbol.address(),
|
|
|
|
|
+ symbol.name().unwrap().to_owned(),
|
|
|
|
|
+ );
|
|
|
rodata_offset += symbol.size();
|
|
rodata_offset += symbol.size();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -52,10 +58,11 @@ pub fn parse_bytecode(bytes: &[u8]) -> Result<ParseResult, SbpfLinkerError> {
|
|
|
// lddw takes 16 bytes, other instructions take 8 bytes
|
|
// lddw takes 16 bytes, other instructions take 8 bytes
|
|
|
let mut offset = 0;
|
|
let mut offset = 0;
|
|
|
while offset < section.data().unwrap().len() {
|
|
while offset < section.data().unwrap().len() {
|
|
|
- let node_len = match Opcode::from_u8(section.data().unwrap()[offset]) {
|
|
|
|
|
- Some(Opcode::Lddw) => 16,
|
|
|
|
|
- _ => 8,
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ let node_len =
|
|
|
|
|
+ match Opcode::from_u8(section.data().unwrap()[offset]) {
|
|
|
|
|
+ Some(Opcode::Lddw) => 16,
|
|
|
|
|
+ _ => 8,
|
|
|
|
|
+ };
|
|
|
let node = §ion.data().unwrap()[offset..offset + node_len];
|
|
let node = §ion.data().unwrap()[offset..offset + node_len];
|
|
|
ast.nodes.push(ASTNode::Instruction {
|
|
ast.nodes.push(ASTNode::Instruction {
|
|
|
instruction: Instruction::from_bytes(node).unwrap(),
|
|
instruction: Instruction::from_bytes(node).unwrap(),
|
|
@@ -72,9 +79,11 @@ pub fn parse_bytecode(bytes: &[u8]) -> Result<ParseResult, SbpfLinkerError> {
|
|
|
Symbol(sym) => Some(obj.symbol_by_index(sym).unwrap()),
|
|
Symbol(sym) => Some(obj.symbol_by_index(sym).unwrap()),
|
|
|
_ => None,
|
|
_ => None,
|
|
|
};
|
|
};
|
|
|
- println!("Symbol: {:?}", symbol);
|
|
|
|
|
|
|
+ println!("Symbol: {symbol:?}");
|
|
|
|
|
|
|
|
- if symbol.unwrap().section_index() == Some(ro_section.index()) {
|
|
|
|
|
|
|
+ if symbol.unwrap().section_index()
|
|
|
|
|
+ == Some(ro_section.index())
|
|
|
|
|
+ {
|
|
|
println!("Relocation found");
|
|
println!("Relocation found");
|
|
|
// addend is not explicit in the relocation entry, but implicitly encoded
|
|
// addend is not explicit in the relocation entry, but implicitly encoded
|
|
|
// as the immediate value of the instruction
|
|
// as the immediate value of the instruction
|
|
@@ -86,16 +95,21 @@ pub fn parse_bytecode(bytes: &[u8]) -> Result<ParseResult, SbpfLinkerError> {
|
|
|
.unwrap()
|
|
.unwrap()
|
|
|
.clone()
|
|
.clone()
|
|
|
{
|
|
{
|
|
|
- Token::ImmediateValue(ImmediateValue::Int(val), _) => val,
|
|
|
|
|
|
|
+ Token::ImmediateValue(
|
|
|
|
|
+ ImmediateValue::Int(val),
|
|
|
|
|
+ _,
|
|
|
|
|
+ ) => val,
|
|
|
_ => 0,
|
|
_ => 0,
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// Replace the immediate value with the rodata label
|
|
// Replace the immediate value with the rodata label
|
|
|
- let ro_label = rodata_table.get(&(addend as u64)).unwrap();
|
|
|
|
|
|
|
+ let ro_label = &rodata_table[&(addend as u64)];
|
|
|
let ro_label_name = ro_label.clone();
|
|
let ro_label_name = ro_label.clone();
|
|
|
- let node: &mut Instruction = ast.get_instruction_at_offset(rel.0).unwrap();
|
|
|
|
|
|
|
+ let node: &mut Instruction =
|
|
|
|
|
+ ast.get_instruction_at_offset(rel.0).unwrap();
|
|
|
let last_idx = node.operands.len() - 1;
|
|
let last_idx = node.operands.len() - 1;
|
|
|
- node.operands[last_idx] = Token::Identifier(ro_label_name, 0..1);
|
|
|
|
|
|
|
+ node.operands[last_idx] =
|
|
|
|
|
+ Token::Identifier(ro_label_name, 0..1);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|