summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Applications/Debugger/main.cpp5
-rw-r--r--CMakeLists.txt26
-rw-r--r--Demos/CMakeLists.txt2
-rw-r--r--Demos/DynamicObject/CMakeLists.txt4
-rw-r--r--Demos/DynamicObject/SampleLib/CMakeLists.txt4
-rw-r--r--Demos/DynamicObject/SampleLib/lib.cpp25
-rw-r--r--Demos/DynamicObject/lib.h27
-rw-r--r--Demos/DynamicObject/main.cpp63
-rw-r--r--Kernel/CMakeLists.txt2
-rw-r--r--Kernel/FileSystem/VirtualFileSystem.cpp2
-rw-r--r--Kernel/Process.h4
-rw-r--r--Kernel/Syscalls/execve.cpp11
-rw-r--r--Kernel/Syscalls/mmap.cpp3
-rw-r--r--Libraries/LibC/CMakeLists.txt9
-rw-r--r--Libraries/LibC/crt0_shared.cpp37
-rw-r--r--Libraries/LibCore/CMakeLists.txt2
-rw-r--r--Libraries/LibELF/DynamicLoader.cpp128
-rw-r--r--Libraries/LibELF/DynamicLoader.h7
-rw-r--r--Libraries/LibELF/DynamicObject.cpp56
-rw-r--r--Libraries/LibELF/DynamicObject.h7
-rw-r--r--Libraries/LibGUI/CMakeLists.txt2
-rw-r--r--Libraries/LibGfx/CMakeLists.txt2
-rw-r--r--Libraries/LibM/CMakeLists.txt7
-rw-r--r--Userland/CMakeLists.txt2
-rw-r--r--Userland/DynamicLoader/main.cpp126
-rw-r--r--Userland/DynamicLoader/misc.cpp3
-rw-r--r--Userland/Tests/Kernel/CMakeLists.txt1
-rw-r--r--Userland/Tests/LibC/CMakeLists.txt1
28 files changed, 398 insertions, 170 deletions
diff --git a/Applications/Debugger/main.cpp b/Applications/Debugger/main.cpp
index 93922f46e4..cefc1ad124 100644
--- a/Applications/Debugger/main.cpp
+++ b/Applications/Debugger/main.cpp
@@ -212,8 +212,9 @@ int main(int argc, char** argv)
sa.sa_handler = handle_sigint;
sigaction(SIGINT, &sa, nullptr);
- bool rc = g_debug_session->insert_breakpoint(g_debug_session->elf().entry().as_ptr());
- ASSERT(rc);
+ // bool rc = g_debug_session->insert_breakpoint(g_debug_session->elf().entry().as_ptr());
+ // bool rc = g_debug_session->insert_breakpoint((void*)0x08048f49);
+ // ASSERT(rc);
Debug::DebugInfo::SourcePosition previous_source_position;
bool in_step_line = false;
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f17a7eb0d0..5aa600954c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -119,25 +119,27 @@ endfunction()
function(serenity_lib target_name fs_name)
serenity_install_headers(${target_name})
serenity_install_sources("Libraries/${target_name}")
- add_library(${target_name} ${SOURCES} ${GENERATED_SOURCES})
- install(TARGETS ${target_name} ARCHIVE DESTINATION usr/lib)
+ #add_library(${target_name} SHARED ${SOURCES} ${GENERATED_SOURCES})
+ add_library(${target_name} SHARED ${SOURCES} ${GENERATED_SOURCES} ${CMAKE_SOURCE_DIR}/Libraries/LibC/crt0_shared.cpp)
+ #library_sources("{target_name}" PRIVATE ${CMAKE_SOURCE_DIR}/Libraries/LibC/crt0_shared.cpp)
+ install(TARGETS ${target_name} DESTINATION usr/lib)
set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${fs_name})
serenity_generated_sources(${target_name})
endfunction()
-function(serenity_libc target_name fs_name)
- serenity_install_headers("")
- serenity_install_sources("Libraries/LibC")
- add_library(${target_name} ${SOURCES})
- install(TARGETS ${target_name} ARCHIVE DESTINATION usr/lib)
+function(serenity_shared_lib target_name fs_name)
+ serenity_install_headers(${target_name})
+ serenity_install_sources("Libraries/${target_name}")
+ add_library(${target_name} SHARED ${SOURCES} ${GENERATED_SOURCES})
+ install(TARGETS ${target_name} DESTINATION usr/lib)
set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${fs_name})
- target_link_directories(LibC PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
serenity_generated_sources(${target_name})
endfunction()
-function(serenity_libc_shared target_name fs_name)
+function(serenity_libc target_name fs_name)
serenity_install_headers("")
serenity_install_sources("Libraries/LibC")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib -fpic")
add_library(${target_name} SHARED ${SOURCES})
install(TARGETS ${target_name} DESTINATION usr/lib)
set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${fs_name})
@@ -147,6 +149,7 @@ endfunction()
function(serenity_bin target_name)
add_executable(${target_name} ${SOURCES})
+ target_sources(${target_name} PRIVATE ${CMAKE_SOURCE_DIR}/Libraries/LibC/crt0_shared.cpp)
install(TARGETS ${target_name} RUNTIME DESTINATION bin)
serenity_generated_sources(${target_name})
endfunction()
@@ -220,8 +223,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Os -g1 -fno-exceptions -fno-rtti -Wno-a
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffile-prefix-map=${CMAKE_SOURCE_DIR}=.")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDEBUG -DSANITIZE_PTRS")
-set(CMAKE_CXX_FLAGS_WITHOUT_STATIC ${CMAKE_CXX_FLAGS})
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static")
+set(CMAKE_CXX_FLAGS_STATIC ${CMAKE_CXX_FLAGS})
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostartfiles -lgcc_s -pie -fpic")
+
add_link_options(--sysroot ${CMAKE_BINARY_DIR}/Root)
include_directories(Libraries/LibC)
diff --git a/Demos/CMakeLists.txt b/Demos/CMakeLists.txt
index 9f939e84a3..f6ddd58db3 100644
--- a/Demos/CMakeLists.txt
+++ b/Demos/CMakeLists.txt
@@ -1,6 +1,6 @@
add_subdirectory(Cube)
add_subdirectory(DynamicObject)
-add_subdirectory(DynamicLink)
+#add_subdirectory(DynamicLink)
add_subdirectory(Eyes)
add_subdirectory(Fire)
add_subdirectory(HelloWorld)
diff --git a/Demos/DynamicObject/CMakeLists.txt b/Demos/DynamicObject/CMakeLists.txt
index d32736e984..d1df1d0cbf 100644
--- a/Demos/DynamicObject/CMakeLists.txt
+++ b/Demos/DynamicObject/CMakeLists.txt
@@ -3,9 +3,9 @@ set(SOURCES
../../Libraries/LibC/crt0_shared.cpp
)
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_WITHOUT_STATIC} -nostartfiles -pie -fpic")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostartfiles -lgcc_s -pie -fpic ")
serenity_bin(DynamicObjectDemo)
-target_link_libraries(DynamicObjectDemo SampleLib LibCShared)
+target_link_libraries(DynamicObjectDemo SampleLib LibC LibCore LibGUI)
add_subdirectory(SampleLib)
diff --git a/Demos/DynamicObject/SampleLib/CMakeLists.txt b/Demos/DynamicObject/SampleLib/CMakeLists.txt
index b02dbe8196..38a75141f0 100644
--- a/Demos/DynamicObject/SampleLib/CMakeLists.txt
+++ b/Demos/DynamicObject/SampleLib/CMakeLists.txt
@@ -3,9 +3,9 @@ set(SOURCES
lib.cpp
)
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_WIHTOUT_STATIC} -nostdlib -fpic")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib -fpic")
add_library(SampleLib SHARED ${SOURCES})
-target_link_libraries(SampleLib LibCShared)
+target_link_libraries(SampleLib LibC)
#target_link_libraries(SampleLib)
install(TARGETS SampleLib DESTINATION usr/lib)
diff --git a/Demos/DynamicObject/SampleLib/lib.cpp b/Demos/DynamicObject/SampleLib/lib.cpp
index 1bfb7693bd..a0e6e76aa7 100644
--- a/Demos/DynamicObject/SampleLib/lib.cpp
+++ b/Demos/DynamicObject/SampleLib/lib.cpp
@@ -1,3 +1,28 @@
+/*
+ * Copyright (c) 2020, the SerenityOS developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
#include "../lib.h"
diff --git a/Demos/DynamicObject/lib.h b/Demos/DynamicObject/lib.h
index eec49a1f4b..05b59afd9e 100644
--- a/Demos/DynamicObject/lib.h
+++ b/Demos/DynamicObject/lib.h
@@ -1,3 +1,30 @@
+/*
+ * Copyright (c) 2020, the SerenityOS developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
int func();
diff --git a/Demos/DynamicObject/main.cpp b/Demos/DynamicObject/main.cpp
index c4d401d4ba..2b575cb185 100644
--- a/Demos/DynamicObject/main.cpp
+++ b/Demos/DynamicObject/main.cpp
@@ -1,4 +1,37 @@
+/*
+ * Copyright (c) 2020, the SerenityOS developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
#include "lib.h"
+#include <LibCore/Command.h>
+#include <LibGUI/Application.h>
+#include <LibGUI/BoxLayout.h>
+#include <LibGUI/Button.h>
+#include <LibGUI/Label.h>
+#include <LibGUI/Widget.h>
+#include <LibGUI/Window.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/internals.h>
@@ -19,6 +52,34 @@ int main(int argc, char** argv, char** env)
int _errno = errno;
perror("open failed");
printf("rc: %d, errno: %d\n", rc, _errno);
- return func() + g_tls1 + g_tls2;
}
+ printf("ls: %s\n", Core::command("ls", {}).characters());
+ auto app = GUI::Application::construct(argc, argv);
+
+ auto window = GUI::Window::construct();
+ window->resize(240, 160);
+ window->set_title("Hello World!");
+ window->set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/app-hello-world.png"));
+
+ auto& main_widget = window->set_main_widget<GUI::Widget>();
+ main_widget.set_fill_with_background_color(true);
+ main_widget.set_background_color(Color::White);
+ auto& layout = main_widget.set_layout<GUI::VerticalBoxLayout>();
+ layout.set_margins({ 4, 4, 4, 4 });
+
+ auto& label = main_widget.add<GUI::Label>();
+ label.set_text("Hello\nWorld!");
+
+ auto& button = main_widget.add<GUI::Button>();
+ button.set_text("Good-bye");
+ button.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed);
+ button.set_preferred_size(0, 20);
+ button.on_click = [&](auto) {
+ app->quit();
+ };
+
+ window->show();
+
+ return app->exec();
+ // return func() + g_tls1 + g_tls2;
}
diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt
index 9e02c5c0b8..ef5c5585f8 100644
--- a/Kernel/CMakeLists.txt
+++ b/Kernel/CMakeLists.txt
@@ -3,6 +3,8 @@ set(KERNEL_HEAP_SOURCES
Heap/kmalloc.cpp
)
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_STATIC}")
+
set(KERNEL_SOURCES
ACPI/DynamicParser.cpp
ACPI/Initialize.cpp
diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp
index 2ba9589dcd..f8dc1698bf 100644
--- a/Kernel/FileSystem/VirtualFileSystem.cpp
+++ b/Kernel/FileSystem/VirtualFileSystem.cpp
@@ -841,6 +841,8 @@ KResult VFS::validate_path_against_process_veil(StringView path, int options)
{
if (Process::current()->veil_state() == VeilState::None)
return KSuccess;
+ if (path == "/usr/lib/Loader.so")
+ return KSuccess;
// FIXME: Figure out a nicer way to do this.
if (String(path).contains("/.."))
diff --git a/Kernel/Process.h b/Kernel/Process.h
index 3e36c61d0e..1ed334eb90 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -423,7 +423,7 @@ public:
int exec(String path, Vector<String> arguments, Vector<String> environment, int recusion_depth = 0);
struct LoadResult {
- FlatPtr load_offset { 0 };
+ FlatPtr load_base { 0 };
FlatPtr entry_eip { 0 };
size_t size { 0 };
FlatPtr program_headers { 0 };
@@ -581,7 +581,7 @@ private:
gid_t m_sgid { 0 };
ThreadID m_exec_tid { 0 };
- FlatPtr m_load_offset { 0U };
+ FlatPtr m_load_base { 0U };
FlatPtr m_entry_eip { 0U };
int m_main_program_fd { -1 };
diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp
index 14ab994b64..9fbd7c1a97 100644
--- a/Kernel/Syscalls/execve.cpp
+++ b/Kernel/Syscalls/execve.cpp
@@ -80,6 +80,7 @@ KResultOr<Process::LoadResult> Process::load_elf_object(FileDescription& object_
size_t master_tls_size = 0;
size_t master_tls_alignment = 0;
m_entry_eip = 0;
+ FlatPtr load_base_address = 0;
MM.enter_process_paging_scope(*this);
String object_name = LexicalPath(object_description.absolute_path()).basename();
@@ -96,6 +97,8 @@ KResultOr<Process::LoadResult> Process::load_elf_object(FileDescription& object_
prot |= PROT_EXEC;
if (auto* region = allocate_region_with_vmobject(vaddr.offset(load_offset), size, *vmobject, offset_in_image, String(name), prot)) {
region->set_shared(true);
+ if (offset_in_image == 0)
+ load_base_address = (FlatPtr)region->vaddr().as_ptr();
return region->vaddr().as_ptr();
}
return nullptr;
@@ -137,7 +140,7 @@ KResultOr<Process::LoadResult> Process::load_elf_object(FileDescription& object_
// NOTE: At this point, we've committed to the new executable.
return LoadResult {
- load_offset,
+ load_base_address,
loader->entry().offset(load_offset).get(),
(size_t)loader_metadata.size,
VirtualAddress(loader->image().program_header_table_offset()).offset(load_offset).get(),
@@ -175,7 +178,7 @@ int Process::load(NonnullRefPtr<FileDescription> main_program_description, RefPt
if (result.is_error())
return result.error();
- m_load_offset = result.value().load_offset;
+ m_load_base = result.value().load_base;
m_entry_eip = result.value().entry_eip;
m_master_tls_region = result.value().tls_region;
m_master_tls_size = result.value().tls_size;
@@ -192,7 +195,7 @@ int Process::load(NonnullRefPtr<FileDescription> main_program_description, RefPt
if (interpreter_load_result.is_error())
return interpreter_load_result.error();
- m_load_offset = interpreter_load_result.value().load_offset;
+ m_load_base = interpreter_load_result.value().load_base;
m_entry_eip = interpreter_load_result.value().entry_eip;
// TLS allocation will be done in userspace by the loader
@@ -357,7 +360,7 @@ Vector<AuxiliaryValue> Process::generate_auxiliary_vector() const
// PHDR/EXECFD
// PH*
auxv.append({ AuxiliaryValue::PageSize, PAGE_SIZE });
- auxv.append({ AuxiliaryValue::BaseAddress, (void*)m_load_offset });
+ auxv.append({ AuxiliaryValue::BaseAddress, (void*)m_load_base });
auxv.append({ AuxiliaryValue::Entry, (void*)m_entry_eip });
// NOTELF
diff --git a/Kernel/Syscalls/mmap.cpp b/Kernel/Syscalls/mmap.cpp
index 36aa2a1b67..6607efc41d 100644
--- a/Kernel/Syscalls/mmap.cpp
+++ b/Kernel/Syscalls/mmap.cpp
@@ -422,8 +422,6 @@ void* Process::sys$allocate_tls(size_t size)
{
REQUIRE_PROMISE(stdio);
- dbg() << "allocate TLS: " << size;
-
if (!size)
return (void*)-EINVAL;
@@ -445,7 +443,6 @@ void* Process::sys$allocate_tls(size_t size)
return (void*)-EFAULT;
m_master_tls_region = tls_region->make_weak_ptr();
- dbg() << "master_tls_region: " << m_master_tls_region->vaddr();
m_master_tls_size = size;
m_master_tls_alignment = PAGE_SIZE;
diff --git a/Libraries/LibC/CMakeLists.txt b/Libraries/LibC/CMakeLists.txt
index bcf1222659..560e795abd 100644
--- a/Libraries/LibC/CMakeLists.txt
+++ b/Libraries/LibC/CMakeLists.txt
@@ -1,7 +1,7 @@
set(LIBC_SOURCES
arpa/inet.cpp
assert.cpp
- #crt0.cpp
+ crt0_shared.cpp
ctype.cpp
cxxabi.cpp
dirent.cpp
@@ -66,12 +66,7 @@ add_custom_command(
)
set(SOURCES ${LIBC_SOURCES} ${AK_SOURCES} ${ELF_SOURCES})
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib")
serenity_libc(LibC c)
target_link_libraries(LibC crt0)
add_dependencies(LibC LibM)
-
-set(SOURCES ${SOURCES} "crt0_shared.cpp")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib")
-serenity_libc_shared(LibCShared c)
-#add_library(LibCShared SHARED ${SOURCES})
-#install(TARGETS LibCShared DESTINATION usr/lib)
diff --git a/Libraries/LibC/crt0_shared.cpp b/Libraries/LibC/crt0_shared.cpp
index c016e24556..4a813cd840 100644
--- a/Libraries/LibC/crt0_shared.cpp
+++ b/Libraries/LibC/crt0_shared.cpp
@@ -1,3 +1,29 @@
+/*
+ * Copyright (c) 2020, the SerenityOS developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
#include <AK/Types.h>
#include <assert.h>
#include <stdio.h>
@@ -17,16 +43,11 @@ extern bool __environ_is_malloced;
int _start(int argc, char** argv, char** env);
int _start(int argc, char** argv, char** env)
{
- // asm("int3");
- environ = env;
- __environ_is_malloced = false;
-
- __libc_init();
- // _init();
+ _init();
- int status = main(argc, argv, environ);
+ int status = main(argc, argv, env);
return status;
}
}
-void* __dso_handle = nullptr;
+void* __dso_handle __attribute__((__weak__));
diff --git a/Libraries/LibCore/CMakeLists.txt b/Libraries/LibCore/CMakeLists.txt
index 1a7467170d..02b1b6b999 100644
--- a/Libraries/LibCore/CMakeLists.txt
+++ b/Libraries/LibCore/CMakeLists.txt
@@ -33,4 +33,4 @@ set(SOURCES
)
serenity_lib(LibCore core)
-target_link_libraries(LibCore LibC)
+target_link_libraries(LibCore LibC LibCrypt)
diff --git a/Libraries/LibELF/DynamicLoader.cpp b/Libraries/LibELF/DynamicLoader.cpp
index ad5c486bc0..c238a15c41 100644
--- a/Libraries/LibELF/DynamicLoader.cpp
+++ b/Libraries/LibELF/DynamicLoader.cpp
@@ -59,7 +59,7 @@ static void* mmap_with_name(void* addr, size_t length, int prot, int flags, int
namespace ELF {
-static bool s_always_bind_now = true;
+static bool s_always_bind_now = false;
NonnullRefPtr<DynamicLoader> DynamicLoader::construct(const char* filename, int fd, size_t size)
{
@@ -90,7 +90,7 @@ DynamicLoader::DynamicLoader(const char* filename, int fd, size_t size)
m_tls_size = calculate_tls_size();
- m_valid = is_valid();
+ m_valid = validate();
}
RefPtr<DynamicObject> DynamicLoader::dynamic_object_from_image() const
@@ -121,16 +121,14 @@ size_t DynamicLoader::calculate_tls_size() const
bool DynamicLoader::validate()
{
auto* elf_header = (Elf32_Ehdr*)m_file_mapping;
-
- if (!validate_elf_header(*elf_header, m_file_size) || !validate_program_headers(*elf_header, m_file_size, (u8*)m_file_mapping, m_file_size, &m_program_interpreter)) {
- m_valid = false;
- }
+ return validate_elf_header(*elf_header, m_file_size) && validate_program_headers(*elf_header, m_file_size, (u8*)m_file_mapping, m_file_size, &m_program_interpreter);
}
DynamicLoader::~DynamicLoader()
{
if (MAP_FAILED != m_file_mapping)
munmap(m_file_mapping, m_file_size);
+ close(m_image_fd);
}
void* DynamicLoader::symbol_for_name(const char* name)
@@ -161,6 +159,8 @@ RefPtr<DynamicObject> DynamicLoader::load_from_image(unsigned flags, size_t tota
m_dynamic_object = DynamicObject::construct(m_text_segment_load_address, m_dynamic_section_address);
m_dynamic_object->set_tls_offset(m_tls_offset);
m_dynamic_object->set_tls_size(m_tls_size);
+ ASSERT(m_global_symbol_lookup_func);
+ m_dynamic_object->m_global_symbol_lookup_func = m_global_symbol_lookup_func;
auto rc = load_stage_2(flags, total_tls_size);
if (!rc)
@@ -171,14 +171,13 @@ RefPtr<DynamicObject> DynamicLoader::load_from_image(unsigned flags, size_t tota
bool DynamicLoader::load_stage_2(unsigned flags, size_t total_tls_size)
{
ASSERT(flags & RTLD_GLOBAL);
- ASSERT(!(flags & RTLD_LAZY));
#ifdef DYNAMIC_LOAD_DEBUG
m_dynamic_object->dump();
#endif
if (m_dynamic_object->has_text_relocations()) {
- dbg() << "Someone linked non -fPIC code into " << m_filename << " :(";
+ // dbg() << "Someone linked non -fPIC code into " << m_filename << " :(";
ASSERT(m_text_segment_load_address.get() != 0);
if (0 > mprotect(m_text_segment_load_address.as_ptr(), m_text_segment_size, PROT_READ | PROT_WRITE)) {
perror("mprotect .text: PROT_READ | PROT_WRITE"); // FIXME: dlerror?
@@ -189,7 +188,6 @@ bool DynamicLoader::load_stage_2(unsigned flags, size_t total_tls_size)
do_relocations(total_tls_size);
if (flags & RTLD_LAZY) {
- ASSERT_NOT_REACHED(); // TODO: Support lazy binding
setup_plt_trampoline();
}
@@ -203,9 +201,7 @@ bool DynamicLoader::load_stage_2(unsigned flags, size_t total_tls_size)
call_object_init_functions();
-#ifdef DYNAMIC_LOAD_DEBUG
- dbgprintf("Loaded %s\n", m_filename.characters());
-#endif
+ VERBOSE("Loaded %s\n", m_filename.characters());
return true;
}
@@ -239,7 +235,13 @@ void DynamicLoader::load_program_headers()
// Process regions in order: .text, .data, .tls
auto* region = text_region_ptr;
- void* text_segment_begin = mmap_with_name(nullptr, region->required_load_size(), region->mmap_prot(), MAP_PRIVATE, m_image_fd, region->offset(), String::format(".text: %s", m_filename.characters()).characters());
+ void* text_segment_begin = mmap_with_name(nullptr,
+ region->required_load_size(),
+ region->mmap_prot(),
+ MAP_PRIVATE,
+ m_image_fd,
+ region->offset(),
+ String::format("%s: .text", m_filename.characters()).characters());
if (MAP_FAILED == text_segment_begin) {
ASSERT_NOT_REACHED();
}
@@ -249,7 +251,13 @@ void DynamicLoader::load_program_headers()
m_dynamic_section_address = dynamic_region_desired_vaddr.offset(m_text_segment_load_address.get());
region = data_region_ptr;
- void* data_segment_begin = mmap_with_name((u8*)text_segment_begin + m_text_segment_size, region->required_load_size(), region->mmap_prot(), MAP_ANONYMOUS | MAP_PRIVATE, 0, 0, String::format(".data: %s", m_filename.characters()).characters());
+ void* data_segment_begin = mmap_with_name((u8*)text_segment_begin + m_text_segment_size,
+ region->required_load_size(),
+ region->mmap_prot(),
+ MAP_ANONYMOUS | MAP_PRIVATE,
+ 0,
+ 0,
+ String::format("%s: .data", m_filename.characters()).characters());
if (MAP_FAILED == data_segment_begin) {
ASSERT_NOT_REACHED();
}
@@ -279,7 +287,10 @@ void DynamicLoader::do_relocations(size_t total_tls_size)
auto symbol = relocation.symbol();
VERBOSE("Absolute relocation: name: '%s', value: %p\n", symbol.name(), symbol.value());
auto res = lookup_symbol(symbol);
- ASSERT(res.found);
+ if (!res.found) {
+ dbgln("ERROR: symbol not found: {}", symbol.name());
+ ASSERT_NOT_REACHED();
+ }
u32 symbol_address = res.address;
*patch_ptr += symbol_address;
VERBOSE(" Symbol address: %p\n", *patch_ptr);
@@ -298,13 +309,16 @@ void DynamicLoader::do_relocations(size_t total_tls_size)
case R_386_GLOB_DAT: {
auto symbol = relocation.symbol();
if (!strcmp(symbol.name(), "__deregister_frame_info") || !strcmp(symbol.name(), "_ITM_registerTMCloneTable")
- || !strcmp(symbol.name(), "_ITM_deregisterTMCloneTable") || !strcmp(symbol.name(), "__register_frame_info")) {
+ || !strcmp(symbol.name(), "_ITM_deregisterTMCloneTable") || !strcmp(symbol.name(), "__register_frame_info")
+ || !strcmp(symbol.name(), "__cxa_finalize") // __cxa_finalize will be called from libc's exit()
+ ) {
// We do not support these
break;
}
VERBOSE("Global data relocation: '%s', value: %p\n", symbol.name(), symbol.value());
auto res = lookup_symbol(symbol);
VERBOSE("was symbol found? %d, address: 0x%x\n", res.found, res.address);
+ ASSERT(res.found);
if (!res.found) {
// TODO this is a hack
@@ -331,28 +345,28 @@ void DynamicLoader::do_relocations(size_t total_tls_size)
}
case R_386_TLS_TPOFF32:
case R_386_TLS_TPOFF: {
- dbgprintf("Relocation type: R_386_TLS_TPOFF at offset %X\n", relocation.offset());
+ VERBOSE("Relocation type: R_386_TLS_TPOFF at offset %X\n", relocation.offset());
auto symbol = relocation.symbol();
// For some reason, LibC has a R_386_TLS_TPOFF that referes to the undefined symbol.. huh
if (relocation.symbol_index() == 0)
break;
- dbgprintf("Symbol index: %d\n", symbol.index());
- dbgprintf("Symbol is_undefined?: %d\n", symbol.is_undefined());
- dbgprintf("TLS relocation: '%s', value: %p\n", symbol.name(), symbol.value());
+ VERBOSE("Symbol index: %d\n", symbol.index());
+ VERBOSE("Symbol is_undefined?: %d\n", symbol.is_undefined());
+ VERBOSE("TLS relocation: '%s', value: %p\n", symbol.name(), symbol.value());
auto res = lookup_symbol(symbol);
if (!res.found)
break;
ASSERT(res.found);
u32 symbol_value = res.value;
- dbgprintf("symbol value: %d\n", symbol_value);
+ VERBOSE("symbol value: %d\n", symbol_value);
const auto dynamic_object_of_symbol = res.dynamic_object;
ASSERT(dynamic_object_of_symbol);
size_t offset_of_tls_end = dynamic_object_of_symbol->tls_offset().value() + dynamic_object_of_symbol->tls_size().value();
// size_t offset_of_tls_end = tls_offset() + tls_size();
- dbgprintf("patch ptr: 0x%x\n", patch_ptr);
- dbgprintf("tls end offset: %d, total tls size: %d\n", offset_of_tls_end, total_tls_size);
+ VERBOSE("patch ptr: 0x%x\n", patch_ptr);
+ VERBOSE("tls end offset: %d, total tls size: %d\n", offset_of_tls_end, total_tls_size);
*patch_ptr = (offset_of_tls_end - total_tls_size - symbol_value - sizeof(Elf32_Addr));
- dbgprintf("*patch ptr: %d\n", (i32)*patch_ptr);
+ VERBOSE("*patch ptr: %d\n", (i32)*patch_ptr);
break;
}
default:
@@ -376,8 +390,8 @@ void DynamicLoader::do_relocations(size_t total_tls_size)
if (m_dynamic_object->must_bind_now() || s_always_bind_now) {
// Eagerly BIND_NOW the PLT entries, doing all the symbol looking goodness
// The patch method returns the address for the LAZY fixup path, but we don't need it here
- VERBOSE("patching plt reloaction: 0x%x", relocation.offset_in_section());
- (void)patch_plt_entry(relocation.offset_in_section());
+ VERBOSE("patching plt reloaction: 0x%x\n", relocation.offset_in_section());
+ (void)m_dynamic_object->patch_plt_entry(relocation.offset_in_section());
} else {
// LAZY-ily bind the PLT slots by just adding the base address to the offsets stored there
// This avoids doing symbol lookup, which might be expensive
@@ -390,9 +404,7 @@ void DynamicLoader::do_relocations(size_t total_tls_size)
return IterationDecision::Continue;
});
-#ifdef DYNAMIC_LOAD_DEBUG
- dbgprintf("Done relocating!\n");
-#endif
+ VERBOSE("Done relocating!\n");
}
// Defined in <arch>/plt_trampoline.S
@@ -400,57 +412,32 @@ extern "C" void _plt_trampoline(void) __attribute__((visibility("hidden")));
void DynamicLoader::setup_plt_trampoline()
{
+ ASSERT(m_dynamic_object);
VirtualAddress got_address = m_dynamic_object->plt_got_base_address();
FlatPtr* got_ptr = (FlatPtr*)got_address.as_ptr();
- got_ptr[1] = (FlatPtr)this;
+ got_ptr[1] = (FlatPtr)m_dynamic_object.ptr();
got_ptr[2] = (FlatPtr)&_plt_trampoline;
-#ifdef DYNAMIC_LOAD_DEBUG
- dbgprintf("Set GOT PLT entries at %p: [0] = %p [1] = %p, [2] = %p\n", got_ptr, (void*)got_ptr[0], (void*)got_ptr[1], (void*)got_ptr[2]);
-#endif
+ VERBOSE("Set GOT PLT entries at %p: [0] = %p [1] = %p, [2] = %p\n", got_ptr, (void*)got_ptr[0], (void*)got_ptr[1], (void*)got_ptr[2]);
}
// Called from our ASM routine _plt_trampoline.
// Tell the compiler that it might be called from other places:
-extern "C" Elf32_Addr _fixup_plt_entry(DynamicLoader* object, u32 relocation_offset);
-extern "C" Elf32_Addr _fixup_plt_entry(DynamicLoader* object, u32 relocation_offset)
+extern "C" Elf32_Addr _fixup_plt_entry(DynamicObject* object, u32 relocation_offset);
+extern "C" Elf32_Addr _fixup_plt_entry(DynamicObject* object, u32 relocation_offset)
{
return object->patch_plt_entry(relocation_offset);
}
-// offset is in PLT relocation table
-Elf32_Addr DynamicLoader::patch_plt_entry(u32 relocation_offset)
-{
- auto relocation = m_dynamic_object->plt_relocation_section().relocation_at_offset(relocation_offset);
-
- ASSERT(relocation.type() == R_386_JMP_SLOT);
-
- auto sym = relocation.symbol();
-
- u8* relocation_address = relocation.address().as_ptr();
- auto res = lookup_symbol(sym);
- ASSERT(res.found);
- u32 symbol_location = res.address;
-
- VERBOSE("DynamicLoader: Jump slot relocation: putting %s (%p) into PLT at %p\n", sym.name(), symbol_location, relocation_address);
-
- *(u32*)relocation_address = symbol_location;
-
- return symbol_location;
-}
-
void DynamicLoader::call_object_init_functions()
{
- dbg() << "inside call_object_init_functions of " << m_filename;
typedef void (*InitFunc)();
if (m_dynamic_object->has_init_section()) {
auto init_function = (InitFunc)(m_dynamic_object->init_section().address().as_ptr());
- // #ifdef DYNAMIC_LOAD_DEBUG
- dbgprintf("Calling DT_INIT at %p\n", init_function);
- // #endif
+ VERBOSE("Calling DT_INIT at %p\n", init_function);
(init_function)();
}
@@ -464,9 +451,7 @@ void DynamicLoader::call_object_init_functions()
// 0 definitely shows up. Apparently 0/-1 are valid? Confusing.
if (!*init_begin || ((FlatPtr)*init_begin == (FlatPtr)-1))
continue;
- // #ifdef DYNAMIC_LOAD_DEBUG
- dbgprintf("Calling DT_INITARRAY entry at %p\n", *init_begin);
- // #endif
+ VERBOSE("Calling DT_INITARRAY entry at %p\n", *init_begin);
(*init_begin)();
++init_begin;
}
@@ -484,22 +469,7 @@ u32 DynamicLoader::ProgramHeaderRegion::mmap_prot() const
DynamicObject::SymbolLookupResult DynamicLoader::lookup_symbol(const ELF::DynamicObject::Symbol& symbol) const
{
- VERBOSE("looking up symbol: %s\n", symbol.name());
- if (!symbol.is_undefined()) {
- VERBOSE("symbol is defiend in its object\n");
- return { true, symbol.value(), (FlatPtr)symbol.address().as_ptr(), &symbol.object() };
- }
- ASSERT(m_global_symbol_lookup_func);
- return m_global_symbol_lookup_func(symbol.name());
+ return m_dynamic_object->lookup_symbol(symbol);
}
-// Optional<DynamicLoader::SymbolLookupResult> DynamicLoader::lookup_symbol(const char* name) const
-// {
-// ASSERT(m_dynamic_object);
-// auto res = m_dynamic_object->hash_section().lookup_symbol(name);
-// if (res.is_undefined())
-// return {};
-// return SymbolLookupResult { true, res.value(), (FlatPtr)res.address().as_ptr(), m_dynamic_object.ptr() };
-// }
-
} // end namespace ELF
diff --git a/Libraries/LibELF/DynamicLoader.h b/Libraries/LibELF/DynamicLoader.h
index e812ab0d35..fcc2886d6c 100644
--- a/Libraries/LibELF/DynamicLoader.h
+++ b/Libraries/LibELF/DynamicLoader.h
@@ -62,9 +62,6 @@ public:
void dump();
- // Will be called from _fixup_plt_entry, as part of the PLT trampoline
- Elf32_Addr patch_plt_entry(u32 relocation_offset);
-
// Requested program interpreter from program headers. May be empty string
StringView program_interpreter() const { return m_program_interpreter; }
@@ -78,8 +75,8 @@ public:
template<typename F>
void for_each_needed_library(F) const;
- using SymbolLookupFunction = DynamicObject::SymbolLookupResult (*)(const char*);
- SymbolLookupFunction m_global_symbol_lookup_func { nullptr };
+ DynamicObject::SymbolLookupFunction m_global_symbol_lookup_func { nullptr };
+ void set_global_symbol_lookup_function(DynamicObject::SymbolLookupFunction func) { m_global_symbol_lookup_func = func; }
VirtualAddress text_segment_load_address() const { return m_text_segment_load_address; }
diff --git a/Libraries/LibELF/DynamicObject.cpp b/Libraries/LibELF/DynamicObject.cpp
index bae2dd5024..09e162ced4 100644
--- a/Libraries/LibELF/DynamicObject.cpp
+++ b/Libraries/LibELF/DynamicObject.cpp
@@ -32,6 +32,16 @@
#include <stdio.h>
#include <string.h>
+// #define DYNAMIC_OBJECT_VERBOSE
+
+#ifdef DYNAMIC_OBJECT_VERBOSE
+# define VERBOSE(fmt, ...) dbgprintf(fmt, ##__VA_ARGS__)
+#else
+# define VERBOSE(fmt, ...) \
+ do { \
+ } while (0)
+#endif
+
namespace ELF {
static const char* name_for_dtag(Elf32_Sword d_tag);
@@ -63,8 +73,8 @@ void DynamicObject::dump() const
if (m_has_soname)
builder.appendf("DT_SONAME: %s\n", soname()); // FIXME: Valdidate that this string is null terminated?
- dbgprintf("Dynamic section at address %p contains %zu entries:\n", m_dynamic_address.as_ptr(), num_dynamic_sections);
- dbgprintf("%s", builder.to_string().characters());
+ VERBOSE("Dynamic section at address %p contains %zu entries:\n", m_dynamic_address.as_ptr(), num_dynamic_sections);
+ VERBOSE("%s", builder.to_string().characters());
}
void DynamicObject::parse()
@@ -402,4 +412,46 @@ NonnullRefPtr<DynamicObject> DynamicObject::construct(VirtualAddress base_addres
return adopt(*new DynamicObject(base_address, dynamic_section_address));
}
+// offset is in PLT relocation table
+Elf32_Addr DynamicObject::patch_plt_entry(u32 relocation_offset)
+{
+ auto relocation = plt_relocation_section().relocation_at_offset(relocation_offset);
+
+ ASSERT(relocation.type() == R_386_JMP_SLOT);
+
+ auto sym = relocation.symbol();
+ if (StringView { sym.name() } == "__cxa_demangle") {
+ dbgln("__cxa_demangle is currently not supported for shared objects");
+ // FIXME: Where is it defined?
+ ASSERT_NOT_REACHED();
+ }
+
+ u8* relocation_address = relocation.address().as_ptr();
+ auto res = lookup_symbol(sym);
+
+ if (!res.found) {
+ dbgln("did not find symbol: {} ", sym.name());
+ ASSERT_NOT_REACHED();
+ }
+
+ u32 symbol_location = res.address;
+
+ VERBOSE("DynamicLoader: Jump slot relocation: putting %s (%p) into PLT at %p\n", sym.name(), symbol_location, relocation_address);
+
+ *(u32*)relocation_address = symbol_location;
+
+ return symbol_location;
+}
+
+DynamicObject::SymbolLookupResult DynamicObject::lookup_symbol(const ELF::DynamicObject::Symbol& symbol) const
+{
+ VERBOSE("looking up symbol: %s\n", symbol.name());
+ if (!symbol.is_undefined()) {
+ VERBOSE("symbol is defiend in its object\n");
+ return { true, symbol.value(), (FlatPtr)symbol.address().as_ptr(), &symbol.object() };
+ }
+ ASSERT(m_global_symbol_lookup_func);
+ return m_global_symbol_lookup_func(symbol.name());
+}
+
} // end namespace ELF
diff --git a/Libraries/LibELF/DynamicObject.h b/Libraries/LibELF/DynamicObject.h
index 5541f1fa3e..08c536c43c 100644
--- a/Libraries/LibELF/DynamicObject.h
+++ b/Libraries/LibELF/DynamicObject.h
@@ -267,6 +267,13 @@ public:
};
Optional<SymbolLookupResult> lookup_symbol(const char* name) const;
+ // Will be called from _fixup_plt_entry, as part of the PLT trampoline
+ Elf32_Addr patch_plt_entry(u32 relocation_offset);
+
+ SymbolLookupResult lookup_symbol(const ELF::DynamicObject::Symbol& symbol) const;
+ using SymbolLookupFunction = DynamicObject::SymbolLookupResult (*)(const char*);
+ SymbolLookupFunction m_global_symbol_lookup_func { nullptr };
+
private:
explicit DynamicObject(VirtualAddress base_address, VirtualAddress dynamic_section_address);
diff --git a/Libraries/LibGUI/CMakeLists.txt b/Libraries/LibGUI/CMakeLists.txt
index 9e819f2731..cc5e199f36 100644
--- a/Libraries/LibGUI/CMakeLists.txt
+++ b/Libraries/LibGUI/CMakeLists.txt
@@ -95,4 +95,4 @@ set(GENERATED_SOURCES
)
serenity_lib(LibGUI gui)
-target_link_libraries(LibGUI LibCore LibGfx LibIPC LibThread LibCpp LibRegex)
+target_link_libraries(LibGUI LibCore LibGfx LibIPC LibThread LibCpp LibShell LibRegex LibJS)
diff --git a/Libraries/LibGfx/CMakeLists.txt b/Libraries/LibGfx/CMakeLists.txt
index b919b3246a..c4fb1e13b6 100644
--- a/Libraries/LibGfx/CMakeLists.txt
+++ b/Libraries/LibGfx/CMakeLists.txt
@@ -33,4 +33,4 @@ set(SOURCES
)
serenity_lib(LibGfx gfx)
-target_link_libraries(LibGfx LibM LibCore)
+target_link_libraries(LibGfx LibM LibCore LibIPC)
diff --git a/Libraries/LibM/CMakeLists.txt b/Libraries/LibM/CMakeLists.txt
index 7ed9959738..bdb9baf78a 100644
--- a/Libraries/LibM/CMakeLists.txt
+++ b/Libraries/LibM/CMakeLists.txt
@@ -2,6 +2,9 @@ set(SOURCES
math.cpp
)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib")
serenity_libc(LibM m)
-target_include_directories(LibM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
-target_link_libraries(LibM LibC)
+#target_link_libraries(LibM)
+#set_target_properties(LibM PROPERTIES OUTPUT_NAME m)
+#target_link_directories(LibM PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
diff --git a/Userland/CMakeLists.txt b/Userland/CMakeLists.txt
index 537180a29c..1ca0fe9afc 100644
--- a/Userland/CMakeLists.txt
+++ b/Userland/CMakeLists.txt
@@ -5,11 +5,13 @@ foreach(CMD_SRC ${CMD_SOURCES})
get_filename_component(CMD_NAME ${CMD_SRC} NAME_WE)
if (CMD_NAME IN_LIST SPECIAL_TARGETS)
add_executable("${CMD_NAME}-bin" ${CMD_SRC})
+ target_sources("${CMD_NAME}-bin" PRIVATE ${CMAKE_SOURCE_DIR}/Libraries/LibC/crt0_shared.cpp)
target_link_libraries("${CMD_NAME}-bin" LibCore)
install(TARGETS "${CMD_NAME}-bin" RUNTIME DESTINATION bin)
install(CODE "execute_process(COMMAND mv ${CMD_NAME}-bin ${CMD_NAME} WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin)")
else ()
add_executable(${CMD_NAME} ${CMD_SRC})
+ target_sources("${CMD_NAME}" PRIVATE ${CMAKE_SOURCE_DIR}/Libraries/LibC/crt0_shared.cpp)
target_link_libraries(${CMD_NAME} LibCore)
install(TARGETS ${CMD_NAME} RUNTIME DESTINATION bin)
endif()
diff --git a/Userland/DynamicLoader/main.cpp b/Userland/DynamicLoader/main.cpp
index 981ecf763d..8bd5e74798 100644
--- a/Userland/DynamicLoader/main.cpp
+++ b/Userland/DynamicLoader/main.cpp
@@ -63,6 +63,7 @@ static HashMap<String, NonnullRefPtr<ELF::DynamicObject>> g_loaded_objects;
static size_t g_current_tls_offset = 0;
static size_t g_total_tls_size = 0;
+static char** g_envp = nullptr;
static void init_libc()
{
@@ -72,30 +73,37 @@ static void init_libc()
__malloc_init();
}
-static void perform_self_relocations()
+static void perform_self_relocations(auxv_t* auxvp)
{
// We need to relocate ourselves.
// (these relocations seem to be generated because of our vtables)
- // TODO: Pass this address in the Auxiliary Vector
- u32 base = 0x08000000;
- Elf32_Ehdr* header = (Elf32_Ehdr*)(base);
- Elf32_Phdr* pheader = (Elf32_Phdr*)(base + header->e_phoff);
+ FlatPtr base_address = 0;
+ bool found_base_address = false;
+ for (; auxvp->a_type != AT_NULL; ++auxvp) {
+ if (auxvp->a_type == AuxiliaryValue::BaseAddress) {
+ base_address = auxvp->a_un.a_val;
+ found_base_address = true;
+ }
+ }
+ ASSERT(found_base_address);
+ Elf32_Ehdr* header = (Elf32_Ehdr*)(base_address);
+ Elf32_Phdr* pheader = (Elf32_Phdr*)(base_address + header->e_phoff);
u32 dynamic_section_addr = 0;
for (size_t i = 0; i < (size_t)header->e_phnum; ++i, ++pheader) {
if (pheader->p_type != PT_DYNAMIC)
continue;
- dynamic_section_addr = pheader->p_vaddr + base;
+ dynamic_section_addr = pheader->p_vaddr + base_address;
}
if (!dynamic_section_addr)
exit(1);
- auto dynamic_object = ELF::DynamicObject::construct((VirtualAddress(base)), (VirtualAddress(dynamic_section_addr)));
+ auto dynamic_object = ELF::DynamicObject::construct((VirtualAddress(base_address)), (VirtualAddress(dynamic_section_addr)));
- dynamic_object->relocation_section().for_each_relocation([base](auto& reloc) {
+ dynamic_object->relocation_section().for_each_relocation([base_address](auto& reloc) {
if (reloc.type() != R_386_RELATIVE)
return IterationDecision::Continue;
- *(u32*)reloc.address().as_ptr() += base;
+ *(u32*)reloc.address().as_ptr() += base_address;
return IterationDecision::Continue;
});
}
@@ -110,7 +118,7 @@ static ELF::DynamicObject::SymbolLookupResult global_symbol_lookup(const char* s
continue;
return res.value();
}
- ASSERT_NOT_REACHED();
+ // ASSERT_NOT_REACHED();
return {};
}
@@ -122,7 +130,7 @@ static void map_library(const String& name, int fd)
auto loader = ELF::DynamicLoader::construct(name.characters(), fd, lib_stat.st_size);
loader->set_tls_offset(g_current_tls_offset);
- loader->m_global_symbol_lookup_func = global_symbol_lookup;
+ loader->set_global_symbol_lookup_function(global_symbol_lookup);
g_loaders.set(name, loader);
@@ -143,51 +151,94 @@ static String get_library_name(const StringView& path)
return LexicalPath(path).basename();
}
-static void map_dependencies(const String& name)
+static Vector<String> get_dependencies(const String& name)
{
- dbg() << "mapping dependencies for: " << name;
auto lib = g_loaders.get(name).value();
- lib->for_each_needed_library([](auto needed_name) {
- dbg() << "needed library: " << needed_name;
+ Vector<String> dependencies;
+
+ lib->for_each_needed_library([&dependencies](auto needed_name) {
+ dependencies.append(needed_name);
+ return IterationDecision::Continue;
+ });
+ return dependencies;
+}
+
+static void map_dependencies(const String& name)
+{
+ VERBOSE("mapping dependencies for: %s", name.characters());
+
+ for (const auto& needed_name : get_dependencies(name)) {
+ VERBOSE("needed library: %s", needed_name.characters());
String library_name = get_library_name(needed_name);
if (!g_loaders.contains(library_name)) {
map_library(library_name);
map_dependencies(library_name);
}
- return IterationDecision::Continue;
- });
+ }
}
static void allocate_tls()
{
size_t total_tls_size = 0;
for (const auto& data : g_loaders) {
+ VERBOSE("%s: TLS Size: %u\n", data.key.characters(), data.value->tls_size());
total_tls_size += data.value->tls_size();
}
if (total_tls_size) {
void* tls_address = allocate_tls(total_tls_size);
- dbg() << "from userspace, tls_address: " << tls_address;
+ (void)tls_address;
+ VERBOSE("from userspace, tls_address: %p", tls_address);
}
g_total_tls_size = total_tls_size;
}
+static void initialize_libc()
+{
+ // Traditionally, `_start` of the main program initializes libc.
+ // However, since some libs use malloc() and getenv() in global constructors,
+ // we have to initialize libc just after it is loaded.
+ // Also, we can't just mark `__libc_init` with "__attribute__((constructor))"
+ // because it uses getenv() internally, so `environ` has to be initialized before we call `__libc_init`.
+ auto res = global_symbol_lookup("environ");
+ *((char***)res.address) = g_envp;
+ ASSERT(res.found);
+ res = global_symbol_lookup("__environ_is_malloced");
+ ASSERT(res.found);
+ *((bool*)res.address) = false;
+
+ res = global_symbol_lookup("__libc_init");
+ ASSERT(res.found);
+ typedef void libc_init_func(void);
+ ((libc_init_func*)res.address)();
+}
+
static void load_elf(const String& name)
{
- dbg() << "load_elf: " << name;
+ VERBOSE("load_elf: %s", name.characters());
auto loader = g_loaders.get(name).value();
- loader->for_each_needed_library([](auto needed_name) {
- dbg() << "needed library: " << needed_name;
+ for (const auto& needed_name : get_dependencies(name)) {
+ VERBOSE("needed library: %s", needed_name.characters());
String library_name = get_library_name(needed_name);
if (!g_loaded_objects.contains(library_name)) {
load_elf(library_name);
}
- return IterationDecision::Continue;
- });
+ }
- auto dynamic_object = loader->load_from_image(RTLD_GLOBAL, g_total_tls_size);
+ VERBOSE("loading: %s", name.characters());
+ auto dynamic_object = loader->load_from_image(RTLD_GLOBAL | RTLD_LAZY, g_total_tls_size);
ASSERT(!dynamic_object.is_null());
g_loaded_objects.set(name, dynamic_object.release_nonnull());
+
+ if (name == "libc.so") {
+ initialize_libc();
+ }
+}
+
+static void clear_temporary_objects_mappings()
+{
+
+ g_loaders.clear();
}
static FlatPtr loader_main(auxv_t* auxvp)
@@ -205,9 +256,10 @@ static FlatPtr loader_main(auxv_t* auxvp)
map_library(main_program_name, main_program_fd);
map_dependencies(main_program_name);
- dbg() << "loaded all dependencies";
+ VERBOSE("loaded all dependencies");
for (auto& lib : g_loaders) {
- dbg() << lib.key << "- tls size: " << lib.value->tls_size() << ", tls offset: " << lib.value->tls_offset();
+ (void)lib;
+ VERBOSE("%s - tls size: $u, tls offset: %u", lib.key.characters(), lib.value->tls_size(), lib.value->tls_offset());
}
allocate_tls();
@@ -216,10 +268,10 @@ static FlatPtr loader_main(auxv_t* auxvp)
auto main_program_lib = g_loaders.get(main_program_name).value();
FlatPtr entry_point = reinterpret_cast<FlatPtr>(main_program_lib->image().entry().as_ptr() + (FlatPtr)main_program_lib->text_segment_load_address().as_ptr());
- dbg() << "entry point: " << (void*)entry_point;
+ VERBOSE("entry point: %p", entry_point);
// This will unmap the temporary memory maps we had for loading the libraries
- g_loaders.clear();
+ clear_temporary_objects_mappings();
return entry_point;
}
@@ -233,20 +285,26 @@ using MainFunction = int (*)(int, char**, char**);
void _start(int argc, char** argv, char** envp)
{
- perform_self_relocations();
- init_libc();
-
+ g_envp = envp;
char** env;
for (env = envp; *env; ++env) {
}
auxv_t* auxvp = (auxv_t*)++env;
+ perform_self_relocations(auxvp);
+ init_libc();
+
FlatPtr entry = loader_main(auxvp);
+ VERBOSE("Loaded libs:\n");
+ for (auto& obj : g_loaded_objects) {
+ (void)obj;
+ VERBOSE("%s: %p\n", obj.key.characters(), obj.value->base_address().as_ptr());
+ }
+
MainFunction main_function = (MainFunction)(entry);
- dbg() << "jumping to main program entry point: " << (void*)main_function;
+ VERBOSE("jumping to main program entry point: %p", main_function);
int rc = main_function(argc, argv, envp);
- dbg() << "rc: " << rc;
- sleep(100);
+ VERBOSE("rc: %d", rc);
_exit(rc);
}
}
diff --git a/Userland/DynamicLoader/misc.cpp b/Userland/DynamicLoader/misc.cpp
index 18234a6636..5eda0fe535 100644
--- a/Userland/DynamicLoader/misc.cpp
+++ b/Userland/DynamicLoader/misc.cpp
@@ -34,6 +34,5 @@ const char* __cxa_demangle(const char*, void*, void*, int*)
return "";
}
-// FIXME: Is this correct?
-void* __dso_handle = nullptr;
+void* __dso_handle __attribute__((__weak__));
}
diff --git a/Userland/Tests/Kernel/CMakeLists.txt b/Userland/Tests/Kernel/CMakeLists.txt
index cd9438dc4a..c18d364cab 100644
--- a/Userland/Tests/Kernel/CMakeLists.txt
+++ b/Userland/Tests/Kernel/CMakeLists.txt
@@ -3,6 +3,7 @@ file(GLOB CMD_SOURCES CONFIGURE_DEPENDS "*.cpp")
foreach(CMD_SRC ${CMD_SOURCES})
get_filename_component(CMD_NAME ${CMD_SRC} NAME_WE)
add_executable(${CMD_NAME} ${CMD_SRC})
+ target_sources("${CMD_NAME}" PRIVATE ${CMAKE_SOURCE_DIR}/Libraries/LibC/crt0_shared.cpp)
target_link_libraries(${CMD_NAME} LibCore)
install(TARGETS ${CMD_NAME} RUNTIME DESTINATION usr/Tests/Kernel)
endforeach()
diff --git a/Userland/Tests/LibC/CMakeLists.txt b/Userland/Tests/LibC/CMakeLists.txt
index 799dfa9ff4..8ce9b5c2b9 100644
--- a/Userland/Tests/LibC/CMakeLists.txt
+++ b/Userland/Tests/LibC/CMakeLists.txt
@@ -3,6 +3,7 @@ file(GLOB CMD_SOURCES CONFIGURE_DEPENDS "*.cpp")
foreach(CMD_SRC ${CMD_SOURCES})
get_filename_component(CMD_NAME ${CMD_SRC} NAME_WE)
add_executable(${CMD_NAME} ${CMD_SRC})
+ target_sources("${CMD_NAME}" PRIVATE ${CMAKE_SOURCE_DIR}/Libraries/LibC/crt0_shared.cpp)
target_link_libraries(${CMD_NAME} LibCore)
install(TARGETS ${CMD_NAME} RUNTIME DESTINATION usr/Tests/LibC)
endforeach()