From b9bd878207c6b784694c15675a09636d112242d7 Mon Sep 17 00:00:00 2001
From: David Li
Date: Mon, 4 Jan 2016 11:09:51 -0700
Subject: Implement initializing memory from text/data segments
---
src/binary.rs | 2 ++
src/lib.rs | 33 ++++++++++++++++++++++++++++++-
src/memory.rs | 45 +++++++++++++++++++++++++++++++++++++++++++
src/rust-elfloader/src/elf.rs | 20 +++++++++----------
4 files changed, 89 insertions(+), 11 deletions(-)
(limited to 'src')
diff --git a/src/binary.rs b/src/binary.rs
index 122af51..a1d447e 100644
--- a/src/binary.rs
+++ b/src/binary.rs
@@ -22,6 +22,7 @@ use std::num;
use std::path::Path;
use std::str;
+/// Representation of a binary
pub struct Binary {
pub words: Vec,
}
@@ -72,6 +73,7 @@ impl From for BinaryError {
}
impl Binary {
+ /// Load a binary from a hex file (generated with elf2hex)
pub fn new_from_hex_file(path: &Path) -> Result {
let file = try!(File::open(path));
let file = io::BufReader::new(file);
diff --git a/src/lib.rs b/src/lib.rs
index 5dda62e..1a176fd 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with rustv. If not, see .
-#![feature(braced_empty_structs, step_by)]
+#![feature(braced_empty_structs, clone_from_slice, raw, step_by)]
pub mod isa;
pub mod binary;
pub mod memory;
@@ -40,6 +40,37 @@ fn it_works() {
}
}
+#[test]
+fn test_elfloader() {
+ use std::io::prelude::*;
+ use std::fs::File;
+ extern crate elfloader;
+
+ let mut f = File::open("../riscv/kernel").unwrap();
+ let mut buffer = Vec::new();
+
+ f.read_to_end(&mut buffer).unwrap();
+
+ let elf = elfloader::ElfBinary::new("test", &buffer).unwrap();
+ println!("HEADERS");
+ for p in elf.program_headers() {
+ println!("{}", p);
+ }
+ for p in elf.section_headers() {
+ println!("{}", p);
+ if p.name.0 == 0x1b {
+ let data = elf.section_data(p);
+ print!("\t");
+ for x in data[0..8].iter() {
+ print!("{:02x}", x);
+ }
+ println!("");
+ }
+ }
+
+ println!("{:?}", elf);
+}
+
#[cfg(test)]
mod tests {
#[test]
diff --git a/src/memory.rs b/src/memory.rs
index 92aefd5..db0dca4 100644
--- a/src/memory.rs
+++ b/src/memory.rs
@@ -157,6 +157,31 @@ pub struct DirectMappedCache<'a> {
next_level: SharedMemory<'a>,
}
+fn copy_u8_into_u32(src: &[u8], dst: &mut [u32]) {
+ for (offset, word) in src.chunks(4).enumerate() {
+ let word = if word.len() == 4 {
+ (word[0] as u32) |
+ ((word[1] as u32) << 8) |
+ ((word[2] as u32) << 16) |
+ ((word[3] as u32) << 24)
+ }
+ else if word.len() == 3 {
+ (word[0] as u32) |
+ ((word[1] as u32) << 8) |
+ ((word[2] as u32) << 16)
+ }
+ else if word.len() == 2 {
+ (word[0] as u32) |
+ ((word[1] as u32) << 8)
+ }
+ else {
+ word[0] as u32
+ };
+
+ dst[offset] = word;
+ }
+}
+
impl Memory {
pub fn new(size: isa::Address) -> Memory {
Memory {
@@ -175,6 +200,26 @@ impl Memory {
memory: memory,
}
}
+
+ pub fn new_from_text_and_data(size: usize,
+ text: &[u8], text_offset: usize,
+ data: &[u8], data_offset: usize) -> Memory {
+ let mut memory = vec![0; size];
+
+ {
+ let mut text_segment = &mut memory[(text_offset / 4)..size];
+ copy_u8_into_u32(text, text_segment);
+ }
+
+ {
+ let mut data_segment = &mut memory[(data_offset / 4)..size];
+ copy_u8_into_u32(data, data_segment);
+ }
+
+ Memory {
+ memory: memory,
+ }
+ }
}
impl MemoryInterface for Memory {
diff --git a/src/rust-elfloader/src/elf.rs b/src/rust-elfloader/src/elf.rs
index 5a1df57..46b8eb8 100644
--- a/src/rust-elfloader/src/elf.rs
+++ b/src/rust-elfloader/src/elf.rs
@@ -641,7 +641,7 @@ impl fmt::Display for SectionType {
/// Wrapper type for SectionFlag
///
#[derive(Copy, Clone, PartialEq)]
-pub struct SectionFlag(pub u64);
+pub struct SectionFlag(pub u32);
/// Empty flags
pub const SHF_NONE : SectionFlag = SectionFlag(0);
@@ -704,19 +704,19 @@ pub struct SectionHeader {
/// Section Flags
pub flags: SectionFlag,
/// in-memory address where this section is loaded
- pub addr: u64,
+ pub addr: u32,
/// Byte-offset into the file where this section starts
- pub offset: u64,
+ pub offset: u32,
/// Section size in bytes
- pub size: u64,
+ pub size: u32,
/// Defined by section type
pub link: u32,
/// Defined by section type
pub info: u32,
/// address alignment
- pub addralign: u64,
+ pub addralign: u32,
/// size of an entry if section data is an array of entries
- pub entsize: u64,
+ pub entsize: u32,
}
impl fmt::Display for SectionHeader {
@@ -817,13 +817,13 @@ impl fmt::Display for SymbolVis {
pub struct Symbol {
/// Symbol name
pub name: StrOffset,
+ /// Symbol value
+ pub value: u32,
+ /// Symbol size
+ pub size: u32,
info: u8,
other: u8,
section_index: u16,
- /// Symbol value
- pub value: u64,
- /// Symbol size
- pub size: u64,
}
impl fmt::Display for Symbol {
--
cgit v1.2.3