diff --git a/src/header/dlfcn/mod.rs b/src/header/dlfcn/mod.rs
index d5b53db5fbcc35a90b386c77be4e85ff316d4fb6..cc10390c07e12800b2f2ce7a7a31d8fe969e7fee 100644
--- a/src/header/dlfcn/mod.rs
+++ b/src/header/dlfcn/mod.rs
@@ -108,9 +108,9 @@ pub unsafe extern "C" fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *m
         eprintln!("dlsym: linker_ptr: {:p}", tcb.linker_ptr);
         let linker = (&*tcb.linker_ptr).lock();
 
-        if let Some(global) = linker.globals.get(symbol_str) {
-            eprintln!("dlsym({:p}, {}) = 0x{:x}", handle, symbol_str, *global);
-            *global as *mut c_void
+        if let Some(global) = linker.get_sym(symbol_str) {
+            eprintln!("dlsym({:p}, {}) = 0x{:x}", handle, symbol_str, global);
+            global as *mut c_void
         } else {
             eprintln!("dlsym: symbol not found");
             ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst);
diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs
index 3b15fd7e310f754d3014c1c5946cc5adcb97c558..449128ab43e4c7a1b1cc6c32b97ca7fca870af2b 100644
--- a/src/header/unistd/mod.rs
+++ b/src/header/unistd/mod.rs
@@ -5,7 +5,8 @@ use core::{convert::TryFrom, mem, ptr, slice};
 use crate::{
     c_str::CStr,
     header::{
-        errno, fcntl, limits, stdlib::getenv, sys_ioctl, sys_time, sys_utsname, termios, time::timespec,
+        errno, fcntl, limits, stdlib::getenv, sys_ioctl, sys_time, sys_utsname, termios,
+        time::timespec,
     },
     platform::{self, types::*, Pal, Sys},
 };
diff --git a/src/ld_so/linker.rs b/src/ld_so/linker.rs
index dd396112804631e507852a6dc9c6dc88daa8a11b..848645146058b9695a7493b6902ce18656904226 100644
--- a/src/ld_so/linker.rs
+++ b/src/ld_so/linker.rs
@@ -38,7 +38,9 @@ pub struct Linker {
 
     // Used by link
     /// Global symbols
-    pub globals: BTreeMap<String, usize>,
+    globals: BTreeMap<String, usize>,
+    /// Weak symbols
+    weak_syms: BTreeMap<String, usize>,
     /// Loaded library in-memory data
     mmaps: BTreeMap<String, &'static mut [u8]>,
     verbose: bool,
@@ -51,6 +53,7 @@ impl Linker {
             library_path: library_path.to_string(),
             objects: BTreeMap::new(),
             globals: BTreeMap::new(),
+            weak_syms: BTreeMap::new(),
             mmaps: BTreeMap::new(),
             verbose,
             tls_index_offset: 0,
@@ -129,6 +132,64 @@ impl Linker {
         }
     }
 
+    fn collect_syms(
+        elf: &Elf,
+        mmap: &[u8],
+        verbose: bool,
+    ) -> Result<(BTreeMap<String, usize>, BTreeMap<String, usize>)> {
+        let mut globals = BTreeMap::new();
+        let mut weak_syms = BTreeMap::new();
+        for sym in elf.dynsyms.iter() {
+            let bind = sym.st_bind();
+            if sym.st_value == 0 || ![sym::STB_GLOBAL, sym::STB_WEAK].contains(&bind) {
+                continue;
+            }
+            let name: String;
+            let value: usize;
+            if let Some(name_res) = elf.dynstrtab.get(sym.st_name) {
+                name = name_res?.to_string();
+                value = mmap.as_ptr() as usize + sym.st_value as usize;
+            } else {
+                continue;
+            }
+            match sym.st_bind() {
+                sym::STB_GLOBAL => {
+                    if verbose {
+                        println!("  global {}: {:x?} = {:#x}", &name, sym, value);
+                    }
+                    globals.insert(name, value);
+                }
+                sym::STB_WEAK => {
+                    if verbose {
+                        println!("  weak {}: {:x?} = {:#x}", &name, sym, value);
+                    }
+                    weak_syms.insert(name, value);
+                }
+                _ => unreachable!(),
+            }
+        }
+        return Ok((globals, weak_syms));
+    }
+
+    pub fn get_sym(&self, name: &str) -> Option<usize> {
+        if let Some(value) = self.globals.get(name) {
+            if self.verbose {
+                println!("    sym {} = {:#x}", name, value);
+            }
+            Some(*value)
+        } else if let Some(value) = self.weak_syms.get(name) {
+            if self.verbose {
+                println!("    sym {} = {:#x}", name, value);
+            }
+            Some(*value)
+        } else {
+            if self.verbose {
+                println!("    sym {} = undefined", name);
+            }
+            None
+        }
+    }
+
     pub fn link(&mut self, primary_opt: Option<&str>) -> Result<Option<usize>> {
         let elfs = {
             let mut elfs = BTreeMap::new();
@@ -179,7 +240,7 @@ impl Linker {
                             }
                         }
                         program_header::PT_TLS => {
-                            if self.verbose{
+                            if self.verbose {
                                 println!("  load tls {:#x}: {:x?}", vsize, ph);
                             }
                             tls_size += vsize;
@@ -221,18 +282,9 @@ impl Linker {
             if self.verbose {
                 println!("  mmap {:p}, {:#x}", mmap.as_mut_ptr(), mmap.len());
             }
-            // Locate all globals
-            for sym in elf.dynsyms.iter() {
-                if sym.st_bind() == sym::STB_GLOBAL && sym.st_value != 0 {
-                    if let Some(name_res) = elf.dynstrtab.get(sym.st_name) {
-                        let name = name_res?;
-                        let value = mmap.as_ptr() as usize + sym.st_value as usize;
-                        // println!("  global {}: {:x?} = {:#x}", name, sym, value);
-                        self.globals.insert(name.to_string(), value);
-                    }
-                }
-            }
-
+            let (globals, weak_syms) = Linker::collect_syms(&elf, &mmap, self.verbose)?;
+            self.globals.extend(globals.into_iter());
+            self.weak_syms.extend(weak_syms.into_iter());
             self.mmaps.insert(elf_name.to_string(), mmap);
         }
 
@@ -242,7 +294,7 @@ impl Linker {
         } else {
             None
         };
-        if self.verbose{
+        if self.verbose {
             println!("tcb {:x?}", tcb_opt);
         }
         // Copy data
@@ -331,14 +383,20 @@ impl Linker {
                             );
                         }
                         if Some(*elf_name) == primary_opt {
-                            tls_ranges.insert(elf_name.to_string(), (self.tls_index_offset, tcb_master.range()));
+                            tls_ranges.insert(
+                                elf_name.to_string(),
+                                (self.tls_index_offset, tcb_master.range()),
+                            );
                             tcb_masters[0] = tcb_master;
                         } else {
                             tcb_master.offset -= tls_offset;
                             tls_offset += vsize;
                             tls_ranges.insert(
                                 elf_name.to_string(),
-                                (self.tls_index_offset + tcb_masters.len(), tcb_master.range()),
+                                (
+                                    self.tls_index_offset + tcb_masters.len(),
+                                    tcb_master.range(),
+                                ),
                             );
                             tcb_masters.push(tcb_master);
                         }
@@ -360,10 +418,6 @@ impl Linker {
 
         // Perform relocations, and protect pages
         for (elf_name, elf) in elfs.iter() {
-            let mmap = match self.mmaps.get_mut(*elf_name) {
-                Some(some) => some,
-                None => continue,
-            };
             if self.verbose {
                 println!("link {}", elf_name);
             }
@@ -379,10 +433,6 @@ impl Linker {
                 //     rel
                 // );
 
-                let a = rel.r_addend.unwrap_or(0) as usize;
-
-                let b = mmap.as_mut_ptr() as usize;
-
                 let s = if rel.r_sym > 0 {
                     let sym = elf.dynsyms.get(rel.r_sym).ok_or(Error::Malformed(format!(
                         "missing symbol for relocation {:?}",
@@ -396,18 +446,20 @@ impl Linker {
                                 "missing name for symbol {:?}",
                                 sym
                             )))??;
-
-                    if let Some(value) = self.globals.get(name) {
-                        // println!("    sym {}: {:x?} = {:#x}", name, sym, value);
-                        *value
-                    } else {
-                        // println!("    sym {}: {:x?} = undefined", name, sym);
-                        0
-                    }
+                    self.get_sym(name).unwrap_or(0)
                 } else {
                     0
                 };
 
+                let a = rel.r_addend.unwrap_or(0) as usize;
+
+                let mmap = match self.mmaps.get_mut(*elf_name) {
+                    Some(some) => some,
+                    None => continue,
+                };
+
+                let b = mmap.as_mut_ptr() as usize;
+
                 let (tm, t) = if let Some((tls_index, tls_range)) = tls_ranges.get(*elf_name) {
                     (*tls_index, tls_range.start)
                 } else {
@@ -473,6 +525,10 @@ impl Linker {
                         prot |= sys_mman::PROT_WRITE;
                     }
 
+                    let mmap = match self.mmaps.get_mut(*elf_name) {
+                        Some(some) => some,
+                        None => continue,
+                    };
                     let res = unsafe {
                         let ptr = mmap.as_mut_ptr().add(vaddr);
                         if self.verbose {
diff --git a/src/ld_so/tcb.rs b/src/ld_so/tcb.rs
index 3b71ebfaadfe3ff381218c27d2166ee9dfd941c5..3a303088827e2e3b4d01dcb0bdac2131bb302b0f 100644
--- a/src/ld_so/tcb.rs
+++ b/src/ld_so/tcb.rs
@@ -2,11 +2,7 @@ use alloc::boxed::Box;
 use core::{mem, ops::Range, ptr, slice};
 use goblin::error::{Error, Result};
 
-use crate::{
-    header::sys_mman,
-    ld_so::linker::Linker,
-    sync::mutex::Mutex,
-};
+use crate::{header::sys_mman, ld_so::linker::Linker, sync::mutex::Mutex};
 
 use super::PAGE_SIZE;
 
diff --git a/src/platform/redox/socket.rs b/src/platform/redox/socket.rs
index 80eb515e8ba837b8404747d7d424c22220afac24..fd875c763513451529d8c06c8ba6a666cb78ebea 100644
--- a/src/platform/redox/socket.rs
+++ b/src/platform/redox/socket.rs
@@ -215,7 +215,7 @@ impl PalSocket for Sys {
                     *error = 0;
 
                     return 0;
-                },
+                }
                 _ => (),
             },
             _ => (),