Kaynağa Gözat

Merge pull request #70 from clairechingching/master

fix: incorrect .dynamic .dysym .rel.dym link
Claire Fan 3 gün önce
ebeveyn
işleme
d408635766

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

@@ -114,6 +114,7 @@ impl Program {
                     rel_dyns.push(RelDyn::new(offset + elf_header.e_entry, rel_type as u64, 0));
                 }
             }
+            // create four dynamic related sections
             let mut dynamic_section = SectionType::Dynamic(DynamicSection::new(
                 (section_names
                     .iter()
@@ -121,11 +122,6 @@ impl Program {
                     .sum::<usize>()
                     + 1) as u32,
             ));
-            dynamic_section.set_offset(current_offset);
-            if let SectionType::Dynamic(ref mut dynamic_section) = dynamic_section {
-                dynamic_section.set_rel_count(rel_count);
-            }
-            current_offset += dynamic_section.size();
             section_names.push(dynamic_section.name().to_string());
 
             let mut dynsym_section = SectionType::DynSym(DynSymSection::new(
@@ -136,8 +132,6 @@ impl Program {
                     + 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 = SectionType::DynStr(DynStrSection::new(
@@ -148,8 +142,6 @@ impl Program {
                     + 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 = SectionType::RelDyn(RelDynSection::new(
@@ -160,9 +152,50 @@ impl Program {
                     + 1) as u32,
                 rel_dyns,
             ));
+            section_names.push(rel_dyn_section.name().to_string());
+
+            dynamic_section.set_offset(current_offset);
+            if let SectionType::Dynamic(ref mut dynamic_section) = dynamic_section {
+                // link to .dynstr
+                dynamic_section.set_link(
+                    section_names
+                        .iter()
+                        .position(|name| name == ".dynstr")
+                        .expect("missing .dynstr section") as u32
+                        + 1,
+                );
+                dynamic_section.set_rel_count(rel_count);
+            }
+            current_offset += dynamic_section.size();
+
+            dynsym_section.set_offset(current_offset);
+            if let SectionType::DynSym(ref mut dynsym_section) = dynsym_section {
+                // link to .dynstr
+                dynsym_section.set_link(
+                    section_names
+                        .iter()
+                        .position(|name| name == ".dynstr")
+                        .expect("missing .dynstr section") as u32
+                        + 1,
+                );
+            }
+            current_offset += dynsym_section.size();
+
+            dynstr_section.set_offset(current_offset);
+            current_offset += dynstr_section.size();
+
             rel_dyn_section.set_offset(current_offset);
+            if let SectionType::RelDyn(ref mut rel_dyn_section) = rel_dyn_section {
+                // link to .dynsym
+                rel_dyn_section.set_link(
+                    section_names
+                        .iter()
+                        .position(|name| name == ".dynsym")
+                        .expect("missing .dynsym section") as u32
+                        + 1,
+                );
+            }
             current_offset += rel_dyn_section.size();
-            section_names.push(rel_dyn_section.name().to_string());
 
             if let SectionType::Dynamic(ref mut dynamic_section) = dynamic_section {
                 dynamic_section.set_rel_offset(rel_dyn_section.offset());

+ 21 - 3
crates/assembler/src/section.rs

@@ -309,6 +309,7 @@ pub struct DynamicSection {
     name: String,
     name_offset: u32,
     offset: u64,
+    link: u32,
     rel_offset: u64,
     rel_size: u64,
     rel_count: u64,
@@ -323,6 +324,7 @@ impl DynamicSection {
             name: String::from(".dynamic"),
             name_offset,
             offset: 0,
+            link: 0,
             rel_offset: 0,
             rel_size: 0,
             rel_count: 0,
@@ -336,6 +338,10 @@ impl DynamicSection {
         self.offset = offset;
     }
 
+    pub fn set_link(&mut self, link: u32) {
+        self.link = link;
+    }
+
     pub fn set_rel_offset(&mut self, offset: u64) {
         self.rel_offset = offset;
     }
@@ -368,7 +374,7 @@ impl DynamicSection {
             self.offset,
             self.offset,
             self.size(),
-            5,
+            self.link,
             0,
             8,
             16,
@@ -520,6 +526,7 @@ pub struct DynSymSection {
     name: String,
     name_offset: u32,
     offset: u64,
+    link: u32,
     symbols: Vec<DynamicSymbol>,
 }
 
@@ -529,6 +536,7 @@ impl DynSymSection {
             name: String::from(".dynsym"),
             name_offset,
             offset: 0,
+            link: 0,
             symbols,
         }
     }
@@ -537,6 +545,10 @@ impl DynSymSection {
         self.offset = offset;
     }
 
+    pub fn set_link(&mut self, link: u32) {
+        self.link = link;
+    }
+
     pub fn section_header_bytecode(&self) -> Vec<u8> {
         let flags = SectionHeader::SHF_ALLOC;
         SectionHeader::new(
@@ -546,7 +558,7 @@ impl DynSymSection {
             self.offset,
             self.offset,
             self.size(),
-            5,
+            self.link,
             1,
             8,
             24,
@@ -579,6 +591,7 @@ pub struct RelDynSection {
     name: String,
     name_offset: u32,
     offset: u64,
+    link: u32,
     entries: Vec<RelDyn>,
 }
 
@@ -588,6 +601,7 @@ impl RelDynSection {
             name: String::from(".rel.dyn"),
             name_offset,
             offset: 0,
+            link: 0,
             entries,
         }
     }
@@ -596,6 +610,10 @@ impl RelDynSection {
         self.offset = offset;
     }
 
+    pub fn set_link(&mut self, link: u32) {
+        self.link = link;
+    }
+
     pub fn size(&self) -> u64 {
         (self.entries.len() * 16) as u64 // Each RelDyn entry is 16 bytes
     }
@@ -609,7 +627,7 @@ impl RelDynSection {
             self.offset,
             self.offset,
             self.size(),
-            4,
+            self.link,
             0,
             8,
             16,

+ 2 - 2
crates/assembler/tests/fixtures/index.toml

@@ -4,7 +4,7 @@ hash = "c13b88606e194b06e9acba56b2cdc46c92895b17006a8df0eb8e80df6a8e94b9"
 
 [cases.calls]
 file = "calls.s"
-hash = "8ac48356694172cae5e47109804d1a3550e5cdd441c6c85bf7da957b1570e0e1"
+hash = "721f1b40d11288f841a71d84378da9c1fb1227008dc3b9493d326bf39e1466c1"
 
 [cases.equ]
 file = "equ.s"
@@ -16,7 +16,7 @@ hash = "7be6d8971386a6fb59845d0353d688183677b3115cc683cddfc2d636efa01bc0"
 
 [cases.neg64]
 file = "neg64.s"
-hash = "cdc53c03d3c3455ab27d98a8f82086fc7a5f2d4427d08e6bd6f1cc218f5fbeb5"
+hash = "330570ef597e21b67aa44abe00f31766739c81dbbb2e8a555734dd727d1e7851"
 
 [cases.ro_bytearray]
 file = "ro_bytearray.s"

+ 4 - 2
crates/disassembler/src/program.rs

@@ -21,8 +21,10 @@ pub struct Program {
 
 impl Program {
     pub fn from_bytes(b: &[u8]) -> Result<Self, DisassemblerError> {
-        let elf_file = ElfFile64::<Endianness>::parse(b)
-            .map_err(|_| DisassemblerError::NonStandardElfHeader)?;
+        let elf_file = ElfFile64::<Endianness>::parse(b).map_err(|e| {
+            eprintln!("ELF parse error: {}", e);
+            DisassemblerError::NonStandardElfHeader
+        })?;
 
         // Parse elf header.
         let elf_header = ELFHeader::from_elf_file(&elf_file)?;