summaryrefslogtreecommitdiffhomepage
path: root/Private/Source/PEFSharedObjectRT.cxx
blob: 018b618e13936c69490b12c6daee64ee0083e495 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
 * ========================================================
 *
 * HCore
 * Copyright Mahrouss Logic, all rights reserved.
 *
 *  ========================================================
 */

#include <KernelKit/DebugOutput.hpp>
#include <KernelKit/PEF.hpp>
#include <KernelKit/PEFSharedObject.hxx>
#include <KernelKit/ProcessManager.hpp>
#include <KernelKit/ThreadLocalStorage.hxx>
#include <NewKit/Defines.hpp>

#include "NewKit/RuntimeCheck.hpp"

/* -------------------------------------------

 Revision History:

     01/02/24: Rework shared library ABI, except a __LibInit and __LibFini
 (amlel)

 ------------------------------------------- */

using namespace HCore;

/***********************************************************************************/
/// @file SharedObjectRT.cxx
/// @brief Shared Object runtime.
/***********************************************************************************/

/***********************************************************************************/
/* @brief Allocates a new library. */
/***********************************************************************************/

extern "C" SharedObject *__LibInit() {
  SharedObject *library = hcore_tls_new_class<SharedObject>();

  if (!library) {
    kcout << "__LibInit: Out of Memory!\n";
    ProcessManager::Shared().Leak().GetCurrent().Leak().Crash();

    return nullptr;
  }

  library->Mount(hcore_tls_new_class<SharedObject::SharedObjectTraits>());

  if (!library->Get()) {
    kcout << "__LibInit: Out of Memory!\n";
    ProcessManager::Shared().Leak().GetCurrent().Leak().Crash();

    return nullptr;
  }

  library->Get()->fImageObject =
      ProcessManager::Shared().Leak().GetCurrent().Leak().Image;

  if (!library->Get()->fImageObject) {
    kcout << "__LibInit: Invalid image!\n";
    ProcessManager::Shared().Leak().GetCurrent().Leak().Crash();

    return nullptr;
  }

  library->Get()->fImageEntrypointOffset =
      library->Load<VoidPtr>(kPefStart, string_length(kPefStart, 0), kPefCode);

  kcout << "__LibInit: Task was successful... Returning library...\n";

  return library;
}

/***********************************************************************************/

/***********************************************************************************/
/* @brief Frees the library. */
/* @note Please check if the lib got freed! */
/* @param SharedObjectPtr the library to free. */
/***********************************************************************************/

extern "C" Void __LibFini(SharedObjectPtr lib, bool *successful) {
  MUST_PASS(successful);

  // sanity check (will also trigger a bug check)
  if (lib == nullptr) {
    kcout << "__LibFini: Invalid image!\n";
    *successful = false;
    ProcessManager::Shared().Leak().GetCurrent().Leak().Crash();
  }

  delete lib->Get();
  delete lib;

  lib = nullptr;

  *successful = true;
}

/***********************************************************************************/

extern "C" void __mh_purecall(void) {
  // virtual placeholder.
  return;
}