From 16f318408d26ed4f22ee968321ad908b5bc6e450 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 25 Oct 2018 10:00:37 +0200 Subject: [PATCH] ELFLoader should fail with an error message for unresolved symbols. --- AK/Assertions.h | 2 +- AK/Compiler.h | 9 +++++++++ AK/RetainPtr.h | 1 + AK/kmalloc.cpp | 14 ++++++++++++-- AK/kmalloc.h | 6 +++++- ELFLoader/ELFImage.h | 18 ++++++++++++------ ELFLoader/ELFLoader.cpp | 39 +++++++++++++++++++++++++++++++-------- ELFLoader/ELFLoader.h | 4 ++-- Kernel/Task.cpp | 1 + Kernel/_fs_contents | Bin 1024000 -> 1024000 bytes Kernel/kprintf.h | 2 ++ LibC/types.h | 2 +- LibC/unistd.cpp | 4 ++-- Userland/Makefile | 2 +- 14 files changed, 80 insertions(+), 24 deletions(-) create mode 100644 AK/Compiler.h diff --git a/AK/Assertions.h b/AK/Assertions.h index a941d7a697..9e95bcc6c2 100644 --- a/AK/Assertions.h +++ b/AK/Assertions.h @@ -1,7 +1,7 @@ #pragma once #ifdef SERENITY -#include "kassert.h" +#include #else #include #define ASSERT(x) assert(x) diff --git a/AK/Compiler.h b/AK/Compiler.h new file mode 100644 index 0000000000..0ae775e888 --- /dev/null +++ b/AK/Compiler.h @@ -0,0 +1,9 @@ +#pragma once + +#define PACKED __attribute__ ((packed)) +#define NORETURN __attribute__ ((noreturn)) +#define ALWAYS_INLINE __attribute__ ((always_inline)) +#define NEVER_INLINE __attribute__ ((noinline)) +#define MALLOC_ATTR __attribute__ ((malloc)) +#define PURE __attribute__ ((pure)) + diff --git a/AK/RetainPtr.h b/AK/RetainPtr.h index c2fbd215d0..d234b45e91 100644 --- a/AK/RetainPtr.h +++ b/AK/RetainPtr.h @@ -1,5 +1,6 @@ #pragma once +#include "Compiler.h" #include "Types.h" namespace AK { diff --git a/AK/kmalloc.cpp b/AK/kmalloc.cpp index 448b2ca6db..80b662304f 100644 --- a/AK/kmalloc.cpp +++ b/AK/kmalloc.cpp @@ -1,10 +1,20 @@ -#include -#include "SimpleMalloc.h" #include "kmalloc.h" + +#ifndef SERENITY +#include #include +#endif + +#if defined(SERENITY) && defined(USERLAND) +#define USE_SYSTEM_MALLOC +#endif #define USE_SYSTEM_MALLOC +#ifndef USE_SYSTEM_MALLOC +#include "SimpleMalloc.h" +#endif + #ifdef USE_SYSTEM_MALLOC extern "C" { diff --git a/AK/kmalloc.h b/AK/kmalloc.h index 2c5c2bdb4f..24f48f376f 100644 --- a/AK/kmalloc.h +++ b/AK/kmalloc.h @@ -1,7 +1,11 @@ #pragma once #ifdef SERENITY +#ifdef USERLAND +#include +#else #include +#endif #else #include @@ -10,7 +14,7 @@ extern "C" { void* kcalloc(size_t nmemb, size_t size); -void* kmalloc(size_t size) __attribute__ ((malloc)); +void* kmalloc(size_t size) MALLOC_ATTR; void kfree(void* ptr); void* krealloc(void* ptr, size_t size); diff --git a/ELFLoader/ELFImage.h b/ELFLoader/ELFImage.h index 839fa20c0b..ff0715ee21 100644 --- a/ELFLoader/ELFImage.h +++ b/ELFLoader/ELFImage.h @@ -147,22 +147,28 @@ inline void ELFImage::forEachSectionOfType(unsigned type, F func) const { for (unsigned i = 0; i < sectionCount(); ++i) { auto& section = this->section(i); - if (section.type() == type) - func(section); + if (section.type() == type) { + if (!func(section)) + break; + } } } template inline void ELFImage::RelocationSection::forEachRelocation(F func) const { - for (unsigned i = 0; i < relocationCount(); ++i) - func(relocation(i)); + for (unsigned i = 0; i < relocationCount(); ++i) { + if (!func(relocation(i))) + break; + } } template inline void ELFImage::forEachSymbol(F func) const { - for (unsigned i = 0; i < symbolCount(); ++i) - func(symbol(i)); + for (unsigned i = 0; i < symbolCount(); ++i) { + if (!func(symbol(i))) + break; + } } diff --git a/ELFLoader/ELFLoader.cpp b/ELFLoader/ELFLoader.cpp index 3b3bf4845e..a14b3443f7 100644 --- a/ELFLoader/ELFLoader.cpp +++ b/ELFLoader/ELFLoader.cpp @@ -25,26 +25,38 @@ bool ELFLoader::load() if (!m_image->isValid()) return false; - layout(); + if (!layout()) + return false; exportSymbols(); - performRelocations(); + if (!performRelocations()) + return false; return true; } -void ELFLoader::layout() +bool ELFLoader::layout() { #ifdef ELFLOADER_DEBUG kprintf("[ELFLoader] Layout\n"); #endif - m_image->forEachSectionOfType(SHT_PROGBITS, [this] (const ELFImage::Section& section) { + bool failed = false; + m_image->forEachSectionOfType(SHT_PROGBITS, [this, &failed] (const ELFImage::Section& section) { #ifdef ELFLOADER_DEBUG kprintf("[ELFLoader] Allocating progbits section: %s\n", section.name()); #endif + if (!section.size()) + return true; char* ptr = m_execSpace.allocateArea(section.name(), section.size()); + if (!ptr) { + kprintf("ELFLoader: failed to allocate section '%s'\n", section.name()); + failed = true; + return false; + } memcpy(ptr, section.rawData(), section.size()); m_sections.set(section.name(), move(ptr)); + return true; }); + return !failed; } void* ELFLoader::lookup(const ELFImage::Symbol& symbol) @@ -67,23 +79,30 @@ char* ELFLoader::areaForSectionName(const char* name) return nullptr; } -void ELFLoader::performRelocations() +bool ELFLoader::performRelocations() { #ifdef ELFLOADER_DEBUG kprintf("[ELFLoader] Performing relocations\n"); #endif - m_image->forEachSectionOfType(SHT_PROGBITS, [this] (const ELFImage::Section& section) { + bool failed = false; + + m_image->forEachSectionOfType(SHT_PROGBITS, [this, &failed] (const ELFImage::Section& section) -> bool { auto& relocations = section.relocations(); if (relocations.isUndefined()) - return; - relocations.forEachRelocation([this, section] (const ELFImage::Relocation& relocation) { + return true; + relocations.forEachRelocation([this, section, &failed] (const ELFImage::Relocation& relocation) { auto symbol = relocation.symbol(); auto& patchPtr = *reinterpret_cast(areaForSection(section) + relocation.offset()); switch (relocation.type()) { case R_386_PC32: { char* targetPtr = (char*)lookup(symbol); + if (!targetPtr) { + kprintf("ELFLoader: unresolved symbol '%s'\n", symbol.name()); + failed = true; + return false; + } ptrdiff_t relativeOffset = (char*)targetPtr - ((char*)&patchPtr + 4); #ifdef ELFLOADER_DEBUG kprintf("[ELFLoader] Relocate PC32: offset=%x, symbol=%u(%s) value=%x target=%p, offset=%d\n", @@ -115,8 +134,11 @@ void ELFLoader::performRelocations() ASSERT_NOT_REACHED(); break; } + return true; }); + return !failed; }); + return !failed; } void ELFLoader::exportSymbols() @@ -128,6 +150,7 @@ void ELFLoader::exportSymbols() if (symbol.type() == STT_FUNC) m_execSpace.addSymbol(symbol.name(), areaForSection(symbol.section()) + symbol.value(), symbol.size()); // FIXME: What about other symbol types? + return true; }); } diff --git a/ELFLoader/ELFLoader.h b/ELFLoader/ELFLoader.h index f8f4877243..b7a1f5161f 100644 --- a/ELFLoader/ELFLoader.h +++ b/ELFLoader/ELFLoader.h @@ -19,8 +19,8 @@ public: bool load(); private: - void layout(); - void performRelocations(); + bool layout(); + bool performRelocations(); void exportSymbols(); void* lookup(const ELFImage::Symbol&); char* areaForSection(const ELFImage::Section&); diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp index 50bc885708..0ef0831070 100644 --- a/Kernel/Task.cpp +++ b/Kernel/Task.cpp @@ -201,6 +201,7 @@ Task* Task::create(const String& path, uid_t uid, gid_t gid, pid_t parentPID) bool success = space.loadELF(move(elfData)); if (!success) { delete t; + kprintf("Failure loading ELF %s\n", path.characters()); return nullptr; } diff --git a/Kernel/_fs_contents b/Kernel/_fs_contents index fbf9da7dbd5ef29a9cb06874f60a9272d501ee38..d3cf094bfb677388498aea3b48c881e5e7071095 100644 GIT binary patch delta 5117 zcmdT{eNa@_6+drban}fL^m&aYu;1VanH|v zO@X|REs{1hJDc?#Ywg6*;zi4{{70spZv`J-z)lb+zv@a*`g_v$7A+D-W_Zv;bObU6 zc?j|q$WbR)xq6~^L%HXMuB9-&4N?YK4Jn7LVOQsT^~pMO(SU2wufptdx>sg+>;<$ z%bj+jn?%vTxSQxc86RgvfZt~X!8jxA1B}Q(jbNA&3r87u62%z5fI4AB04bS&Uglq6 zOhEA)?!fB}Mi6r*Ji8rp8@?kB1TS{QRCJV?V`jEH)G@g5YY=#Ps2yE1-S#uG9= zBjY~;6P`w*#VBtN@^>3!7f~f60^7`pRCP0AXZ=79;2@6?KvKphcpM>mmJw0?Oy*zZ zG3?GVHWB@n5gUDz5gVPcaQ?gl94}cxA}?yw+JFEAza-c%cv_HmZdD;uGQLyru;8PD zuL~~V9rqFW82Mb$EL3(j)>j=?@B}~ai~&Ja#TfIE@I3w$+JdEm<$|bNrLPp+D7Z;* zi(p8w3F|8dl>xA$Uep-bSBUyjh~rfVAPc3NEvN#=SOpGLfdf_GKovMp1rD^uPX&(g zJ{37SDsrHT9H=4(s>p#Va$raZaGWX-6*%Tq;6N2PPz4TDf!~t)$C$O=+4gZ!qU+w) zs_iYo%EqyHwDHisebLy)p5c+Pa9d0NeyWH^kHjlr(gK^Bj(BWfsIO))I@A~M4DBhikEgXk_$Lo^Y&7 z`?bZ@Li63Kd*Br_mviN@ZuHRJ(RhMW8s3joyEDak*!AGh9I@;M@yy#%IGlMEcF&N2 zOvXFZ@n^EGiHwXyhkC=iI)YvEqjPPddURxPARg{XwJrDmKDBbE<#nF;dwnQfRFZjp zlog}#Sg;}puHoKDJYtkpIvtV?XWf;Ogtn3b{ol?g9IWf=YHJU7cJA)lad+z-oz1&i zyEy)9Y_9Ozn06t|@m<4q{AjaHCOf_kv>o0UrX62*>BjejHpDB&G!(1!{h^VaS?zra zlWS9vh`+#j=ECCj<15m)FlUlKIoO^Pu^EE*BIV$n#qBJl-HBYtce+3E^XDJ8H{i@y zIy>h=wDbMwyPX3VEX15{;;uI3wp)H3yXWAj?1Z496eCWnZkq5}O!y%oQCviT<>+&O zTxTl4RB(&GAOVJ2v0~5+Q|P-H0(ezvhJ5Js7SE&a4(X>DRAWvz%{PMyH{T}kamo@L z5`WcdLO%!;p?Llc19sF+6V@1Z?_fWiE=R4T^u};F0J1V96_n=4y`9`fgGE%LZ{0N1*q*#zlPA zaR1Qn{P5kPhF==)<1Y7gF84ne?nStVd>mKd+lHn@X@c(+6c~!KIhT(NO$9V7n5^Mn z(74kygK%{5^R9HJJve%IrklY~tkRTgXd=0(vv*lb3ykRla9F6~Uu|d(K@(7#4Tk2J zUZgN&Xr6&4PxHWfhpFpbpCD$prR8)A( zn0_0?A!pU4{K6j_nq_(TfvhxtH8dxnNwFsJo@j6os)ZJ(e+9^pZ0XeEDEI`lT@rTg zi(cEs47(}V@k>uPTROi^+ubxr`0vHe(50gK*D&u+&SfO$41D;(X@o$nD&#F=oqGc8 z-tcF`{p8AP?oBTD3x@lv0j`1vF6A%zKs3mUYUcvZ{TGUs;MrE|8q+!6bXvri&IMBM zJn1XTJqNyVJj*RmG^VCItQ9%&rN~6KbM@-2Io&oGt|kfdMNpS$xuW mapJ_A_Dl8$zBc{`3pSQ1j7t48wG+wOWcmNazvq&*`Tqg`QTp5f delta 3775 zcmaJ@dsLLi6`%XDE8hYuyMR1mfaSf`N5MC?7@GJ%BN4P}Yix{F?A{${>e5&p=YbN9}D z%-s2A<~Q@JYoA=#KDl*-!}apwGfzq>35|0+Mn;MAAT=1jHK%x@g%CHw;YXUNC{&Xg zmln11-41I@(F@VKhm|<`KShz=$iC{^ z`WRBDK&C>bL8e2>WLN9bxM1)mYW_vzJ@%!wcPaa@p3bPYr0L}jDKKFtLRnhyIm#AlEia*q8ZQ$Vu*NA+o{U-h?lgz6w8+&9O4yi`=X@n65F*s zSmh^**R(xU*@ML{EAJmoynnWtU+aL&$QMGc4S9ulNb5}L&lN&yN)Q4~VT=@FoVF+F z_$;aM<;$fWCd7|*e4UOrX?usZTeKar?OO4^Y-9=Hz_-Xk$Pn0%h z@u<|<*et10xJ(Y1D1;Mj8X`oY)(f<*()zI0l`=m`h*V`4+NVHvT&oi{Y5ixd<@q*7 z2w_V76`uS!9Sxnm$iyk-T0vaCawr@OYp+NCV#l^?mr zVlz+;vFEQ$cP+nfbzJ$QYdb7Cd=}3Lny=AdYsuwA?-e-kjbac){^oE~&`k0E8_fsZ zi}-8{rLb?m=@{oitP~=D&5<$D#@FGL*frETqdgiTe;cgy-V|>phLod5ymfqbKZ;Gz zZY+iRC0Rf0O(~XJ@?fdGD0Kw!EJzw8QflUa-YaGAl4%2aFN*K$Ee~j<_rd|aPobp8 zTGgBAtCo~-<18t=NZP>HOsO9hVu{o_Lafs9wQWg`DkB4+bE0Ue<5xp znVc~RTDW-{G_B;O1<2Vn3HfzQ&tSZ_9%!Gl+m+8y0mAODQGwHgNjKUHd<5W_h6PS+ z@Kb}|Xz)ih_#F*?XM=xGgFkwo-%PSr_j(d~(t}w!Lzqg`;ZoD*qluh#-po&1gbwmli=MmT zaCme5&i{qO_3iQXTli^{(oz=V>};t&24|kYbV@|25b^a#d7DXda>JYduoscQujT*Y zK)qD!Hop`2#25I2(*6?o9^|63=&l(11CKd72!i? zkWw`#;#~Oc@F7{ZY5@mbG<Eo$EC6EOKrA0iZJkKJ6~%<(Za zjAn3g42`TU#tPE z)lO-2QQ!`xwFkNm1=`ooom){gTZV!duc-aiw(gJ2g=Tc#dY@0^t#6xo(Ts7>@7m^F zF@Hw2i?Jw_j28x4zA&q_y;j?MwEd>GTeKb0_6ey+3Gt!!cT0Pm5VxcT1|8T)Ilc>8 zj-RLPVp|s|Y9JGq=)fASU)1_nO1GWfM;Vwk-%O_*YUGaVW&!nZ$sSjM@i{Jv36$@u z^V$IQE6^I(o&36Vx88S4+!}5dAFlygk9}&U^2#cZh7p;R%4a5-9%mko?NIqVa61Cj z#ozf1WlFi@4V3woi~kOo(^5|NQGrqI;?t|ld}j^%s3(P6SD??!TznK?#Tto3YfGPfSU)KdBR zTNr$=a_wk^=L~nijbH~Y zxN33^SCcO_@jO;r{^Wrc!Y}efZfMN8ER)@f6Q)Q~9@{+bpCk4zHm! z#n>_wW3wb<^9~un*pjVKSMjh28~ddyggt;x5J_UUwj*q8AK2J#E?q_s*=!6?1Q4dk zkYZyAHVZTIG#kU`epQDJKAW zqS#n+p=M(UC^iPI*ch~8W6-$C6`JMkZ;Xhru{VfY_LIq(<>c&7$%1%ie8|mKl#iS{T=J6B^@did;hGl%|WE@KMS&3&j|j#Jq3 cQl&oz5(|lgxFLhvD*f>X*0tSuk9MB?Kgyj~VE_OC diff --git a/Kernel/kprintf.h b/Kernel/kprintf.h index bf7e74c2cf..d35d9d492a 100644 --- a/Kernel/kprintf.h +++ b/Kernel/kprintf.h @@ -1,5 +1,7 @@ #pragma once +#include + int kprintf(const char *fmt, ...); int ksprintf(char* buf, const char *fmt, ...); diff --git a/LibC/types.h b/LibC/types.h index d28920f7f2..23f532c938 100644 --- a/LibC/types.h +++ b/LibC/types.h @@ -12,7 +12,7 @@ typedef signed char signed_byte; typedef dword uid_t; typedef dword gid_t; -typedef dword pid_t; +typedef int pid_t; typedef dword size_t; typedef signed_dword ssize_t; diff --git a/LibC/unistd.cpp b/LibC/unistd.cpp index f0c5831940..814346e075 100644 --- a/LibC/unistd.cpp +++ b/LibC/unistd.cpp @@ -9,12 +9,12 @@ uid_t getuid() return Syscall::invoke(Syscall::PosixGetuid); } -uid_t getgid() +gid_t getgid() { return Syscall::invoke(Syscall::PosixGetgid); } -uid_t getpid() +pid_t getpid() { return Syscall::invoke(Syscall::PosixGetpid); } diff --git a/Userland/Makefile b/Userland/Makefile index e47a8578b6..2a866fcc04 100644 --- a/Userland/Makefile +++ b/Userland/Makefile @@ -20,7 +20,7 @@ FLAVOR_FLAGS = -fomit-frame-pointer -mregparm=3 -march=i386 -m32 -fno-exceptions OPTIMIZATION_FLAGS = -Os -fno-asynchronous-unwind-tables INCLUDE_FLAGS = -I.. -I. -DEFINES = -DSERENITY -DSANITIZE_PTRS +DEFINES = -DSERENITY -DSANITIZE_PTRS -DUSERLAND CXXFLAGS = $(WARNING_FLAGS) $(OPTIMIZATION_FLAGS) $(USERLAND_FLAGS) $(FLAVOR_FLAGS) $(ARCH_FLAGS) $(STANDARD_FLAGS) $(INCLUDE_FLAGS) $(DEFINES) CXX = g++