Prechádzať zdrojové kódy

fix/misc: lddw with i64 numbder; const_fold func min token num/add key-pair creation back

Claire xyz 4 mesiacov pred
rodič
commit
39fe5be2b1

+ 32 - 2
crates/assembler/src/astnode.rs

@@ -24,7 +24,6 @@ pub enum ASTNode {
     },
 }
 
-// remove this
 #[derive(Debug, Clone)]
 pub struct Directive {
     pub name: String,
@@ -159,6 +158,26 @@ impl ASTNode {
                 if *opcode == Opcode::Call {
                     // currently hardcoded to call sol_log_
                     bytes.extend_from_slice(&[0x10, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF]);
+                } else if *opcode == Opcode::Lddw {
+                    match &operands[..] {
+                        [Token::Register(reg, _), Token::ImmediateValue(imm, _)] => {
+                            // 1 byte register number (strip 'r' prefix)
+                            bytes.push(*reg);
+                            
+                            // 2 bytes of zeros (offset/reserved)
+                            bytes.extend_from_slice(&[0, 0]);
+
+                            // 8 bytes immediate value in little-endian
+                            let imm64 = match imm {
+                                ImmediateValue::Int(val) => *val as i64,
+                                ImmediateValue::Addr(val) => *val as i64,
+                            };
+                            bytes.extend_from_slice(&imm64.to_le_bytes()[..4]);
+                            bytes.extend_from_slice(&[0, 0, 0, 0]);
+                            bytes.extend_from_slice(&imm64.to_le_bytes()[4..8]);
+                        }
+                        _ => {}
+                    }
                 } else {
                     match &operands[..] {
                         [Token::ImmediateValue(imm, _)] => {
@@ -242,7 +261,6 @@ impl ASTNode {
                             let reg_byte = (reg << 4) | dst;
                             bytes.push(reg_byte);
                             
-                            // TODO : should only be an int
                             // Add the offset as a 16-bit value in little-endian
                             let offset16 = match offset {
                                 ImmediateValue::Int(val) => *val as u16,
@@ -250,6 +268,18 @@ impl ASTNode {
                             };
                             bytes.extend_from_slice(&offset16.to_le_bytes());
                         },
+                        [Token::Register(reg, _), Token::ImmediateValue(offset, _), Token::Register(dst, _)] => {
+                            // Combine base register and destination register into a single byte
+                            let reg_byte = (dst << 4) | reg;
+                            bytes.push(reg_byte);
+                            
+                            // Add the offset as a 16-bit value in little-endian
+                            let offset16 = match offset {
+                                ImmediateValue::Int(val) => *val as u16,
+                                ImmediateValue::Addr(val) => *val as u16,
+                            };
+                            bytes.extend_from_slice(&offset16.to_le_bytes());
+                        }
                         
                         _ => {}
                     }

+ 6 - 2
crates/assembler/src/lexer.rs

@@ -17,7 +17,9 @@ impl std::ops::Add for ImmediateValue {
     fn add(self, other: Self) -> ImmediateValue {
         match (self, other) {
             (ImmediateValue::Int(a), ImmediateValue::Int(b)) => ImmediateValue::Int(a + b),
-            _ => panic!("Invalid addition of ImmediateValue"),
+            (ImmediateValue::Addr(a), ImmediateValue::Addr(b)) => ImmediateValue::Addr(a + b),
+            (ImmediateValue::Int(a), ImmediateValue::Addr(b)) => ImmediateValue::Addr(a + b),
+            (ImmediateValue::Addr(a), ImmediateValue::Int(b)) => ImmediateValue::Addr(a + b),
         }
     }
 }
@@ -27,7 +29,9 @@ impl std::ops::Sub for ImmediateValue {
     fn sub(self, other: Self) -> ImmediateValue {
         match (self, other) {
             (ImmediateValue::Int(a), ImmediateValue::Int(b)) => ImmediateValue::Int(a - b),
-            _ => panic!("Invalid subtraction of ImmediateValue"),
+            (ImmediateValue::Addr(a), ImmediateValue::Addr(b)) => ImmediateValue::Addr(a - b),
+            (ImmediateValue::Int(a), ImmediateValue::Addr(b)) => ImmediateValue::Addr(a - b),
+            (ImmediateValue::Addr(a), ImmediateValue::Int(b)) => ImmediateValue::Addr(a - b),
         }
     }
 }

+ 9 - 3
crates/assembler/src/parser.rs

@@ -44,6 +44,7 @@ pub trait Parse {
         where Self: Sized;
 }
 
+// can maybe be removed
 pub trait ParseInstruction {
     fn parse_instruction<'a>(tokens: &'a [Token], const_map: &HashMap<String, ImmediateValue>) -> Option<(Self, &'a [Token])>
         where Self: Sized;
@@ -442,9 +443,10 @@ fn inline_and_fold_constant_helper(tokens: &[Token]
                                 , const_map: &HashMap<String, ImmediateValue>   //
                                 , value: ImmediateValue                         //
                                 , idx: usize) -> (Option<ImmediateValue>, usize) {
-    if tokens.len() < idx + 1 {
+    if tokens.len() < idx + 3 {
         return (Some(value), idx + 1);
     }
+
     match (
         &tokens[idx + 1],
         &tokens[idx + 2],
@@ -454,8 +456,12 @@ fn inline_and_fold_constant_helper(tokens: &[Token]
             Token::ImmediateValue(value2, _)
         ) => {
             let result = match op {
-                Op::Add => value + value2.clone(),
-                Op::Sub => value - value2.clone(),
+                Op::Add => {
+                    value + value2.clone()
+                }
+                Op::Sub => {
+                    value - value2.clone()
+                }
             };
             inline_and_fold_constant_helper(tokens, const_map, result, idx + 2)
         }

+ 8 - 10
crates/assembler/src/program.rs

@@ -79,8 +79,6 @@ impl Program {
             dyn_syms.push(DynamicSymbol::new(0, 0, 0, 0, 0, 0));
 
             // all symbols handled right now are all global symbols
-            // TODO: handle local symbols
-
             for (name, _) in dynamic_symbols.get_entry_points() {
                 symbol_names.push(name.clone());
                 dyn_syms.push(DynamicSymbol::new(dyn_str_offset as u32, 0x10, 0, 1, elf_header.e_entry, 0));
@@ -115,17 +113,17 @@ impl Program {
             current_offset += dynamic_section.size();
             section_names.push(dynamic_section.name().to_string());
 
-            let mut dynsym_section = DynSymSection::new((section_names.iter().map(|name| name.len() + 1).sum::<usize>() + 1) as u32, dyn_syms);
+            let mut dynsym_section = SectionType::DynSym(DynSymSection::new((section_names.iter().map(|name| name.len() + 1).sum::<usize>() + 1) as u32, dyn_syms));
             dynsym_section.set_offset(current_offset);
             current_offset += dynsym_section.size();
             section_names.push(dynsym_section.name().to_string());
 
-            let mut dynstr_section = DynStrSection::new((section_names.iter().map(|name| name.len() + 1).sum::<usize>() + 1) as u32, symbol_names);
+            let mut dynstr_section = SectionType::DynStr(DynStrSection::new((section_names.iter().map(|name| name.len() + 1).sum::<usize>() + 1) as u32, symbol_names));
             dynstr_section.set_offset(current_offset);
             current_offset += dynstr_section.size();
             section_names.push(dynstr_section.name().to_string());
 
-            let mut rel_dyn_section = RelDynSection::new((section_names.iter().map(|name| name.len() + 1).sum::<usize>() + 1) as u32, rel_dyns);
+            let mut rel_dyn_section = SectionType::RelDyn(RelDynSection::new((section_names.iter().map(|name| name.len() + 1).sum::<usize>() + 1) as u32, rel_dyns));
             rel_dyn_section.set_offset(current_offset);
             current_offset += rel_dyn_section.size();
             section_names.push(rel_dyn_section.name().to_string());
@@ -138,7 +136,7 @@ impl Program {
                 dynamic_section.set_dynstr_size(dynstr_section.size());
             }
 
-            let mut shstrtab_section = ShStrTabSection::new((section_names.iter().map(|name| name.len() + 1).sum::<usize>() + 1) as u32, section_names);
+            let mut shstrtab_section = SectionType::ShStrTab(ShStrTabSection::new((section_names.iter().map(|name| name.len() + 1).sum::<usize>() + 1) as u32, section_names));
             shstrtab_section.set_offset(current_offset);
             current_offset += shstrtab_section.size();
 
@@ -154,10 +152,10 @@ impl Program {
             );
 
             sections.push(dynamic_section);
-            sections.push(SectionType::DynSym(dynsym_section));
-            sections.push(SectionType::DynStr(dynstr_section));
-            sections.push(SectionType::RelDyn(rel_dyn_section));
-            sections.push(SectionType::ShStrTab(shstrtab_section));
+            sections.push(dynsym_section);
+            sections.push(dynstr_section);
+            sections.push(rel_dyn_section);
+            sections.push(shstrtab_section);
 
             program_headers.push(ro_header);
             program_headers.push(dynamic_header);

+ 14 - 34
crates/assembler/src/section.rs

@@ -16,10 +16,15 @@ pub trait Section {
     fn bytecode(&self) -> Vec<u8> {
         Vec::new()  // Default empty bytecode
     }
-
+    
+    // fn get_size(&self) -> u64
     fn size(&self) -> u64 {
         self.bytecode().len() as u64
     }
+
+    // fn get_aligned_size(&self) -> u64
+
+    // fn section_header_bytecode(&self) -> Vec<u8>
 }
 
 // Code Section implementation
@@ -76,9 +81,6 @@ impl CodeSection {
         self.offset = offset;
     }
 
-    pub fn offset(&self) -> u64 {
-        self.offset
-    }
 
     pub fn section_header_bytecode(&self) -> Vec<u8> {
         let flags = SectionHeader::SHF_ALLOC | SectionHeader::SHF_EXECINSTR;
@@ -171,10 +173,6 @@ impl DataSection {
         self.offset = offset;
     }
 
-    pub fn offset(&self) -> u64 {
-        self.offset
-    }
-
     pub fn rodata(&self) -> Vec<(String, usize, String)> {
         let mut ro_data_labels = Vec::new();
         for node in &self.nodes {    
@@ -258,9 +256,6 @@ impl NullSection {
         ).bytecode()
     }
 
-    pub fn offset(&self) -> u64 {
-        self.offset
-    }
 }
 
 impl Section for NullSection {
@@ -308,9 +303,6 @@ impl ShStrTabSection {
         ).bytecode()
     }
 
-    pub fn offset(&self) -> u64 {
-        self.offset
-    }
 }
 
 impl Section for ShStrTabSection {
@@ -426,9 +418,6 @@ impl DynamicSection {
         ).bytecode()
     }
 
-    pub fn offset(&self) -> u64 {
-        self.offset
-    }
 }
 
 impl Section for DynamicSection {
@@ -534,9 +523,6 @@ impl DynStrSection {
         ).bytecode()
     }
 
-    pub fn offset(&self) -> u64 {
-        self.offset
-    }
 }
 
 impl Section for DynStrSection {
@@ -612,9 +598,6 @@ impl DynSymSection {
         ).bytecode()
     }
 
-    pub fn offset(&self) -> u64 {
-        self.offset
-    }
 }
 
 impl Section for DynSymSection {
@@ -679,9 +662,6 @@ impl RelDynSection {
         ).bytecode()
     }
 
-    pub fn offset(&self) -> u64 {
-        self.offset
-    }
 }
 
 impl Section for RelDynSection {
@@ -784,14 +764,14 @@ impl SectionType {
 
     pub fn offset(&self) -> u64 {
         match self {
-            SectionType::Code(cs) => cs.offset(),
-            SectionType::Data(ds) => ds.offset(),
-            SectionType::ShStrTab(ss) => ss.offset(),
-            SectionType::Dynamic(ds) => ds.offset(),
-            SectionType::DynStr(ds) => ds.offset(),
-            SectionType::DynSym(ds) => ds.offset(),
-            SectionType::Default(ns) => ns.offset(),
-            SectionType::RelDyn(rs) => rs.offset(),
+            SectionType::Code(cs) => cs.offset,
+            SectionType::Data(ds) => ds.offset,
+            SectionType::ShStrTab(ss) => ss.offset,
+            SectionType::Dynamic(ds) => ds.offset,
+            SectionType::DynStr(ds) => ds.offset,
+            SectionType::DynSym(ds) => ds.offset,
+            SectionType::Default(ns) => ns.offset,
+            SectionType::RelDyn(rs) => rs.offset,
         }
     }
 }

+ 37 - 0
src/commands/build.rs

@@ -1,6 +1,9 @@
 use anyhow::{Error, Result};
 use dirs::home_dir;
 
+use ed25519_dalek::SigningKey;
+use rand::rngs::OsRng;
+
 use std::fs;
 use std::fs::create_dir_all;
 use std::io;
@@ -118,6 +121,40 @@ pub fn build() -> Result<()> {
         Ok(())
     }
 
+    // Function to check if keypair file exists.
+    fn has_keypair_file(dir: &Path) -> bool {
+        if dir.exists() && dir.is_dir() {
+            match fs::read_dir(dir) {
+                Ok(entries) => entries.filter_map(Result::ok).any(|entry| {
+                    entry
+                        .path()
+                        .file_name()
+                        .and_then(|name| name.to_str())
+                        .map(|name| name.ends_with("-keypair.json"))
+                        .unwrap_or(false)
+                }),
+                Err(_) => false,
+            }
+        } else {
+            false
+        }
+    }
+
+    // Check if keypair file exists. If not, create one.
+    let deploy_path = Path::new(deploy);
+    if !has_keypair_file(deploy_path) {
+        let project_path = std::env::current_dir()?;
+        let project_name = project_path
+            .file_name()
+            .and_then(|n| n.to_str())
+            .unwrap_or("program");
+        let mut rng = OsRng;
+        fs::write(
+            deploy_path.join(format!("{}-keypair.json", project_name)),
+            serde_json::json!(SigningKey::generate(&mut rng).to_keypair_bytes()[..]).to_string(),
+        )?;
+    }
+
     // Processing directories
     let src_path = Path::new(src);
     for entry in src_path.read_dir()? {

+ 38 - 0
src/commands/light_build.rs

@@ -1,5 +1,9 @@
 use sbpf_assembler::assemble;
 
+use ed25519_dalek::SigningKey;
+use rand::rngs::OsRng;
+use std::fs;
+
 use anyhow::Result;
 use std::path::Path;
 use std::time::Instant;
@@ -18,6 +22,40 @@ pub fn light_build() -> Result<()> {
         assemble(src, deploy)
     }
 
+    // Function to check if keypair file exists.
+    fn has_keypair_file(dir: &Path) -> bool {
+        if dir.exists() && dir.is_dir() {
+            match fs::read_dir(dir) {
+                Ok(entries) => entries.filter_map(Result::ok).any(|entry| {
+                    entry
+                        .path()
+                        .file_name()
+                        .and_then(|name| name.to_str())
+                        .map(|name| name.ends_with("-keypair.json"))
+                        .unwrap_or(false)
+                }),
+                Err(_) => false,
+            }
+        } else {
+            false
+        }
+    }
+
+    // Check if keypair file exists. If not, create one.
+    let deploy_path = Path::new(deploy);
+    if !has_keypair_file(deploy_path) {
+        let project_path = std::env::current_dir()?;
+        let project_name = project_path
+            .file_name()
+            .and_then(|n| n.to_str())
+            .unwrap_or("program");
+        let mut rng = OsRng;
+        fs::write(
+            deploy_path.join(format!("{}-keypair.json", project_name)),
+            serde_json::json!(SigningKey::generate(&mut rng).to_keypair_bytes()[..]).to_string(),
+        )?;
+    }
+
     // Processing directories
     let src_path = Path::new(src);
     for entry in src_path.read_dir()? {