Browse Source

Merge branch 'gcc_compile' into 'master'

Gcc compile

See merge request redox-os/relibc!303
Jeremy Soller 4 years ago
parent
commit
7db83596a2
7 changed files with 82 additions and 40 deletions
  1. 2 2
      Makefile
  2. 0 1
      src/header/stdio/printf.rs
  3. 1 1
      src/ld_so/callbacks.rs
  4. 1 1
      src/ld_so/library.rs
  5. 75 31
      src/ld_so/linker.rs
  6. 1 2
      src/ld_so/mod.rs
  7. 2 2
      src/ld_so/start.rs

+ 2 - 2
Makefile

@@ -110,7 +110,7 @@ $(BUILD)/debug/libc.a: $(BUILD)/debug/librelibc.a $(BUILD)/pthreads-emb/libpthre
 	$(AR) -M < "[email protected]"
 
 $(BUILD)/debug/libc.so: $(BUILD)/debug/librelibc.a $(BUILD)/pthreads-emb/libpthread.a $(BUILD)/openlibm/libopenlibm.a
-	$(CC) -nostdlib -shared -Wl,--allow-multiple-definition -Wl,--whole-archive $^ -Wl,--no-whole-archive -o $@
+	$(CC) -nostdlib -shared -Wl,--allow-multiple-definition -Wl,--whole-archive $^ -Wl,--no-whole-archive -Wl,-soname,libc.so.6 -o $@
 
 $(BUILD)/debug/librelibc.a: $(SRC)
 	CARGO_INCREMENTAL=0 $(CARGO) rustc $(CARGOFLAGS) -- --emit link=$@ $(RUSTCFLAGS)
@@ -149,7 +149,7 @@ $(BUILD)/release/libc.a: $(BUILD)/release/librelibc.a $(BUILD)/pthreads-emb/libp
 	$(AR) -M < "[email protected]"
 
 $(BUILD)/release/libc.so: $(BUILD)/release/librelibc.a $(BUILD)/pthreads-emb/libpthread.a $(BUILD)/openlibm/libopenlibm.a
-	$(CC) -nostdlib -shared -Wl,--allow-multiple-definition -Wl,--whole-archive $^ -Wl,--no-whole-archive -o $@
+	$(CC) -nostdlib -shared -Wl,--allow-multiple-definition -Wl,--whole-archive $^ -Wl,--no-whole-archive -Wl,-soname,libc.so.6 -o $@
 
 $(BUILD)/release/librelibc.a: $(SRC)
 	CARGO_INCREMENTAL=0 $(CARGO) rustc --release $(CARGOFLAGS) -- --emit link=$@ $(RUSTCFLAGS)

+ 0 - 1
src/header/stdio/printf.rs

@@ -690,7 +690,6 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, mut ap: VaList) ->
             _ => None,
         };
 
