diff options
| author | Amlal El Mahrouss <amlalelmahrouss@icloud.com> | 2024-02-18 08:18:25 +0000 |
|---|---|---|
| committer | Amlal El Mahrouss <amlalelmahrouss@icloud.com> | 2024-02-18 08:18:25 +0000 |
| commit | a7686350855be22e3322f0df6ceb22964bf75965 (patch) | |
| tree | 9bd17adb13d10db83cc87cb1dd5d8274b87abeb0 | |
| parent | 0ab360a35545a0a03c90b97499c85c4381fe7088 (diff) | |
| parent | 5bceef71ec6e7f8e4e9b7fcb987e44403d6de72c (diff) | |
Merge branch 'compiler-parser' into 'master'
Linker: custom ABI according to CPU.
See merge request mahrouss-logic/mp-cc!3
| -rw-r--r-- | Private/CompilerKit/AsmKit/Arch/amd64.hpp | 28 | ||||
| -rw-r--r-- | Private/Toolchain/Compiler/cl-parser.hxx | 14 | ||||
| -rw-r--r-- | Private/Toolchain/bin/Source/hello_amd64.masm | 2 | ||||
| -rw-r--r-- | Private/Toolchain/ccplus.cc | 3 | ||||
| -rw-r--r-- | Private/Toolchain/compile_flags.txt | 1 | ||||
| -rw-r--r-- | Private/Toolchain/i64asm.cc | 90 | ||||
| -rw-r--r-- | Private/Toolchain/link.cc | 26 | ||||
| -rw-r--r-- | Private/Toolchain/makefile | 2 |
8 files changed, 97 insertions, 69 deletions
diff --git a/Private/CompilerKit/AsmKit/Arch/amd64.hpp b/Private/CompilerKit/AsmKit/Arch/amd64.hpp index bb8637f..2438965 100644 --- a/Private/CompilerKit/AsmKit/Arch/amd64.hpp +++ b/Private/CompilerKit/AsmKit/Arch/amd64.hpp @@ -40,25 +40,25 @@ struct CpuCodeAMD64 { #define kJumpLimitStandardLimit 0xEB inline std::vector<CpuCodeAMD64> kOpcodesAMD64 = { - kAsmOpcodeDecl("int", 0xCD) kAsmOpcodeDecl("into", 0xCE) kAsmOpcodeDecl( - "intd", 0xF1) kAsmOpcodeDecl("int3", 0xC3) +kAsmOpcodeDecl("int", 0xCD) +kAsmOpcodeDecl("into", 0xCE) +kAsmOpcodeDecl("intd", 0xF1) +kAsmOpcodeDecl("int3", 0xC3) - kAsmOpcodeDecl("iret", 0xCF) kAsmOpcodeDecl("retf", 0xCB) - kAsmOpcodeDecl("retn", 0xC3) kAsmOpcodeDecl("sti", 0xfb) - kAsmOpcodeDecl("cli", 0xfa) +kAsmOpcodeDecl("iret", 0xCF) +kAsmOpcodeDecl("retf", 0xCB) +kAsmOpcodeDecl("retn", 0xC3) +kAsmOpcodeDecl("sti", 0xfb) +kAsmOpcodeDecl("cli", 0xfa) - kAsmOpcodeDecl("nop", 0x90) +kAsmOpcodeDecl("nop", 0x90) - kAsmOpcodeDecl("mov eax", 0xb8) kAsmOpcodeDecl( - "mov ecx", 0xb9) kAsmOpcodeDecl("mov edx", 0xba) - kAsmOpcodeDecl("mov ebx", 0xbb) kAsmOpcodeDecl( - "mov esp", 0xbc) kAsmOpcodeDecl("mov ebp", 0xbd) - kAsmOpcodeDecl("mov esi", 0xbe) +kAsmOpcodeDecl("mov", 0x48) - kAsmOpcodeDecl("jmp", 0xE9) - kAsmOpcodeDecl("call", 0xE9) +kAsmOpcodeDecl("jmp", 0xE9) +kAsmOpcodeDecl("call", 0xFF) - kAsmOpcodeDecl("mov", 0x00)}; +kAsmOpcodeDecl("mov", 0x00)}; // \brief 64x0 register prefix // example: r32, r0 diff --git a/Private/Toolchain/Compiler/cl-parser.hxx b/Private/Toolchain/Compiler/cl-parser.hxx index d93cdc5..7881127 100644 --- a/Private/Toolchain/Compiler/cl-parser.hxx +++ b/Private/Toolchain/Compiler/cl-parser.hxx @@ -18,4 +18,16 @@ #include <CompilerKit/CompilerKit.hpp> #include <CompilerKit/ParserKit.hpp> -namespace CompilerKit {} // namespace CompilerKit +namespace CompilerKit { +class CLParserExpression { + private: + StringView mExprView; + + public: + CLParserExpression(const char* expr) + : mExprView(StringBuilder::Construct(expr)) {} + virtual ~CLParserExpression() = default; + + MPCC_COPY_DEFAULT(CLParserExpression); +}; +} // namespace CompilerKit diff --git a/Private/Toolchain/bin/Source/hello_amd64.masm b/Private/Toolchain/bin/Source/hello_amd64.masm index 8ae4f12..2223305 100644 --- a/Private/Toolchain/bin/Source/hello_amd64.masm +++ b/Private/Toolchain/bin/Source/hello_amd64.masm @@ -3,7 +3,7 @@ bits 64 export .text MySampleFoo cli -mov rsp, rdx +mov rsp, rsp int 0x80 jmp 0x100000 sti diff --git a/Private/Toolchain/ccplus.cc b/Private/Toolchain/ccplus.cc index e2fe964..77bd22a 100644 --- a/Private/Toolchain/ccplus.cc +++ b/Private/Toolchain/ccplus.cc @@ -11,8 +11,9 @@ #include <uuid/uuid.h> -#include <CompilerKit/AsmKit/Arch/64x0.hpp> +#include <CompilerKit/AsmKit/Arch/amd64.hpp> #include <CompilerKit/ParserKit.hpp> +#include <Compiler/cl-parser.hxx> #include <cstdio> #include <fstream> #include <iostream> diff --git a/Private/Toolchain/compile_flags.txt b/Private/Toolchain/compile_flags.txt index 9afc1ed..bf90a5c 100644 --- a/Private/Toolchain/compile_flags.txt +++ b/Private/Toolchain/compile_flags.txt @@ -1,3 +1,4 @@ -std=c++20 -I../ -I../CompilerKit +-I./ diff --git a/Private/Toolchain/i64asm.cc b/Private/Toolchain/i64asm.cc index b86f88a..55719cf 100644 --- a/Private/Toolchain/i64asm.cc +++ b/Private/Toolchain/i64asm.cc @@ -982,6 +982,18 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line, const std::string &file) { if (ParserKit::find_word(line, "export ")) return true; + struct RegMapAMD64 { + std::string fName; + e64_byte_t fModRM; + }; + + std::vector<RegMapAMD64> regsPt2{ + {.fName = "ax", .fModRM = 0b000}, {.fName = "cx", .fModRM = 0b001}, + {.fName = "dx", .fModRM = 0b010}, {.fName = "bx", .fModRM = 0b011}, + {.fName = "sp", .fModRM = 0b100}, {.fName = "bp", .fModRM = 0b101}, + {.fName = "si", .fModRM = 0b110}, {.fName = "di", .fModRM = 0b111}, + }; + for (auto &opcodeAMD64 : kOpcodesAMD64) { // strict check here if (ParserKit::find_word(line, opcodeAMD64.fName) && @@ -989,21 +1001,9 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line, std::string name(opcodeAMD64.fName); if (name.find("mov") != std::string::npos) { - struct RegMapAMD64 { - std::string fName; - e64_byte_t fModRM; - }; - - std::vector<RegMapAMD64> regs{ - {.fName = "ax", .fModRM = 0}, {.fName = "cx", .fModRM = 1}, - {.fName = "dx", .fModRM = 2}, {.fName = "bx", .fModRM = 3}, - {.fName = "sp", .fModRM = 4}, {.fName = "bp", .fModRM = 5}, - {.fName = "si", .fModRM = 6}, {.fName = "di", .fModRM = 7}, - }; - std::string substr = line.substr(line.find(name) + name.size()); - uint64_t bits = 16; + uint64_t bits = 64; if (substr.find(",") == std::string::npos) { detail::print_error("Invalid combination of operands and registers.", @@ -1011,42 +1011,36 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line, throw std::runtime_error("comb_op_reg"); } - bool found = false; + bits = 64; - for (auto ® : regs) { - if (line.find(reg.fName) != std::string::npos) { - if (!found) { - if (line.substr(line.find(reg.fName) - 1)[0] == 'r') { - bits = 64; + bool noRightRegister = false; - kBytes.emplace_back(0x48); - kBytes.emplace_back(0x89); - kBytes.emplace_back(0x00); - } else { - detail::print_error( - "Invalid combination of registers, each 64-bit register " - "must start with 'r'.", - "i64asm"); - throw std::runtime_error("comb_op_reg"); - } + if (!noRightRegister) { + if (bits == 64 || + bits == 32) + { + if (bits != 32) + kBytes.emplace_back(opcodeAMD64.fOpcode); - found = true; + kBytes.emplace_back(0x89); - kBytes.push_back(0xc0 + reg.fModRM); + // TODO - continue; - } + this->WriteNumber32(line.find(name) + name.size() + 2, line); } - } + else if (bits == 16) { + kBytes.emplace_back(0x66); + kBytes.emplace_back(0x89); - if (bits == 64) - this->WriteNumber32(line.find(name) + name.size() + 2, line); - else if (bits == 16) - this->WriteNumber16(line.find(name) + name.size() + 2, line); - else { - detail::print_error("Invalid combination of operands and registers.", - "i64asm"); - throw std::runtime_error("comb_op_reg"); + // TODO + + this->WriteNumber16(line.find(name) + name.size() + 2, line); + } + else { + detail::print_error("Invalid combination of operands and registers.", + "i64asm"); + throw std::runtime_error("comb_op_reg"); + } } break; @@ -1057,7 +1051,10 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line, break; } else if (name == "jmp" || name == "call") { kBytes.emplace_back(opcodeAMD64.fOpcode); - this->WriteNumber32(line.find(name) + name.size() + 1, line); + + if (!this->WriteNumber32(line.find(name) + name.size() + 1, line)) { + // TODO + } break; } else { @@ -1069,10 +1066,9 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line, } } - if (line.find("db") != std::string::npos) { - this->WriteNumber(line.find("db") + strlen("db") + 1, line); - } - else if (line.find("org ") != std::string::npos) { + if (line.find("db ") != std::string::npos) { + this->WriteNumber(line.find("db ") + strlen("db ") + 1, line); + } else if (line.find("org ") != std::string::npos) { size_t base[] = {10, 16, 2, 7}; for (size_t i = 0; i < 4; i++) { diff --git a/Private/Toolchain/link.cc b/Private/Toolchain/link.cc index 19ca084..eef72ea 100644 --- a/Private/Toolchain/link.cc +++ b/Private/Toolchain/link.cc @@ -46,7 +46,7 @@ #define kPefDeaultOrg (uint64_t)0x10000 #define kPefLinkerNumId 0x5046FF -#define kPefAbiId "Container:Abi:64x0" +#define kPefAbiId "Container:Abi:" enum { kAbiMpUx = 0x5046 /* PF */ }; @@ -279,8 +279,8 @@ MPCC_MODULE(HCoreLinker) { command_header.Size = ae_records[ae_record_index].fSize; if (kVerbose) - kStdOut << "link: object record: " << ae_records[ae_record_index].fName - << " was marked.\n"; + kStdOut << "link: object record: " + << ae_records[ae_record_index].fName << " was marked.\n"; pef_command_hdrs.emplace_back(command_header); } @@ -423,7 +423,25 @@ MPCC_MODULE(HCoreLinker) { CompilerKit::PEFCommandHeader abi_header{}; - memcpy(abi_header.Name, kPefAbiId, strlen(kPefAbiId)); + std::string abi = kPefAbiId; + + switch (kArch) { + case CompilerKit::kPefArchAMD64: { + abi += "MSFT"; + break; + } + case CompilerKit::kPefArch32000: + case CompilerKit::kPefArch64000: { + abi += "MP-UX"; + break; + } + default: { + abi += "UNIX"; + break; + } + } + + memcpy(abi_header.Name, abi.c_str(), abi.size()); abi_header.Size = strlen(kPefAbiId); abi_header.Offset = output_fc.tellp(); diff --git a/Private/Toolchain/makefile b/Private/Toolchain/makefile index 92aecea..3e8583f 100644 --- a/Private/Toolchain/makefile +++ b/Private/Toolchain/makefile @@ -7,7 +7,7 @@ # ======================================================== # -COMMON_INC=-I../ -I../CompilerKit +COMMON_INC=-I../ -I../CompilerKit -I./ LINK_CC=g++ -std=c++20 |
