This commit is contained in:
Michael Zhang 2021-06-28 16:10:10 -05:00
parent f4cbd3ca54
commit 42ea48b97f
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
8 changed files with 132 additions and 31 deletions

7
Cargo.lock generated
View file

@ -34,6 +34,12 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "clap"
version = "2.33.3"
@ -126,6 +132,7 @@ name = "rsld"
version = "0.1.0"
dependencies = [
"anyhow",
"byteorder",
"structopt",
]

View file

@ -5,4 +5,5 @@ edition = "2018"
[dependencies]
anyhow = "1.0.41"
byteorder = "1.4.3"
structopt = "0.3.21"

1
ctest/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
bin

View file

@ -1,13 +1,13 @@
CC := clang
SOURCES := $(shell find -type f -name "*.c")
OBJECTS := $(patsubst %.c, bin/%.bin, $(SOURCES))
OBJECTS := $(patsubst %.c, bin/%, $(SOURCES))
CFLAGS := -v -static -fuse-ld=$(shell pwd)/../target/debug/rsld
all: $(OBJECTS)
bin/%.bin: %.c bin
bin/%: %.c bin
$(CC) $(CFLAGS) -o $@ $<
bin:

47
src/elf.rs Normal file
View file

@ -0,0 +1,47 @@
use std::io::{Read, Write};
use std::mem::MaybeUninit;
use anyhow::Result;
use byteorder::{LittleEndian, ReadBytesExt};
#[derive(Debug, Default)]
pub struct Elf {
header: Header,
program_header: Option<ProgramHeader>,
}
#[derive(Debug)]
pub struct Header {
e_ident: [u8; 16],
e_type: u16,
e_machine: u16,
e_version: u32,
}
impl Default for Header {
fn default() -> Self {
let mut header: Self = unsafe { MaybeUninit::zeroed().assume_init() };
header.e_ident[0] = 0x7f;
header.e_ident[1] = b'E';
header.e_ident[2] = b'L';
header.e_ident[3] = b'F';
header
}
}
#[derive(Debug, Default)]
pub struct ProgramHeader {}
impl Elf {
pub fn read<R: Read>(mut r: R) -> Result<Elf> {
let mut elf = Elf::default();
// header
r.read_exact(&mut elf.header.e_ident)?;
elf.header.e_type = r.read_u16::<LittleEndian>()?;
Ok(elf)
}
pub fn write<W: Write>(&self, mut w: W) {}
}

View file

@ -1,5 +1,34 @@
use crate::Opt;
use std::fs::{File, OpenOptions};
use std::os::unix::fs::OpenOptionsExt;
pub(crate) fn link(opt: &Opt) {
use anyhow::{Context, Result};
use crate::elf::Elf;
use crate::{LinkUnit, Opt};
pub(crate) fn link(opt: &Opt) -> Result<()> {
for unit in &opt.units {
match unit {
LinkUnit::Path(path) => {
let file = File::open(path)?;
let elf = Elf::read(&file)?;
}
_ => {}
}
}
let res = Elf::default();
if let Some(path) = &opt.out {
let path = crate::utils::normalize_path(path);
let file = OpenOptions::new()
.create(true)
.write(true)
.mode(0o755)
.open(&path)
.with_context(|| format!("could not create output file {:?}", path))?;
res.write(file);
println!("wrote to {:?}", path);
}
Ok(())
}

View file

@ -1,8 +1,12 @@
mod elf;
mod link;
mod utils;
use std::env;
use std::path::PathBuf;
use anyhow::Result;
#[derive(Debug, Default)]
struct Opt {
eh_frame_hdr: bool,
@ -20,7 +24,7 @@ enum LinkUnit {
Group(Vec<PathBuf>),
}
fn main() {
fn main() -> Result<()> {
let mut opt = Opt::default();
let mut it = env::args();
let mut curr_group = None;
@ -31,44 +35,28 @@ fn main() {
while let Some(arg) = it.next() {
if arg == "-static" {
opt.is_static = true;
}
else if arg == "--eh-frame-hdr" {
} else if arg == "--eh-frame-hdr" {
opt.eh_frame_hdr = true;
}
else if arg == "-m" {
} else if arg == "-m" {
let next = it.next().unwrap();
opt.emulate = next;
}
else if arg == "-o" {
} else if arg == "-o" {
let next = it.next().unwrap();
opt.out = Some(PathBuf::from(next));
}
else if arg == "--start-group" {
} else if arg == "--start-group" {
curr_group = Some(Vec::new());
}
else if arg == "--end-group" {
} else if arg == "--end-group" {
if let Some(curr_group) = curr_group.take() {
if !curr_group.is_empty() {
opt.units.push(LinkUnit::Group(curr_group));
}
}
}
else if arg.starts_with("-L") {
} else if arg.starts_with("-L") {
let path = PathBuf::from(arg.trim_start_matches("-L"));
opt.link_includes.push(path);
}
else if arg.starts_with("-l") {
} else if arg.starts_with("-l") {
opt.link_to.push(arg.trim_start_matches("-l").to_owned());
}
else {
} else {
let path = PathBuf::from(&arg);
if let Some(curr_group) = curr_group.as_mut() {
curr_group.push(path);
@ -78,7 +66,7 @@ fn main() {
}
}
link::link(&opt);
link::link(&opt)?;
println!("opt: {:?}", opt);
Ok(())
}

28
src/utils.rs Normal file
View file

@ -0,0 +1,28 @@
use std::path::{Path, PathBuf, Component};
pub fn normalize_path(path: &Path) -> PathBuf {
let mut components = path.components().peekable();
let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() {
components.next();
PathBuf::from(c.as_os_str())
} else {
PathBuf::new()
};
for component in components {
match component {
Component::Prefix(..) => unreachable!(),
Component::RootDir => {
ret.push(component.as_os_str());
}
Component::CurDir => {}
Component::ParentDir => {
ret.pop();
}
Component::Normal(c) => {
ret.push(c);
}
}
}
ret
}