diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 3f2d99e44..634f4d572 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -1,6 +1,6 @@
 set(SRCS    core.cpp
             core_timing.cpp
-            loader/elf_reader.cpp
+            loader/elf.cpp
             loader/loader.cpp
             loader/ncch.cpp
             mem_map.cpp
@@ -51,8 +51,7 @@ set(SRCS    core.cpp
 
 set(HEADERS core.h
             core_timing.h
-            loader/elf_reader.h
-            loader/elf_types.h
+            loader/elf.h
             loader/loader.h
             loader/ncch.h
             mem_map.h
diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj
index bda89ff1d..e2216760a 100644
--- a/src/core/core.vcxproj
+++ b/src/core/core.vcxproj
@@ -181,7 +181,7 @@
     <ClCompile Include="hw\gpu.cpp" />
     <ClCompile Include="hw\hw.cpp" />
     <ClCompile Include="hw\ndma.cpp" />
-    <ClCompile Include="loader\elf_reader.cpp" />
+    <ClCompile Include="loader\elf.cpp" />
     <ClCompile Include="loader\loader.cpp" />
     <ClCompile Include="loader\ncch.cpp" />
     <ClCompile Include="mem_map.cpp" />
@@ -232,8 +232,7 @@
     <ClInclude Include="hw\gpu.h" />
     <ClInclude Include="hw\hw.h" />
     <ClInclude Include="hw\ndma.h" />
-    <ClInclude Include="loader\elf_reader.h" />
-    <ClInclude Include="loader\elf_types.h" />
+    <ClInclude Include="loader\elf.h" />
     <ClInclude Include="loader\loader.h" />
     <ClInclude Include="loader\ncch.h" />
     <ClInclude Include="mem_map.h" />
diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters
index 84f6160b5..91d3292da 100644
--- a/src/core/core.vcxproj.filters
+++ b/src/core/core.vcxproj.filters
@@ -167,15 +167,15 @@
     <ClCompile Include="hle\service\ndm.cpp">
       <Filter>hle\service</Filter>
     </ClCompile>
-    <ClCompile Include="loader\elf_reader.cpp">
-      <Filter>loader</Filter>
-    </ClCompile>
     <ClCompile Include="loader\loader.cpp">
       <Filter>loader</Filter>
     </ClCompile>
     <ClCompile Include="loader\ncch.cpp">
       <Filter>loader</Filter>
     </ClCompile>
+    <ClCompile Include="loader\elf.cpp">
+      <Filter>loader</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="arm\disassembler\arm_disasm.h">
@@ -305,18 +305,15 @@
     <ClInclude Include="hle\service\ndm.h">
       <Filter>hle\service</Filter>
     </ClInclude>
-    <ClInclude Include="loader\elf_reader.h">
-      <Filter>loader</Filter>
-    </ClInclude>
-    <ClInclude Include="loader\elf_types.h">
-      <Filter>loader</Filter>
-    </ClInclude>
     <ClInclude Include="loader\loader.h">
       <Filter>loader</Filter>
     </ClInclude>
     <ClInclude Include="loader\ncch.h">
       <Filter>loader</Filter>
     </ClInclude>
+    <ClInclude Include="loader\elf.h">
+      <Filter>loader</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Text Include="CMakeLists.txt" />
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
new file mode 100644
index 000000000..153c30f51
--- /dev/null
+++ b/src/core/loader/elf.cpp
@@ -0,0 +1,190 @@
+// Copyright 2013 Dolphin Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#include <string>
+
+#include "common/common.h"
+
+#include "common/symbols.h"
+#include "core/mem_map.h"
+#include "core/loader/elf.h"
+
+//void bswap(Elf32_Word &w) {w = Common::swap32(w);}
+//void bswap(Elf32_Half &w) {w = Common::swap16(w);}
+
+#define bswap(w) w // Dirty bswap disable for now... 3DS is little endian, anyway
+
+static void byteswapHeader(Elf32_Ehdr &ELF_H)
+{
+    bswap(ELF_H.e_type);
+    bswap(ELF_H.e_machine);
+    bswap(ELF_H.e_ehsize);
+    bswap(ELF_H.e_phentsize);
+    bswap(ELF_H.e_phnum);
+    bswap(ELF_H.e_shentsize);
+    bswap(ELF_H.e_shnum);
+    bswap(ELF_H.e_shstrndx);
+    bswap(ELF_H.e_version);
+    bswap(ELF_H.e_entry);
+    bswap(ELF_H.e_phoff);
+    bswap(ELF_H.e_shoff);
+    bswap(ELF_H.e_flags);
+}
+
+static void byteswapSegment(Elf32_Phdr &sec)
+{
+    bswap(sec.p_align);
+    bswap(sec.p_filesz);
+    bswap(sec.p_flags);
+    bswap(sec.p_memsz);
+    bswap(sec.p_offset);
+    bswap(sec.p_paddr);
+    bswap(sec.p_vaddr);
+    bswap(sec.p_type);
+}
+
+static void byteswapSection(Elf32_Shdr &sec)
+{
+    bswap(sec.sh_addr);
+    bswap(sec.sh_addralign);
+    bswap(sec.sh_entsize);
+    bswap(sec.sh_flags);
+    bswap(sec.sh_info);
+    bswap(sec.sh_link);
+    bswap(sec.sh_name);
+    bswap(sec.sh_offset);
+    bswap(sec.sh_size);
+    bswap(sec.sh_type);
+}
+
+ElfReader::ElfReader(void *ptr)
+{
+    base = (char*)ptr;
+    base32 = (u32 *)ptr;
+    header = (Elf32_Ehdr*)ptr;
+    byteswapHeader(*header);
+
+    segments = (Elf32_Phdr *)(base + header->e_phoff);
+    sections = (Elf32_Shdr *)(base + header->e_shoff);
+
+    entryPoint = header->e_entry;
+
+    LoadSymbols();
+}
+
+const char *ElfReader::GetSectionName(int section) const
+{
+    if (sections[section].sh_type == SHT_NULL)
+        return nullptr;
+
+    int nameOffset = sections[section].sh_name;
+    char *ptr = (char*)GetSectionDataPtr(header->e_shstrndx);
+
+    if (ptr)
+        return ptr + nameOffset;
+    else
+        return nullptr;
+}
+
+bool ElfReader::LoadInto(u32 vaddr)
+{
+    DEBUG_LOG(MASTER_LOG, "String section: %i", header->e_shstrndx);
+
+    // Should we relocate?
+    bRelocate = (header->e_type != ET_EXEC);
+
+    if (bRelocate)
+    {
+        DEBUG_LOG(MASTER_LOG, "Relocatable module");
+        entryPoint += vaddr;
+    }
+    else
+    {
+        DEBUG_LOG(MASTER_LOG, "Prerelocated executable");
+    }
+
+    INFO_LOG(MASTER_LOG, "%i segments:", header->e_phnum);
+
+    // First pass : Get the bits into RAM
+    u32 segmentVAddr[32];
+
+    u32 baseAddress = bRelocate ? vaddr : 0;
+
+    for (int i = 0; i < header->e_phnum; i++)
+    {
+        Elf32_Phdr *p = segments + i;
+
+        INFO_LOG(MASTER_LOG, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type, p->p_vaddr, p->p_filesz, p->p_memsz);
+
+        if (p->p_type == PT_LOAD)
+        {
+            segmentVAddr[i] = baseAddress + p->p_vaddr;
+            u32 writeAddr = segmentVAddr[i];
+
+            const u8 *src = GetSegmentPtr(i);
+            u8 *dst = Memory::GetPointer(writeAddr);
+            u32 srcSize = p->p_filesz;
+            u32 dstSize = p->p_memsz;
+            u32 *s = (u32*)src;
+            u32 *d = (u32*)dst;
+            for (int j = 0; j < (int)(srcSize + 3) / 4; j++)
+            {
+                *d++ = /*_byteswap_ulong*/(*s++);
+            }
+            if (srcSize < dstSize)
+            {
+                //memset(dst + srcSize, 0, dstSize-srcSize); //zero out bss
+            }
+            INFO_LOG(MASTER_LOG, "Loadable Segment Copied to %08x, size %08x", writeAddr, p->p_memsz);
+        }
+    }
+
+
+    INFO_LOG(MASTER_LOG, "Done loading.");
+    return true;
+}
+
+SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const
+{
+    for (int i = firstSection; i < header->e_shnum; i++)
+    {
+        const char *secname = GetSectionName(i);
+
+        if (secname != nullptr && strcmp(name, secname) == 0)
+            return i;
+    }
+    return -1;
+}
+
+bool ElfReader::LoadSymbols()
+{
+    bool hasSymbols = false;
+    SectionID sec = GetSectionByName(".symtab");
+    if (sec != -1)
+    {
+        int stringSection = sections[sec].sh_link;
+        const char *stringBase = (const char *)GetSectionDataPtr(stringSection);
+
+        //We have a symbol table!
+        Elf32_Sym *symtab = (Elf32_Sym *)(GetSectionDataPtr(sec));
+        int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym);
+        for (int sym = 0; sym < numSymbols; sym++)
+        {
+            int size = symtab[sym].st_size;
+            if (size == 0)
+                continue;
+
+            // int bind = symtab[sym].st_info >> 4;
+            int type = symtab[sym].st_info & 0xF;
+
+            const char *name = stringBase + symtab[sym].st_name;
+
+            Symbols::Add(symtab[sym].st_value, name, size, type);
+
+            hasSymbols = true;
+        }
+    }
+
+    return hasSymbols;
+}
diff --git a/src/core/loader/elf_types.h b/src/core/loader/elf.h
similarity index 51%
rename from src/core/loader/elf_types.h
rename to src/core/loader/elf.h
index f1bf3db72..2e6b80982 100644
--- a/src/core/loader/elf_types.h
+++ b/src/core/loader/elf.h
@@ -1,34 +1,34 @@
-// Copyright 2013 Dolphin Emulator Project
+// Copyright 2013 Dolphin Emulator Project / Citra Emulator Project
 // Licensed under GPLv2
 // Refer to the license.txt file included.
 
 #pragma once
 
+#include "common/common.h"
+
 // ELF Header Constants
 
 // File type
-enum ElfType
-{
-	ET_NONE   = 0,
-	ET_REL    = 1,
-	ET_EXEC   = 2,
-	ET_DYN    = 3,
-	ET_CORE   = 4,
-	ET_LOPROC = 0xFF00,
-	ET_HIPROC = 0xFFFF,
+enum ElfType {
+    ET_NONE = 0,
+    ET_REL = 1,
+    ET_EXEC = 2,
+    ET_DYN = 3,
+    ET_CORE = 4,
+    ET_LOPROC = 0xFF00,
+    ET_HIPROC = 0xFFFF,
 };
 
 // Machine/Architecture
-enum ElfMachine
-{
-	EM_NONE  = 0,
-	EM_M32   = 1,
-	EM_SPARC = 2,
-	EM_386   = 3,
-	EM_68K   = 4,
-	EM_88K   = 5,
-	EM_860   = 7,
-	EM_MIPS  = 8
+enum ElfMachine {
+    EM_NONE = 0,
+    EM_M32 = 1,
+    EM_SPARC = 2,
+    EM_386 = 3,
+    EM_68K = 4,
+    EM_88K = 5,
+    EM_860 = 7,
+    EM_MIPS = 8
 };
 
 // File version
@@ -62,8 +62,6 @@ enum ElfMachine
 #define ELFDATA2LSB 1
 #define ELFDATA2MSB 2
 
-
-
 // Sections constants
 
 // Section indexes
@@ -96,14 +94,13 @@ enum ElfMachine
 // Custom section types
 #define SHT_PSPREL 0x700000a0
 
-
 // Section flags
 enum ElfSectionFlags
 {
-	SHF_WRITE     = 0x1,
-	SHF_ALLOC     = 0x2,
-	SHF_EXECINSTR = 0x4,
-	SHF_MASKPROC  = 0xF0000000,
+    SHF_WRITE = 0x1,
+    SHF_ALLOC = 0x2,
+    SHF_EXECINSTR = 0x4,
+    SHF_MASKPROC = 0xF0000000,
 };
 
 // Symbol binding
@@ -188,63 +185,58 @@ typedef unsigned int  Elf32_Off;
 typedef signed   int  Elf32_Sword;
 typedef unsigned int  Elf32_Word;
 
-
 // ELF file header
-struct Elf32_Ehdr
-{
-	unsigned char e_ident[EI_NIDENT];
-	Elf32_Half    e_type;
-	Elf32_Half    e_machine;
-	Elf32_Word    e_version;
-	Elf32_Addr    e_entry;
-	Elf32_Off     e_phoff;
-	Elf32_Off     e_shoff;
-	Elf32_Word    e_flags;
-	Elf32_Half    e_ehsize;
-	Elf32_Half    e_phentsize;
-	Elf32_Half    e_phnum;
-	Elf32_Half    e_shentsize;
-	Elf32_Half    e_shnum;
-	Elf32_Half    e_shstrndx;
+struct Elf32_Ehdr {
+    unsigned char e_ident[EI_NIDENT];
+    Elf32_Half    e_type;
+    Elf32_Half    e_machine;
+    Elf32_Word    e_version;
+    Elf32_Addr    e_entry;
+    Elf32_Off     e_phoff;
+    Elf32_Off     e_shoff;
+    Elf32_Word    e_flags;
+    Elf32_Half    e_ehsize;
+    Elf32_Half    e_phentsize;
+    Elf32_Half    e_phnum;
+    Elf32_Half    e_shentsize;
+    Elf32_Half    e_shnum;
+    Elf32_Half    e_shstrndx;
 };
 
 // Section header
-struct Elf32_Shdr
-{
-	Elf32_Word sh_name;
-	Elf32_Word sh_type;
-	Elf32_Word sh_flags;
-	Elf32_Addr sh_addr;
-	Elf32_Off  sh_offset;
-	Elf32_Word sh_size;
-	Elf32_Word sh_link;
-	Elf32_Word sh_info;
-	Elf32_Word sh_addralign;
-	Elf32_Word sh_entsize;
+struct Elf32_Shdr {
+    Elf32_Word sh_name;
+    Elf32_Word sh_type;
+    Elf32_Word sh_flags;
+    Elf32_Addr sh_addr;
+    Elf32_Off  sh_offset;
+    Elf32_Word sh_size;
+    Elf32_Word sh_link;
+    Elf32_Word sh_info;
+    Elf32_Word sh_addralign;
+    Elf32_Word sh_entsize;
 };
 
 // Segment header
-struct Elf32_Phdr
-{
-	Elf32_Word p_type;
-	Elf32_Off  p_offset;
-	Elf32_Addr p_vaddr;
-	Elf32_Addr p_paddr;
-	Elf32_Word p_filesz;
-	Elf32_Word p_memsz;
-	Elf32_Word p_flags;
-	Elf32_Word p_align;
+struct Elf32_Phdr {
+    Elf32_Word p_type;
+    Elf32_Off  p_offset;
+    Elf32_Addr p_vaddr;
+    Elf32_Addr p_paddr;
+    Elf32_Word p_filesz;
+    Elf32_Word p_memsz;
+    Elf32_Word p_flags;
+    Elf32_Word p_align;
 };
 
 // Symbol table entry
-struct Elf32_Sym
-{
-	Elf32_Word    st_name;
-	Elf32_Addr    st_value;
-	Elf32_Word    st_size;
-	unsigned char st_info;
-	unsigned char st_other;
-	Elf32_Half    st_shndx;
+struct Elf32_Sym {
+    Elf32_Word    st_name;
+    Elf32_Addr    st_value;
+    Elf32_Word    st_size;
+    unsigned char st_info;
+    unsigned char st_other;
+    Elf32_Half    st_shndx;
 };
 
 #define ELF32_ST_BIND(i)   ((i)>>4)
@@ -252,30 +244,88 @@ struct Elf32_Sym
 #define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
 
 // Relocation entries
-struct Elf32_Rel
-{
-	Elf32_Addr r_offset;
-	Elf32_Word r_info;
+struct Elf32_Rel {
+    Elf32_Addr r_offset;
+    Elf32_Word r_info;
 };
 
-struct Elf32_Rela
-{
-	Elf32_Addr  r_offset;
-	Elf32_Word  r_info;
-	Elf32_Sword r_addend;
+struct Elf32_Rela {
+    Elf32_Addr  r_offset;
+    Elf32_Word  r_info;
+    Elf32_Sword r_addend;
 };
 
 #define ELF32_R_SYM(i) ((i)>>8)
 #define ELF32_R_TYPE(i) ((unsigned char)(i))
 #define ELF32_R_INFO(s,t) (((s)<<8 )+(unsigned char)(t))
 
-
-struct Elf32_Dyn
-{
-	Elf32_Sword d_tag;
-	union
-	{
-		Elf32_Word d_val;
-		Elf32_Addr d_ptr;
-	} d_un;
+struct Elf32_Dyn {
+    Elf32_Sword d_tag;
+    union {
+        Elf32_Word d_val;
+        Elf32_Addr d_ptr;
+    } d_un;
+};
+
+enum KnownElfTypes {
+    KNOWNELF_PSP = 0,
+    KNOWNELF_DS = 1,
+    KNOWNELF_GBA = 2,
+    KNOWNELF_GC = 3,
+};
+
+typedef int SectionID;
+
+class ElfReader {
+private:
+    char *base;
+    u32 *base32;
+
+    Elf32_Ehdr *header;
+    Elf32_Phdr *segments;
+    Elf32_Shdr *sections;
+
+    u32 *sectionAddrs;
+    bool bRelocate;
+    u32 entryPoint;
+
+public:
+    ElfReader(void *ptr);
+    ~ElfReader() { }
+
+    u32 Read32(int off) const { return base32[off >> 2]; }
+
+    // Quick accessors
+    ElfType GetType() const { return (ElfType)(header->e_type); }
+    ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); }
+    u32 GetEntryPoint() const { return entryPoint; }
+    u32 GetFlags() const { return (u32)(header->e_flags); }
+    bool LoadInto(u32 vaddr);
+    bool LoadSymbols();
+
+    int GetNumSegments() const { return (int)(header->e_phnum); }
+    int GetNumSections() const { return (int)(header->e_shnum); }
+    const u8 *GetPtr(int offset) const { return (u8*)base + offset; }
+    const char *GetSectionName(int section) const;
+    const u8 *GetSectionDataPtr(int section) const {
+        if (section < 0 || section >= header->e_shnum)
+            return nullptr;
+        if (sections[section].sh_type != SHT_NOBITS)
+            return GetPtr(sections[section].sh_offset);
+        else
+            return nullptr;
+    }
+    bool IsCodeSection(int section) const {
+        return sections[section].sh_type == SHT_PROGBITS;
+    }
+    const u8 *GetSegmentPtr(int segment) {
+        return GetPtr(segments[segment].p_offset);
+    }
+    u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; }
+    int GetSectionSize(SectionID section) const { return sections[section].sh_size; }
+    SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found
+
+    bool DidRelocate() {
+        return bRelocate;
+    }
 };
diff --git a/src/core/loader/elf_reader.cpp b/src/core/loader/elf_reader.cpp
deleted file mode 100644
index 123747f8e..000000000
--- a/src/core/loader/elf_reader.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2013 Dolphin Emulator Project
-// Licensed under GPLv2
-// Refer to the license.txt file included.
-
-#include <string>
-
-#include "common/common.h"
-
-#include "common/symbols.h"
-#include "core/mem_map.h"
-#include "core/loader/elf_reader.h"
-
-//void bswap(Elf32_Word &w) {w = Common::swap32(w);}
-//void bswap(Elf32_Half &w) {w = Common::swap16(w);}
-
-#define bswap(w) w // Dirty bswap disable for now... 3DS is little endian, anyway
-
-static void byteswapHeader(Elf32_Ehdr &ELF_H)
-{
-	bswap(ELF_H.e_type);
-	bswap(ELF_H.e_machine);
-	bswap(ELF_H.e_ehsize);
-	bswap(ELF_H.e_phentsize);
-	bswap(ELF_H.e_phnum);
-	bswap(ELF_H.e_shentsize);
-	bswap(ELF_H.e_shnum);
-	bswap(ELF_H.e_shstrndx);
-	bswap(ELF_H.e_version);
-	bswap(ELF_H.e_entry);
-	bswap(ELF_H.e_phoff);
-	bswap(ELF_H.e_shoff);
-	bswap(ELF_H.e_flags);
-}
-
-static void byteswapSegment(Elf32_Phdr &sec)
-{
-	bswap(sec.p_align);
-	bswap(sec.p_filesz);
-	bswap(sec.p_flags);
-	bswap(sec.p_memsz);
-	bswap(sec.p_offset);
-	bswap(sec.p_paddr);
-	bswap(sec.p_vaddr);
-	bswap(sec.p_type);
-}
-
-static void byteswapSection(Elf32_Shdr &sec)
-{
-	bswap(sec.sh_addr);
-	bswap(sec.sh_addralign);
-	bswap(sec.sh_entsize);
-	bswap(sec.sh_flags);
-	bswap(sec.sh_info);
-	bswap(sec.sh_link);
-	bswap(sec.sh_name);
-	bswap(sec.sh_offset);
-	bswap(sec.sh_size);
-	bswap(sec.sh_type);
-}
-
-ElfReader::ElfReader(void *ptr)
-{
-	base = (char*)ptr;
-	base32 = (u32 *)ptr;
-	header = (Elf32_Ehdr*)ptr;
-	byteswapHeader(*header);
-
-	segments = (Elf32_Phdr *)(base + header->e_phoff);
-	sections = (Elf32_Shdr *)(base + header->e_shoff);
-
-	entryPoint = header->e_entry;
-
-    LoadSymbols();
-}
-
-const char *ElfReader::GetSectionName(int section) const
-{
-	if (sections[section].sh_type == SHT_NULL)
-		return nullptr;
-
-	int nameOffset = sections[section].sh_name;
-	char *ptr = (char*)GetSectionDataPtr(header->e_shstrndx);
-
-	if (ptr)
-		return ptr + nameOffset;
-	else
-		return nullptr;
-}
-
-bool ElfReader::LoadInto(u32 vaddr)
-{
-	DEBUG_LOG(MASTER_LOG,"String section: %i", header->e_shstrndx);
-
-	// Should we relocate?
-	bRelocate = (header->e_type != ET_EXEC);
-
-	if (bRelocate)
-	{
-		DEBUG_LOG(MASTER_LOG,"Relocatable module");
-		entryPoint += vaddr;
-	}
-	else
-	{
-		DEBUG_LOG(MASTER_LOG,"Prerelocated executable");
-	}
-
-	INFO_LOG(MASTER_LOG,"%i segments:", header->e_phnum);
-
-	// First pass : Get the bits into RAM
-	u32 segmentVAddr[32];
-
-	u32 baseAddress = bRelocate?vaddr:0;
-
-	for (int i = 0; i < header->e_phnum; i++)
-	{
-		Elf32_Phdr *p = segments + i;
-
-		INFO_LOG(MASTER_LOG, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type, p->p_vaddr, p->p_filesz, p->p_memsz);
-
-		if (p->p_type == PT_LOAD)
-		{
-			segmentVAddr[i] = baseAddress + p->p_vaddr;
-			u32 writeAddr = segmentVAddr[i];
-
-			const u8 *src = GetSegmentPtr(i);
-			u8 *dst = Memory::GetPointer(writeAddr);
-			u32 srcSize = p->p_filesz;
-			u32 dstSize = p->p_memsz;
-			u32 *s = (u32*)src;
-			u32 *d = (u32*)dst;
-			for (int j = 0; j < (int)(srcSize + 3) / 4; j++)
-			{
-				*d++ = /*_byteswap_ulong*/(*s++);
-			}
-			if (srcSize < dstSize)
-			{
-				//memset(dst + srcSize, 0, dstSize-srcSize); //zero out bss
-			}
-			INFO_LOG(MASTER_LOG,"Loadable Segment Copied to %08x, size %08x", writeAddr, p->p_memsz);
-		}
-	}
-
-
-    INFO_LOG(MASTER_LOG,"Done loading.");
-	return true;
-}
-
-SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const
-{
-	for (int i = firstSection; i < header->e_shnum; i++)
-	{
-		const char *secname = GetSectionName(i);
-
-		if (secname != nullptr && strcmp(name, secname) == 0)
-			return i;
-	}
-	return -1;
-}
-
-bool ElfReader::LoadSymbols()
-{
-	bool hasSymbols = false;
-	SectionID sec = GetSectionByName(".symtab");
-	if (sec != -1)
-	{
-		int stringSection = sections[sec].sh_link;
-		const char *stringBase = (const char *)GetSectionDataPtr(stringSection);
-
-		//We have a symbol table!
-		Elf32_Sym *symtab = (Elf32_Sym *)(GetSectionDataPtr(sec));
-		int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym);
-		for (int sym = 0; sym < numSymbols; sym++)
-		{
-            int size = symtab[sym].st_size;
-			if (size == 0)
-				continue;
-
-			// int bind = symtab[sym].st_info >> 4;
-			int type = symtab[sym].st_info & 0xF;
-
-			const char *name = stringBase + symtab[sym].st_name;
-
-            Symbols::Add(symtab[sym].st_value, name, size, type);
-
-            hasSymbols = true;
-		}
-	}
-
-    return hasSymbols;
-}
diff --git a/src/core/loader/elf_reader.h b/src/core/loader/elf_reader.h
deleted file mode 100644
index 6f0ad84b3..000000000
--- a/src/core/loader/elf_reader.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2013 Dolphin Emulator Project
-// Licensed under GPLv2
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include "core/loader/elf_types.h"
-
-enum KnownElfTypes
-{
-	KNOWNELF_PSP = 0,
-	KNOWNELF_DS  = 1,
-	KNOWNELF_GBA = 2,
-	KNOWNELF_GC  = 3,
-};
-
-typedef int SectionID;
-
-class ElfReader
-{
-private:
-	char *base;
-	u32 *base32;
-
-	Elf32_Ehdr *header;
-	Elf32_Phdr *segments;
-	Elf32_Shdr *sections;
-
-	u32 *sectionAddrs;
-	bool bRelocate;
-	u32 entryPoint;
-
-public:
-	ElfReader(void *ptr);
-	~ElfReader() { }
-
-	u32 Read32(int off) const { return base32[off>>2]; }
-
-	// Quick accessors
-	ElfType GetType() const { return (ElfType)(header->e_type); }
-	ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); }
-	u32 GetEntryPoint() const { return entryPoint; }
-	u32 GetFlags() const { return (u32)(header->e_flags); }
-	bool LoadInto(u32 vaddr);
-	bool LoadSymbols();
-
-	int GetNumSegments() const { return (int)(header->e_phnum); }
-	int GetNumSections() const { return (int)(header->e_shnum); }
-	const u8 *GetPtr(int offset) const { return (u8*)base + offset; }
-	const char *GetSectionName(int section) const;
-	const u8 *GetSectionDataPtr(int section) const
-	{
-		if (section < 0 || section >= header->e_shnum)
-			return nullptr;
-		if (sections[section].sh_type != SHT_NOBITS)
-			return GetPtr(sections[section].sh_offset);
-		else
-			return nullptr;
-	}
-	bool IsCodeSection(int section) const
-	{
-		return sections[section].sh_type == SHT_PROGBITS;
-	}
-	const u8 *GetSegmentPtr(int segment)
-	{
-		return GetPtr(segments[segment].p_offset);
-	}
-	u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; }
-	int GetSectionSize(SectionID section) const { return sections[section].sh_size; }
-	SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found
-
-	bool DidRelocate() {
-		return bRelocate;
-	}
-};
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 41fa9c32e..d8060c0e6 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -6,7 +6,7 @@
 #include "common/file_util.h"
 
 #include "core/loader/loader.h"
-#include "core/loader/elf_reader.h"
+#include "core/loader/elf.h"
 #include "core/loader/ncch.h"
 #include "core/system.h"
 #include "core/core.h"