-
         let index = arg.index.map(|i| i - 1).unwrap_or_else(|| {
             if fmtkind == FmtKind::Percent {
                 0

+ 1 - 1
src/ld_so/callbacks.rs

@@ -1,4 +1,4 @@
-use super::linker::{DSO, Linker, Symbol};
+use super::linker::{Linker, Symbol, DSO};
 use alloc::boxed::Box;
 use goblin::error::Result;
 

+ 1 - 1
src/ld_so/library.rs

@@ -1,10 +1,10 @@
+use super::linker::Symbol;
 use alloc::{
     boxed::Box,
     collections::{BTreeMap, BTreeSet},
     string::String,
     vec::Vec,
 };
-use super::linker::Symbol;
 
 #[derive(Default, Debug)]
 pub struct DepTree {

+ 75 - 31
src/ld_so/linker.rs

@@ -1,6 +1,6 @@
 use alloc::{
     boxed::Box,
-    collections::BTreeMap,
+    collections::{BTreeMap, BTreeSet},
     rc::Rc,
     string::{String, ToString},
     vec::Vec,
@@ -15,9 +15,7 @@ use goblin::{
         header::ET_DYN,
         program_header,
         r#dyn::{Dyn, DT_DEBUG},
-        reloc,
-        sym,
-        Elf,
+        reloc, sym, Elf,
     },
     error::{Error, Result},
 };
@@ -25,7 +23,7 @@ use goblin::{
 use crate::{
     c_str::CString,
     fs::File,
-    header::{fcntl, sys_mman, unistd, errno::STR_ERROR},
+    header::{errno::STR_ERROR, fcntl, sys_mman, unistd},
     io::Read,
     platform::{errno, types::c_void},
 };
@@ -147,9 +145,14 @@ impl Linker {
                 deps.push(dep);
             }
         }
-
-        lib.objects.insert(name.to_string(), data);
-
+        let elf = Elf::parse(&data)?;
+        let key = match elf.soname {
+            Some(soname) => soname,
+            _ => name,
+        };
+        if !lib.objects.contains_key(key) {
+            lib.objects.insert(key.to_string(), data);
+        }
         return Ok(deps);
     }
 
@@ -337,12 +340,15 @@ impl Linker {
     ) -> Result<Option<usize>> {
         unsafe { _r_debug.state = RTLDState::RT_ADD };
         _dl_debug_state();
+        let mut skip_list = BTreeSet::new();
         let elfs = {
             let mut elfs = BTreeMap::new();
             for (name, data) in lib.objects.iter() {
                 // Skip already linked libraries
                 if !lib.mmaps.contains_key(&*name) && !self.root.mmaps.contains_key(&*name) {
                     elfs.insert(name.as_str(), Elf::parse(&data)?);
+                } else {
+                    skip_list.insert(name.as_str());
                 }
             }
             elfs
@@ -352,6 +358,9 @@ impl Linker {
         let mut tls_primary = 0;
         let mut tls_size = 0;
         for (elf_name, elf) in elfs.iter() {
+            if skip_list.contains(elf_name) {
+                continue;
+            }
             if self.verbose {
                 println!("map {}", elf_name);
             }
@@ -447,7 +456,9 @@ impl Linker {
                     let mut start = addr;
                     for (vaddr, vsize) in ranges.iter() {
                         if start < addr + vaddr {
-                            println!("mmap({:#x}, {})", start, addr + vaddr - start);
+                            if self.verbose {
+                                println!("mmap({:#x}, {})", start, addr + vaddr - start);
+                            }
                             let mut flags = sys_mman::MAP_ANONYMOUS | sys_mman::MAP_PRIVATE;
                             if start != 0 {
                                 flags |= sys_mman::MAP_FIXED_NOREPLACE;
@@ -461,11 +472,19 @@ impl Linker {
                                 -1,
                                 0,
                             );
-                            if ptr as usize == !0 /* MAP_FAILED */ {
-                                return Err(Error::Malformed(format!("failed to map {}. errno: {}", elf_name, STR_ERROR[errno as usize])));
+                            if ptr as usize == !0
+                            /* MAP_FAILED */
+                            {
+                                return Err(Error::Malformed(format!(
+                                    "failed to map {}. errno: {}",
+                                    elf_name, STR_ERROR[errno as usize]
+                                )));
                             }
                             if start as *mut c_void != ptr::null_mut() {
-                                assert_eq!(ptr, start as *mut c_void, "mmap must always map on the destination we requested");
+                                assert_eq!(
+                                    ptr, start as *mut c_void,
+                                    "mmap must always map on the destination we requested"
+                                );
                             }
                         }
                         start = addr + vaddr + vsize
@@ -476,11 +495,16 @@ impl Linker {
                         sys_mman::PROT_READ | sys_mman::PROT_WRITE,
                     );
                     _r_debug.insert_first(addr as usize, &elf_name, addr + l_ld as usize);
-                    (addr as usize, slice::from_raw_parts_mut(addr as *mut u8, size))
+                    (
+                        addr as usize,
+                        slice::from_raw_parts_mut(addr as *mut u8, size),
+                    )
                 } else {
                     let (start, end) = bounds;
                     let size = end - start;
-                    println!("mmap({:#x}, {})", start, size);
+                    if self.verbose {
+                        println!("mmap({:#x}, {})", start, size);
+                    }
                     let mut flags = sys_mman::MAP_ANONYMOUS | sys_mman::MAP_PRIVATE;
                     if start != 0 {
                         flags |= sys_mman::MAP_FIXED_NOREPLACE;
@@ -494,11 +518,19 @@ impl Linker {
                         -1,
                         0,
                     );
-                    if ptr as usize == !0 /* MAP_FAILED */ {
-                        return Err(Error::Malformed(format!("failed to map {}. errno: {}", elf_name, STR_ERROR[errno as usize])));
+                    if ptr as usize == !0
+                    /* MAP_FAILED */
+                    {
+                        return Err(Error::Malformed(format!(
+                            "failed to map {}. errno: {}",
+                            elf_name, STR_ERROR[errno as usize]
+                        )));
                     }
                     if start as *mut c_void != ptr::null_mut() {
-                        assert_eq!(ptr, start as *mut c_void, "mmap must always map on the destination we requested");
+                        assert_eq!(
+                            ptr, start as *mut c_void,
+                            "mmap must always map on the destination we requested"
+                        );
                     }
                     ptr::write_bytes(ptr as *mut u8, 0, size);
                     _r_debug.insert(ptr as usize, &elf_name, ptr as usize + l_ld as usize);
@@ -534,6 +566,9 @@ impl Linker {
         });
         let mut tls_ranges = BTreeMap::new();
         for (elf_name, elf) in elfs.iter() {
+            if skip_list.contains(elf_name) {
+                continue;
+            }
             let same_elf = if let Some(prog) = dso.as_ref() {
                 if prog.name == *elf_name {
                     true
@@ -580,7 +615,8 @@ impl Linker {
                         };
 
                         let mmap_data = {
-                            let range = ph.p_vaddr as usize - base_addr..ph.p_vaddr as usize + obj_data.len() - base_addr;
+                            let range = ph.p_vaddr as usize - base_addr
+                                ..ph.p_vaddr as usize + obj_data.len() - base_addr;
                             match mmap.get_mut(range.clone()) {
                                 Some(some) => some,
                                 None => {
@@ -588,7 +624,7 @@ impl Linker {
                                     return Err(Error::Malformed(format!(
                                         "failed to write {:x?}",
                                         range
-                                    )))
+                                    )));
                                 }
                             }
                         };
@@ -657,6 +693,9 @@ impl Linker {
 
         // Perform relocations, and protect pages
         for (elf_name, elf) in elfs.iter() {
+            if skip_list.contains(elf_name) {
+                continue;
+            }
             if self.verbose {
                 println!("link {}", elf_name);
             }
@@ -671,7 +710,6 @@ impl Linker {
                 //     reloc::r_to_str(rel.r_type, elf.header.e_machine),
                 //     rel
                 // );
-
                 let symbol = if rel.r_sym > 0 {
                     let sym = elf.dynsyms.get(rel.r_sym).ok_or(Error::Malformed(format!(
                         "missing symbol for relocation {:?}",
@@ -680,18 +718,20 @@ impl Linker {
 
                     let name =
                         elf.dynstrtab
-                           .get(sym.st_name)
-                           .ok_or(Error::Malformed(format!(
-                               "missing name for symbol {:?}",
-                               sym
-                           )))??;
-                    lib.get_sym(name)
-                       .or_else(|| self.root.get_sym(name))
+                            .get(sym.st_name)
+                            .ok_or(Error::Malformed(format!(
+                                "missing name for symbol {:?}",
+                                sym
+                            )))??;
+                    lib.get_sym(name).or_else(|| self.root.get_sym(name))
                 } else {
                     None
                 };
 
-                let s = symbol.as_ref().map(|sym| sym.as_ptr() as usize).unwrap_or(0);
+                let s = symbol
+                    .as_ref()
+                    .map(|sym| sym.as_ptr() as usize)
+                    .unwrap_or(0);
 
                 let a = rel.r_addend.unwrap_or(0) as usize;
 
@@ -713,7 +753,6 @@ impl Linker {
                 } else {
                     rel.r_offset as *mut u8
                 };
-
                 let set_u64 = |value| {
                     // println!("    set_u64 {:#x}", value);
                     unsafe {
@@ -747,9 +786,11 @@ impl Linker {
                     reloc::R_X86_64_IRELATIVE => (), // Handled below
                     reloc::R_X86_64_COPY => unsafe {
                         // TODO: Make this work
-                        let sym = symbol.as_ref().expect("R_X86_64_COPY called without valid symbol");
+                        let sym = symbol
+                            .as_ref()
+                            .expect("R_X86_64_COPY called without valid symbol");
                         ptr::copy_nonoverlapping(sym.as_ptr() as *const u8, ptr, sym.size as usize);
-                    }
+                    },
                     _ => {
                         panic!(
                             "    {} unsupported",
@@ -851,6 +892,9 @@ impl Linker {
         // Perform indirect relocations (necessary evil), gather entry point
         let mut entry_opt = None;
         for (elf_name, elf) in elfs.iter() {
+            if skip_list.contains(elf_name) {
+                continue;
+            }
             let (_, mmap) = match lib.mmaps.get_mut(*elf_name) {
                 Some(some) => some,
                 None => continue,

+ 1 - 2
src/ld_so/mod.rs

@@ -1,9 +1,8 @@
 use core::{mem, ptr};
 use goblin::elf::program_header::{self, program_header32, program_header64, ProgramHeader};
 
-use crate::header::sys_auxv::AT_NULL;
-use crate::start::Stack;
 use self::tcb::{Master, Tcb};
+use crate::{header::sys_auxv::AT_NULL, start::Stack};
 
 pub const PAGE_SIZE: usize = 4096;
 

+ 2 - 2
src/ld_so/start.rs

@@ -10,11 +10,11 @@ use alloc::{
 
 use crate::{
     c_str::CStr,
-    header::{unistd, sys_auxv::AT_NULL},
+    header::{sys_auxv::AT_NULL, unistd},
     platform::{new_mspace, types::c_char},
     start::Stack,
     sync::mutex::Mutex,
-    ALLOCATOR
+    ALLOCATOR,
 };
 
 use super::{