diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index aee8bc27d2..6319414bad 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -419,8 +419,6 @@ add_library(core STATIC
     loader/deconstructed_rom_directory.h
     loader/elf.cpp
     loader/elf.h
-    loader/linker.cpp
-    loader/linker.h
     loader/loader.cpp
     loader/loader.h
     loader/nax.cpp
diff --git a/src/core/loader/linker.cpp b/src/core/loader/linker.cpp
deleted file mode 100644
index 57ca8c3eeb..0000000000
--- a/src/core/loader/linker.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2018 yuzu emulator team
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <vector>
-
-#include "common/common_funcs.h"
-#include "common/logging/log.h"
-#include "common/swap.h"
-#include "core/loader/linker.h"
-#include "core/memory.h"
-
-namespace Loader {
-
-enum class RelocationType : u32 { ABS64 = 257, GLOB_DAT = 1025, JUMP_SLOT = 1026, RELATIVE = 1027 };
-
-enum DynamicType : u32 {
-    DT_NULL = 0,
-    DT_PLTRELSZ = 2,
-    DT_STRTAB = 5,
-    DT_SYMTAB = 6,
-    DT_RELA = 7,
-    DT_RELASZ = 8,
-    DT_STRSZ = 10,
-    DT_JMPREL = 23,
-};
-
-struct Elf64_Rela {
-    u64_le offset;
-    RelocationType type;
-    u32_le symbol;
-    s64_le addend;
-};
-static_assert(sizeof(Elf64_Rela) == 0x18, "Elf64_Rela has incorrect size.");
-
-struct Elf64_Dyn {
-    u64_le tag;
-    u64_le value;
-};
-static_assert(sizeof(Elf64_Dyn) == 0x10, "Elf64_Dyn has incorrect size.");
-
-struct Elf64_Sym {
-    u32_le name;
-    INSERT_PADDING_BYTES(0x2);
-    u16_le shndx;
-    u64_le value;
-    u64_le size;
-};
-static_assert(sizeof(Elf64_Sym) == 0x18, "Elf64_Sym has incorrect size.");
-
-void Linker::WriteRelocations(std::vector<u8>& program_image, const std::vector<Symbol>& symbols,
-                              u64 relocation_offset, u64 size, VAddr load_base) {
-    for (u64 i = 0; i < size; i += sizeof(Elf64_Rela)) {
-        Elf64_Rela rela;
-        std::memcpy(&rela, &program_image[relocation_offset + i], sizeof(Elf64_Rela));
-
-        const Symbol& symbol = symbols[rela.symbol];
-        switch (rela.type) {
-        case RelocationType::RELATIVE: {
-            const u64 value = load_base + rela.addend;
-            if (!symbol.name.empty()) {
-                exports[symbol.name] = value;
-            }
-            std::memcpy(&program_image[rela.offset], &value, sizeof(u64));
-            break;
-        }
-        case RelocationType::JUMP_SLOT:
-        case RelocationType::GLOB_DAT:
-            if (!symbol.value) {
-                imports[symbol.name] = {rela.offset + load_base, 0};
-            } else {
-                exports[symbol.name] = symbol.value;
-                std::memcpy(&program_image[rela.offset], &symbol.value, sizeof(u64));
-            }
-            break;
-        case RelocationType::ABS64:
-            if (!symbol.value) {
-                imports[symbol.name] = {rela.offset + load_base, rela.addend};
-            } else {
-                const u64 value = symbol.value + rela.addend;
-                exports[symbol.name] = value;
-                std::memcpy(&program_image[rela.offset], &value, sizeof(u64));
-            }
-            break;
-        default:
-            LOG_CRITICAL(Loader, "Unknown relocation type: {}", static_cast<int>(rela.type));
-            break;
-        }
-    }
-}
-
-void Linker::Relocate(std::vector<u8>& program_image, u32 dynamic_section_offset, VAddr load_base) {
-    std::map<u64, u64> dynamic;
-    while (dynamic_section_offset < program_image.size()) {
-        Elf64_Dyn dyn;
-        std::memcpy(&dyn, &program_image[dynamic_section_offset], sizeof(Elf64_Dyn));
-        dynamic_section_offset += sizeof(Elf64_Dyn);
-
-        if (dyn.tag == DT_NULL) {
-            break;
-        }
-        dynamic[dyn.tag] = dyn.value;
-    }
-
-    u64 offset = dynamic[DT_SYMTAB];
-    std::vector<Symbol> symbols;
-    while (offset < program_image.size()) {
-        Elf64_Sym sym;
-        std::memcpy(&sym, &program_image[offset], sizeof(Elf64_Sym));
-        offset += sizeof(Elf64_Sym);
-
-        if (sym.name >= dynamic[DT_STRSZ]) {
-            break;
-        }
-
-        std::string name = reinterpret_cast<char*>(&program_image[dynamic[DT_STRTAB] + sym.name]);
-        if (sym.value) {
-            exports[name] = load_base + sym.value;
-            symbols.emplace_back(std::move(name), load_base + sym.value);
-        } else {
-            symbols.emplace_back(std::move(name), 0);
-        }
-    }
-
-    if (dynamic.find(DT_RELA) != dynamic.end()) {
-        WriteRelocations(program_image, symbols, dynamic[DT_RELA], dynamic[DT_RELASZ], load_base);
-    }
-
-    if (dynamic.find(DT_JMPREL) != dynamic.end()) {
-        WriteRelocations(program_image, symbols, dynamic[DT_JMPREL], dynamic[DT_PLTRELSZ],
-                         load_base);
-    }
-}
-
-void Linker::ResolveImports() {
-    // Resolve imports
-    for (const auto& import : imports) {
-        const auto& search = exports.find(import.first);
-        if (search != exports.end()) {
-            Memory::Write64(import.second.ea, search->second + import.second.addend);
-        } else {
-            LOG_ERROR(Loader, "Unresolved import: {}", import.first);
-        }
-    }
-}
-
-} // namespace Loader
diff --git a/src/core/loader/linker.h b/src/core/loader/linker.h
deleted file mode 100644
index 1076258377..0000000000
--- a/src/core/loader/linker.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 yuzu emulator team
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <map>
-#include <string>
-#include "common/common_types.h"
-
-namespace Loader {
-
-class Linker {
-protected:
-    struct Symbol {
-        Symbol(std::string&& name, u64 value) : name(std::move(name)), value(value) {}
-        std::string name;
-        u64 value;
-    };
-
-    struct Import {
-        VAddr ea;
-        s64 addend;
-    };
-
-    void WriteRelocations(std::vector<u8>& program_image, const std::vector<Symbol>& symbols,
-                          u64 relocation_offset, u64 size, VAddr load_base);
-    void Relocate(std::vector<u8>& program_image, u32 dynamic_section_offset, VAddr load_base);
-
-    void ResolveImports();
-
-    std::map<std::string, Import> imports;
-    std::map<std::string, VAddr> exports;
-};
-
-} // namespace Loader
diff --git a/src/core/loader/nro.h b/src/core/loader/nro.h
index 013d629c0a..85b0ed6441 100644
--- a/src/core/loader/nro.h
+++ b/src/core/loader/nro.h
@@ -4,10 +4,10 @@
 
 #pragma once
 
+#include <memory>
 #include <string>
 #include <vector>
 #include "common/common_types.h"
-#include "core/loader/linker.h"
 #include "core/loader/loader.h"
 
 namespace FileSys {
@@ -21,7 +21,7 @@ class Process;
 namespace Loader {
 
 /// Loads an NRO file
-class AppLoader_NRO final : public AppLoader, Linker {
+class AppLoader_NRO final : public AppLoader {
 public:
     explicit AppLoader_NRO(FileSys::VirtualFile file);
     ~AppLoader_NRO() override;
diff --git a/src/core/loader/nso.h b/src/core/loader/nso.h
index 135b6ea5af..167c8a694c 100644
--- a/src/core/loader/nso.h
+++ b/src/core/loader/nso.h
@@ -6,8 +6,8 @@
 
 #include <optional>
 #include "common/common_types.h"
+#include "common/swap.h"
 #include "core/file_sys/patch_manager.h"
-#include "core/loader/linker.h"
 #include "core/loader/loader.h"
 
 namespace Kernel {
@@ -26,7 +26,7 @@ struct NSOArgumentHeader {
 static_assert(sizeof(NSOArgumentHeader) == 0x20, "NSOArgumentHeader has incorrect size.");
 
 /// Loads an NSO file
-class AppLoader_NSO final : public AppLoader, Linker {
+class AppLoader_NSO final : public AppLoader {
 public:
     explicit AppLoader_NSO(FileSys::VirtualFile file);