diff --git a/src/header/errno/mod.rs b/src/header/errno/mod.rs
index 7a51f0b202546e46970eeac59c4688be1895f85e..c42e76fcaf02347d120df82f591882ae79a0c9a7 100644
--- a/src/header/errno/mod.rs
+++ b/src/header/errno/mod.rs
@@ -15,24 +15,12 @@ pub unsafe extern "C" fn __errno_location() -> *mut c_int {
 
 #[no_mangle]
 pub unsafe extern "C" fn __program_invocation_name() -> *mut *mut c_char {
-    &mut platform::inner_argv[0]
+    &mut platform::program_invocation_name
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn __program_invocation_short_name() -> *mut *mut c_char {
-    let mut ptr = platform::inner_argv[0];
-    let mut slash_ptr = ptr;
-    loop {
-        let b = *ptr as u8;
-        if b == 0 {
-            return &mut slash_ptr;
-        } else {
-            ptr = ptr.add(1);
-            if b == b'/' {
-                slash_ptr = ptr;
-            }
-        }
-    }
+    &mut platform::program_invocation_short_name
 }
 
 pub const EPERM: c_int = 1; /* Operation not permitted */
diff --git a/src/platform/mod.rs b/src/platform/mod.rs
index 3978625e4f991ee2197ecb2a3746a9118cf4d8d3..35a35e4f70e5fad88fcaca2ce623d559d57aeced 100644
--- a/src/platform/mod.rs
+++ b/src/platform/mod.rs
@@ -46,6 +46,10 @@ pub static mut errno: c_int = 0;
 pub static mut argv: *mut *mut c_char = ptr::null_mut();
 #[allow(non_upper_case_globals)]
 pub static mut inner_argv: Vec<*mut c_char> = Vec::new();
+#[allow(non_upper_case_globals)]
+pub static mut program_invocation_name: *mut c_char = ptr::null_mut();
+#[allow(non_upper_case_globals)]
+pub static mut program_invocation_short_name: *mut c_char = ptr::null_mut();
 
 #[allow(non_upper_case_globals)]
 #[no_mangle]
diff --git a/src/start.rs b/src/start.rs
index 2082dc84efa8f3d18c7fdfe7a5a6b5f371595381..8e715c47ec4e4f948b53cb3e0866f0f695f0b4cb 100644
--- a/src/start.rs
+++ b/src/start.rs
@@ -2,7 +2,7 @@ use alloc::vec::Vec;
 use core::{intrinsics, ptr};
 
 use crate::{
-    header::{stdio, stdlib},
+    header::{libgen, stdio, stdlib},
     ld_so,
     platform::{self, new_mspace, types::*, Pal, Sys},
     ALLOCATOR,
@@ -141,6 +141,11 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
     let argv = sp.argv();
     platform::inner_argv = copy_string_array(argv, argc as usize);
     platform::argv = platform::inner_argv.as_mut_ptr();
+    // Special code for program_invocation_name and program_invocation_short_name
+    if let Some(arg) = platform::inner_argv.get(0) {
+        platform::program_invocation_name = *arg;
+        platform::program_invocation_short_name = libgen::basename(*arg);
+    }
 
     // Set up envp
     let envp = sp.envp();
diff --git a/tests/errno.c b/tests/errno.c
index 92bc5515a8f4fc1e24107bae05f2da8c3fe3c468..41d8769103958b00a4f099b8bf243740e12c5a90 100644
--- a/tests/errno.c
+++ b/tests/errno.c
@@ -7,7 +7,9 @@ int main(int argc, char **argv) {
     puts(program_invocation_name);
     puts(program_invocation_short_name);
 
-    program_invocation_name = "yes, you can change this";
+    argv[0] = "changed to argv[0]";
+    program_invocation_name = "changed to program_invocation_name";
+    program_invocation_short_name = "changed to program_invocation_short_name";
 
     puts(argv[0]);
     puts(program_invocation_name);
diff --git a/tests/expected/bins_static/errno.stdout b/tests/expected/bins_static/errno.stdout
index a8236cdb85b918c41a7850e63fbfecd254b558f6..abb5998e76321665fca882167ba6922a68b632a1 100644
--- a/tests/expected/bins_static/errno.stdout
+++ b/tests/expected/bins_static/errno.stdout
@@ -1,6 +1,6 @@
 bins_static/errno
 bins_static/errno
 errno
-yes, you can change this
-yes, you can change this
-yes, you can change this
+changed to argv[0]
+changed to program_invocation_name
+changed to program_invocation_short_name