diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2026-01-17 11:29:45 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal@nekernel.org> | 2026-01-17 11:29:45 +0100 |
| commit | 03a18278b9217490f69da3fe6b5ac84c484889fa (patch) | |
| tree | 2d50513243be1c597fdda43b90c28baabc5644bc /src/CompilerKit | |
| parent | 3544384f57fbc63191370f9ac02b7874ea25ea81 (diff) | |
feat! breaking changes on Mach-O and PEF linker.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'src/CompilerKit')
| -rw-r--r-- | src/CompilerKit/src/Compilers/NectarCompiler+AMD64.cc | 24 | ||||
| -rw-r--r-- | src/CompilerKit/src/Linkers/DynamicLinker64+MachO.cc | 88 | ||||
| -rw-r--r-- | src/CompilerKit/src/Linkers/DynamicLinker64+PEF.cc | 5 |
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(); |
