Skip to content
Snippets Groups Projects
Commit 40328a0d authored by Ahmed Abd El Mawgood's avatar Ahmed Abd El Mawgood Committed by jD91mZM2
Browse files

Modify ld_script so that it works on linux.

Honestly, I have no idea why are these modifications needed, but it
seams they are needed
parent d08c63b1
No related branches found
No related tags found
No related merge requests found
...@@ -2,3 +2,5 @@ ...@@ -2,3 +2,5 @@
prefix/ prefix/
sysroot/ sysroot/
**/target/ **/target/
.gdb_history
*.patch
...@@ -134,7 +134,7 @@ $(BUILD)/debug/ld_so.o: $(SRC) ...@@ -134,7 +134,7 @@ $(BUILD)/debug/ld_so.o: $(SRC)
touch $@ touch $@
$(BUILD)/debug/ld_so: $(BUILD)/debug/ld_so.o $(BUILD)/debug/crti.o $(BUILD)/debug/libc.a $(BUILD)/debug/crtn.o $(BUILD)/debug/ld_so: $(BUILD)/debug/ld_so.o $(BUILD)/debug/crti.o $(BUILD)/debug/libc.a $(BUILD)/debug/crtn.o
$(LD) -T src/ld_so/ld_script --allow-multiple-definition --gc-sections --gc-keep-exported $^ -o $@ $(LD) --no-relax -T src/ld_so/ld_script --allow-multiple-definition --gc-sections --gc-keep-exported $^ -o $@
# Release targets # Release targets
...@@ -173,7 +173,7 @@ $(BUILD)/release/ld_so.o: $(SRC) ...@@ -173,7 +173,7 @@ $(BUILD)/release/ld_so.o: $(SRC)
touch $@ touch $@
$(BUILD)/release/ld_so: $(BUILD)/release/ld_so.o $(BUILD)/release/crti.o $(BUILD)/release/libc.a $(BUILD)/release/crtn.o $(BUILD)/release/ld_so: $(BUILD)/release/ld_so.o $(BUILD)/release/crti.o $(BUILD)/release/libc.a $(BUILD)/release/crtn.o
$(LD) -T src/ld_so/ld_script --allow-multiple-definition --gc-sections --gc-keep-exported $^ -o $@ $(LD) --no-relax -T src/ld_so/ld_script --allow-multiple-definition --gc-sections --gc-keep-exported $^ -o $@
# Other targets # Other targets
......
// Wrapper over the access syscall that doesn't touch errno variable, // Wrapper over the access syscall that doesn't touch errno variable,
// Do not use outside of ld_so // Do not use outside of ld_so
use crate::{c_str::CStr, platform::types::*};
#[cfg(target_os = "redox")] #[cfg(target_os = "redox")]
use crate::header::unistd::{F_OK, R_OK, W_OK, X_OK}; use crate::header::unistd::{F_OK, R_OK, W_OK, X_OK};
use crate::{
c_str::{CStr, CString},
platform::types::*,
};
pub fn accessible(path: &str, mode: c_int) -> c_int {
let path_c = CString::new(path.as_bytes()).unwrap(); /*.map_err(|err| {
Error::Malformed(format!("invalid path '{}': {}", path, err))
})?;*/
unsafe { access(path_c.as_ptr(), mode) }
}
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub unsafe fn access(path: *const c_char, mode: c_int) -> c_int { unsafe fn access(path: *const c_char, mode: c_int) -> c_int {
let path = CStr::from_ptr(path); let path = CStr::from_ptr(path);
syscall!(ACCESS, (path).as_ptr(), mode) as c_int syscall!(ACCESS, (path).as_ptr(), mode) as c_int
} }
// Wrapper over the systemcall, Do not use outside of ld_so // Wrapper over the systemcall, Do not use outside of ld_so
#[cfg(target_os = "redox")] #[cfg(target_os = "redox")]
pub unsafe fn access(path: *const c_char, mode: c_int) -> c_int { unsafe fn access(path: *const c_char, mode: c_int) -> c_int {
let path = CStr::from_ptr(path).to_bytes(); let path = CStr::from_ptr(path).to_bytes();
let fd = match syscall::open(path, syscall::O_CLOEXEC) { let fd = match syscall::open(path, syscall::O_CLOEXEC) {
Ok(fd) => fd, Ok(fd) => fd,
......
...@@ -8,10 +8,20 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", ...@@ -8,10 +8,20 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
OUTPUT_ARCH(i386:x86-64) OUTPUT_ARCH(i386:x86-64)
ENTRY(_start) ENTRY(_start)
SEARCH_DIR("/x86_64-unknown-redox/lib"); SEARCH_DIR("/x86_64-unknown-redox/lib");
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64");
SEARCH_DIR("/usr/lib64/binutils/x86_64-pc-linux-gnu/2.33.164");
SEARCH_DIR("/usr/local/lib64");
SEARCH_DIR("/lib64");
SEARCH_DIR("/usr/lib64");
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib");
SEARCH_DIR("/usr/lib64/binutils/x86_64-pc-linux-gnu/2.33.1");
SEARCH_DIR("/usr/local/lib");
SEARCH_DIR("/lib");
SEARCH_DIR("/usr/lib");
SECTIONS SECTIONS
{ {
/* Read-only sections, merged into text segment: */ /* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x20000000) + SIZEOF_HEADERS; PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x12340000)); . = SEGMENT_START("text-segment", 0x1234000) + SIZEOF_HEADERS;
.interp : { *(.interp) } .interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) } .note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) } .hash : { *(.hash) }
...@@ -46,6 +56,7 @@ SECTIONS ...@@ -46,6 +56,7 @@ SECTIONS
*(.rela.iplt) *(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .); PROVIDE_HIDDEN (__rela_iplt_end = .);
} }
. = ALIGN(CONSTANT (MAXPAGESIZE));
.init : .init :
{ {
KEEP (*(SORT_NONE(.init))) KEEP (*(SORT_NONE(.init)))
...@@ -59,7 +70,6 @@ SECTIONS ...@@ -59,7 +70,6 @@ SECTIONS
*(.text.exit .text.exit.*) *(.text.exit .text.exit.*)
*(.text.startup .text.startup.*) *(.text.startup .text.startup.*)
*(.text.hot .text.hot.*) *(.text.hot .text.hot.*)
*(SORT(.text.sorted.*))
*(.text .stub .text.* .gnu.linkonce.t.*) *(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */ /* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning) *(.gnu.warning)
...@@ -71,6 +81,10 @@ SECTIONS ...@@ -71,6 +81,10 @@ SECTIONS
PROVIDE (__etext = .); PROVIDE (__etext = .);
PROVIDE (_etext = .); PROVIDE (_etext = .);
PROVIDE (etext = .); PROVIDE (etext = .);
. = ALIGN(CONSTANT (MAXPAGESIZE));
/* Adjust the address for the rodata segment. We want to adjust up to
the same address within the page on the next page up. */
. = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) } .rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
......
...@@ -31,7 +31,7 @@ use crate::{ ...@@ -31,7 +31,7 @@ use crate::{
}; };
use super::{ use super::{
access::access, access::accessible,
callbacks::LinkerCallbacks, callbacks::LinkerCallbacks,
debug::{RTLDDebug, RTLDState, _dl_debug_state, _r_debug}, debug::{RTLDDebug, RTLDState, _dl_debug_state, _r_debug},
library::{DepTree, Library}, library::{DepTree, Library},
...@@ -39,10 +39,10 @@ use super::{ ...@@ -39,10 +39,10 @@ use super::{
PAGE_SIZE, PAGE_SIZE,
}; };
#[cfg(target_os = "redox")] #[cfg(target_os = "redox")]
const PATH_SEP: char = ';'; pub const PATH_SEP: char = ';';
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
const PATH_SEP: char = ':'; pub const PATH_SEP: char = ':';
pub struct DSO { pub struct DSO {
pub name: String, pub name: String,
...@@ -178,18 +178,8 @@ impl Linker { ...@@ -178,18 +178,8 @@ impl Linker {
if self.verbose { if self.verbose {
println!("check {}", path); println!("check {}", path);
} }
let access = unsafe {
let path_c = CString::new(path.as_bytes()).map_err(|err| {
Error::Malformed(format!("invalid path '{}': {}", path, err))
})?;
// TODO: Use R_OK | X_OK
// We cannot use unix stdlib because errno is thead local variable
// and fs:[0] is not set yet.
access(path_c.as_ptr(), unistd::F_OK) == 0
};
if access { if accessible(&path, unistd::F_OK) == 0 {
return Ok(Some(self.load_recursive(name, &path, lib)?)); return Ok(Some(self.load_recursive(name, &path, lib)?));
} }
} }
......
// Start code adapted from https://gitlab.redox-os.org/redox-os/relibc/blob/master/src/start.rs // Start code adapted from https://gitlab.redox-os.org/redox-os/relibc/blob/master/src/start.rs
use alloc::{borrow::ToOwned, boxed::Box, collections::BTreeMap, string::String, vec::Vec}; use alloc::{
borrow::ToOwned,
boxed::Box,
collections::BTreeMap,
string::{String, ToString},
vec::Vec,
};
use crate::{ use crate::{
c_str::CStr, c_str::CStr,
...@@ -12,8 +18,9 @@ use crate::{ ...@@ -12,8 +18,9 @@ use crate::{
}; };
use super::{ use super::{
access::accessible,
debug::_r_debug, debug::_r_debug,
linker::{Linker, DSO}, linker::{Linker, DSO, PATH_SEP},
tcb::Tcb, tcb::Tcb,
}; };
use crate::header::sys_auxv::{AT_ENTRY, AT_PHDR}; use crate::header::sys_auxv::{AT_ENTRY, AT_PHDR};
...@@ -116,9 +123,41 @@ unsafe fn adjust_stack(sp: &'static mut Stack) { ...@@ -116,9 +123,41 @@ unsafe fn adjust_stack(sp: &'static mut Stack) {
break; break;
} }
} }
sp.argc -= 1; sp.argc -= 1;
} }
fn resolve_path_name(
name_or_path: &str,
envs: &BTreeMap<String, String>,
) -> Option<(String, String)> {
if accessible(name_or_path, unistd::F_OK) == 0 {
return Some((
name_or_path.to_string(),
name_or_path
.split("/")
.collect::<Vec<&str>>()
.last()
.unwrap()
.to_string(),
));
}
if name_or_path.split("/").collect::<Vec<&str>>().len() != 1 {
return None;
}
let env_path = envs.get("PATH")?;
for part in env_path.split(PATH_SEP) {
let path = if part.is_empty() {
format!("./{}", name_or_path)
} else {
format!("{}/{}", part, name_or_path)
};
if accessible(&path, unistd::F_OK) == 0 {
return Some((path.to_string(), name_or_path.to_string()));
}
}
None
}
#[no_mangle] #[no_mangle]
pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) -> usize { pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) -> usize {
// First thing we initialize the mspace // First thing we initialize the mspace
...@@ -149,7 +188,7 @@ pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) -> ...@@ -149,7 +188,7 @@ pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) ->
None => "/lib".to_owned(), None => "/lib".to_owned(),
}; };
let path = if is_manual { let name_or_path = if is_manual {
// ld.so is run directly by user and not via execve() or similar systemcall // ld.so is run directly by user and not via execve() or similar systemcall
println!("argv: {:#?}", argv); println!("argv: {:#?}", argv);
println!("envs: {:#?}", envs); println!("envs: {:#?}", envs);
...@@ -161,13 +200,23 @@ pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) -> ...@@ -161,13 +200,23 @@ pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) ->
loop {} loop {}
} }
unsafe { adjust_stack(sp) }; unsafe { adjust_stack(sp) };
&argv[1] argv[1].to_string()
} else { } else {
&argv[0] argv[0].to_string()
}; };
// if we are not running in manual mode, then the main program is already
// loaded by the linux kernel and we want to use it. on redox, we treat it let (path, name) = match resolve_path_name(&name_or_path, &envs) {
// the same. Some((p, n)) => (p, n),
None => {
eprintln!("ld.so: failed to locate '{}'", name_or_path);
unistd::_exit(1);
loop {}
}
};
// if we are not running in manual mode, then the main
// program is already loaded by the kernel and we want
// to use it. on redox, we treat it the same.
let program = { let program = {
let mut pr = None; let mut pr = None;
if !is_manual && cfg!(not(target_os = "redox")) { if !is_manual && cfg!(not(target_os = "redox")) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment