summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2026-01-17 11:29:45 +0100
committerAmlal El Mahrouss <amlal@nekernel.org>2026-01-17 11:29:45 +0100
commit03a18278b9217490f69da3fe6b5ac84c484889fa (patch)
tree2d50513243be1c597fdda43b90c28baabc5644bc /src
parent3544384f57fbc63191370f9ac02b7874ea25ea81 (diff)
feat! breaking changes on Mach-O and PEF linker.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'src')
-rw-r--r--src/CompilerKit/src/Compilers/NectarCompiler+AMD64.cc24
-rw-r--r--src/CompilerKit/src/Linkers/DynamicLinker64+MachO.cc88
-rw-r--r--src/CompilerKit/src/Linkers/DynamicLinker64+PEF.cc5
3 files changed, 79 insertions, 38 deletions
diff --git a/src/CompilerKit/src/Compilers/NectarCompiler+AMD64.cc b/src/CompilerKit/src/Compilers/NectarCompiler+AMD64.cc
index 17ec443..b11ac58 100644
--- a/src/CompilerKit/src/Compilers/NectarCompiler+AMD64.cc
+++ b/src/CompilerKit/src/Compilers/NectarCompiler+AMD64.cc
@@ -473,7 +473,12 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarAMD64::Compile(
mangled_name.erase(mangled_name.find(" "), 1);
}
- syntax_tree.fUserValue += "public_segment .code64 " + mangled_name + "\n";
+ if (!kNasmOutput)
+ syntax_tree.fUserValue += "public_segment .code64 " + mangled_name + "\n";
+ else
+ syntax_tree.fUserValue +=
+ "section .text\nglobal " + mangled_name + "\n" + mangled_name + ":\n";
+
syntax_tree.fUserValue += nectar_generate_prologue();
// Initialize function-local state
@@ -1304,8 +1309,11 @@ class AssemblyNectarInterfaceAMD64 final CK_ASSEMBLY_INTERFACE {
std::stringstream ss;
ss << std::hex << kOrigin;
- out_fp << "%bits 64\n";
- out_fp << "%org 0x" << ss.str() << "\n\n";
+ if (!kNasmOutput)
+ out_fp << "%bits 64\n";
+ else
+ out_fp << "[BITS 64]\n";
+
out_fp << ";; HINT: NECTAR\n";
while (std::getline(src_fp, line_source)) {
@@ -1382,6 +1390,16 @@ NECTAR_MODULE(CompilerNectarAMD64) {
continue;
}
+ if (strcmp(argv[index], "-nec-masm") == 0) {
+ kNasmOutput = false;
+ continue;
+ }
+
+ if (strcmp(argv[index], "-nec-nasm") == 0) {
+ kNasmOutput = true;
+ continue;
+ }
+
if (strcmp(argv[index], "-nec-dialect") == 0) {
if (kFrontend) std::cout << kFrontend->Language() << "\n";
diff --git a/src/CompilerKit/src/Linkers/DynamicLinker64+MachO.cc b/src/CompilerKit/src/Linkers/DynamicLinker64+MachO.cc
index f2dc527..3db2c92 100644
--- a/src/CompilerKit/src/Linkers/DynamicLinker64+MachO.cc
+++ b/src/CompilerKit/src/Linkers/DynamicLinker64+MachO.cc
@@ -28,17 +28,17 @@
#define kConsoleOut \
(std::cout << "\e[0;31m" \
- << "ld64: " \
+ << "mld64: " \
<< "\e[0;97m")
static CompilerKit::STLString kOutput = kMachODefaultOutput;
-static cpu_type_t kCpuType = CPU_TYPE_ARM64;
-static cpu_subtype_t kCpuSubType = CPU_SUBTYPE_ARM64_ALL;
+static cpu_type_t kCpuType = CPU_TYPE_X86_64;
+static cpu_subtype_t kCpuSubType = CPU_SUBTYPE_X86_64_ALL;
static bool kFatBinaryEnable = false;
static bool kStartFound = false;
static bool kDuplicateSymbols = false;
static bool kIsDylib = false;
-static Int64 kMachODefaultStackSz = 8196;
+static Int64 kMachODefaultStackSz = 0;
static CompilerKit::STLString kLinkerStart = "_main";
@@ -346,20 +346,27 @@ NECTAR_MODULE(DynamicLinker64MachO) {
using namespace CompilerKit::MachO;
- // Calculate layout
- // Commands: LC_SEGMENT_64 (__TEXT) + LC_SEGMENT_64 (__DATA) + LC_SYMTAB + LC_MAIN (if executable)
- uint32_t numCommands = kIsDylib ? 3 : 4;
+ uint32_t numCommands = 4;
+
+ if (!kIsDylib) {
+ numCommands += 1; // LC_MAIN
+ }
+
+ uint32_t dataSegCmdSize =
+ kDataBytes.size() > 0 ? sizeof(segment_command_64) + sizeof(section_64) : 0;
+
+ if (dataSegCmdSize < 1) --numCommands; // No __DATA segment
+
uint32_t sizeOfCmds = 0;
uint32_t headerSize = sizeof(mach_header_64);
+ uint32_t pageZeroSize = sizeof(segment_command_64);
uint32_t textSegCmdSize = sizeof(segment_command_64) + sizeof(section_64);
- uint32_t dataSegCmdSize = sizeof(segment_command_64) + sizeof(section_64);
- uint32_t symtabCmdSize = sizeof(symtab_command);
+ uint32_t buildCmdSize = sizeof(build_version_command);
uint32_t mainCmdSize = sizeof(entry_point_command);
- sizeOfCmds = textSegCmdSize + dataSegCmdSize + symtabCmdSize;
- if (!kIsDylib) {
- sizeOfCmds += mainCmdSize;
- }
+ sizeOfCmds = pageZeroSize + textSegCmdSize + dataSegCmdSize + buildCmdSize;
+
+ if (!kIsDylib) sizeOfCmds += mainCmdSize;
uint64_t headerAndCmdsSize = headerSize + sizeOfCmds;
uint64_t textFileOffset = AlignToPage(headerAndCmdsSize);
@@ -376,13 +383,14 @@ NECTAR_MODULE(DynamicLinker64MachO) {
// Write Mach-O header
mach_header_64 header{};
+
header.magic = MH_MAGIC_64;
header.cputype = kCpuType;
header.cpusubtype = kCpuSubType;
header.filetype = kIsDylib ? MH_DYLIB : MH_EXECUTE;
header.ncmds = numCommands;
header.sizeofcmds = sizeOfCmds;
- header.flags = MH_NOUNDEFS | MH_DYLDLINK | MH_TWOLEVEL | MH_PIE;
+ header.flags = MH_PIE;
header.reserved = 0;
output_fc.write(reinterpret_cast<const char*>(&header), sizeof(header));
@@ -391,6 +399,34 @@ NECTAR_MODULE(DynamicLinker64MachO) {
kConsoleOut << "Wrote Mach-O header, ncmds: " << numCommands << "\n";
}
+ segment_command_64 pageZeroSegment{};
+ pageZeroSegment.cmd = LC_SEGMENT_64;
+ pageZeroSegment.cmdsize = sizeof(segment_command_64);
+ CopySegmentName(pageZeroSegment.segname, kSegmentPageZero);
+ pageZeroSegment.vmaddr = 0;
+ pageZeroSegment.vmsize = 0x100000000ULL;
+ pageZeroSegment.fileoff = 0;
+ pageZeroSegment.filesize = 0;
+ pageZeroSegment.maxprot = 0;
+ pageZeroSegment.initprot = 0;
+ pageZeroSegment.nsects = 0;
+ pageZeroSegment.flags = 0;
+
+ output_fc.write(reinterpret_cast<const char*>(&pageZeroSegment), sizeof(pageZeroSegment));
+
+ build_version_command build = {.cmd = LC_BUILD_VERSION,
+ .cmdsize = sizeof(struct build_version_command),
+ .platform = PLATFORM_MACOS,
+ .minos = (11 << 16), // macOS 11.0
+ .sdk = (11 << 16), // macOS 11.0
+ .ntools = 0};
+
+ output_fc.write(reinterpret_cast<const char*>(&build), sizeof(build));
+
+ if (kVerbose) {
+ kConsoleOut << "Wrote LC_BUILD_VERSION, platform: macOS, minos: 11.0, sdk: 11.0\n";
+ }
+
// Write __TEXT segment command
segment_command_64 textSegment{};
textSegment.cmd = LC_SEGMENT_64;
@@ -399,7 +435,7 @@ NECTAR_MODULE(DynamicLinker64MachO) {
textSegment.vmaddr = textVMAddr;
textSegment.vmsize = textSegmentSize;
textSegment.fileoff = textFileOffset;
- textSegment.filesize = textSize;
+ textSegment.filesize = kPageSize;
textSegment.maxprot = VM_PROT_READ | VM_PROT_EXECUTE;
textSegment.initprot = VM_PROT_READ | VM_PROT_EXECUTE;
textSegment.nsects = 1;
@@ -443,7 +479,8 @@ NECTAR_MODULE(DynamicLinker64MachO) {
dataSegment.nsects = 1;
dataSegment.flags = 0;
- output_fc.write(reinterpret_cast<const char*>(&dataSegment), sizeof(dataSegment));
+ if (dataSegCmdSize > 0)
+ output_fc.write(reinterpret_cast<const char*>(&dataSegment), sizeof(dataSegment));
// Write __data section header
section_64 dataSection{};
@@ -460,29 +497,14 @@ NECTAR_MODULE(DynamicLinker64MachO) {
dataSection.reserved2 = 0;
dataSection.reserved3 = 0;
- output_fc.write(reinterpret_cast<const char*>(&dataSection), sizeof(dataSection));
+ if (dataSegCmdSize > 0)
+ output_fc.write(reinterpret_cast<const char*>(&dataSection), sizeof(dataSection));
if (kVerbose) {
kConsoleOut << "Wrote __DATA segment, vmaddr: 0x" << std::hex << dataVMAddr << std::dec << "\n";
kConsoleOut << " __data section, size: " << dataSize << " bytes\n";
}
- // Write LC_SYMTAB command
- symtab_command symtabCmd{};
- symtabCmd.cmd = LC_SYMTAB;
- symtabCmd.cmdsize = sizeof(symtab_command);
- symtabCmd.symoff = static_cast<uint32_t>(symtabFileOffset);
- symtabCmd.nsyms = static_cast<uint32_t>(kSymbolTable.size());
- symtabCmd.stroff = static_cast<uint32_t>(strtabFileOffset);
- symtabCmd.strsize = static_cast<uint32_t>(kStringTable.size());
-
- output_fc.write(reinterpret_cast<const char*>(&symtabCmd), sizeof(symtabCmd));
-
- if (kVerbose) {
- kConsoleOut << "Wrote LC_SYMTAB, nsyms: " << symtabCmd.nsyms
- << ", strsize: " << symtabCmd.strsize << "\n";
- }
-
// Write LC_MAIN entry point command (executables only)
if (!kIsDylib) {
entryCommand.cmd = LC_MAIN;
diff --git a/src/CompilerKit/src/Linkers/DynamicLinker64+PEF.cc b/src/CompilerKit/src/Linkers/DynamicLinker64+PEF.cc
index f1b28d5..0729d7b 100644
--- a/src/CompilerKit/src/Linkers/DynamicLinker64+PEF.cc
+++ b/src/CompilerKit/src/Linkers/DynamicLinker64+PEF.cc
@@ -28,6 +28,7 @@
#define kLinkerDefaultOrigin kPefBaseOrigin
#define kLinkerId (0x5046FF)
#define kLinkerAbiContainer "__PEFContainer:ABI:"
+#define kLinkerGuidContainer "__PEFContainer:GUID:"
#define kLinkerSplash() kStdOut << kLinkerVersionStr << kStdEndl
@@ -514,8 +515,8 @@ NECTAR_MODULE(DynamicLinker64PEF) {
uuids::uuid id = gen();
auto uuidStr = uuids::to_string(id);
- std::memcpy(uuid_cmd_hdr.Name, "Container:GUID:4:", strlen("Container:GUID:4:"));
- std::memcpy(uuid_cmd_hdr.Name + strlen("Container:GUID:4:"), uuidStr.c_str(), uuidStr.size());
+ std::memcpy(uuid_cmd_hdr.Name, kLinkerGuidContainer, strlen(kLinkerGuidContainer));
+ std::memcpy(uuid_cmd_hdr.Name + strlen(kLinkerGuidContainer), uuidStr.c_str(), uuidStr.size());
uuid_cmd_hdr.VirtualSize = strlen(uuid_cmd_hdr.Name);
uuid_cmd_hdr.Offset = output_fc.tellp();