Compare commits
3 Commits
c28c567e72
...
92ae487143
Author | SHA1 | Date |
---|---|---|
Astro | 92ae487143 | |
Astro | 48025339b3 | |
Astro | 895a3f47e2 |
|
@ -153,7 +153,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libasync"
|
name = "libasync"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://git.m-labs.hk/M-Labs/zc706.git#008a9954292980b34fc20cc519a19e92b4ac077d"
|
source = "git+https://git.m-labs.hk/M-Labs/zc706.git#d86f69a2539a9b76575caee0f665829c488ea962"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"embedded-hal",
|
"embedded-hal",
|
||||||
"libcortex_a9",
|
"libcortex_a9",
|
||||||
|
@ -165,12 +165,13 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libboard_zynq"
|
name = "libboard_zynq"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://git.m-labs.hk/M-Labs/zc706.git#008a9954292980b34fc20cc519a19e92b4ac077d"
|
source = "git+https://git.m-labs.hk/M-Labs/zc706.git#d86f69a2539a9b76575caee0f665829c488ea962"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"embedded-hal",
|
"embedded-hal",
|
||||||
"libcortex_a9",
|
"libcortex_a9",
|
||||||
"libregister",
|
"libregister",
|
||||||
|
"log",
|
||||||
"nb",
|
"nb",
|
||||||
"smoltcp",
|
"smoltcp",
|
||||||
"void",
|
"void",
|
||||||
|
@ -180,7 +181,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libcortex_a9"
|
name = "libcortex_a9"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://git.m-labs.hk/M-Labs/zc706.git#008a9954292980b34fc20cc519a19e92b4ac077d"
|
source = "git+https://git.m-labs.hk/M-Labs/zc706.git#d86f69a2539a9b76575caee0f665829c488ea962"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"libregister",
|
"libregister",
|
||||||
|
@ -189,7 +190,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libregister"
|
name = "libregister"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://git.m-labs.hk/M-Labs/zc706.git#008a9954292980b34fc20cc519a19e92b4ac077d"
|
source = "git+https://git.m-labs.hk/M-Labs/zc706.git#d86f69a2539a9b76575caee0f665829c488ea962"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"vcell",
|
"vcell",
|
||||||
|
@ -199,14 +200,13 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libsupport_zynq"
|
name = "libsupport_zynq"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://git.m-labs.hk/M-Labs/zc706.git#008a9954292980b34fc20cc519a19e92b4ac077d"
|
source = "git+https://git.m-labs.hk/M-Labs/zc706.git#d86f69a2539a9b76575caee0f665829c488ea962"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"libboard_zynq",
|
"libboard_zynq",
|
||||||
"libcortex_a9",
|
"libcortex_a9",
|
||||||
"libregister",
|
"libregister",
|
||||||
"linked_list_allocator",
|
"linked_list_allocator",
|
||||||
"log",
|
|
||||||
"r0",
|
"r0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
"1mfprkcq4cr4jiihy1qn8q8qymxwhafh90vyr3i4brj4aq5kksn1"
|
"199qfs7fbbj8kxkyb0dcns6hdq9hvlppk7l3pnz204j9zkd7dkcp"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use core::{mem, ptr, fmt, slice, str, convert, ops::{Deref, Range}};
|
use core::{mem, ptr, ops::{Deref, Range}};
|
||||||
use super::{
|
use super::{
|
||||||
Arch,
|
Arch,
|
||||||
elf::*,
|
elf::*,
|
||||||
|
|
|
@ -9,64 +9,15 @@ use super::{
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn elf_hash(name: &[u8]) -> u32 {
|
pub struct DynamicSection {
|
||||||
let mut h: u32 = 0;
|
pub strtab: Range<usize>,
|
||||||
for c in name {
|
pub symtab: Range<usize>,
|
||||||
h = (h << 4) + *c as u32;
|
pub hash: Range<usize>,
|
||||||
let g = h & 0xf0000000;
|
pub hash_bucket: Range<usize>,
|
||||||
if g != 0 {
|
pub hash_chain: Range<usize>,
|
||||||
h ^= g >> 24;
|
pub rel: Range<usize>,
|
||||||
h &= !g;
|
pub rela: Range<usize>,
|
||||||
}
|
pub pltrel: Range<usize>,
|
||||||
}
|
|
||||||
h
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DynamicSection<'a> {
|
|
||||||
pub strtab: &'a [u8],
|
|
||||||
pub symtab: &'a [Elf32_Sym],
|
|
||||||
pub hash_bucket: &'a [Elf32_Word],
|
|
||||||
pub hash_chain: &'a [Elf32_Word],
|
|
||||||
pub rel: &'a [Elf32_Rel],
|
|
||||||
pub rela: &'a [Elf32_Rela],
|
|
||||||
pub pltrel: &'a [Elf32_Rel],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> DynamicSection<'a> {
|
|
||||||
pub fn lookup(&self, name: &[u8]) -> Option<Elf32_Word> {
|
|
||||||
let hash = elf_hash(name);
|
|
||||||
let mut index = self.hash_bucket[hash as usize % self.hash_bucket.len()] as usize;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
if index == STN_UNDEF { return None }
|
|
||||||
|
|
||||||
let sym = &self.symtab[index];
|
|
||||||
let sym_name_off = sym.st_name as usize;
|
|
||||||
match self.strtab.get(sym_name_off..sym_name_off + name.len()) {
|
|
||||||
Some(sym_name) if sym_name == name => {
|
|
||||||
if ELF32_ST_BIND(sym.st_info) & STB_GLOBAL == 0 {
|
|
||||||
return None
|
|
||||||
}
|
|
||||||
|
|
||||||
match sym.st_shndx {
|
|
||||||
SHN_UNDEF => return None,
|
|
||||||
SHN_ABS => return Some(sym.st_value),
|
|
||||||
_ => return Some(sym.st_value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
index = self.hash_chain[index] as usize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn name_starting_at(&self, offset: usize) -> Result<&'a [u8], Error> {
|
|
||||||
let size = self.strtab.iter().skip(offset).position(|&x| x == 0)
|
|
||||||
.ok_or("symbol in symbol table not null-terminated")?;
|
|
||||||
Ok(self.strtab.get(offset..offset + size)
|
|
||||||
.ok_or("cannot read symbol name")?)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// target memory image
|
/// target memory image
|
||||||
|
@ -90,7 +41,7 @@ impl Image {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// assumes that self.data is properly aligned
|
/// assumes that self.data is properly aligned
|
||||||
pub fn get_ref<T>(&self, offset: usize) -> Option<&T>
|
pub(crate) fn get_ref<T>(&self, offset: usize) -> Option<&T>
|
||||||
where
|
where
|
||||||
T: Copy,
|
T: Copy,
|
||||||
{
|
{
|
||||||
|
@ -104,15 +55,15 @@ impl Image {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_ref_slice<T: Copy>(&self, offset: usize, len: usize) -> Option<&[T]> {
|
/// assumes that self.data is properly aligned
|
||||||
if self.data.len() < offset + mem::size_of::<T>() * len {
|
///
|
||||||
None
|
/// range: in bytes
|
||||||
} else if (self.data.as_ptr() as usize + offset) & (mem::align_of::<T>() - 1) != 0 {
|
pub(crate) fn get_ref_slice_unchecked<T: Copy>(&self, range: &Range<usize>) -> &[T] {
|
||||||
None
|
let offset = range.start;
|
||||||
} else {
|
let len = (range.end - range.start) / mem::size_of::<T>();
|
||||||
let ptr = self.data.as_ptr().wrapping_offset(offset as isize) as *const T;
|
|
||||||
Some(unsafe { slice::from_raw_parts(ptr, len) })
|
let ptr = self.data.as_ptr().wrapping_offset(offset as isize) as *const T;
|
||||||
}
|
unsafe { slice::from_raw_parts(ptr, len) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dyn_headers<'a>(&'a self, range: Range<usize>) ->
|
fn dyn_headers<'a>(&'a self, range: Range<usize>) ->
|
||||||
|
@ -148,13 +99,13 @@ impl Image {
|
||||||
DT_SYMTAB => symtab_off = val,
|
DT_SYMTAB => symtab_off = val,
|
||||||
DT_SYMENT => sym_ent = val,
|
DT_SYMENT => sym_ent = val,
|
||||||
DT_REL => rel_off = val,
|
DT_REL => rel_off = val,
|
||||||
DT_RELSZ => rel_sz = val / mem::size_of::<Elf32_Rel>(),
|
DT_RELSZ => rel_sz = val,
|
||||||
DT_RELENT => rel_ent = val,
|
DT_RELENT => rel_ent = val,
|
||||||
DT_RELA => rela_off = val,
|
DT_RELA => rela_off = val,
|
||||||
DT_RELASZ => rela_sz = val / mem::size_of::<Elf32_Rela>(),
|
DT_RELASZ => rela_sz = val,
|
||||||
DT_RELAENT => rela_ent = val,
|
DT_RELAENT => rela_ent = val,
|
||||||
DT_JMPREL => pltrel_off = val,
|
DT_JMPREL => pltrel_off = val,
|
||||||
DT_PLTRELSZ => pltrel_sz = val / mem::size_of::<Elf32_Rel>(),
|
DT_PLTRELSZ => pltrel_sz = val,
|
||||||
DT_HASH => {
|
DT_HASH => {
|
||||||
nbucket = *self.get_ref::<Elf32_Word>(val + 0)
|
nbucket = *self.get_ref::<Elf32_Word>(val + 0)
|
||||||
.ok_or("cannot read hash bucket count")? as usize;
|
.ok_or("cannot read hash bucket count")? as usize;
|
||||||
|
@ -167,44 +118,44 @@ impl Image {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strtab_off + strtab_sz > self.data.len() {
|
||||||
|
return Err("invalid strtab offset/size")?
|
||||||
|
}
|
||||||
|
if symtab_off + symtab_sz > self.data.len() {
|
||||||
|
return Err("invalid symtab offset/size")?
|
||||||
|
}
|
||||||
if sym_ent != mem::size_of::<Elf32_Sym>() {
|
if sym_ent != mem::size_of::<Elf32_Sym>() {
|
||||||
return Err("incorrect symbol entry size")?
|
return Err("incorrect symbol entry size")?
|
||||||
}
|
}
|
||||||
|
if rel_off + rel_sz > self.data.len() {
|
||||||
|
return Err("invalid rel offset/size")?
|
||||||
|
}
|
||||||
if rel_ent != 0 && rel_ent != mem::size_of::<Elf32_Rel>() {
|
if rel_ent != 0 && rel_ent != mem::size_of::<Elf32_Rel>() {
|
||||||
return Err("incorrect relocation entry size")?
|
return Err("incorrect relocation entry size")?
|
||||||
}
|
}
|
||||||
|
if rela_off + rela_sz > self.data.len() {
|
||||||
|
return Err("invalid rela offset/size")?
|
||||||
|
}
|
||||||
if rela_ent != 0 && rela_ent != mem::size_of::<Elf32_Rela>() {
|
if rela_ent != 0 && rela_ent != mem::size_of::<Elf32_Rela>() {
|
||||||
return Err("incorrect relocation entry size")?
|
return Err("incorrect relocation entry size")?
|
||||||
}
|
}
|
||||||
|
if pltrel_off + pltrel_sz > self.data.len() {
|
||||||
|
return Err("invalid pltrel offset/size")?
|
||||||
|
}
|
||||||
|
|
||||||
// These are the same--there are as many chains as buckets, and the chains only contain
|
// These are the same--there are as many chains as buckets, and the chains only contain
|
||||||
// the symbols that overflowed the bucket.
|
// the symbols that overflowed the bucket.
|
||||||
symtab_sz = nchain;
|
symtab_sz = nchain;
|
||||||
|
|
||||||
let hash = self.get_ref_slice::<Elf32_Word>(hash_off, hash_sz)
|
|
||||||
.ok_or("cannot read hash entries")?;
|
|
||||||
let strtab = self.get_ref_slice(strtab_off, strtab_sz)
|
|
||||||
.ok_or("cannot read string table")?;
|
|
||||||
let symtab = self.get_ref_slice::<Elf32_Sym>(symtab_off, symtab_sz)
|
|
||||||
.ok_or("cannot read symbol table")?;
|
|
||||||
let hash_bucket = &hash[..nbucket];
|
|
||||||
let hash_chain = &hash[nbucket..nbucket + nchain];
|
|
||||||
let rel = self.get_ref_slice::<Elf32_Rel>(rel_off, rel_sz)
|
|
||||||
.ok_or("cannot read rel entries")?;
|
|
||||||
let rela = self.get_ref_slice::<Elf32_Rela>(rela_off, rela_sz)
|
|
||||||
.ok_or("cannot read rela entries")?;
|
|
||||||
let pltrel = self.get_ref_slice::<Elf32_Rel>(pltrel_off, pltrel_sz)
|
|
||||||
.ok_or("cannot read pltrel entries")?;
|
|
||||||
// debug!("ELF: {} rela, {} rel, {} pltrel entries", rela_sz, rel_sz, pltrel_sz);
|
|
||||||
|
|
||||||
Ok(DynamicSection {
|
Ok(DynamicSection {
|
||||||
strtab,
|
strtab: strtab_off..strtab_off + strtab_sz,
|
||||||
symtab,
|
symtab: symtab_off..symtab_off + symtab_sz,
|
||||||
hash_bucket,
|
hash: hash_off..hash_off + hash_sz,
|
||||||
hash_chain,
|
hash_bucket: 0..nbucket,
|
||||||
rel,
|
hash_chain: nbucket..nbucket + nchain,
|
||||||
rela,
|
rel: rel_off..rel_off + rel_sz,
|
||||||
pltrel,
|
rela: rela_off..rela_off + rela_sz,
|
||||||
|
pltrel: pltrel_off..pltrel_off + rela_sz,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
use core::{mem, ptr, fmt, slice, str, convert, ops::Range};
|
use core::{fmt, str, convert};
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use log::{info, trace, error};
|
use log::{info, trace};
|
||||||
use elf::*;
|
use elf::*;
|
||||||
|
|
||||||
pub mod elf;
|
pub mod elf;
|
||||||
|
@ -44,16 +44,90 @@ impl fmt::Display for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn elf_hash(name: &[u8]) -> u32 {
|
||||||
|
let mut h: u32 = 0;
|
||||||
|
for c in name {
|
||||||
|
h = (h << 4) + *c as u32;
|
||||||
|
let g = h & 0xf0000000;
|
||||||
|
if g != 0 {
|
||||||
|
h ^= g >> 24;
|
||||||
|
h &= !g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Library {
|
pub struct Library {
|
||||||
image: Image,
|
image: Image,
|
||||||
dyn_range: Range<usize>,
|
dyn_section: DynamicSection,
|
||||||
dyn_section: DynamicSection<'static>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Library {
|
impl Library {
|
||||||
pub fn lookup(&self, name: &[u8]) -> Option<u32> {
|
fn strtab(&self) -> &[u8] {
|
||||||
self.dyn_section.lookup(name)
|
self.image.get_ref_slice_unchecked(&self.dyn_section.strtab)
|
||||||
.map(|addr| self.image.ptr() as u32 + addr)
|
}
|
||||||
|
|
||||||
|
fn symtab(&self) -> &[Elf32_Sym] {
|
||||||
|
self.image.get_ref_slice_unchecked(&self.dyn_section.symtab)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hash(&self) -> &[Elf32_Word] {
|
||||||
|
self.image.get_ref_slice_unchecked(&self.dyn_section.hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hash_bucket(&self) -> &[Elf32_Word] {
|
||||||
|
&self.hash()[self.dyn_section.hash_bucket.clone()]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hash_chain(&self) -> &[Elf32_Word] {
|
||||||
|
&self.hash()[self.dyn_section.hash_chain.clone()]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rel(&self) -> &[Elf32_Rel] {
|
||||||
|
self.image.get_ref_slice_unchecked(&self.dyn_section.rel)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rela(&self) -> &[Elf32_Rela] {
|
||||||
|
self.image.get_ref_slice_unchecked(&self.dyn_section.rela)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pltrel(&self) -> &[Elf32_Rel] {
|
||||||
|
self.image.get_ref_slice_unchecked(&self.dyn_section.pltrel)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lookup(&self, name: &[u8]) -> Option<Elf32_Word> {
|
||||||
|
let hash = elf_hash(name);
|
||||||
|
let mut index = self.hash_bucket()[hash as usize % self.hash_bucket().len()] as usize;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if index == STN_UNDEF { return None }
|
||||||
|
|
||||||
|
let sym = &self.symtab()[index];
|
||||||
|
let sym_name_off = sym.st_name as usize;
|
||||||
|
match self.strtab().get(sym_name_off..sym_name_off + name.len()) {
|
||||||
|
Some(sym_name) if sym_name == name => {
|
||||||
|
if ELF32_ST_BIND(sym.st_info) & STB_GLOBAL == 0 {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
|
||||||
|
match sym.st_shndx {
|
||||||
|
SHN_UNDEF => return None,
|
||||||
|
SHN_ABS => return Some(self.image.ptr() as u32 + sym.st_value),
|
||||||
|
_ => return Some(self.image.ptr() as u32 + sym.st_value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
index = self.hash_chain()[index] as usize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name_starting_at(&self, offset: usize) -> Result<&[u8], Error> {
|
||||||
|
let size = self.strtab().iter().skip(offset).position(|&x| x == 0)
|
||||||
|
.ok_or("symbol in symbol table not null-terminated")?;
|
||||||
|
Ok(self.strtab().get(offset..offset + size)
|
||||||
|
.ok_or("cannot read symbol name")?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,23 +187,20 @@ pub fn load(
|
||||||
let dyn_section = image.dyn_section(dyn_range.clone())?;
|
let dyn_section = image.dyn_section(dyn_range.clone())?;
|
||||||
info!("Relocating {} rela, {} rel, {} pltrel",
|
info!("Relocating {} rela, {} rel, {} pltrel",
|
||||||
dyn_section.rela.len(), dyn_section.rel.len(), dyn_section.pltrel.len());
|
dyn_section.rela.len(), dyn_section.rel.len(), dyn_section.pltrel.len());
|
||||||
|
let lib = Library {
|
||||||
for rela in dyn_section.rela {
|
|
||||||
reloc::relocate(arch, &image, &dyn_section, rela, resolve)?;
|
|
||||||
}
|
|
||||||
for rel in dyn_section.rela {
|
|
||||||
reloc::relocate(arch, &image, &dyn_section, rel, resolve)?;
|
|
||||||
}
|
|
||||||
for pltrel in dyn_section.pltrel {
|
|
||||||
reloc::relocate(arch, &image, &dyn_section, pltrel, resolve)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let dyn_section = unsafe {
|
|
||||||
core::mem::transmute(dyn_section)
|
|
||||||
};
|
|
||||||
Ok(Library {
|
|
||||||
image,
|
image,
|
||||||
dyn_range,
|
|
||||||
dyn_section,
|
dyn_section,
|
||||||
})
|
};
|
||||||
|
|
||||||
|
for rela in lib.rela() {
|
||||||
|
reloc::relocate(arch, &lib, rela, resolve)?;
|
||||||
|
}
|
||||||
|
for rel in lib.rel() {
|
||||||
|
reloc::relocate(arch, &lib, rel, resolve)?;
|
||||||
|
}
|
||||||
|
for pltrel in lib.pltrel() {
|
||||||
|
reloc::relocate(arch, &lib, pltrel, resolve)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(lib)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,8 @@ use super::{
|
||||||
Arch,
|
Arch,
|
||||||
elf::*,
|
elf::*,
|
||||||
Error,
|
Error,
|
||||||
image::{DynamicSection, Image},
|
image::Image,
|
||||||
|
Library,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Relocatable {
|
pub trait Relocatable {
|
||||||
|
@ -87,16 +88,16 @@ fn format_sym_name(sym_name: &[u8]) -> String {
|
||||||
.unwrap_or(String::from("<invalid symbol name>"))
|
.unwrap_or(String::from("<invalid symbol name>"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn relocate<'a, R: Relocatable>(
|
pub fn relocate<R: Relocatable>(
|
||||||
arch: Arch, image: &'a Image, dynamic_section: &'a DynamicSection<'a>,
|
arch: Arch, lib: &Library,
|
||||||
rel: &'a R, resolve: &dyn Fn(&[u8]) -> Option<Elf32_Word>
|
rel: &R, resolve: &dyn Fn(&[u8]) -> Option<Elf32_Word>
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
// debug!("rel r_offset={:08X} r_info={:08X} r_addend={:08X}", rel.offset(), rel.r_info, rela.r_addend);
|
// debug!("rel r_offset={:08X} r_info={:08X} r_addend={:08X}", rel.offset(), rel.r_info, rela.r_addend);
|
||||||
let sym;
|
let sym;
|
||||||
if rel.sym_info() == 0 {
|
if rel.sym_info() == 0 {
|
||||||
sym = None;
|
sym = None;
|
||||||
} else {
|
} else {
|
||||||
sym = Some(dynamic_section.symtab.get(rel.sym_info() as usize)
|
sym = Some(lib.symtab().get(rel.sym_info() as usize)
|
||||||
.ok_or("symbol out of bounds of symbol table")?)
|
.ok_or("symbol out of bounds of symbol table")?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,18 +109,18 @@ pub fn relocate<'a, R: Relocatable>(
|
||||||
return Ok(()),
|
return Ok(()),
|
||||||
|
|
||||||
RelType::Relative => {
|
RelType::Relative => {
|
||||||
let addend = rel.addend(image);
|
let addend = rel.addend(&lib.image);
|
||||||
value = image.ptr().wrapping_offset(addend as isize) as Elf32_Word;
|
value = lib.image.ptr().wrapping_offset(addend as isize) as Elf32_Word;
|
||||||
}
|
}
|
||||||
|
|
||||||
RelType::Lookup => {
|
RelType::Lookup => {
|
||||||
let sym = sym.ok_or("relocation requires an associated symbol")?;
|
let sym = sym.ok_or("relocation requires an associated symbol")?;
|
||||||
let sym_name = dynamic_section.name_starting_at(sym.st_name as usize)?;
|
let sym_name = lib.name_starting_at(sym.st_name as usize)?;
|
||||||
|
|
||||||
if let Some(addr) = dynamic_section.lookup(sym_name) {
|
if let Some(addr) = lib.lookup(sym_name) {
|
||||||
// First, try to resolve against itself.
|
// First, try to resolve against itself.
|
||||||
trace!("looked up symbol {} in image", format_sym_name(sym_name));
|
trace!("looked up symbol {} in image", format_sym_name(sym_name));
|
||||||
value = image.ptr() as u32 + addr;
|
value = lib.image.ptr() as u32 + addr;
|
||||||
} else if let Some(addr) = resolve(sym_name) {
|
} else if let Some(addr) = resolve(sym_name) {
|
||||||
// Second, call the user-provided function.
|
// Second, call the user-provided function.
|
||||||
trace!("resolved symbol {:?}", format_sym_name(sym_name));
|
trace!("resolved symbol {:?}", format_sym_name(sym_name));
|
||||||
|
@ -132,5 +133,5 @@ pub fn relocate<'a, R: Relocatable>(
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("rel_type={:?} write at {:08X} value {:08X}", rel_type, rel.offset(), value);
|
debug!("rel_type={:?} write at {:08X} value {:08X}", rel_type, rel.offset(), value);
|
||||||
image.write(rel.offset(), value)
|
lib.image.write(rel.offset(), value)
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,8 +107,15 @@ async fn handle_connection(stream: &TcpStream, control: Rc<RefCell<kernel::Contr
|
||||||
expect(&stream, b"ARTIQ coredev\n").await?;
|
expect(&stream, b"ARTIQ coredev\n").await?;
|
||||||
debug!("received connection");
|
debug!("received connection");
|
||||||
loop {
|
loop {
|
||||||
if !expect(&stream, &[0x5a, 0x5a, 0x5a, 0x5a]).await? {
|
match expect(&stream, &[0x5a, 0x5a, 0x5a, 0x5a]).await {
|
||||||
return Err(Error::UnexpectedPattern)
|
Ok(true) => {}
|
||||||
|
Ok(false) =>
|
||||||
|
return Err(Error::UnexpectedPattern),
|
||||||
|
// peer has closed the connection
|
||||||
|
Err(smoltcp::Error::Illegal) =>
|
||||||
|
return Ok(()),
|
||||||
|
Err(e) =>
|
||||||
|
return Err(e)?,
|
||||||
}
|
}
|
||||||
let request: Request = FromPrimitive::from_i8(read_i8(&stream).await?)
|
let request: Request = FromPrimitive::from_i8(read_i8(&stream).await?)
|
||||||
.ok_or(Error::UnrecognizedPacket)?;
|
.ok_or(Error::UnrecognizedPacket)?;
|
||||||
|
|
|
@ -8,8 +8,8 @@ extern crate log;
|
||||||
use core::{cmp, str};
|
use core::{cmp, str};
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
use libboard_zynq::timer::GlobalTimer;
|
use libboard_zynq::{logger, timer::GlobalTimer};
|
||||||
use libsupport_zynq::{logger, ram};
|
use libsupport_zynq::ram;
|
||||||
|
|
||||||
mod proto;
|
mod proto;
|
||||||
mod comms;
|
mod comms;
|
||||||
|
|
|
@ -9,9 +9,10 @@ use cstr_core::CStr;
|
||||||
|
|
||||||
use libboard_zynq::{
|
use libboard_zynq::{
|
||||||
self as zynq, clocks::Clocks, clocks::source::{ClockSource, ArmPll, IoPll},
|
self as zynq, clocks::Clocks, clocks::source::{ClockSource, ArmPll, IoPll},
|
||||||
|
logger,
|
||||||
timer::GlobalTimer,
|
timer::GlobalTimer,
|
||||||
};
|
};
|
||||||
use libsupport_zynq::{boot, logger};
|
use libsupport_zynq::boot;
|
||||||
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
Loading…
Reference in New Issue