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 zcmZoTVApWKZi5aB=lT4L(Mc5-qwP1FvN$s`?PuM{*v7Pp!$pAa2O|R%9QgmAc_O3M z<{AkeNoLN9i<7$z8`(jck}57v7B>262xUh@)H5>hKo|@l6Uvzw7%G?;7%G_<7^;{U z7^;~V7-}XP8mMnhG1g$ht5t=GfkBmtfkBOlfkB;#fkA_bfk6|bb@CI_6_)6h3Lsfp z%f!G?$Hc%;&&0scz{J4N$i%?V#KgeR%*4RZGTG2Te)1DD4ZL=@GBGf;F)=W-Gcho9 zFflN6GBGf8f$ZL#Vm@a_y#)gU1Cu)ggCmHJVPIeb(V+|sq6`cSj0Ox0G9X%;fk6>U ztAXS_7#PGsbO-~30*H2JV9*B9$qWpYo&4+BFr zhz?+2m=2^;`Z~;UIK|+Gb9~uI>3=H59$Y5Zw0{K`M z5)w>q3=DxF_1p{$nIJlXfuS5KUjyR1F)&Pn@@GT&o1y$2Q2tp4P`YwrVBlwDU|>pN zU{D3o@eB+GAUc47!5TzIF)$>6Xm!IRXKzug_hJ7H~g@NHDh)!i-xB{Ys7#JQfGSo9LaWgP@fLvzCz`)AHz`$tCz+eES z!=ZErl->rVK|W_RVqlPf^1YyR8I*2;(#N1QJIKfB3=A9~8WgV}`(zjxSQzRV7#L+B z5+E9s-$67eZb39S70W=P1jGmD1{p}I2l2s)REB{;18SfSls16UCQurb%RuUFpnL}? z?NSeAfI~orfx!pL2c>F|h7c$}0!o9521Z$s%NZCzG{{FF8tiacNTLMs!48*&I$Rc- zjb)(@mxZP+Sq6qQu*+o`7{D%~dKK2C&Oz85qDWmt|l8yIhum!3E?X zS!mSBLLDy4zyNl*ECU1B;j#=2V28_2e^<$xVw##;P*RD<1Vf{ee1w}p3Q^n|mYQ6WU*zc* z91nH2tE)+IW>qRkA+nA2V9y7omLz88B_`#hf^--fKz!<%Tae@GYF?C@lbTqJq0`9G z+Y+KLpag6Ysy5T)oYcf3bnB49(XzNSsko#b6r`?MSqvEA;9s5xHyG-h+=3jC``|uu zb;WKAC>WtykOKglVmEN~n_*FHmRL}bnwR40A8Z(p>N+G(m=+i0WR|!lPY;mdJUw0B zmyvaH-%~3GNTPze6BdfABS0~L1=n?dCSOkotJLWm*;NcjPCAgEaevJ`~TEe2KpFm)ia zL25u4Rb4s*LjeN=xLF7CNe~{3LA5B%Kv0zqG7N-K4P;>GKr#02Ft9N}{JxKYfgxye z;xpmN3BNc&%|DRv1!+i;4$=&2X~8tdp=lOigfw(OdO#RzCIiS*ptdZ`5-A+&7Q@T~ zX=Y$xuvKA%6zxzx1I)nr3=9mM43KI8B=9w=Vd{*a`W>JG0Wy%<6lAXi14BIn%;J1B15KD9 z^)tvY5Qge!$VM};0oqUj87PGmGD~3QfiyEPFa$6$Ff4jXRJ7K^+a4fo32Bk)qCxnStRN%rHumU-NTR!GY}-mz`$SuZQ+2-1GNQV4g__y!1)ZS z?iULK6T|n(jBkW(L2Xm8AE8ncWEmJfKqCRvxq=xn8_h`{*%%mjLFIwaS~Qt|Y?J+- zi&?Eib6bNPBK?875HN%Hp=tldIeFf5G22~e+BYC+2X*dX+RvbA7vp7M-~hQx^d_2& z99YKirHBZcgc?{P@tLsbcQhG2UIqqfkYTo;(VX)@4$?{og*2#*3Udw1XXvLce30o zG0|2u;hVe+3=WeOUkQt@LX(l?V_>KR%Ung1nZ(DyFdZaQ{}L(#OZyJ|kX``PPH@j3 z#5QMv!~jfP13zj(56ZY8bwz0E4)8NDfGRzZ90UQia{AYCB$oQXmn*)b}!gd80&IjV#csLa#wkz;(J`kUrz{)XQAd^vGyTl5P o7n>(tQCP064onOT zj!X;;PLmA{)HkOXYcS!}>deHz;KIbf;L60n;Kszj;LgOr-~rM)`HATYOLR*GkSz6N zVqoxMVqoxQVqoxLVqoxPVqoxNVqoxRVqgfEY-k`q`H7hZUb_RC7#M<>7#MQFfb1_mJpQHCZcUjob*U}%T(lNdqr zEDSwRz5+9d&&eC7iO3Zg@M5bL^Clkq=0Bm28JT2d^w1( z!oV;Q%AW@1uY>Y8L-_R!CqN8E1_l;J1_qEtVvGz7Oxg?#${<>ufx#FmZUN$}FfcfQ zXe9;)KM)OyZjgb(3=FJH3=E8-3=9TPIvh%8KZ<%r}6f0+7ZsumA%? z3zR+vr9tVNNr!=f1LRPx>2}_XyEk8aJe_g6xGy8`fVp16TgTriIj5{hWT#Zc8y#SC|*Z`{DB&U=TGf#Cxa1A`LC;nM|G7^PXy@Gvke zn{If8Lzz`XfPtZTGUJ=u+cX#zM3@-(rz>eNDsOkqVPs|p7ho99@8tEIg+OtGpbmEaxEi21A{Cm0jV=E=zwC7pMk*;#FuAa z@B+~?3=D}NTA6{N5Gr4`-PM?JGV}Bm)r=~vGq@QT9HujxGb&Ga=->$8yul4gPO{Sv zrZdV<V5;N;+ei3w&f%1>9wWMr9spoVb{lLgQ8J_|;*=@&XVYNoS77cyIC=+F&0dp7|tO+y~T=AfU#jZV>YAs^fgHAD-d>IHlsRY!*pJ2Ms-#J zZU%;q>EHm~!OOtlHkt8_aGM5Wn+8*x26LMROPdC3n+98(2KzD%4w1z?G4Kq4^C@hA#sH#Mb5`0s#U4w_f=7 z|9?ghOfV|)|5lK_8R64ca58F}%>l`RYF4mAkF%&Gz*IIL5$FcH8!Xd$fWPG?0|P_z z0q)M$In(*M7&RF^r(1F{>egHS`~TmTA%TIRlow<_sBCzt3Kmm3z{D&-VlV&x{|_<04H+0%K;^s`0|O@$0|S#L1A{7*ZwaB* z!A%23F$RW2hyX(=lx~93bHViXbITazSQxiV|0v6-%-Avg>{||X#uw9V7jddHePx>N zXU?d`*&qnXpc>#z%k-9Y`aF>E2DmUN-!k!XPTyCqZE@DqnJlLz_tAV3e3%`-wxHX$e?p+6G1e#tYNWe&SGP1+^E!W&iX5kf^|P+0Pv6OaeTh z!eIJ>4U7Uz0zBZX4x(>uU{qt>z|X*N6_UR@gc%stO=f(fye)@OK|=V3Ajky_44?$f zz@WjP%Am5@_=+OObl!Myb8QFHbXZGGVEQ>wo9!KlsCvp_z^FL=e<`CRxWy(1Zm~@U zwb%qj(OPU`lQ%!G)P%LhWd@Ah z5VSQW1ZjmasX}N*VQ6biAKDrdhPK93(OP5L(AJnR0|U4A+fJiy5b{Tgk{VUEY_G6}3sW0@@@~0yoJ{K$~PrlR-_g3}_=vX)>ruHUrK(`+Wa) zhZP(LHg7k0!%@M=xCor5SxW>M7+y@j_?APN@fsvwKZfS(7 + 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++