├── .gitignore ├── Allocator.cpp ├── App.config ├── AssemblyDef.cpp ├── ChangeLog.txt ├── Class.cpp ├── CodeContainer.cpp ├── CreateGUID.cpp ├── CustomAttributeContainer.cpp ├── DLLExportReader.cpp ├── DLLExportReader.h ├── DataContainer.cpp ├── DotNetPELib.h ├── DotNetPELib.sln ├── DotNetPELib.vcxproj ├── DotNetPELib.vcxproj.filters ├── DotNetPELib.vcxproj.user ├── Enum.cpp ├── Field.cpp ├── Instruction.cpp ├── MZHeader.h ├── Method.cpp ├── MethodSignature.cpp ├── NameSpace.cpp ├── NetCore.cpp ├── NetSignature.cpp ├── ObjTest ├── ObjTest.cpp ├── ObjTest.vcxproj ├── ObjTest.vcxproj.filters ├── ReadMe.txt ├── stdafx.cpp ├── stdafx.h └── targetver.h ├── Operand.cpp ├── PECor20Headers.cpp ├── PEFile.h ├── PEHeader.h ├── PELib.cpp ├── PELibError.cpp ├── PEReader.cpp ├── PEWriter.cpp ├── Property.cpp ├── Qualifiers.cpp ├── README.md ├── RSAEncoder.cpp ├── RSAEncoder.h ├── Type.cpp ├── Value.cpp ├── appveyor.yml ├── bigd license.txt ├── bigdigits.cpp ├── bigdigits.h ├── bigdtypes.h ├── copying ├── docs ├── Allocator.html ├── AssemblyDef.html ├── BoxedType.html ├── Class.html ├── CodeContainer.html ├── CustomAttributeContainer.html ├── DataContainer.html ├── DotNETPELib 3.0 Documentation.html ├── Enum.html ├── Field.html ├── FieldName.html ├── Instruction.html ├── Local.html ├── Method.html ├── MethodName.html ├── MethodSignature.html ├── Namespace.html ├── Operand.html ├── PELib.html ├── PELibError.html ├── Param.html ├── Property.html ├── Qualifier.html ├── SEH.html ├── Type.html └── Value.html ├── libhostfxr ├── _version.h ├── error_codes.h ├── fx_ver.cpp ├── fx_ver.h ├── fxr_resolver.cpp ├── fxr_resolver.h ├── fxrutils.cpp ├── fxrutils.h ├── hostfxr.h ├── libhostfxr.vcxproj ├── libhostfxr.vcxproj.filters ├── longfile.h ├── longfile.windows.cpp ├── pal.h ├── pal.windows.cpp ├── runtime_version.h ├── trace.cpp └── trace.h ├── license.txt ├── ms.bat ├── netlink ├── CmdFiles.cpp ├── CmdFiles.h ├── CmdSwitch.cpp ├── CmdSwitch.h ├── NetLink.vcxproj ├── NetLink.vcxproj.filters ├── NetLink.vcxproj.user ├── NetLinkMain.cpp ├── NetLinkMain.h ├── ToolChain.cpp ├── ToolChain.h ├── Utils.cpp ├── Utils.h ├── dummy.cpp ├── makefile ├── netlink.exe.manifest ├── targetver.h └── version.h ├── sha1.cpp ├── sha1.h ├── targetver.h ├── test ├── App.config ├── DumpMSCorLib.cpp ├── DumpMSCorLib.vcxproj ├── DumpMSCorLib.vcxproj.filters ├── Properties │ └── AssemblyInfo.cs ├── test.cpp ├── test.vcxproj ├── test.vcxproj.filters ├── testcsc.cs └── testcsc.csproj ├── testcore ├── test.cpp ├── testcore.vcxproj └── testcore.vcxproj.filters ├── util ├── dump.c └── dump.cpp ├── vcvars32.bat └── vcvarsall.bat /.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | *.db 3 | release 4 | debug -------------------------------------------------------------------------------- /App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ChangeLog.txt: -------------------------------------------------------------------------------- 1 | Version 4.00: 2 | add license.txt and copying files 3 | update for .net core 4 | update as per latest from orange c 5 | support at least parsing the CMOD_OPT and CMOD_REQD type elements 6 | handle reading pointer/array types better 7 | allow loading of dlls that don't have exactly five corelib streams 8 | allow loading of dlls that use the alternate location for the pointers to the cor20 header structure 9 | search for managed libraries on the path 10 | elide unused variables from function argument lists: 11 | fix bugs in optimizing locals 12 | 13 | Version 3.04: 14 | make use of maps with strings a little faster 15 | 16 | Version 3.03: 17 | add support for explicit types (for sizeof) 18 | add support for pinning 19 | add support for generic classes and allow find functions to match by generic arguments 20 | add minimal support for generic functions (find not updated) 21 | add qualifiers for virtual/newslot 22 | add qualifier for runtime functions 23 | remove old 'virtual' functions 24 | 25 | Version 3.02: 26 | fix problems parsing and generating properties 27 | allow 'find' functions to find constructors 28 | 29 | Version 3.01: 30 | support virtual functions 31 | use correct boxed types 'Byte and SByte' for the 8-bit values 32 | speed up assembly loading a little 33 | make read of ILO files more portable 34 | make the sources compileable by mingw64 and clang 35 | 36 | Version 3.00: 37 | support SEH 38 | 39 | Version 2.12: 40 | allow boxing of 'object' and creation of arrays of objects 41 | 42 | Version 2.11: 43 | support extends for classes 44 | 45 | Version 2.10: 46 | bug fix: escape '"' and '\' in ldstr operand 47 | bug fix: fix a crash 48 | bug fix: handle enum references properly and load enum values 49 | 50 | Version 2.9: 51 | bug fix: allow System.Diagnostics.Process to load 52 | 53 | Version 2.8: 54 | bug fix: if a global field is of type class and the class is from an external assembly ref, 55 | the IL file wass correct but the PE file had a bad signature for the field's type 56 | bug fix: last property in a long list of properties could be loaded incorrectly 57 | netlink: don't thunk C-style entry point if the incoming program has an entry point 58 | bug fix: custom attributes not registered correctly 59 | 60 | Version 2.7: 61 | various improvements to property creation 62 | bug fix: fix the problem with quoted types in external assemblies in a better way 63 | 64 | Version 2.6: 65 | bug fix: search for assembly on path failed 66 | 67 | Version 2.5: 68 | bug fix: escape control characters when writing strings to the .il file... 69 | bug fix: don't quote types from external assemblies 70 | bug fix: fix crash when System.Windows.dll is loaded 71 | 72 | Version 2.4: 73 | bug fix: in some assemblies parent classes sometimes are listed AFTER the child classes, which resulted in a crash 74 | bug fix: name and box native integers properly 75 | 76 | Version 2.3: 77 | bug fix: using namespace.cls in an object file failed for empty method signatures 78 | bug fix: integers were being maxed at 2gigs because of use of atoi 79 | 80 | Version 2.2: 81 | add routines to read and write object files 82 | add a linker to link object files 83 | bug fix: add the valuetype flag to the qualifiers on enumerations 84 | bug fix: ldarg instruction was considered to have five bytes, not 4. This could mess up branch generation if 85 | there are hundreds of arguments 86 | bug fix: the object[] variable used for setup for calling VARARG functions was declared as void * in the locals, 87 | .NET was ok with it but MONO was too restrictive to accept it. 88 | bug fix: allocator could call a destructor for unconstructed memory on close 89 | bug fix: fix the 'dump' utility to work with the latest code base 90 | 91 | Version 2.1: 92 | speed up GAC searches 93 | allow searching for a specific version of a DLL in the GAC. 94 | add support for 'explicit' classes 95 | fix bug: allow boxing of 'string' type 96 | 97 | Version 2.0: 98 | read public members of assemblies into the internal database - searches the GAC or takes the path of an assembly 99 | add support for simple properties 100 | add support for arrays and remove 'objectarray' type 101 | add support for 'ref' argument types 102 | fully support assembly versions 103 | cache the custom attribute database for purposes of being able to parse files; 104 | in general you cannot declare custom attributes though 105 | add lookup functions to find assembly members of referenced assemblies 106 | clean up some duplicate definitions in the API. 107 | update demo code to use new APIs. 108 | add new demos 109 | fix bug: integer constants were being represented in hexadecimal in the .il file 110 | fix bug: in the IL src types were quoted in boxing and newarr 111 | 112 | Version 1.2: 113 | remove sdata section; move the data into the CIL data section (fix for avast 114 | not liking generated files) 115 | add strong name key hashing 116 | fix bug putting large data in the blob 117 | 118 | Version 1.1: 119 | fix problems with generating the binary for large programs 120 | 121 | Version 1.0: 122 | initial release 123 | 124 | -------------------------------------------------------------------------------- /CreateGUID.cpp: -------------------------------------------------------------------------------- 1 | /* Software License Agreement 2 | * 3 | * Copyright(C) 1994-2023 David Lindauer, (LADSoft) 4 | * 5 | * This file is part of the Orange C Compiler package. 6 | * 7 | * The Orange C Compiler package is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * The Orange C Compiler package is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Orange C. If not, see . 19 | * 20 | * contact information: 21 | * email: TouchStone222@runbox.com 22 | * 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "DotNetPELib.h" 30 | #include "PEFile.h" 31 | 32 | void DotNetPELib::PEWriter::CreateGuid(Byte* Guid) 33 | { 34 | std::array rnd; 35 | 36 | std::uniform_int_distribution distribution(0, 0xff); 37 | // note that this whole thing will fall apart if the C++ lib uses 38 | // a prng with constant seed for the random_device implementation. 39 | // that shouldn't be a problem on OS we are interested in. 40 | std::random_device dev; 41 | std::mt19937 engine(dev()); 42 | auto generator = std::bind(distribution, engine); 43 | 44 | std::generate(rnd.begin(), rnd.end(), generator); 45 | 46 | // make it a valid version 4 (random) GUID 47 | // remember that on windows GUIDs are native endianness so this may need 48 | // work if you port it 49 | rnd[7 /*6*/] &= 0xf; 50 | rnd[7 /*6*/] |= 0x40; 51 | rnd[9 /*8*/] &= 0x3f; 52 | rnd[9 /*8*/] |= 0x80; 53 | 54 | memcpy(Guid, rnd.data(), rnd.size()); 55 | } 56 | -------------------------------------------------------------------------------- /DLLExportReader.cpp: -------------------------------------------------------------------------------- 1 | /* Software License Agreement 2 | * 3 | * Copyright(C) 1994-2023 David Lindauer, (LADSoft) 4 | * 5 | * This file is part of the Orange C Compiler package. 6 | * 7 | * The Orange C Compiler package is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * The Orange C Compiler package is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Orange C. If not, see . 19 | * 20 | * contact information: 21 | * email: TouchStone222@runbox.com 22 | * 23 | */ 24 | 25 | #include 26 | #include 27 | #include "DLLExportReader.h" 28 | #include "DotNetPELib.h" 29 | #include "PEHeader.h" 30 | #include "MZHeader.h" 31 | 32 | #include "PEFile.h" 33 | using namespace DotNetPELib; 34 | 35 | const char* DIR_SEP = "\\"; 36 | 37 | DLLExportReader::~DLLExportReader() 38 | { 39 | for (iterator it = begin(); it != end(); ++it) 40 | { 41 | DLLExport* p = *it; 42 | delete p; 43 | } 44 | } 45 | 46 | bool DLLExportReader::FindDLL() 47 | { 48 | char* p = (char*)strrchr((char*)name.c_str(), '.'); 49 | if (!p || p[1] == DIR_SEP[0]) 50 | { 51 | name += ".dll"; 52 | } 53 | // just try to open the file 54 | // this will catch absolute files and files relative to the current directory 55 | FILE* fil = fopen(name.c_str(), "rb"); 56 | if (fil) 57 | { 58 | fclose(fil); 59 | return true; 60 | } 61 | // now look in windows/system32 62 | p = getenv("SystemRoot"); 63 | if (p) 64 | { 65 | char buf[260]; 66 | StrCpy(buf, p); 67 | if (buf[strlen(buf) - 1] != DIR_SEP[0]) 68 | StrCat(buf, DIR_SEP); 69 | StrCat(buf, "System32"); 70 | StrCat(buf, DIR_SEP); 71 | StrCat(buf, name.c_str()); 72 | fil = fopen(buf, "rb"); 73 | if (fil) 74 | { 75 | name = buf; 76 | fclose(fil); 77 | return true; 78 | } 79 | } 80 | // now search the path 81 | p = getenv("PATH"); 82 | if (p) 83 | { 84 | while (*p) 85 | { 86 | char buf[260], *q = buf; 87 | while (*p && *p != ';') 88 | *q++ = *p++; 89 | *q = 0; 90 | if (*p) 91 | p++; 92 | if (buf[strlen(buf) - 1] != DIR_SEP[0]) 93 | StrCat(buf, DIR_SEP); 94 | StrCat(buf, name.c_str()); 95 | fil = fopen(buf, "rb"); 96 | if (fil) 97 | { 98 | name = buf; 99 | fclose(fil); 100 | return true; 101 | } 102 | } 103 | } 104 | return false; 105 | } 106 | bool DLLExportReader::doExports(std::fstream& in, int phys, int rva) 107 | { 108 | in.seekg(phys); 109 | if (!in.fail()) 110 | { 111 | PEExportHeader eh; 112 | in.read((char*)&eh, sizeof(eh)); 113 | for (int i = 0; i < eh.n_name_ptrs; i++) 114 | { 115 | int nameptr; 116 | short ord = 0; 117 | char buf[256]; 118 | bool byOrd; 119 | buf[0] = 0; 120 | in.seekg(eh.name_rva - rva + phys + i * 4); 121 | in.read((char*)&nameptr, sizeof(nameptr)); 122 | if (nameptr) 123 | { 124 | in.seekg(nameptr - rva + phys); 125 | in.read(buf, 256); 126 | buf[255] = 0; // just in case 127 | byOrd = false; 128 | } 129 | else 130 | { 131 | byOrd = true; 132 | } 133 | in.seekg(eh.ordinal_rva - rva + phys + i * 2); 134 | in.read((char*)&ord, sizeof(ord)); 135 | exports.push_back(new DLLExport(buf, ord, byOrd)); 136 | } 137 | } 138 | return !in.fail(); 139 | } 140 | bool DLLExportReader::LoadExports() 141 | { 142 | bool rv = false; 143 | std::fstream in(name.c_str(), std::ios::in | std::ios::binary); 144 | if (!in.fail()) 145 | { 146 | MZHeader mzh; 147 | in.read((char*)&mzh, sizeof(mzh)); 148 | if (!in.fail() && mzh.signature == MZ_SIGNATURE) 149 | { 150 | // seek to the position where the offset to the PEHeader is stored 151 | in.seekg(mzh.n_header_paragraphs * 16 - 4); 152 | int pos; 153 | in.read((char*)&pos, sizeof(pos)); 154 | if (!in.fail()) 155 | { 156 | in.seekg(pos); 157 | if (!in.fail()) 158 | { 159 | PEHeader peh; 160 | in.read((char*)&peh, sizeof(peh)); 161 | if (!in.fail() && peh.signature == PESIG) 162 | { 163 | for (int i = 0; i < peh.num_objects; i++) 164 | { 165 | PEObject obj; 166 | in.read((char*)&obj, sizeof(obj)); 167 | if (!in.fail()) 168 | { 169 | if (peh.export_rva >= obj.virtual_addr && peh.export_rva < obj.virtual_addr + obj.virtual_size) 170 | { 171 | rv = doExports(in, obj.raw_ptr + peh.export_rva - obj.virtual_addr, peh.export_rva); 172 | break; 173 | } 174 | } 175 | } 176 | } 177 | } 178 | } 179 | } 180 | } 181 | return rv; 182 | } -------------------------------------------------------------------------------- /DLLExportReader.h: -------------------------------------------------------------------------------- 1 | /* Software License Agreement 2 | * 3 | * Copyright(C) 1994-2023 David Lindauer, (LADSoft) 4 | * 5 | * This file is part of the Orange C Compiler package. 6 | * 7 | * The Orange C Compiler package is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * The Orange C Compiler package is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Orange C. If not, see . 19 | * 20 | * contact information: 21 | * email: TouchStone222@runbox.com 22 | * 23 | */ 24 | 25 | #ifndef DLLExportReader_H 26 | #define DLLExportReader_H 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | struct DLLExport 33 | { 34 | DLLExport(const std::string &Name, int ord, bool ByOrd) : name(Name), ordinal(ord), byOrd(ByOrd) { } 35 | std::string name; 36 | int ordinal; 37 | bool byOrd; 38 | }; 39 | 40 | class DLLExportReader 41 | { 42 | public: 43 | DLLExportReader(const std::string &fname) : name(fname) { } 44 | ~DLLExportReader(); 45 | bool Read() { bool rv = FindDLL(); if (rv) rv = LoadExports(); return rv; } 46 | 47 | std::string Name() { return name; } 48 | typedef std::deque::iterator iterator; 49 | iterator begin() { return exports.begin(); } 50 | iterator end() { return exports.end(); } 51 | protected: 52 | bool doExports(std::fstream &in, int phys, int rva); 53 | bool FindDLL(); 54 | bool LoadExports(); 55 | private: 56 | std::string name; 57 | std::deque exports; 58 | }; 59 | #endif 60 | -------------------------------------------------------------------------------- /DotNetPELib.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Resource Files 47 | 48 | 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | Source Files 61 | 62 | 63 | Source Files 64 | 65 | 66 | Source Files 67 | 68 | 69 | Source Files 70 | 71 | 72 | Source Files 73 | 74 | 75 | Source Files 76 | 77 | 78 | Source Files 79 | 80 | 81 | Source Files 82 | 83 | 84 | Source Files 85 | 86 | 87 | Source Files 88 | 89 | 90 | Source Files 91 | 92 | 93 | Source Files 94 | 95 | 96 | Source Files 97 | 98 | 99 | Source Files 100 | 101 | 102 | Source Files 103 | 104 | 105 | Source Files 106 | 107 | 108 | Source Files 109 | 110 | 111 | Source Files 112 | 113 | 114 | Source Files 115 | 116 | 117 | Source Files 118 | 119 | 120 | Source Files 121 | 122 | 123 | Source Files 124 | 125 | 126 | Source Files 127 | 128 | 129 | Source Files 130 | 131 | 132 | Source Files 133 | 134 | 135 | Source Files 136 | 137 | 138 | 139 | 140 | Source Files 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /DotNetPELib.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /MZHeader.h: -------------------------------------------------------------------------------- 1 | /* Software License Agreement 2 | * 3 | * Copyright(C) 1994-2023 David Lindauer, (LADSoft) 4 | * 5 | * This file is part of the Orange C Compiler package. 6 | * 7 | * The Orange C Compiler package is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * The Orange C Compiler package is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Orange C. If not, see . 19 | * 20 | * contact information: 21 | * email: TouchStone222@runbox.com 22 | * 23 | */ 24 | 25 | #ifndef MZHeader_h 26 | #define MZHeader_h 27 | 28 | #define MZ_SIGNATURE 0x5A4D /* MZ */ 29 | 30 | struct MZHeader 31 | { 32 | unsigned short signature; 33 | unsigned short image_length_MOD_512; 34 | unsigned short image_length_DIV_512; 35 | unsigned short n_relocation_items; 36 | unsigned short n_header_paragraphs; 37 | unsigned short min_paragraphs_above; 38 | unsigned short max_paragraphs_above; 39 | unsigned short initial_SS; 40 | unsigned short initial_SP; 41 | unsigned short checksum; 42 | unsigned short initial_IP; 43 | unsigned short initial_CS; 44 | unsigned short offset_to_relocation_table; 45 | unsigned short overlay; 46 | unsigned short always_one; 47 | }; 48 | #endif 49 | -------------------------------------------------------------------------------- /NameSpace.cpp: -------------------------------------------------------------------------------- 1 | /* Software License Agreement 2 | * 3 | * Copyright(C) 1994-2023 David Lindauer, (LADSoft) 4 | * 5 | * This file is part of the Orange C Compiler package. 6 | * 7 | * The Orange C Compiler package is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * The Orange C Compiler package is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Orange C. If not, see . 19 | * 20 | * contact information: 21 | * email: TouchStone222@runbox.com 22 | * 23 | */ 24 | 25 | #include "DotNetPELib.h" 26 | #include "PEFile.h" 27 | namespace DotNetPELib 28 | { 29 | 30 | bool Namespace::ILSrcDump(PELib& peLib) const 31 | { 32 | 33 | peLib.Out() << ".namespace '" << name_ << "' {" << std::endl; 34 | DataContainer::ILSrcDump(peLib); 35 | peLib.Out() << "}" << std::endl; 36 | return true; 37 | } 38 | void Namespace::ObjOut(PELib& peLib, int pass) const 39 | { 40 | peLib.Out() << std::endl << "$nb" << peLib.FormatName(name_); 41 | DataContainer::ObjOut(peLib, pass); 42 | peLib.Out() << std::endl << "$ne"; 43 | } 44 | Namespace* Namespace::ObjIn(PELib& peLib, bool definition) 45 | { 46 | // always a definition (never used as an operand) 47 | std::string name = peLib.UnformatName(); 48 | Namespace *temp, *rv = nullptr; 49 | temp = (Namespace*)peLib.GetContainer()->FindContainer(name); 50 | if (temp && typeid(*temp) != typeid(Namespace)) 51 | peLib.ObjError(oe_nonamespace); 52 | if (!temp) 53 | rv = temp = peLib.AllocateNamespace(name); 54 | ((DataContainer*)temp)->ObjIn(peLib); 55 | if (peLib.ObjEnd() != 'n') 56 | peLib.ObjError(oe_syntax); 57 | return rv; 58 | } 59 | std::string Namespace::ReverseName(DataContainer* child) 60 | { 61 | std::string rv; 62 | if (child->Parent()) 63 | { 64 | if (child->Parent()->Parent()) 65 | rv = ReverseName(child->Parent()) + "."; 66 | rv += child->Name(); 67 | } 68 | return rv; 69 | } 70 | bool Namespace::PEDump(PELib& peLib) 71 | { 72 | if (!InAssemblyRef() || !PEIndex()) 73 | { 74 | std::string fullName = ReverseName(this); 75 | peIndex_ = peLib.PEOut().HashString(fullName); 76 | } 77 | if (!InAssemblyRef()) 78 | DataContainer::PEDump(peLib); 79 | return true; 80 | } 81 | } // namespace DotNetPELib -------------------------------------------------------------------------------- /ObjTest/ObjTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /ObjTest/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : q Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this q application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your q application. 9 | 10 | 11 | q.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | q.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | q.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named q.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /ObjTest/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // q.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /ObjTest/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | -------------------------------------------------------------------------------- /ObjTest/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /PELibError.cpp: -------------------------------------------------------------------------------- 1 | /* Software License Agreement 2 | * 3 | * Copyright(C) 1994-2023 David Lindauer, (LADSoft) 4 | * 5 | * This file is part of the Orange C Compiler package. 6 | * 7 | * The Orange C Compiler package is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * The Orange C Compiler package is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Orange C. If not, see . 19 | * 20 | * contact information: 21 | * email: TouchStone222@runbox.com 22 | * 23 | */ 24 | 25 | #include "DotNetPELib.h" 26 | namespace DotNetPELib 27 | { 28 | const char* PELibError::errorNames[] = { 29 | "Variable Length Argument parameters already declared", 30 | "Stack underflow", 31 | "Mismatched stack at label", 32 | "Stack not empty at end of function", 33 | "Duplicate label", 34 | "Missing label", 35 | "Short branch out of range", 36 | "Index out of range", 37 | "Multiple Entry Points", 38 | "Missing Entry Point", 39 | "Expected SEH Try block", 40 | "Expected SEH Handler", 41 | "SEH Tag Mismatch", 42 | "Orphaned SEH Tag", 43 | "Invalid SEH Filter", 44 | "Invalid epilogue of SEH section", 45 | }; 46 | } -------------------------------------------------------------------------------- /Qualifiers.cpp: -------------------------------------------------------------------------------- 1 | /* Software License Agreement 2 | * 3 | * Copyright(C) 1994-2023 David Lindauer, (LADSoft) 4 | * 5 | * This file is part of the Orange C Compiler package. 6 | * 7 | * The Orange C Compiler package is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * The Orange C Compiler package is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Orange C. If not, see . 19 | * 20 | * contact information: 21 | * email: TouchStone222@runbox.com 22 | * 23 | */ 24 | 25 | #include "DotNetPELib.h" 26 | namespace DotNetPELib 27 | { 28 | const char* Qualifiers::qualifierNames_[] = {"public", 29 | "private", 30 | "static", 31 | "instance", 32 | "explicit", 33 | "ansi", 34 | "sealed", 35 | "enum", 36 | "value", 37 | "sequential", 38 | "auto", 39 | "literal", 40 | "hidebysig", 41 | "preservesig", 42 | "specialname", 43 | "rtspecialname", 44 | "cil", 45 | "managed", 46 | "runtime", 47 | "", 48 | "virtual", 49 | "newslot", 50 | "beforefieldinit", 51 | "", 52 | "", 53 | "", 54 | "", 55 | "", 56 | "", 57 | "", 58 | "", 59 | ""}; 60 | int Qualifiers::afterFlags_ = Qualifiers::PreserveSig | Qualifiers::CIL | Qualifiers::Managed | Qualifiers::Runtime; 61 | void Qualifiers::ILSrcDumpBeforeFlags(PELib& peLib) const 62 | { 63 | int n = ~afterFlags_ & flags_; 64 | for (int i = 0; i < 32; i++) 65 | if (n & (1 << i)) 66 | peLib.Out() << " " << qualifierNames_[i]; 67 | } 68 | void Qualifiers::ILSrcDumpAfterFlags(PELib& peLib) const 69 | { 70 | int n = afterFlags_ & flags_; 71 | for (int i = 0; i < 32; i++) 72 | if (n & (1 << i)) 73 | peLib.Out() << " " << qualifierNames_[i]; 74 | } 75 | void Qualifiers::ObjOut(PELib& peLib, int pass) const { peLib.Out() << flags_; } 76 | void Qualifiers::ObjIn(PELib& peLib, bool definition) { flags_ = peLib.ObjInt(); } 77 | void Qualifiers::ReverseNamePrefix(std::string& rv, const DataContainer* parent, int& pos, bool type) 78 | { 79 | if (parent) 80 | { 81 | ReverseNamePrefix(rv, parent->Parent(), pos, type); 82 | if (pos != 0) 83 | { 84 | rv += parent->Name(); 85 | if (typeid(*parent) == typeid(Class) && (!parent->Parent() || typeid(*(parent->Parent())) != typeid(Class))) 86 | rv += type ? "\xf8" : "/"; 87 | else 88 | rv += '.'; 89 | } 90 | else if (typeid(*parent) == typeid(AssemblyDef)) 91 | { 92 | if (parent->InAssemblyRef()) 93 | { 94 | rv += std::string("[") + parent->Name() + "]"; 95 | } 96 | } 97 | pos++; 98 | } 99 | } 100 | std::string Qualifiers::GetNamePrefix(const DataContainer* parent, bool type) 101 | { 102 | std::string rv; 103 | if (parent) 104 | { 105 | int pos = 0; 106 | ReverseNamePrefix(rv, parent, pos, type); 107 | } 108 | return rv; 109 | } 110 | std::string Qualifiers::GetName(const std::string& root, const DataContainer* parent, bool type) 111 | { 112 | std::string rv = GetNamePrefix(parent, type); 113 | if (rv.size()) 114 | { 115 | rv = rv.substr(0, rv.size() - 1); 116 | } 117 | if (root.size()) 118 | { 119 | if (rv.size()) 120 | rv += "::"; 121 | rv += "'" + root + "'"; 122 | } 123 | return rv; 124 | } 125 | 126 | std::string Qualifiers::GetObjName(const std::string& stem, const DataContainer* parent) 127 | { 128 | int pos = 0; 129 | std::string rv; 130 | ReverseNamePrefix(rv, parent, pos, false); 131 | int npos = rv.find('/'); 132 | if (npos != std::string::npos) 133 | rv[npos] = '.'; 134 | if (rv.size()) 135 | { 136 | if (rv[rv.size() - 1] == '.') 137 | { 138 | if (rv.size() == 1) 139 | rv = ""; 140 | else 141 | rv = rv.substr(0, rv.size() - 1); 142 | } 143 | } 144 | if (stem.size()) 145 | { 146 | if (rv.size()) 147 | { 148 | rv = rv + "::" + stem; 149 | } 150 | else 151 | { 152 | rv = stem; 153 | } 154 | } 155 | return rv; 156 | } 157 | } // namespace DotNetPELib -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DotNetPELib 2 | 3 | DotNetPELib is a library which abstracts managed information such as namespaces, classes, fields, methods, properties, and instructions. The information can then be used to generate intermediate language source files, or PE executables or DLLs. 4 | 5 | Build Status 6 | [![Build status](https://ci.appveyor.com/api/projects/status/rtuxe2ef8w7udjda?svg=true)](https://ci.appveyor.com/project/LADSoft/dotnetpelib) 7 | 8 | The library has been tested as the backend for the OCCIL compiler, and is reasonably functional. That said this version of the library does have various limitations; not all aspects of the managed environment are enabled at this time. 9 | 10 | In addition to being able to generate .net programs, version 2.0 of the library has support for importing managed assemblies, and strong names. See 'changelog.txt' for a full description of the changes. 11 | 12 | Version 2.2 of the library introduces read/write of a simple object file format in the familiar object-file-per-module paradigm, along with a linker. 13 | 14 | A simple test program is included which generates several example executables in both IL and EXE format. 15 | 16 | The project files are for Visual Studio 2017 community edition. This source code does use some of the new features in C++11. 17 | 18 | -------------------------------------------------------------------------------- /RSAEncoder.cpp: -------------------------------------------------------------------------------- 1 | /* Software License Agreement 2 | * 3 | * Copyright(C) 1994-2023 David Lindauer, (LADSoft) 4 | * 5 | * This file is part of the Orange C Compiler package. 6 | * 7 | * The Orange C Compiler package is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * The Orange C Compiler package is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Orange C. If not, see . 19 | * 20 | * contact information: 21 | * email: TouchStone222@runbox.com 22 | * 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "RSAEncoder.h" 32 | #include "sha1.h" 33 | #include "bigdigits.h" 34 | #include "limits.h" 35 | 36 | namespace DotNetPELib 37 | { 38 | 39 | Byte PKCS1Formatter::DerHeader[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14}; 40 | 41 | void PKCS1Formatter::Calculate(ByteArray& result) 42 | { 43 | memset(result(), 0xff, result.size()); 44 | result[0] = 0; 45 | result[1] = 1; 46 | int pos = result.size() - 20 - sizeof(DerHeader) - 1; 47 | result[pos] = 0; 48 | memcpy(result() + pos + 1, DerHeader, sizeof(DerHeader)); 49 | memcpy(result() + result.size() - 20, msg_, 20); 50 | // reverse it before encryption.. 51 | for (int i = 0; i < result.size() / 2; i++) 52 | { 53 | int temp = result[i]; 54 | result[i] = result[result.size() - i - 1]; 55 | result[result.size() - i - 1] = temp; 56 | } 57 | } 58 | size_t RSAEncoder::LoadStrongNameKeys(const std::string& file) 59 | { 60 | int rv = 0; 61 | FILE* fil = fopen(file.c_str(), "rb"); 62 | if (fil) 63 | { 64 | static Byte test[] = {0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x32}; 65 | Byte buf[0x14]; 66 | if (fread(buf, 1, 0x14, fil) == 0x14 && !memcmp(buf, test, sizeof(test))) 67 | { 68 | modulusBits = *(int*)(buf + sizeof(test)); 69 | modulus = new Byte[2048]; 70 | privateExponent = new Byte[2048]; 71 | keyPair = new Byte[2048]; 72 | publicExponent = *(DWord*)(buf + sizeof(test) + 4); 73 | if (fread(modulus, 1, modulusBits / 8, fil) == modulusBits / 8) 74 | { 75 | if (!fseek(fil, 5 * modulusBits / 16, SEEK_CUR)) 76 | { 77 | if (fread(privateExponent, 1, modulusBits / 8, fil) == modulusBits / 8) 78 | { 79 | if (!fseek(fil, 0, SEEK_SET)) 80 | { 81 | if (fread(keyPair, 1, modulusBits / 8 + 0x14, fil) == modulusBits / 8 + 0x14) 82 | { 83 | rv = modulusBits / 8; 84 | } 85 | } 86 | } 87 | } 88 | } 89 | } 90 | fclose(fil); 91 | } 92 | return rv; 93 | } 94 | void RSAEncoder::GetPublicKeyData(Byte* key, size_t* keySize) 95 | { 96 | DIGIT_T* dkey = (DIGIT_T*)key; 97 | dkey[0] = 0x2400; 98 | dkey[1] = 0x8004; 99 | dkey[2] = 0x14 + modulusBits / 8; 100 | memcpy(dkey + 3, keyPair, dkey[2]); 101 | ((char*)dkey)[12 + 0x0b] = '1'; // change to RSA1 (pub key only) 102 | ((char*)dkey)[12 + 0] = 6; // change to pub key only 103 | *keySize = dkey[2] + 12; 104 | } 105 | void RSAEncoder::GetStrongNameSignature(Byte* sig, size_t* sigSize, const Byte* hash, size_t hashSize) 106 | { 107 | ByteArray x(modulusBits / 8); 108 | PKCS1Formatter formatter(hash); 109 | formatter.Calculate(x); 110 | mpModExp((DIGIT_T*)sig, (DIGIT_T*)x(), (DIGIT_T*)privateExponent, (DIGIT_T*)modulus, modulusBits / 8 / sizeof(DIGIT_T)); 111 | *sigSize = modulusBits / 8; 112 | } 113 | } // namespace DotNetPELib -------------------------------------------------------------------------------- /RSAEncoder.h: -------------------------------------------------------------------------------- 1 | #include "DotNetPELib.h" 2 | #include "bigdigits.h" 3 | namespace DotNetPELib { 4 | 5 | class ByteArray 6 | { 7 | public: 8 | ByteArray(size_t len) : len_(len), mem_(new Byte[len]) { memset(mem_,0, len_); } 9 | ~ByteArray() 10 | { 11 | memset(mem_, 0, len_); 12 | delete[] mem_; 13 | } 14 | 15 | Byte *operator()() { return mem_; } 16 | const Byte *operator()() const { return mem_; } 17 | Byte &operator[](size_t pos) { return *(mem_ + pos); } 18 | size_t size() { return len_; } 19 | 20 | Byte *begin() { return mem_; } 21 | Byte *end() { return mem_ + len_; } 22 | private: 23 | Byte *mem_; 24 | size_t len_; 25 | }; 26 | // format a message hash into PKCS1 format 27 | // assumes SHA-1 hashing 28 | class PKCS1Formatter 29 | { 30 | public: 31 | PKCS1Formatter(const Byte *msg) : msg_(msg) { } 32 | void Calculate(ByteArray &result); 33 | private: 34 | const Byte *msg_; 35 | static Byte DerHeader[]; 36 | }; 37 | 38 | // Manage SNK file & perform RSA signature 39 | class RSAEncoder 40 | { 41 | public: 42 | RSAEncoder() : modulusBits(0), privateExponent(0), publicExponent(0), keyPair(0), modulus(0) { } 43 | virtual ~RSAEncoder() { 44 | if (privateExponent) 45 | memset(privateExponent, 0, 2048); 46 | if (keyPair) 47 | memset(keyPair, 0, 2048); 48 | if (modulus) 49 | memset(modulus, 0, 2048); 50 | delete [] privateExponent; 51 | delete [] keyPair; 52 | delete [] modulus; 53 | } 54 | size_t LoadStrongNameKeys(const std::string & file); 55 | void GetPublicKeyData(Byte *key, size_t *keySize); 56 | void GetStrongNameSignature(Byte *sig, size_t *sigSize, const Byte *hash, size_t hashSize ); 57 | 58 | //private: 59 | size_t modulusBits; 60 | int publicExponent; 61 | Byte *privateExponent; 62 | Byte *keyPair; 63 | Byte *modulus; 64 | }; 65 | } -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | image: Visual Studio 2022 2 | 3 | build_script: 4 | - ps: "cd ..\\..; move projects\\DotNetPELib .; cd DotNetPELib; .\\ms; cd ..; move DotNetPELib projects" 5 | 6 | artifacts: 7 | - path: "Release\\DotNetPELib.lib" 8 | name: DotNetPELib 9 | - path: "Release\\NetLink.exe" 10 | name: NetLink 11 | - path: "DotNetPELib.h" 12 | name: Header File -------------------------------------------------------------------------------- /bigdigits.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LADSoft/DotNetPELib/8282f8a7ef7bc53ad5f443a9c382ce91d89c3aee/bigdigits.cpp -------------------------------------------------------------------------------- /bigdtypes.h: -------------------------------------------------------------------------------- 1 | /* $Id: bigdtypes.h $ */ 2 | 3 | /***** BEGIN LICENSE BLOCK ***** 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | * 9 | * Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited 10 | * . All rights reserved. 11 | * 12 | ***** END LICENSE BLOCK *****/ 13 | /* 14 | * Last updated: 15 | * $Date: 2016-03-31 09:51:00 $ 16 | * $Revision: 2.6.1 $ 17 | * $Author: dai $ 18 | */ 19 | 20 | #ifndef BIGDTYPES_H_ 21 | #define BIGDTYPES_H_ 1 22 | 23 | #include 24 | 25 | /* 26 | The following PP instructions assume that all Linux systems have a C99-conforming 27 | ; that other Unix systems have the uint32_t definitions in ; 28 | and that MS et al don't have them at all. This version assumes that a long is 32 bits. 29 | Adjust if necessary to suit your system. 30 | You can override by defining HAVE_C99INCLUDES or HAVE_SYS_TYPES. 31 | */ 32 | 33 | #ifndef EXACT_INTS_DEFINED_ 34 | #define EXACT_INTS_DEFINED_ 1 35 | #ifndef HAVE_C99INCLUDES 36 | #if (__STDC_VERSION >= 199901L) || defined(linux) || defined(__linux__) || defined(__APPLE__) 37 | #define HAVE_C99INCLUDES 38 | #endif 39 | #endif 40 | #ifndef HAVE_SYS_TYPES 41 | #if defined(unix) || defined(__unix__) 42 | #define HAVE_SYS_TYPES 43 | #endif 44 | #endif 45 | #ifdef HAVE_C99INCLUDES 46 | #include 47 | #elif defined(HAVE_SYS_TYPES) 48 | #include 49 | #else 50 | #define uint32_t unsigned long 51 | #define uint16_t unsigned short 52 | #define uint8_t unsigned char 53 | #endif /* HAVE_C99INCLUDES */ 54 | #endif /* EXACT_INTS_DEFINED_ */ 55 | 56 | /* Macros for format specifiers 57 | -- change to "u", "x" and "X" if necessary */ 58 | #ifdef HAVE_C99INCLUDES 59 | #include 60 | #else 61 | #define PRIu32 "lu" 62 | #define PRIx32 "lx" 63 | #define PRIX32 "lX" 64 | #endif 65 | /* We define our own 66 | -- Example: ``printf("%" PRIxBIGD "\n", d);`` */ 67 | #define PRIuBIGD PRIu32 68 | #define PRIxBIGD PRIx32 69 | #define PRIXBIGD PRIX32 70 | 71 | #endif /* BIGDTYPES_H_ */ 72 | -------------------------------------------------------------------------------- /docs/Allocator.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - Allocator 6 | 7 | 8 |
Allocator
9 |
10 |

11 | Allocator allocates and manages memory related to the various 12 | constructors used by the objects in DotNetPELib.   13 | When the Allocator object is destroyed, all objects allocated 14 | through it will be destructed and then destroyed.   15 | The main DotNetPELib class PELib 16 | derives from allocator, and may be used interchangeably with it.
17 |
18 | Following is a summary of the supported allocators.   19 | These generally related to constructors on a one to one basis.
20 |
21 |         AssemblyDef 22 | *AllocateAssemblyDef(std::string Name, bool External, Byte 23 | *KeyToken = 0);
24 |
        Namespace 25 | *AllocateNamespace(std::string Name);
26 |
        Class 27 | *AllocateClass(std::string Name, Qualifiers Flags, int Pack, 28 | int Size);
29 |
        Method 30 | *AllocateMethod(MethodSignature *Prototype, Qualifiers flags, 31 | bool entry = false);
32 |
        Field 33 | *AllocateField(std::string Name, Type *tp, Qualifiers Flags);
34 |
        Property 35 | *AllocateProperty(PELib & peLib, std::string name, Type 36 | *type, std::vector<Type *>& indices, bool hasSetter 37 | = true, DataContainer *parent = nullptr);
38 |
        Property 39 | *AllocateProperty();
40 |
        Enum 41 | *AllocateEnum(std::string Name, Qualifiers Flags, 42 | Field::ValueSize Size);
43 |
        Operand 44 | *AllocateOperand();
45 |
        Operand 46 | *AllocateOperand(Value *V);
47 |
        Operand 48 | *AllocateOperand(longlong Value, Operand::OpSize Size);
49 |
        Operand 50 | *AllocateOperand(int Value, Operand::OpSize Size) {
51 |
            52 | return AllocateOperand((longlong)Value, Size);
53 |
        }
54 |
        Operand 55 | *AllocateOperand(unsigned Value, Operand::OpSize Size) {
56 |
            57 | return AllocateOperand((longlong)Value, Size);
58 |
        }
59 |
        Operand 60 | *AllocateOperand(double Value, Operand::OpSize Size);
61 |
        Operand 62 | *AllocateOperand(std::string Value, bool);
63 |
        Operand 64 | *AllocateOperand(std::string Value);
65 |
        Instruction 66 | *AllocateInstruction(Instruction::iop Op, Operand *Operand = 67 | nullptr);
68 |
        Instruction 69 | *AllocateInstruction(Instruction::iop Op, std::string Text);
70 |
        Instruction 71 | *AllocateInstruction(Instruction::iseh type, bool begin, Type *catchType=nullptr);
72 |
        Value 73 | *AllocateValue(std::string name, Type *tp);
74 |
        Local 75 | *AllocateLocal(std::string name, Type *tp);
76 |
        Param 77 | *AllocateParam(std::string name, Type *tp);
78 |
        FieldName 79 | *AllocateFieldName(Field *F);
80 |
        MethodName 81 | *AllocateMethodName(MethodSignature *M);
82 |
        83 | MethodSignature *AllocateMethodSignature(std::string Name, int 84 | Flags, DataContainer *Container);
85 |
        Type 86 | *AllocateType(Type::BasicType Tp, int PointerLevel);
87 |
        Type 88 | *AllocateType(DataContainer *clsref);
89 |
        Type 90 | *AllocateType(MethodSignature *methodref);
91 |
        BoxedType 92 | *AllocateBoxedType(Type::BasicType Tp);
93 |
        Byte 94 | *AllocateBytes(size_t sz);
95 |

96 |
97 |
98 | 99 | 100 | -------------------------------------------------------------------------------- /docs/AssemblyDef.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - AssemblyDef 6 | 7 | 8 |
AssemblyDef
9 |
10 |

11 | Usually one would not construct an AssemblyDef object directly 12 | either through the AssemblyDef class or with the Allocator class.   Instead 14 | the object would be constructed as part of processing in the PELib class, or when loading an external 16 | assembly's members.   But the constructor allows for 17 | giving the AssemblyDef a name, indicating whether it is 18 | external, and setting the public name token.
19 |
20 |         21 | AssemblyDef(std::string Name, bool External, Byte * KeyToken = 22 | nullptr) ;
23 |
24 |
It is possible to set version info for an assembly.  25 | Usually, one wouldn't explicitly set the version except on the 26 | assembly for which code is being generated, as it would be 27 | loaded from the assembly's file.
28 |
29 |         void 30 | SetVersion(int major, int minor, int build, int revision);
31 |
32 |
Assigning an SNK file sets strong name key signing into 33 | motion.   If the file is valid, the generated assembly 34 | will be signed.
35 |
36 |
37 |
38 |         const std::string& 39 | SNKFile() const { return snkFile_; }

40 |
        void 41 | SNKFile(std::string file) { snkFile_ = file; }
42 |
43 |
If you have a referencer to an assembly, you can look up a class 44 | within that assembly
45 |
46 |
        Class 47 | *LookupClass(PELib &lib, std::string nameSpace, std::string 48 | name);
49 |
                50 |
51 |
It is possible to get the custom attributes associated with an 52 | assembly, in order to examine them if necessary.   At 53 | present it is not possible to add custom attributes to a generated 54 | assembly.
55 |
56 |         const 57 | CustomAttributeContainer &CustomAttributes() const { return 58 | customAttributes_;  }
59 |
60 |
The following function returns true if this is an external 61 | assembly (usually a loaded assembly such as mscorlib).  It 62 | returns false if it is the assembly being generated.
63 |
64 |         virtual bool 65 | InAssemblyRef() const { return external_; }
66 |

67 | 68 | 69 | -------------------------------------------------------------------------------- /docs/BoxedType.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - BoxedType 6 | 7 | 8 |
BoxedType
9 |
10 |

11 | BoxedType derives from Type. It 12 | represents the boxed version of a basic value type such as 13 | System::Int32 instead of int32.   The boxed version is 14 | basically a class that derives from System::Object; it is useful 15 | when a simple type needs to be treated more like a class object. 16 | (for example when placed into an array of objects).
17 |
18 | The only useful thing to do with a BoxedType is to construct 19 | it.   It may be constructed either directly or through 20 | an Allocator object.
21 |
22 |         23 | BoxedType(BasicType Tp)
24 |

25 |        
26 |
27 |
28 |
29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /docs/Class.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - Class 6 | 7 | 8 |
Class
9 |
10 |
The Class object holds the declaration for a 11 | .Net class.   A class can be an Enumeration, in fact 12 | the Enum object derives from 13 | Class.   The Class object derives from the DataContainer object, which 15 | allows it to hold Method objects, Field objects, and other Class or Enum 17 | objects.   Additionally, a class object may hold Property objects.   Note 19 | that classes may NOT contain namespaces or assemblies.
20 |
21 | The constructor may be called either directly or through the Allocator object.   It 23 | takes a name, qualifiers such as whether the class is static or 24 | a value type, a packing value, and the size of the 25 | object.   If the pack value and size of the object are 26 | both set to -1, these attributes will not be generated for the 27 | class.
28 |
29 |         Class(std::string 30 | Name, Qualifiers Flags, int Pack, int Size);
31 |
32 |
The pack value and size value may be independently set for 33 | the class.   Note that if either is set to a 34 | non-negative value, the PE file will have an entry which sets 35 | both anyway.
36 |
37 |
        void pack(int 38 | pk) { pack_ = pk; }
39 |
        void size(int 40 | sz) { size_ = sz; }
41 |
42 |
Classes always extend other classes in .Net.   If 43 | an extendsFrom class is not selected, the library will choose 44 | one of the classes System.ValueType, System.Enum, or 45 | System.Object based on whether the class is an enumeration and 46 | the Qualifier flags.
47 |
48 |         void 49 | Extends(Class *extendsFrom) { extendsFrom_ = extendsFrom; }
50 |
51 |
One can add or view class properties.  Methods and 52 | Fields are managed through the underlying DataContainer object.
53 |
54 |         void Add(Property 55 | *property);

56 |
        const 57 | std::vector<Property *>& Properties() const { return 58 | properties_;  }
59 |
60 |
To set the fact that a class reference is to be an external reference 61 | for purpose of the object file, use
62 |
63 |         bool External() const; 64 |

65 | 66 |         void External(bool external); 67 |

68 | It is possible to traverse the members of a 69 | class.   Normally though, one would start the 70 | traversal process by calling the related PELib 71 | traverse function, which would traverse every object known to the 72 | library.
73 |
74 |         virtual bool 75 | Traverse(Callback &callback) const override;
76 |

77 |
78 |
79 | 80 | 81 | -------------------------------------------------------------------------------- /docs/CodeContainer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - CodeContainer 6 | 7 | 8 |
CodeContainer
9 |
10 |

11 | CodeContainers hold the body of Method 12 | objects,  e.g. a list of Instruction 13 | objects (including labels), along with any Operand object required by each 15 | instructions.
16 |
17 | Code containers are usually constructed as part of the 18 | destruction of the derived class Method, and the constructor 19 | will not be accessed by user code.   It does however 20 | allow setting of standard CIL flags.
21 |
22 |         23 | CodeContainer(Qualifiers Flags) :flags_(Flags);
24 |
25 |
An instruction may be added to the end of the container.
26 |
27 |
        void 28 | AddInstruction(Instruction *instruction);
29 |

30 |
Sometimes it is interesting to examine or remove the last 31 | instruction generated.
32 |
33 |         Instruction 34 | *RemoveLastInstruction();

35 |
        Instruction 36 | *LastInstruction() const;
37 |
38 |
39 |
40 |
When the instructions have been generated, one 41 | can validate them directly, or one can wait to call 42 | Method::Optimize(), which will validate them.   43 | Validation may throw a PELibError 44 | exception, with information about what is wrong.   45 | Presently the CodeContainer will throw exceptions for misuse 46 | of labels, and Param and Local object indexes out of range for 48 | the instruction in use.   Method::Optimize will also 49 | check that the stack remains balanced though.
50 |
51 |
52 |         void 53 | ValidateInstructions();
54 |
55 |         void 56 | ValidateSEH();
57 |
58 |
The CIL qualifiers may be examined or modified.
59 |
60 |         Qualifiers 61 | &Flags() { return flags_; }
62 |
        const 63 | Qualifiers &Flags() const { return flags_; }
64 |
65 |
The parent container may be examined or set.   66 | Normally, the set would take place automatically when the Method 67 | is added to an AssemblyDef, Class or Namespace. 69 | This is done in the DataContainer 70 | interface.
71 |
72 |         void 73 | SetContainer(DataContainer *parent) { parent_ = parent; }

74 |
        DataContainer 75 | *GetContainer() const { return parent_; }
76 |

77 |
78 |
79 | 80 | 81 | -------------------------------------------------------------------------------- /docs/CustomAttributeContainer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - CustomAttributeContainer 6 | 7 | 8 |
CustomAttributeContainer
9 |
10 |
11 |
A CustomAttributeContainer is associated with 12 | each loaded assembly.  It contains a list of 13 | CustomAttributeDescriptors.  The CustomAttributeDescriptor 14 | holds information about an attribute and looks as follows:
15 |
16 |         class 17 | CustomAttributeDescriptor
18 |
        {
19 |
        public:
20 |
            21 | 22 | std::string name; // name of custom attribute
23 |
            24 | 25 | Byte *data; // data
26 |
            27 | 28 | size_t sz; // size of data
29 |
        };
30 |

31 | CustomAttributeContainers will never be constructed by a user in 32 | this version of the library.  
33 |
34 | Two accessors exist to locate an attribute.   They use 35 | a class defined by PEFile.h which gives information about  36 | the attribute.  
37 |
38 | Lookup is used to get the CustomAttributeDescriptor data.  39 | In case you don't need to know the data or want to see if 40 | specific data exists, the Has function may be used.
41 |
42 |         const 43 | std::vector<CustomAttributeDescriptor *>& 44 | Lookup(CustomAttribute *attribute) const;
45 |
        bool 46 | Has(CustomAttribute &attribute, std::string name,  47 | Byte *data = nullptr, size_t sz = 0) const;
48 |

49 | Note that on load DotNetPELib will automatically check to see if 50 | SystemParamArrayAttribute is set for the last parameter in any 51 | parameter list, and if so set the VARARG flag in the associated 52 | MethodSignature.   53 | The reverse direction works as well; the attribute will be set 54 | for managed methods if the Method flags in include 'vararg'.
55 |
56 |
57 | 58 | 59 | -------------------------------------------------------------------------------- /docs/DataContainer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - DataContainer 6 | 7 | 8 |
DataContainer
9 |
10 |

11 | The data container is the base class for the various classes 12 | that can hold other things.   It can hold other 13 | datacontainers, methods, or fields.   Note that 14 | depending on the type of DataContainer, there may be limits as 15 | to what other DataContainer types may be held.
16 |
17 | DataContainers will never be directly constructed; the derived 18 | class will call it as part of its own construction.   19 | However the derived class may be user-generated when 20 | constructing an assembly.
21 |
22 |         23 | DataContainer(std::string Name, Qualifiers Flags);
24 |

25 | Add another data container such as a Class 26 | or Namespace.
27 |
28 |         void 29 | Add(DataContainer *item);
30 |

31 | Add a Method to this data container.
32 |
33 |         void 34 | Add(CodeContainer *item);
35 |
36 |
Add a Field to this data 37 | container.
38 |
39 |         void 40 | Add(Field *field);
41 |

42 |
Not currently used.
43 |
44 |         bool 45 | IsInstantiated() const { return instantiated_; }
46 |
        void 47 | SetInstantiated() { instantiated_ = true; }
48 |
49 |
Get the parent container.   A Class, Namespace, or 50 | AssemblyDef object.
51 |
52 |         53 | DataContainer *Parent() const { return parent_; }
54 |
55 |
Get the name or CIL flags
56 |
57 |         const std::string 58 | &Name() const { return name_; }

59 |
        Qualifiers 60 | Flags() const { return flags_; }
61 |
62 |
Utilities to find a subcontainer.  Usually called 63 | indirectly from the PELib object.
64 |
65 |         66 | DataContainer *FindContainer(std::string name) { return 67 | sortedChildren_[name]; }
68 |
        DataContainer 69 | *FindContainer(std::vector<std::string>& split, 70 | size_t &n);
71 |
72 |
Get a list of fields or methods.
73 |
74 |         const 75 | std::list<Field *>&Fields() { return fields_; }
76 |
        const 77 | std::list<CodeContainer *>&Methods() { return 78 | methods_; }
79 |

80 |
Traverse the items in this container.  Usually not 81 | called directly; calles as a result of calling Traverse on the 82 | PELib object.
83 |
84 |         virtual bool 85 | Traverse(Callback &callback) const;
86 |
87 |
Returns true if this is in an 'extern' assembly (usually 88 | loaded)
89 |
90 |         virtual 91 | bool InAssemblyRef() const { return 92 | parent_->InAssemblyRef(); }
93 |

94 |
95 |
96 | 97 | 98 | -------------------------------------------------------------------------------- /docs/Enum.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - Enum 6 | 7 | 8 |
Enum
9 |
10 |

11 |
12 |
13 | An enum is a helper object which basically handles augmenting a 14 | basic class with the elements needed for C# to consider the class as 15 | a list of enumeration constants.   A field in an 16 | enumeration usually has the qualifiers 'static' and 'literal'
17 |
18 | The enumerator would be constructed either directly or by calling 19 | its destructor on the Allocator 20 | object.   Here Size gives the size of the enumeration e.g. 21 | 8 bits, 16 bits, 32 bits, 64 bits...
22 |
23 |         enum ValueSize { i8, 24 | i16, i32, i64 };
25 |         Enum::Enum(std::string 26 | Name, Qualifiers Flags, Field::ValueSize Size) ;
27 |
28 |
AddValue is a helper which completely generates an enumeration 29 | value.
30 |
31 |         void 32 | AddValue(Allocator &allocator, std::string Name, longlong 33 | Value);
34 |

35 | 36 | 37 | -------------------------------------------------------------------------------- /docs/Field.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - Field 6 | 7 | 8 |
Field
9 |
10 |
A Field is a member of a Class 11 | object which holds data.   Fields may also be members 12 | of Enum objects, but this is usually 13 | handled in the background by DotNetPELib.   In some 14 | cases, it is possible to generate a field directly into an AssemblyDef object, however, such 16 | fields cannot be accessed from other assemblies.
17 |
18 | A Field would be constructed either directly, or through the Allocator object.   It 20 | might also be constructed indirectly, when constructing an 21 | enumerated value with functions in the Enum 22 | object.   All fields have a Type 23 | indicating what sort of data is stored in the Field.
24 |
25 |         26 | Field::Field(std::string Name, Type *tp, Qualifiers Flags) ;
27 |

28 | A field can have a value.   Usually, an enumerated 29 | value would be added through calls in the Enum 30 | object.   Other types of binary initializers may be 31 | added; for example occil uses initialization values to support 32 | constant strings in the C language.  Initializer values are 33 | currently stored in managed memory (Older versions of the 34 | library stored them in unmanaged memory).
35 |
36 |         enum ValueSize { 37 | i8, i16, i32, i64 };
38 |         void 39 | AddEnumValue(longlong Value, ValueSize Size);

40 |
        void 41 | AddInitializer(Byte *bytes, int len);
42 |
43 |
Get the name of the field.
44 |
45 |
        const 46 | std::string &Name() const { return name_; }
47 |
48 |
Get/Set the name of the parent class.   It is 49 | usually set automatically when the Field is added to the Class.
50 |
51 |         void 52 | SetContainer(DataContainer *Parent) { parent_ = Parent; }

53 |
        DataContainer 54 | *GetContainer() const { return parent_; }
55 |
56 |
Get/Set the field's type.
57 |
58 |         Type 59 | *FieldType() const { return type_; }
60 |
        void 61 | FieldType(Type *tp) { type_ = tp; }
62 |
63 |
Get the CIL qualifiers
64 |
65 |         const 66 | Qualifiers &Flags() const { return flags_; }
67 |
68 |
Not currently used.
69 |
70 |         void 71 | Ref(bool Ref) { ref_ = Ref; }
72 |
        bool 73 | IsRef() const { return ref_; }
74 |
75 |
Get/set the 'external' flag (used by the linker)
76 |
77 |         void 78 | External(bool external) { external_ = External; }
79 |
        bool 80 | External() const { return external_; }
81 |
82 |
Get/Set the field's .NET explicit offset.   For 83 | example set the class qualifiers to 'explicit' and then set all 84 | its fields to an explicitOffset of zero to make a 85 | union.   explicitOffsets may also be used for 86 | 'sequential' classes.
87 |
88 |         void 89 | ExplicitOffset(size_t offset) { explicitOffset_ = offset;}
90 |
        size_t 91 | ExplicitOffset() const { return explicitOffset_; }
92 |

93 |
94 |
95 | 96 | 97 | -------------------------------------------------------------------------------- /docs/FieldName.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - FieldName 6 | 7 | 8 |
FieldName
9 |
10 |

11 |
12 |
13 | A FieldName is a kind of Value that may be 14 | used as an Operand to an Instruction.  It references a Field definition.   It may be used 17 | in an Operand to an Instruction.   It lets the 19 | Instruction reference a member of a Class.   20 | 21 | Note that fields may also be placed directly in an AssemblyDef, the FieldName would be 23 | used to reference those as well.
24 |
25 | A FieldName may be constructed either directly or through the Allocator object.
27 |
28 |         FieldName(Field *F);
29 |

30 |
It is possible to get the field reference.
31 |
32 |
        Field *GetField() 33 | const { return field_; }
34 |

35 | 36 | 37 | -------------------------------------------------------------------------------- /docs/Instruction.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - Instruction 6 | 7 | 8 |
Instruction
9 |
10 |

11 | An Instruction is placed in a Method, 12 | as part of the definition of the runtime behavior of the 13 | method.   Instructions have various types of Operands, which modify the behavior of 15 | the instruction.
16 |
17 | Each MSIL instruction has an enumerated name, formed by adding 18 | i_ at the front and replacing dots with underscores.
19 |
20 | For example:
21 |
22 |     add becomes i_add
23 |     ldc.i4.4 becomes i_ldc_i4_4
24 |
25 | there are three special instructions
26 |
27 |             28 | 29 | 30 | i_label,    // puts a label at this point in the 31 | instruction stream
32 |             33 | 34 | 35 | i_comment, // puts a comment at this point in the instruction 36 | stream
37 |             38 | 39 | 40 | i_seh,    // puts an SEH region boundary at his point 41 | in the module code.
42 |
43 | The instruction may be constructed either directly or through an 44 | Allocator object.    45 | The first form of the constructor creates a generic instruction, 46 | including a label.   The second form embeds a comment 47 | into the .IL source file.  The third form embeds an SEH boundary. 48 | Note that the complete list of instructions as listed in ECMA-335 49 | is available for use.
50 |
51 |         Instruction(iop 52 | Op, Operand *Operand);
53 |
        54 | Instruction(iop Op, std::string Text);
55 |
        56 | Instruction(iseh type, bool begin, Type *catchType);
57 |

58 |
Access the opcode
59 |
60 |         iop OpCode() const 61 | { return op_; }
62 |
        void 63 | OpCode(iop Op) { op_ = Op; }
64 |
65 |
Add a lable to a 'switch' instruction.  Labels must be 66 | added in order.
67 |
68 |         void 69 | AddCaseLabel(std::string label);
70 |
71 |
Get the list of switch labels
72 |
73 |         74 | std::list<std::string> * GetSwitches() { return 75 | switches_; }
76 |
77 |
Get an operand for instructions that don't require an 78 | operand.
79 |
80 |         void 81 | NullOperand(Allocator &allocator);
82 |
83 |
Retrieve the operand.
84 |
85 |         Operand 86 | *GetOperand() const { return operand_; }
87 |
88 |
Retrieve the comment text.
89 |
90 |
        std::string 91 | Text() const { return text_; }
92 |
93 |
Retrieve any label associated with the 94 | instruction.   Note that labels are strings in this 95 | implementation (they are converted to offsets when generating 96 | CIL code).
97 |         std::string 98 | Label() const;
99 |
100 |
Retrieve the size of the instruction.
101 |
102 |         int 103 | InstructionSize();
104 |
105 |
Retrieve the stack usage of the instruction.   0 = 106 | no effect, >0 = stack grows, <0 = stack shrinks
107 |
108 |         int StackUsage();
109 |

110 |
111 |
112 | 113 | 114 | -------------------------------------------------------------------------------- /docs/Local.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - Local 6 | 7 | 8 |
Local
9 |
10 |

11 |
12 |
13 | Local is a type Value that may be used as 14 | an Operand.   It describes 15 | access to a local variable.   Local variables are used 16 | inside of Methods.
17 |
18 | The only useful thing to do with a local is construct it, either 19 | directly or through the Allocator 20 | object.
21 |
22 |         Local(std::string 23 | Name, Type *Tp);
24 |

25 | Note that local variables are optimized - they are allocated in the 26 | order starting with most used first.   This allows more 27 | optimal forms of the instructions to be generated for variables that 28 | are more heavily used.
29 |
30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/Method.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - Method 6 | 7 | 8 |
Method
9 |
10 |

11 |
12 |
13 | A Method is the container for code.   It inherits from CodeContainer, to hold the 15 | instructions in the function, and holds a MethodSignature which defines the 17 | function's signature.   It also holds a list of local 18 | variables.   A method is usually stored in a class, but 19 | can be stored in an AssemblyDef as 20 | well if it isn't needed outside the assembly.
21 |
22 | The Method may be constructed either directly or through the Allocator object.   Prior to 24 | constructing it a MethodSignature must be constructed.   25 | Note that 'entry' is set to true for the entry point of the 26 | module.   An entry point is not needed for DLL files.
27 |
28 |         Method(MethodSignature 29 | *Prototype, Qualifiers flags, bool entry = false);
30 |

31 | The method may be a PInvoke Method.   These methods don't 32 | have a body, but reference an external DLL and give a calling 33 | convention to call unmanaged code.
34 |
35 |         enum InvokeType { 36 | Cdecl, Stdcall };
37 |
38 |
        void 39 | SetPInvoke(std::string name, InvokeType type = Stdcall);

40 |
        bool IsPInvoke() 41 | const { return invokeMode_ == PInvoke; }
42 |
43 |
Add a local variable
44 |
45 |         void AddLocal(Local 46 | *local);
47 |

48 |
Whether the Method needs a this pointer.
49 |
50 |         void Instance(bool 51 | instance);
52 |
        bool Instance() { 53 | return !!(Flags().Value & Qualifiers::Instance); }
54 |
55 |
Method signature
56 |
57 |         58 | MethodSignature *Signature() const { return prototype_; }
59 |

60 |
Iterate through the local variables
61 |
62 |         typedef 63 | std::vector<Local *>::iterator iterator;

64 |
        iterator begin() { 65 | return varList_.begin(); }
66 |
        iterator end() { 67 | return varList_.end(); }
68 |
        size_t size() 69 | const { return varList_.size(); }
70 |

71 |
Validate and optimize the MSIL code.   Throw a PELibError exception if any problems 73 | are found.
74 |
75 |         virtual void 76 | Optimize(PELib &) override;
77 |
78 |
Determine if the method is an entry point.
79 |
80 |         bool 81 | HasEntryPoint();
82 |
83 |

84 | 85 | 86 | -------------------------------------------------------------------------------- /docs/MethodName.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - MethodName 6 | 7 | 8 |
MethodName
9 |
10 |

11 |
12 |
13 | MethodName is a type of Value that may be 14 | used in an Operand to an Instruction.   It references 16 | a MethodSignature.
17 |
18 | The MethodName may be constructed either directly or through the Allocator object.  It requires that 20 | a MethodSignature be constructed first.
21 |
22 |         23 | MethodName(MethodSignature *M);
24 |

25 | It is possible to retrieve the MethodSignature.
26 |
27 |         MethodSignature 28 | *Signature() const { return signature_; }
29 |

30 | 31 | 32 | -------------------------------------------------------------------------------- /docs/MethodSignature.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - MethodSignature 6 | 7 | 8 |
MethodSignature
9 |
10 |

11 |
12 |
13 | A MethodSignature holds the interface through which a method is 14 | known.  It holds things such as the return Type 15 | and a list of Param objects.
16 |
17 | The methodsignature may have a variable length argument list.  18 | In managed terms this means it has a final parameter of type 19 | System.Object[] to hold the variable length arguments.   20 | When an unmanaged function is called that has variable length 21 | argument list, the call site for the call needs to fully qualify the 22 | types of the specific arguments being used (for marshalling 23 | purposes).   A second list of Param objects is used to 24 | list them out.   Given the two param lists and the fact 25 | that it is a VARARG function, DotNetPELib will automatically 26 | transcribe the results as necessary for the given output type.
27 |
28 | The MethodSignature may be constructed either directly, or through 29 | the Allocator object.   Flags indicates whether it is a 30 | vararg method, an instance method, a managed method
31 |
32 |         enum { Vararg = 1, 33 | Managed = 2, InstanceFlag = 4 };
34 |
35 |
        36 | MethodSignature(std::string Name, int Flags, DataContainer 37 | *Container);
38 |
39 |
Access the return type.
40 |
41 |
        Type 42 | *ReturnType() const { return returnType_; }
43 |
        void 44 | ReturnType(Type *type)
45 |
46 |
Add a parameter.   This function only successfully 47 | adds a parameter if the variable length argument parameter list 48 | hasn't been started; otherwise it throws PELibError.
49 |
50 |         void 51 | AddParam(Param *param)
52 |
53 |
Add a parameter to he variable length parameter list.
54 |
55 |         void 56 | AddVarargParam(Param *param);
57 |
58 |
This is used to associate a call site definition for an 59 | unmanaged function with Variable Lenth argument list with the main 60 | prototype.
61 |
62 |         void 63 | SignatureParent(MethodSignature *parent) { methodParent_ = parent; 64 | }
65 |
        MethodSignature 66 | *SignatureParent() { return methodParent_; }
67 |
68 |
Access the container this signature goes with.
69 |
70 |         void 71 | SetContainer(DataContainer *container) { container_ = container; }

72 |
        DataContainer 73 | *GetContainer() const { return container_; }
74 |
75 |
Access the signature's Method name
76 |
77 |         const std::string 78 | &Name() const { return name_; }

79 |
        void 80 | SetName(std::string Name) { name_ = Name; }
81 |
82 |
Internal use: support signatures for multidimensional array 83 | helper functions
84 |
85 |        void ArrayObject(Type *tp) { 86 | arrayObject_ = tp; }
87 |
88 |
Iterate through the parameter list
89 |
90 |         typedef 91 | std::list<Param *>::iterator iterator;

92 |
        iterator begin() { 93 | return params.begin(); }
94 |
        iterator end() { 95 | return params.end(); }
96 |

97 |
Iterate through the variable length post-parameter list
98 |
99 |         typedef 100 | std::list<Param *>::iterator viterator;

101 |
        iterator vbegin() 102 | { return varargParams_.begin(); }
103 |
        iterator vend() { 104 | return varargParams_.end(); }
105 |
106 |
Access whether it has a this pointer
107 |
108 |        void Instance(bool instance) 109 |

110 |
        bool Instance() 111 | const { return !!(flags_ & InstanceFlag); }
112 |
113 |
Set the vararg flag for varargs
114 |
115 |         void SetVarargFlag() { 116 | flags_ |= Vararg; }

117 |

118 |
Get the vararg, managed, and instance flags
119 |
120 |         int Flags() const { 121 | return flags_; }
122 |
123 |
Access param counts.
124 |
125 |         size_t ParamCount() 126 | const { return params.size(); }

127 |
        size_t 128 | VarargParamCount() const { return varargParams_.size(); }
129 |

130 |
Internal function, can be used to match the main Param list to a 131 | list of types.
132 |
133 |         bool 134 | Matches(std::vector<Type *> args);
135 |

Get/set the 'external' flag (used by the linker)
136 |
137 |         void 138 | External(bool external) { external_ = External; }
139 |
        bool 140 | External() const { return external_; }
141 |
142 |

143 | 144 | 145 | -------------------------------------------------------------------------------- /docs/Namespace.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - Namespace 6 | 7 | 8 |
Namespace
9 |
10 |

11 | Namespaces are the first group of containers that may be stored 12 | in an AssemblyDef.   13 | They may hold other Namespaces, or Class and 14 | Enum objects.  Namespace inherits 15 | from DataContainer.
16 |
17 | Namespaces may be constructed directly, or through the Allocator object.
19 |
20 |         21 | Namespace::Namespace(std::string Name);
22 |
23 |
Get the qualified name of the Namespace.
24 |
25 |
        std::string 26 | ReverseName(DataContainer *child);
27 |

28 |
29 |
30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/Operand.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - Operand 6 | 7 | 8 |
Operand
9 |

10 | An Operand is a qualifier to an instruction.   It 11 | might hold a numeric or string value, or a reference to some 12 | other CIL entity such as a Type, a FieldName, or a Local reference.   It is 15 | usually specified for use in the constructor for an Instruction.
17 |
18 |
19 | Literal values need to have a size specified.
20 |
21 |         enum OpSize { any, 22 | i8, u8, i16, u16, i32, u32, i64, u64, inative, r4, r8 };
23 |

24 | An operand may be constructed either directly or through an Allocator object.   There 26 | are several constructors to create different types of Operands.
27 |
28 | Constructor for a null operand
29 |
30 |         Operand::Operand() 31 | ;
32 |

33 | Constructor for an operand with a value that derives from Value, 34 | for example a Local or Param
35 |
36 |         37 | Operand::Operand(Value *V) :
38 |

39 |
Various constructors for integer values
40 |
41 |
        42 | Operand::Operand(longlong Value, OpSize Size)
43 |
        44 | Operand::Operand(int Value, OpSize Size)
45 |
        46 | Operand::Operand(unsigned Value, OpSize Size)
47 |
48 |
Constructor for a floating point value.
49 |
50 |
        51 | Operand::Operand(double Value, OpSize Size)
52 |
53 |
Constructor for a string value.  The operand is there 54 | purely to distinguish between this and the 'label' constructor.
55 |  
56 |
        57 | Operand(std::string Value, bool)
58 |
59 |
Constructor for a label.
60 |
61 |         62 | Operand(std::string Value)
63 |

64 |
Various getters to get operand values.
65 |
66 |         OpType 67 | OperandType() const { return type_; }
68 |
        Value * 69 | GetValue() const { return type_ == t_value ? refValue_ : 70 | nullptr; }
71 |
        longlong 72 | IntValue() const { return intValue_; }
73 |
        std::string 74 | StringValue() const { return stringValue_; }
75 |
        double 76 | FloatValue() const { return floatValue_; }
77 |

78 |
79 |
80 | 81 | 82 | -------------------------------------------------------------------------------- /docs/PELibError.html: -------------------------------------------------------------------------------- 1 | * 2 | 3 | 4 | 5 | 6 | DotNetPELib - PELibError 7 | 8 | 9 |
PELibError
10 |
11 |
PELibError is the name of an exception that can 12 | be thrown, usually during validation of MSIL code.   13 | For example calling Method::Optimize will validate the code, 14 | which may throw this exception.   The possible errors 15 | are:
16 |
17 |         enum ErrorList
18 |         {
19 |             20 | ///** More params are being aded after a vararg param has been 21 | added
22 |             23 | VarargParamsAlreadyDeclared,
24 |             25 | ///** If calculations show that the stack would underflow 26 | somewhere in the method
27 |             28 | StackUnderflow,
29 |             30 | ///** A label can be reached but the paths don't agree on how 31 | many
32 |             33 | // things are currently on the stack
34 |             35 | MismatchedStack,
36 |             37 | ///** The stack is unbalanced when the RET statement is hit
38 |             39 | // This can mean either that there are elements on the stack in
40 |             41 | // a function that has no return value, or there is not exactly 42 | '
43 |             44 | //one element on the stack when the function has a return value.
45 |             46 | StackNotEmpty,
47 |             48 | ///** A label has been defined twice
49 |             50 | DuplicateLabel,
51 |             52 | ///** A label that has been referenced was not found
53 |             54 | MissingLabel,
55 |             56 | ///** the short version of some branch was requested, but the 57 | target
58 |             59 | // is out of range.
60 |             61 | ShortBranchOutOfRange,
62 |             63 | ///** the short version of an instruction which references a
64 |             65 | // local variable or a parameter was referenced, but the index 66 | is out
67 |             68 | // of range
69 |             70 | IndexOutOfRange,
71 |             72 | ///** There are multiple entry points
73 |             74 | MultipleEntryPoints,
75 |             76 | ///** There is no entry point (note that if it is a DLL an entry 77 | point isn't needed)
78 |             79 | MissingEntryPoint
80 |             81 | ///** Expected this tag to be 'try' begin
82 |             83 | Expected SEH Try,
84 |             85 | ///** Expected an SEH block other than 'try'
86 |             87 | Expected SEH handler,
88 |             89 | ///** An end tag didn't match the begin tag
90 |             91 | MismatchedSEHTag,
92 |             93 | ///** an SEH begin tag has no corresponding end tag, or an end is out of sequence
94 |             95 | OrphanedSEHTag,
96 |             97 | ///** The filter expression is in an invalid place
98 |             99 | InvalidSEHFilter,
100 |             101 | ///** leave, or endfinally/endfault/endfilter not used correctly
102 |             103 | InvalidSEHEpilogue,
104 |     };
105 |
106 | 107 |
108 | Note that the SEH validity checking does not 109 | check whether incorrect combinations of handler blocks are listed 110 | for a single try. 111 |
112 |
113 | 114 | 115 | -------------------------------------------------------------------------------- /docs/Param.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - Param 6 | 7 | 8 |
Param
9 |
10 |

11 |
12 |
13 | Param is a type of Value which may be used 14 | as an Operand to an Instruction.   It is also 16 | used in MethodSignatures to 17 | define the method parameters.
18 |
19 | The only thing useful to be done with a Param is to construct it for 20 | use with another object.   It may be constructed either 21 | directly or through an Allocator 22 | object.
23 |
24 |         Param(std::string 25 | Name, Type *Tp) : Value(Name, Tp), index_(-1) { }
26 |

27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/Property.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - Property 6 | 7 | 8 |
Property
9 |
10 |
A Property is similar to a Field.  11 | 12 | However, instead of holding a place to store data, it holds 13 | functions that are used to set and retrieve the 14 | data.   This way, some operation may be performed on 15 | the data before it is stored or retrieved, or multiple data 16 | fields may be kept in sync automatically simply by referencing 17 | the property.   A property is always a member of a 18 | class; it may not be stored directly in an assembly.
19 |
20 | While properties can have variably long argument lists which can 21 | be used to 'index' the property, the normal case is that the 22 | function which 'gets' the value takes no arguments and returns a 23 | value of the appropriate type.   The function which 24 | 'sets' the value takes one argument, which is the value to set.
25 |
26 | Generally, once a property is defined it can be treated like a 27 | field, except that instead of using LDFLD/LDSFLD STFLD/STSFLD to 28 | store and load the data, one would call the appropriate getter 29 | or setter.   The Property object will create these 30 | calls, and has functions for generating the call instructions.
31 |
32 |
33 | The Property object may be constructed either directly or 34 | through an Allocator 35 | object.   In the normal case one would pass an empty 36 | vector for the 'indices' parameter.
37 |
38 |         Property(PELib 39 | &peLib, std::string name, Type *type, std::vector<Type 40 | *>& indices, bool hasSetter = true);
41 |

42 |
Set the parent container.  Usually done automatically 43 | when the Property is added to a class.
44 |
45 |
        void 46 | SetContainer(DataContainer *parent, bool add = true);
47 |
48 |
Access whether or not this is a static property.
49 |
50 |         void Instance(bool 51 | instance);

52 |
        bool 53 | Instance() const { return instance_;  }
54 |
55 |
Get the property name.
56 |
57 |         const 58 | std::string &Name() const { return name_; }
59 |

60 | Access the type of the data the property represents
61 |
62 |         void 63 | SetType(Type *type) { type_ = type;  }
64 |
        Type 65 | *GetType() const { return type_;  }
66 |
67 |
Call the property's getter.   One should push the 68 | class instance on the stack first if this is not a static 69 | property.
70 |
71 |         void CallGet(PELib 72 | &peLib, CodeContainer *code);
73 |
74 |
Call the property's setter.   One should 75 | optionally push the class instance on the stack, then push the 76 | data to be set
77 |         void 78 | CallSet(PELib &peLib, CodeContainer *code);
79 |

80 |
Retrieve the getter or setter functions.   When 81 | creating a property this is necessary so that you can add code 82 | to these functions.
83 |
84 |         Method 85 | *Getter() { return getter_;  }
86 |
        Method 87 | *Setter() { return setter_;  }
88 |

89 |

90 |
 
91 |
92 |
93 | 94 | 95 | -------------------------------------------------------------------------------- /docs/Qualifier.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - Qualifier 6 | 7 | 8 |
9 |
Qualifier
10 |
11 |

12 |
13 |
14 | The Qualifier class holds standard qualifiers for CIL 15 | objects.   It is used by other objects to set the 16 | environment in which CIL objects will be created.
17 |
18 | Here is a list of supported qualifiers:
19 |
20 |             21 | Public = 0x1,
22 |             23 | Private = 0x2,
24 |             25 | Static = 0x4,
26 |             27 | Instance = 0x8,
28 |             29 | Explicit = 0x10,
30 |             31 | Ansi = 0x20,
32 |             33 | Sealed = 0x40,
34 |             35 | Enum = 0x80,
36 |             37 | Value = 0x100,
38 |             39 | Sequential = 0x200,
40 |             41 | Auto = 0x400,
42 |             43 | Literal = 0x800,
44 |             45 | HideBySig = 0x1000,
46 |             47 | PreserveSig = 0x2000,
48 |             49 | SpecialName = 0x4000,
50 |             51 | RTSpecialName = 0x8000,
52 |             53 | CIL = 0x10000,
54 |             55 | Managed = 0x20000
56 |
57 | The qualifier objects usually aren't constructed but are kept as 58 | direct members of other objects.   They are often 59 | specified in object constructors.
60 |
61 |
62 | GetName() is a function that creates the fully qualified ILASM name 63 | for an entity.
64 |
65 |         static std::string 66 | GetName(std::string root, DataContainer *parent, bool type = 67 | false);
68 |
 
69 | Accessors for the actual flags held by this object
70 |
71 |         int Flags() const { return 72 | flags_; }
73 |
        void Flags(int 74 | flags) { flags_ = flags;  }
75 |

76 | 77 | 78 | -------------------------------------------------------------------------------- /docs/SEH.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - SEH 6 | 7 | 8 |
SEH Blocks
9 |
10 |

11 | SEH blocks are the .NET methodology for storying information about 12 | try--catch or try--catch--finally sequences. (fault and filter are 13 | also supported). To support SEH, one makes region boundaries in the 14 | method body. Each region has a beginning and an ending, and regions may 15 | be nested to allow for nesting of try--catch blocks. A region boundary 16 | is created with a special form of the Instruction 17 | object constructor and added to a method.

18 | 19 |         enum iseh {
20 |
            21 | 22 | 23 | seh_try,
24 |
            25 | 26 | 27 | seh_catch,
28 |
            29 | 30 | 31 | seh_filter,
32 |
            33 | 34 | 35 | seh_fault,
36 |
            37 | 38 | 39 | seh_finally,
40 |
        };
41 |

42 | 43 |         Instruction(iseh type, bool begin, 44 | Type *catchType = nullptr);
45 |
46 | where catchType only needs to be specified when the block type is seh_catch. 47 | Each region must have both a beginning and an ending. For the beginning begin 48 | is true, otherwise it is false. In addition there must be a try block followed by at 49 | least one of the other block types. Note that the .net runtime does not always let 50 | one chain multiple block types, for example a try--catch would look as follows

51 | 52 |            try begin
53 |            ...
54 |            leave ...
55 |            try end
56 |            catch begin
57 |            ...
58 |            leave ...
59 |            catch end
60 |
61 |
62 | but a try--catch--finally would look as follows, to satisfy the runtime engine:
63 |
64 | 65 |            try begin
66 |                try begin
67 |                ...
68 |                leave...
69 |                try end
70 |                catch begin
71 |                ...
72 |                leave...
73 |                catch end
74 |            leave ...
75 |            try end
76 |            finally begin
77 |            ...
78 |            endfinally ...
79 |            finally end
80 |
81 |
82 | In addition to the above, the rules for the epilogues must also be followed in each block 83 | (for example use leave, or endfinally) and if it is a catch block you have to pop the caught 84 | object.
85 |
86 |
87 |
88 | 89 | 90 | -------------------------------------------------------------------------------- /docs/Type.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - Type 6 | 7 | 8 |
Type
9 |
10 |

11 |
12 |
13 | A Type is used in various places to qualify an entity, for example 14 | it can hold the underlying type of a Field 15 | or Local, or the return type or Param types for MethodSignatures.
18 |
19 |         enum BasicType {
20 |
            21 | 22 | 23 | ///** type is a reference to a class
24 |
            25 | 26 | 27 | cls,
28 |
            29 | 30 | 31 | ///** type is a reference to a method signature
32 |
            33 | 34 | 35 | method,
36 |
            37 | 38 | 39 | /* below this is various CIL types*/
40 |
            41 | 42 | 43 | Void, Bool, Char, i8, u8, i16, u16, i32, u32, i64, u64, inative, 44 | unative, r32, r64, object, string
45 |
        };
46 |

47 | Closely related to Type is BoxedType, 48 | which represents the boxed version of basic CIL types.
49 |
50 | A type may be constructed either directly or through an Allocator object.   Choose one 52 | of several constructors depending on the type being 53 | constructed.   Additionally, a qualifying function may 54 | have to be called for example if the type is an array type.
55 |
56 | Constructor for a basic type, e.g. integers, floats, strings, and 57 | the base object type.
58 |
59 |         Type(BasicType Tp, int 60 | PointerLevel) ;
61 |

62 | Constructor for a value of type Class
63 |
64 |
        Type(DataContainer 65 | *clsref) ;
66 |
67 |
Constructor for a method pointer
68 |         Type(MethodSignature 69 | *methodref) ;
70 |
71 |
Access the basic type
72 |
73 |         enum BasicType 74 | GetBasicType() const { return tp_; }
75 |
        void 76 | SetBasicType(BasicType type) { tp_ = type; }
77 |
78 |
Access extended types
79 |
80 |         DataContainer 81 | *GetClass() const { return typeRef_; }

82 |
        MethodSignature 83 | *GetMethod() const { return methodRef_; }
84 |
 
85 |
Access the array rank (note - arrays of > 1 dimension require 86 | use of CIL intrinsics that aren't directly supported by 87 | DotNetPELib....   occil implements them as an addon 88 | though)
89 |
90 |         void ArrayLevel(int 91 | arrayLevel) { arrayLevel_ = arrayLevel;  }

92 |
        int ArrayLevel() 93 | const { return arrayLevel_;  }
94 |

95 |
Access the number of pointer qualifers
96 |
97 |         void PointerLevel(int 98 | n) { pointerLevel_ = n; }

99 |
        int PointerLevel() 100 | const { return pointerLevel_; }
101 |

102 |
Access the ByRef flag.
103 |
104 |         void ByRef(bool val) { 105 | byRef_ = val; }

106 |
        bool ByRef() { 107 | return byRef_; }
108 |

109 | 110 | 111 | -------------------------------------------------------------------------------- /docs/Value.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DotNetPELib - Value 6 | 7 | 8 |
Value
9 |
10 |

11 | A Value is the base type for various types of Operand values, to be used in Instructions.   Some 14 | things inherited from Value are aditionally used to define Local variables and Method Params.
17 |
18 | Sometimes, the Value object is used directly to denote an 19 | Operand which is the name of a type.
20 |
21 |
22 | The following are derived from Value:
23 |
24 | Local
25 | Param
26 | FieldName
27 | MethodName
28 |
29 | Value objects may be directly constructed, or constructed 30 | through an Allocator object.
31 |
32 |         Value(std::string 33 | Name, Type *tp) : name_(Name), type_(tp) { }
34 |

35 | Access type
36 |
37 |         Type *GetType() 38 | const { return type_; }
39 |
        void 40 | SetType(Type *tp) { type_ = tp; }
41 |

42 | Access name
43 |
44 |         const std::string 45 | &Name() const { return name_; }
46 |
        void 47 | Name(const std::string name) { name_ = name; }
48 |

49 |
50 |
51 | 52 | 53 | -------------------------------------------------------------------------------- /libhostfxr/_version.h: -------------------------------------------------------------------------------- 1 | #ifndef VER_COMPANYNAME_STR 2 | #define VER_COMPANYNAME_STR ".NET Foundation" 3 | #endif 4 | #ifndef VER_FILEDESCRIPTION_STR 5 | #define VER_FILEDESCRIPTION_STR ".NET Runtime" 6 | #endif 7 | #ifndef VER_INTERNALNAME_STR 8 | #define VER_INTERNALNAME_STR VER_FILEDESCRIPTION_STR 9 | #endif 10 | #ifndef VER_ORIGINALFILENAME_STR 11 | #define VER_ORIGINALFILENAME_STR VER_FILEDESCRIPTION_STR 12 | #endif 13 | #ifndef VER_PRODUCTNAME_STR 14 | #define VER_PRODUCTNAME_STR ".NET" 15 | #endif 16 | #undef VER_PRODUCTVERSION 17 | #define VER_PRODUCTVERSION 00,00,00,00000 18 | #undef VER_PRODUCTVERSION_STR 19 | #define VER_PRODUCTVERSION_STR "0.0.0" 20 | #undef VER_FILEVERSION 21 | #define VER_FILEVERSION 00,00,00,00000 22 | #undef VER_FILEVERSION_STR 23 | #define VER_FILEVERSION_STR "00,00,00,00000" 24 | #ifndef VER_LEGALCOPYRIGHT_STR 25 | #define VER_LEGALCOPYRIGHT_STR ".NET Foundation" 26 | #endif 27 | #ifndef VER_DEBUG 28 | #define VER_DEBUG VS_FF_DEBUG 29 | #endif 30 | -------------------------------------------------------------------------------- /libhostfxr/error_codes.h: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | #ifndef __ERROR_CODES_H__ 5 | #define __ERROR_CODES_H__ 6 | 7 | // These error and exit codes are document in the host-error-codes.md 8 | enum StatusCode 9 | { 10 | // Success 11 | Success = 0, 12 | Success_HostAlreadyInitialized = 0x00000001, 13 | Success_DifferentRuntimeProperties = 0x00000002, 14 | 15 | // Failure 16 | InvalidArgFailure = 0x80008081, 17 | CoreHostLibLoadFailure = 0x80008082, 18 | CoreHostLibMissingFailure = 0x80008083, 19 | CoreHostEntryPointFailure = 0x80008084, 20 | CoreHostCurHostFindFailure = 0x80008085, 21 | // unused = 0x80008086, 22 | CoreClrResolveFailure = 0x80008087, 23 | CoreClrBindFailure = 0x80008088, 24 | CoreClrInitFailure = 0x80008089, 25 | CoreClrExeFailure = 0x8000808a, 26 | ResolverInitFailure = 0x8000808b, 27 | ResolverResolveFailure = 0x8000808c, 28 | LibHostCurExeFindFailure = 0x8000808d, 29 | LibHostInitFailure = 0x8000808e, 30 | // unused = 0x8000808f, 31 | LibHostExecModeFailure = 0x80008090, 32 | LibHostSdkFindFailure = 0x80008091, 33 | LibHostInvalidArgs = 0x80008092, 34 | InvalidConfigFile = 0x80008093, 35 | AppArgNotRunnable = 0x80008094, 36 | AppHostExeNotBoundFailure = 0x80008095, 37 | FrameworkMissingFailure = 0x80008096, 38 | HostApiFailed = 0x80008097, 39 | HostApiBufferTooSmall = 0x80008098, 40 | LibHostUnknownCommand = 0x80008099, 41 | LibHostAppRootFindFailure = 0x8000809a, 42 | SdkResolverResolveFailure = 0x8000809b, 43 | FrameworkCompatFailure = 0x8000809c, 44 | FrameworkCompatRetry = 0x8000809d, 45 | // unused = 0x8000809e, 46 | BundleExtractionFailure = 0x8000809f, 47 | BundleExtractionIOError = 0x800080a0, 48 | LibHostDuplicateProperty = 0x800080a1, 49 | HostApiUnsupportedVersion = 0x800080a2, 50 | HostInvalidState = 0x800080a3, 51 | HostPropertyNotFound = 0x800080a4, 52 | CoreHostIncompatibleConfig = 0x800080a5, 53 | HostApiUnsupportedScenario = 0x800080a6, 54 | HostFeatureDisabled = 0x800080a7, 55 | }; 56 | 57 | #define STATUS_CODE_SUCCEEDED(status_code) ((static_cast(static_cast(status_code))) >= 0) 58 | 59 | #endif // __ERROR_CODES_H__ 60 | -------------------------------------------------------------------------------- /libhostfxr/fx_ver.h: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | #ifndef __FX_VER_H__ 5 | #define __FX_VER_H__ 6 | 7 | #include 8 | 9 | // Note: This is intended to implement SemVer 2.0 10 | struct fx_ver_t 11 | { 12 | fx_ver_t(); 13 | fx_ver_t(int major, int minor, int patch); 14 | // if not empty pre contains valid prerelease label with leading '-' 15 | fx_ver_t(int major, int minor, int patch, const pal::string_t& pre); 16 | // if not empty pre contains valid prerelease label with leading '-' 17 | // if not empty build contains valid build label with leading '+' 18 | fx_ver_t(int major, int minor, int patch, const pal::string_t& pre, const pal::string_t& build); 19 | 20 | int get_major() const { return m_major; } 21 | int get_minor() const { return m_minor; } 22 | int get_patch() const { return m_patch; } 23 | 24 | bool is_prerelease() const { return !m_pre.empty(); } 25 | 26 | bool is_empty() const { return m_major == -1; } 27 | 28 | pal::string_t as_str() const; 29 | 30 | bool operator ==(const fx_ver_t& b) const; 31 | bool operator !=(const fx_ver_t& b) const; 32 | bool operator <(const fx_ver_t& b) const; 33 | bool operator >(const fx_ver_t& b) const; 34 | bool operator <=(const fx_ver_t& b) const; 35 | bool operator >=(const fx_ver_t& b) const; 36 | 37 | static bool parse(const pal::string_t& ver, fx_ver_t* fx_ver, bool parse_only_production = false); 38 | 39 | private: 40 | int m_major; 41 | int m_minor; 42 | int m_patch; 43 | pal::string_t m_pre; 44 | pal::string_t m_build; 45 | 46 | static int compare(const fx_ver_t&a, const fx_ver_t& b); 47 | }; 48 | 49 | #endif // __FX_VER_H__ 50 | -------------------------------------------------------------------------------- /libhostfxr/fxr_resolver.cpp: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | #include "pal.h" 5 | #include "fxr_resolver.h" 6 | #include "fx_ver.h" 7 | #include "trace.h" 8 | #include "fxrutils.h" 9 | 10 | namespace 11 | { 12 | bool get_latest_fxr(pal::string_t fxr_root, pal::string_t* out_fxr_path) 13 | { 14 | trace::info(_X("Reading fx resolver directory=[%s]"), fxr_root.c_str()); 15 | 16 | std::vector list; 17 | pal::readdir_onlydirectories(fxr_root, &list); 18 | 19 | fx_ver_t max_ver; 20 | for (const auto& dir : list) 21 | { 22 | trace::info(_X("Considering fxr version=[%s]..."), dir.c_str()); 23 | 24 | pal::string_t ver = get_filename(dir); 25 | 26 | fx_ver_t fx_ver; 27 | if (fx_ver_t::parse(ver, &fx_ver, /* parse_only_production */ false)) 28 | { 29 | max_ver = std::max(max_ver, fx_ver); 30 | } 31 | } 32 | 33 | if (max_ver == fx_ver_t()) 34 | { 35 | trace::error(_X("Error: [%s] does not contain any version-numbered child folders"), fxr_root.c_str()); 36 | return false; 37 | } 38 | 39 | pal::string_t max_ver_str = max_ver.as_str(); 40 | append_path(&fxr_root, max_ver_str.c_str()); 41 | trace::info(_X("Detected latest fxr version=[%s]..."), fxr_root.c_str()); 42 | 43 | if (file_exists_in_dir(fxr_root, LIBFXR_NAME, out_fxr_path)) 44 | { 45 | trace::info(_X("Resolved fxr [%s]..."), out_fxr_path->c_str()); 46 | return true; 47 | } 48 | 49 | trace::error(_X("Error: the required library %s could not be found in [%s]"), LIBFXR_NAME, fxr_root.c_str()); 50 | 51 | return false; 52 | } 53 | } 54 | 55 | bool fxr_resolver::try_get_path(const pal::string_t& root_path, pal::string_t* out_dotnet_root, pal::string_t* out_fxr_path) 56 | { 57 | #if defined(FEATURE_APPHOST) || defined(FEATURE_LIBHOST) 58 | // For apphost and libhost, root_path is expected to be a directory. 59 | // For libhost, it may be empty if app-local search is not desired (e.g. com/ijw/winrt hosts, nethost when no assembly path is specified) 60 | // If a hostfxr exists in root_path, then assume self-contained. 61 | if (root_path.length() > 0 && file_exists_in_dir(root_path, LIBFXR_NAME, out_fxr_path)) 62 | { 63 | trace::info(_X("Resolved fxr [%s]..."), out_fxr_path->c_str()); 64 | out_dotnet_root->assign(root_path); 65 | return true; 66 | } 67 | 68 | // For framework-dependent apps, use DOTNET_ROOT_ 69 | pal::string_t default_install_location; 70 | pal::string_t dotnet_root_env_var_name; 71 | if (get_dotnet_root_from_env(&dotnet_root_env_var_name, out_dotnet_root)) 72 | { 73 | trace::info(_X("Using environment variable %s=[%s] as runtime location."), dotnet_root_env_var_name.c_str(), out_dotnet_root->c_str()); 74 | } 75 | else 76 | { 77 | if (pal::get_dotnet_self_registered_dir(&default_install_location) || pal::get_default_installation_dir(&default_install_location)) 78 | { 79 | trace::info(_X("Using global installation location [%s] as runtime location."), default_install_location.c_str()); 80 | out_dotnet_root->assign(default_install_location); 81 | } 82 | else 83 | { 84 | trace::error(_X("Error: the default install location cannot be obtained.")); 85 | return false; 86 | } 87 | } 88 | 89 | pal::string_t fxr_dir = *out_dotnet_root; 90 | append_path(&fxr_dir, _X("host")); 91 | append_path(&fxr_dir, _X("fxr")); 92 | if (!pal::directory_exists(fxr_dir)) 93 | { 94 | if (default_install_location.empty()) 95 | { 96 | pal::get_dotnet_self_registered_dir(&default_install_location); 97 | } 98 | if (default_install_location.empty()) 99 | { 100 | pal::get_default_installation_dir(&default_install_location); 101 | } 102 | 103 | pal::string_t self_registered_config_location = pal::get_dotnet_self_registered_config_location(get_current_arch()); 104 | trace::verbose(_X("The required library %s could not be found. Searched with root path [%s], environment variable [%s], default install location [%s], self-registered config location [%s]"), 105 | LIBFXR_NAME, 106 | root_path.c_str(), 107 | dotnet_root_env_var_name.c_str(), 108 | default_install_location.c_str(), 109 | self_registered_config_location.c_str()); 110 | 111 | pal::string_t host_path; 112 | pal::get_own_executable_path(&host_path); 113 | trace::error( 114 | MISSING_RUNTIME_ERROR_FORMAT, 115 | INSTALL_NET_ERROR_MESSAGE, 116 | host_path.c_str(), 117 | get_current_arch_name(), 118 | _STRINGIFY(HOST_VERSION), 119 | _X("Not found"), 120 | get_download_url().c_str(), 121 | _STRINGIFY(HOST_VERSION)); 122 | return false; 123 | } 124 | 125 | return get_latest_fxr(std::move(fxr_dir), out_fxr_path); 126 | #else // !FEATURE_APPHOST && !FEATURE_LIBHOST 127 | // For non-apphost and non-libhost (i.e. muxer), root_path is expected to be the full path to the host 128 | pal::string_t host_dir; 129 | host_dir.assign(get_directory(root_path)); 130 | 131 | out_dotnet_root->assign(host_dir); 132 | 133 | return fxr_resolver::try_get_path_from_dotnet_root(*out_dotnet_root, out_fxr_path); 134 | #endif // !FEATURE_APPHOST && !FEATURE_LIBHOST 135 | } 136 | 137 | bool fxr_resolver::try_get_path_from_dotnet_root(const pal::string_t& dotnet_root, pal::string_t* out_fxr_path) 138 | { 139 | pal::string_t fxr_dir = dotnet_root; 140 | append_path(&fxr_dir, _X("host")); 141 | append_path(&fxr_dir, _X("fxr")); 142 | if (!pal::directory_exists(fxr_dir)) 143 | { 144 | trace::error(_X("Error: [%s] does not exist"), fxr_dir.c_str()); 145 | return false; 146 | } 147 | 148 | return get_latest_fxr(std::move(fxr_dir), out_fxr_path); 149 | } 150 | 151 | bool fxr_resolver::try_get_existing_fxr(pal::dll_t* out_fxr, pal::string_t* out_fxr_path) 152 | { 153 | if (!pal::get_loaded_library(LIBFXR_NAME, "hostfxr_main", out_fxr, out_fxr_path)) 154 | return false; 155 | 156 | trace::verbose(_X("Found previously loaded library %s [%s]."), LIBFXR_NAME, out_fxr_path->c_str()); 157 | return true; 158 | } 159 | -------------------------------------------------------------------------------- /libhostfxr/fxr_resolver.h: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | #ifndef _COREHOST_CLI_FXR_RESOLVER_H_ 5 | #define _COREHOST_CLI_FXR_RESOLVER_H_ 6 | 7 | #include "pal.h" 8 | #include "hostfxr.h" 9 | #include "trace.h" 10 | #include "fxrutils.h" 11 | #include "error_codes.h" 12 | 13 | namespace fxr_resolver 14 | { 15 | bool try_get_path(const pal::string_t& root_path, pal::string_t* out_dotnet_root, pal::string_t* out_fxr_path); 16 | bool try_get_path_from_dotnet_root(const pal::string_t& dotnet_root, pal::string_t* out_fxr_path); 17 | bool try_get_existing_fxr(pal::dll_t *out_fxr, pal::string_t *out_fxr_path); 18 | } 19 | 20 | template 21 | int load_fxr_and_get_delegate(hostfxr_delegate_type type, THostPathToConfigCallback host_path_to_config_path, TBeforeRunCallback on_before_run, void** delegate, bool try_ignore_missing_config) 22 | { 23 | pal::dll_t fxr; 24 | 25 | pal::string_t host_path; 26 | if (!pal::get_own_module_path(&host_path) || !pal::realpath(&host_path)) 27 | { 28 | trace::error(_X("Failed to resolve full path of the current host module [%s]"), host_path.c_str()); 29 | return StatusCode::CoreHostCurHostFindFailure; 30 | } 31 | 32 | pal::string_t dotnet_root; 33 | pal::string_t fxr_path; 34 | if (fxr_resolver::try_get_existing_fxr(&fxr, &fxr_path)) 35 | { 36 | dotnet_root = get_dotnet_root_from_fxr_path(fxr_path); 37 | trace::verbose(_X("The library %s was already loaded. Reusing the previously loaded library [%s]."), LIBFXR_NAME, fxr_path.c_str()); 38 | } 39 | else 40 | { 41 | // Do not specify the root path. Getting a delegate does not support self-contained (app-local fxr) 42 | if (!fxr_resolver::try_get_path(pal::string_t{}, &dotnet_root, &fxr_path)) 43 | { 44 | return StatusCode::CoreHostLibMissingFailure; 45 | } 46 | 47 | // Load library 48 | if (!pal::load_library(&fxr_path, &fxr)) 49 | { 50 | trace::error(_X("The library %s was found, but loading it from %s failed"), LIBFXR_NAME, fxr_path.c_str()); 51 | trace::error(_X(" - Installing .NET prerequisites might help resolve this problem.")); 52 | trace::error(_X(" %s"), DOTNET_CORE_INSTALL_PREREQUISITES_URL); 53 | return StatusCode::CoreHostLibLoadFailure; 54 | } 55 | } 56 | 57 | // Leak fxr 58 | 59 | auto hostfxr_initialize_for_runtime_config = reinterpret_cast(pal::get_symbol(fxr, "hostfxr_initialize_for_runtime_config")); 60 | auto hostfxr_get_runtime_delegate = reinterpret_cast(pal::get_symbol(fxr, "hostfxr_get_runtime_delegate")); 61 | auto hostfxr_close = reinterpret_cast(pal::get_symbol(fxr, "hostfxr_close")); 62 | if (hostfxr_initialize_for_runtime_config == nullptr || hostfxr_get_runtime_delegate == nullptr || hostfxr_close == nullptr) 63 | return StatusCode::CoreHostEntryPointFailure; 64 | 65 | pal::string_t config_path; 66 | pal::hresult_t status = host_path_to_config_path(host_path, &config_path); 67 | if (status != StatusCode::Success) 68 | return status; 69 | 70 | hostfxr_set_error_writer_fn set_error_writer_fn = reinterpret_cast(pal::get_symbol(fxr, "hostfxr_set_error_writer")); 71 | { 72 | propagate_error_writer_t propagate_error_writer_to_hostfxr(set_error_writer_fn); 73 | if (!try_ignore_missing_config || pal::file_exists(config_path)) 74 | { 75 | hostfxr_initialize_parameters parameters { 76 | sizeof(hostfxr_initialize_parameters), 77 | host_path.c_str(), 78 | dotnet_root.c_str() 79 | }; 80 | 81 | hostfxr_handle context; 82 | int rc = hostfxr_initialize_for_runtime_config(config_path.c_str(), ¶meters, &context); 83 | if (!STATUS_CODE_SUCCEEDED(rc)) 84 | return rc; 85 | 86 | on_before_run(fxr, context); 87 | 88 | rc = hostfxr_get_runtime_delegate(context, type, delegate); 89 | 90 | int rcClose = hostfxr_close(context); 91 | if (rcClose != StatusCode::Success) 92 | { 93 | assert(false && "Failed to close host context"); 94 | trace::verbose(_X("Failed to close host context: 0x%x"), rcClose); 95 | } 96 | 97 | return rc; 98 | } 99 | else 100 | { 101 | // null context means use the current one, if none exists it will fail 102 | int rc = hostfxr_get_runtime_delegate(nullptr, type, delegate); 103 | if (rc == StatusCode::HostInvalidState) 104 | { 105 | trace::error(_X("Expected active runtime context because runtimeconfig.json [%s] does not exist."), config_path.c_str()); 106 | } 107 | return rc; 108 | } 109 | } 110 | } 111 | 112 | #endif //_COREHOST_CLI_FXR_RESOLVER_H_ 113 | -------------------------------------------------------------------------------- /libhostfxr/libhostfxr.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | 47 | 48 | Source Files 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | Source Files 61 | 62 | 63 | Source Files 64 | 65 | 66 | -------------------------------------------------------------------------------- /libhostfxr/longfile.h: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | #ifndef _LONG_FILE_SUPPORT 5 | #define _LONG_FILE_SUPPORT 6 | 7 | class LongFile 8 | { 9 | public: 10 | static const pal::string_t ExtendedPrefix; 11 | static const pal::string_t DevicePathPrefix; 12 | static const pal::string_t UNCPathPrefix; 13 | static const pal::string_t UNCExtendedPathPrefix; 14 | static const pal::char_t VolumeSeparatorChar; 15 | static const pal::char_t DirectorySeparatorChar; 16 | static const pal::char_t AltDirectorySeparatorChar; 17 | public: 18 | static bool IsExtended(const pal::string_t& path); 19 | static bool IsUNCExtended(const pal::string_t& path); 20 | static bool ContainsDirectorySeparator(const pal::string_t & path); 21 | static bool IsDirectorySeparator(const pal::char_t c); 22 | static bool IsPathNotFullyQualified(const pal::string_t& path); 23 | static bool IsDevice(const pal::string_t& path); 24 | static bool IsNormalized(const pal::string_t& path); 25 | static bool ShouldNormalize(const pal::string_t& path); 26 | }; 27 | #endif //_LONG_FILE_SUPPORT 28 | -------------------------------------------------------------------------------- /libhostfxr/longfile.windows.cpp: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | //The logic in this file was ported from https://github.com/dotnet/runtime/blob/17154bd7b8f21d6d8d6fca71b89d7dcb705ec32b/src/coreclr/utilcode/longfilepathwrappers.cpp 5 | //Please reflect any change here into the above file too! 6 | #include "pal.h" 7 | #include "trace.h" 8 | #include "fxrutils.h" 9 | #include "longfile.h" 10 | 11 | const pal::char_t LongFile::DirectorySeparatorChar = _X('\\'); 12 | const pal::char_t LongFile::AltDirectorySeparatorChar = _X('/'); 13 | const pal::char_t LongFile::VolumeSeparatorChar = _X(':'); 14 | const pal::string_t LongFile::ExtendedPrefix = _X("\\\\?\\"); 15 | const pal::string_t LongFile::DevicePathPrefix = _X("\\\\.\\"); 16 | const pal::string_t LongFile::UNCExtendedPathPrefix = _X("\\\\?\\UNC\\"); 17 | const pal::string_t LongFile::UNCPathPrefix = _X("\\\\"); 18 | 19 | bool LongFile::IsNormalized(const pal::string_t& path) 20 | { 21 | return path.empty() || LongFile::IsDevice(path) || LongFile::IsExtended(path) || LongFile::IsUNCExtended(path); 22 | } 23 | bool ShouldNormalizeWorker(const pal::string_t& path) 24 | { 25 | if (LongFile::IsNormalized(path)) 26 | return false; 27 | 28 | if (!LongFile::IsPathNotFullyQualified(path) && path.size() < MAX_PATH) 29 | return false; 30 | 31 | return true; 32 | } 33 | 34 | //For longpath names on windows, if the paths are normalized they are always prefixed with 35 | //extended syntax, Windows does not do any more normalizations on this string and uses it as is 36 | //So we should ensure that there are NO adjacent DirectorySeparatorChar 37 | bool AssertRepeatingDirSeparator(const pal::string_t& path) 38 | { 39 | if (path.empty()) 40 | return true; 41 | 42 | pal::string_t path_to_check = path; 43 | if (LongFile::IsDevice(path)) 44 | { 45 | path_to_check.erase(0, LongFile::DevicePathPrefix.length()); 46 | } 47 | else if (LongFile::IsExtended(path)) 48 | { 49 | path_to_check.erase(0, LongFile::ExtendedPrefix.length()); 50 | } 51 | else if (LongFile::IsUNCExtended(path)) 52 | { 53 | path_to_check.erase(0, LongFile::UNCExtendedPathPrefix.length()); 54 | } 55 | else if (path_to_check.compare(0, LongFile::UNCPathPrefix.length(), LongFile::UNCPathPrefix) == 0) 56 | { 57 | path_to_check.erase(0, LongFile::UNCPathPrefix.length()); 58 | } 59 | 60 | pal::string_t dirSeparator; 61 | dirSeparator.push_back(LongFile::DirectorySeparatorChar); 62 | dirSeparator.push_back(LongFile::DirectorySeparatorChar); 63 | 64 | assert(path_to_check.find(dirSeparator) == pal::string_t::npos); 65 | 66 | pal::string_t altDirSeparator; 67 | altDirSeparator.push_back(LongFile::AltDirectorySeparatorChar); 68 | altDirSeparator.push_back(LongFile::AltDirectorySeparatorChar); 69 | 70 | assert(path_to_check.find(altDirSeparator) == pal::string_t::npos); 71 | 72 | pal::string_t combDirSeparator1; 73 | combDirSeparator1.push_back(LongFile::DirectorySeparatorChar); 74 | combDirSeparator1.push_back(LongFile::AltDirectorySeparatorChar); 75 | 76 | assert(path_to_check.find(combDirSeparator1) == pal::string_t::npos); 77 | 78 | pal::string_t combDirSeparator2; 79 | combDirSeparator2.push_back(LongFile::AltDirectorySeparatorChar); 80 | combDirSeparator2.push_back(LongFile::DirectorySeparatorChar); 81 | 82 | assert(path_to_check.find(combDirSeparator2) == pal::string_t::npos); 83 | 84 | assert(path_to_check.find(_X("..")) == pal::string_t::npos); 85 | return true; 86 | } 87 | bool LongFile::ShouldNormalize(const pal::string_t& path) 88 | { 89 | bool retval = ShouldNormalizeWorker(path); 90 | assert(retval || AssertRepeatingDirSeparator(path)); 91 | return retval; 92 | } 93 | 94 | bool LongFile::IsExtended(const pal::string_t& path) 95 | { 96 | return path.compare(0, ExtendedPrefix.length(), ExtendedPrefix) == 0; 97 | } 98 | 99 | bool LongFile::IsUNCExtended(const pal::string_t& path) 100 | { 101 | return path.compare(0, UNCExtendedPathPrefix.length(), UNCExtendedPathPrefix) == 0; 102 | } 103 | 104 | bool LongFile::IsDevice(const pal::string_t& path) 105 | { 106 | return path.compare(0, DevicePathPrefix.length(), DevicePathPrefix) == 0; 107 | } 108 | 109 | // Relative here means it could be relative to current directory on the relevant drive 110 | // NOTE: Relative segments ( \..\) are not considered relative 111 | // Returns true if the path specified is relative to the current drive or working directory. 112 | // Returns false if the path is fixed to a specific drive or UNC path. This method does no 113 | // validation of the path (URIs will be returned as relative as a result). 114 | // Handles paths that use the alternate directory separator. It is a frequent mistake to 115 | // assume that rooted paths (Path.IsPathRooted) are not relative. This isn't the case. 116 | 117 | bool LongFile::IsPathNotFullyQualified(const pal::string_t& path) 118 | { 119 | if (path.length() < 2) 120 | { 121 | return true; // It isn't fixed, it must be relative. There is no way to specify a fixed path with one character (or less). 122 | } 123 | 124 | if (IsDirectorySeparator(path[0])) 125 | { 126 | return !IsDirectorySeparator(path[1]); // There is no valid way to specify a relative path with two initial slashes 127 | } 128 | 129 | return (path.length() < 3) //The only way to specify a fixed path that doesn't begin with two slashes is the drive, colon, slash format- "i.e. C:\" 130 | || (path[1] != VolumeSeparatorChar) 131 | || !IsDirectorySeparator(path[2]); 132 | } 133 | 134 | bool LongFile::ContainsDirectorySeparator(const pal::string_t & path) 135 | { 136 | return path.find(DirectorySeparatorChar) != pal::string_t::npos || 137 | path.find(AltDirectorySeparatorChar) != pal::string_t::npos; 138 | } 139 | 140 | bool LongFile::IsDirectorySeparator(const pal::char_t c) 141 | { 142 | return c == DirectorySeparatorChar || c == AltDirectorySeparatorChar; 143 | } 144 | -------------------------------------------------------------------------------- /libhostfxr/runtime_version.h: -------------------------------------------------------------------------------- 1 | #define RuntimeAssemblyMajorVersion 0 2 | #define RuntimeAssemblyMinorVersion 0 3 | #define RuntimeFileMajorVersion 0 4 | #define RuntimeFileMinorVersion 0 5 | #define RuntimeFileBuildVersion 0 6 | #define RuntimeFileRevisionVersion 0 7 | #define RuntimeProductMajorVersion 0 8 | #define RuntimeProductMinorVersion 0 9 | #define RuntimeProductPatchVersion 0 10 | #define RuntimeProductVersion 0.0.0-dev 11 | -------------------------------------------------------------------------------- /libhostfxr/trace.h: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | 4 | #ifndef TRACE_H 5 | #define TRACE_H 6 | 7 | #include "pal.h" 8 | 9 | namespace trace 10 | { 11 | void setup(); 12 | bool enable(); 13 | bool is_enabled(); 14 | void verbose(const pal::char_t* format, ...); 15 | void info(const pal::char_t* format, ...); 16 | void warning(const pal::char_t* format, ...); 17 | void error(const pal::char_t* format, ...); 18 | void println(const pal::char_t* format, ...); 19 | void println(); 20 | void flush(); 21 | 22 | typedef void (__cdecl *error_writer_fn)(const pal::char_t* message); 23 | 24 | // Sets a callback which is called whenever error is to be written 25 | // The setting is per-thread (thread local). If no error writer is set for a given thread 26 | // the error is written to stderr. 27 | // The callback is set for the current thread which calls this function. 28 | // The function returns the previously registered writer for the current thread (or null) 29 | error_writer_fn set_error_writer(error_writer_fn error_writer); 30 | 31 | // Returns the currently set callback for error writing 32 | error_writer_fn get_error_writer(); 33 | }; 34 | 35 | #endif // TRACE_H 36 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | /* Software License Agreement 2 | * 3 | * Copyright(C) 1994-2024 David Lindauer, (LADSoft) 4 | * 5 | * The DotNetPELib library package is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 2.1 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * The DotNet PELib library package is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with DotNetPELib. If not, see . 17 | * 18 | * contact information: 19 | * email: TouchStone222@runbox.com 20 | * 21 | */ 22 | GNU LESSER GENERAL PUBLIC LICENSE 23 | Version 2.1, February 1999 24 | -------------------------------------------------------------------------------- /ms.bat: -------------------------------------------------------------------------------- 1 | msbuild /Property:configuration=Release /Property:platform=x86 2 | -------------------------------------------------------------------------------- /netlink/CmdFiles.cpp: -------------------------------------------------------------------------------- 1 | /* Software License Agreement 2 | * 3 | * Copyright(C) 1994-2023 David Lindauer, (LADSoft) 4 | * 5 | * This file is part of the Orange C Compiler package. 6 | * 7 | * The Orange C Compiler package is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * The Orange C Compiler package is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Orange C. If not, see . 19 | * 20 | * contact information: 21 | * email: TouchStone222@runbox.com 22 | * 23 | */ 24 | 25 | #ifdef HAVE_UNISTD_H 26 | # include 27 | # define _access access 28 | #else 29 | # include 30 | #endif 31 | 32 | #include "CmdFiles.h" 33 | #include "CmdSwitch.h" 34 | 35 | using namespace std; // borland puts the io stuff in the std namespace... 36 | // microsoft does not seem to. 37 | 38 | const char* CmdFiles::DIR_SEP = "\\"; 39 | const char* CmdFiles::PATH_SEP = ";"; 40 | 41 | CmdFiles::~CmdFiles() {} 42 | bool CmdFiles::Add(char** array, bool recurseDirs) 43 | { 44 | while (*array) 45 | { 46 | Add(std::string(*array), recurseDirs); 47 | array++; 48 | } 49 | return true; 50 | } 51 | bool CmdFiles::RecurseDirs(const std::string& path, const std::string& name, bool recurseDirs) 52 | { 53 | bool rv = false; 54 | #ifdef TARGET_OS_WINDOWS 55 | struct _finddata_t find; 56 | #endif 57 | std::string q = path + "*.*"; 58 | size_t handle; 59 | // borland does not define the char * as const... 60 | #ifdef TARGET_OS_WINDOWS 61 | if ((handle = _findfirst(const_cast(q.c_str()), &find)) != -1) 62 | { 63 | do 64 | { 65 | if (strcmp(find.name, ".") && strcmp(find.name, "..")) 66 | { 67 | if (find.attrib & _A_SUBDIR) 68 | { 69 | std::string newName = path + std::string(find.name) + DIR_SEP + name; 70 | rv |= Add(newName, recurseDirs); 71 | } 72 | } 73 | } while (_findnext(handle, &find) != -1); 74 | _findclose(handle); 75 | } 76 | #endif 77 | return rv; 78 | } 79 | bool CmdFiles::Add(const std::string& name, bool recurseDirs, bool subdirs) 80 | { 81 | bool rv = false; 82 | #ifdef TARGET_OS_WINDOWS 83 | struct _finddata_t find; 84 | #endif 85 | std::string path, lname; 86 | size_t n = name.find_last_of(DIR_SEP[0]); 87 | size_t n1 = name.find_last_of('/'); 88 | if (n1 != std::string::npos && n != std::string::npos) 89 | n = n1 > n ? n1 : n; 90 | else if (n == std::string::npos) 91 | n = n1; 92 | if (n != std::string::npos) 93 | { 94 | path = name.substr(0, n + 1); 95 | lname = name.substr(n + 1); 96 | } 97 | else 98 | { 99 | n = name.find_last_of(':'); 100 | if (n != std::string::npos) 101 | { 102 | path = name.substr(0, n + 1); 103 | lname = name.substr(n + 1); 104 | } 105 | else 106 | { 107 | lname = name; 108 | } 109 | } 110 | size_t handle; 111 | // borland does not define the char * as const... 112 | #ifdef TARGET_OS_WINDOWS 113 | if ((handle = _findfirst(const_cast(name.c_str()), &find)) != -1) 114 | { 115 | do 116 | { 117 | if ((!(find.attrib & _A_SUBDIR) || subdirs) && /*!(find.attrib & _A_VOLID) && */ 118 | !(find.attrib & _A_HIDDEN)) 119 | { 120 | if (strcmp(find.name, ".") != 0 && strcmp(find.name, "..") != 0) 121 | { 122 | std::string file(path + std::string(find.name)); 123 | names.push_back(file); 124 | rv = true; 125 | } 126 | } 127 | } while (_findnext(handle, &find) != -1); 128 | _findclose(handle); 129 | } 130 | #endif 131 | if (recurseDirs) 132 | { 133 | rv |= RecurseDirs(path, lname, recurseDirs); 134 | } 135 | if (!rv) 136 | { 137 | if (name.find_first_of('*') == std::string::npos && name.find_first_of('?') == std::string::npos) 138 | { 139 | names.push_back(name); 140 | rv = true; 141 | } 142 | } 143 | return rv; 144 | } 145 | bool CmdFiles::AddFromPath(const std::string& name, const std::string& path) 146 | { 147 | bool rv = false; 148 | size_t n = name.find_last_of(DIR_SEP[0]); 149 | size_t n1 = name.find_last_of('/'); 150 | if (n1 != std::string::npos && n != std::string::npos) 151 | n = n1 > n ? n1 : n; 152 | if (n != std::string::npos) 153 | { 154 | n++; 155 | } 156 | else 157 | { 158 | n = name.find_first_of(":"); 159 | if (n != std::string::npos) 160 | n++; 161 | else 162 | n = 0; 163 | } 164 | std::string internalName = name.substr(n, name.size()); 165 | n = 0; 166 | bool done = false; 167 | while (!done) 168 | { 169 | size_t m = path.find_first_of(PATH_SEP, n); 170 | if (m == std::string::npos) 171 | { 172 | m = path.size(); 173 | done = true; 174 | } 175 | std::string curpath = path.substr(n, m - n); 176 | n = m + 1; 177 | if (curpath.size() != 0 && curpath.substr(curpath.size() - 1, curpath.size()) != DIR_SEP) 178 | { 179 | curpath += DIR_SEP; 180 | } 181 | curpath += internalName; 182 | if (_access(curpath.c_str(), 0) == 0) 183 | { 184 | names.push_back(curpath); 185 | rv = true; 186 | break; 187 | } 188 | } 189 | if (!rv) 190 | { 191 | names.push_back(name); 192 | rv = true; 193 | } 194 | return rv; 195 | } 196 | bool CmdFiles::Add(CmdSwitchFile& switchFile) 197 | { 198 | if (switchFile.argv) 199 | Add(switchFile.argv.get() + 1); 200 | return true; 201 | } 202 | void CmdFiles::Remove(const std::string& name) 203 | { 204 | for (int i = 0; i < names.size(); i++) 205 | { 206 | if (names[i] == name) 207 | { 208 | for (; i < names.size() - 1; i++) 209 | names[i] = names[i + 1]; 210 | names.pop_back(); 211 | break; 212 | } 213 | } 214 | } -------------------------------------------------------------------------------- /netlink/CmdFiles.h: -------------------------------------------------------------------------------- 1 | /* Software License Agreement 2 | * 3 | * Copyright(C) 1994-2023 David Lindauer, (LADSoft) 4 | * 5 | * This file is part of the Orange C Compiler package. 6 | * 7 | * The Orange C Compiler package is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * The Orange C Compiler package is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Orange C. If not, see . 19 | * 20 | * contact information: 21 | * email: TouchStone222@runbox.com 22 | * 23 | */ 24 | 25 | #ifndef CMDFILES_H 26 | #define CMDFILES_H 27 | 28 | #include 29 | #include 30 | 31 | class CmdSwitchFile; 32 | class CmdFiles 33 | { 34 | typedef std::vector FileName; 35 | 36 | public: 37 | CmdFiles() {} 38 | CmdFiles(char** fileList, bool recurseSubdirs = false) { Add(fileList, recurseSubdirs); } 39 | CmdFiles(const std::string& name, bool recurseSubdirs = false) { Add(name, recurseSubdirs); } 40 | ~CmdFiles(); 41 | 42 | bool Add(const std::string& name, bool recurseSubdirs = false, bool subdirs = false); 43 | bool AddFromPath(const std::string& name, const std::string& path); 44 | bool Add(char** fileList, bool recurseSubdirs = false); 45 | bool Add(CmdFiles& other) 46 | { 47 | for (auto a : other.names) 48 | { 49 | Add(a); 50 | } 51 | return true; 52 | } 53 | bool Add(CmdSwitchFile& switchFile); 54 | void Remove(const std::string& name); 55 | typedef FileName::iterator iterator; 56 | 57 | iterator begin() { return names.begin(); } 58 | iterator end() { return names.end(); } 59 | size_t size() const { return names.size(); } 60 | inline std::string operator[](int index) const 61 | { 62 | return names[index]; 63 | } 64 | static const char* DIR_SEP; 65 | static const char* PATH_SEP; 66 | 67 | protected: 68 | bool RecurseDirs(const std::string& path, const std::string& name, bool recurseDirs); 69 | 70 | private: 71 | FileName names; 72 | }; 73 | #endif 74 | -------------------------------------------------------------------------------- /netlink/NetLink.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | -------------------------------------------------------------------------------- /netlink/NetLink.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | r1 r2 5 | $(ProjectDir)..\debug 6 | WindowsLocalDebugger 7 | 8 | -------------------------------------------------------------------------------- /netlink/NetLinkMain.h: -------------------------------------------------------------------------------- 1 | /* Software License Agreement 2 | * 3 | * Copyright(C) 1994-2023 David Lindauer, (LADSoft) 4 | * 5 | * This file is part of the Orange C Compiler package. 6 | * 7 | * The Orange C Compiler package is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * The Orange C Compiler package is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Orange C. If not, see . 19 | * 20 | * contact information: 21 | * email: TouchStone222@runbox.com 22 | * 23 | */ 24 | 25 | #ifndef NetLinkMain_H 26 | #define NetLinkMain_H 27 | #include "CmdFiles.h" 28 | #include "CmdSwitch.h" 29 | #include "Utils.h" 30 | #include "ToolChain.h" 31 | #include 32 | #include "DotNetPELib.h" 33 | class NetLinkMain : public DotNetPELib::Callback 34 | { 35 | public: 36 | NetLinkMain() : 37 | mainContainer(nullptr), 38 | mainNameSpace(nullptr), 39 | mainClass(nullptr), 40 | hasEntryPoint(false), 41 | peLib(nullptr), 42 | mainSym(nullptr), 43 | currentMethod(nullptr), 44 | netCore(nullptr) 45 | { } 46 | 47 | int Run(int argc, char **argv); 48 | protected: 49 | 50 | const std::string &GetAssemblyName(CmdFiles &files); 51 | const std::string &GetOutputFile(CmdFiles &files); 52 | bool LoadImage(CmdFiles &files); 53 | bool Validate(); 54 | bool CreateExecutable(CmdFiles &files); 55 | bool LoadAssembly(const char* assemblyName); 56 | 57 | DotNetPELib::MethodSignature *LookupSignature(const char * name); 58 | DotNetPELib::Field *LookupField(const char *name); 59 | DotNetPELib::MethodSignature *LookupManagedSignature(const char *name); 60 | DotNetPELib::Field *LookupManagedField(const char *name); 61 | void MainLocals(void); 62 | void MainInit(void); 63 | void dumpInitializerCalls(std::list&); 64 | void dumpCallToMain(void); 65 | void dumpGlobalFuncs(); 66 | bool AddRTLThunks(); 67 | 68 | // pelib traverse callback 69 | virtual bool EnterNamespace(const DotNetPELib::Namespace *nmspc) override; 70 | virtual bool EnterClass(const DotNetPELib::Class *method) override; 71 | virtual bool EnterMethod(const DotNetPELib::Method *) override; 72 | private: 73 | 74 | DotNetPELib::NetCore* netCore; 75 | DotNetPELib::PELib *peLib; 76 | std::vector localList; 77 | DotNetPELib::MethodSignature *mainSym; 78 | DotNetPELib::Method *currentMethod; 79 | const DotNetPELib::Namespace *mainNameSpace; 80 | const DotNetPELib::Class *mainClass; 81 | DotNetPELib::DataContainer *mainContainer; 82 | std::list initializers, startups; 83 | std::list destructors, rundowns; 84 | std::list stringinitializers; 85 | 86 | std::string namespaceAndClass; 87 | bool hasEntryPoint; 88 | 89 | static CmdSwitchParser SwitchParser; 90 | static CmdSwitchBool NoLogo; 91 | static CmdSwitchBool ShowVersion; 92 | static CmdSwitchBool ShowHelp; 93 | static CmdSwitchString StrongName; 94 | static CmdSwitchBool LibraryFile; 95 | static CmdSwitchBool AssemblyFile; 96 | static CmdSwitchBool GUIApp; 97 | static CmdSwitchBool Managed; 98 | static CmdSwitchOutput AssemblyName; 99 | static CmdSwitchString AssemblyVersion; 100 | static CmdSwitchFile File; 101 | static CmdSwitchBool CManaged; 102 | static CmdSwitchBool NoDefaultlibs; 103 | static CmdSwitchBool WeedPInvokes; 104 | static CmdSwitchInt NetCoreSwitch; 105 | 106 | static const char *usageText; 107 | static const char* helpText; 108 | }; 109 | #endif 110 | -------------------------------------------------------------------------------- /netlink/ToolChain.cpp: -------------------------------------------------------------------------------- 1 | /* Software License Agreement 2 | * 3 | * Copyright(C) 1994-2023 David Lindauer, (LADSoft) 4 | * 5 | * This file is part of the Orange C Compiler package. 6 | * 7 | * The Orange C Compiler package is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * The Orange C Compiler package is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Orange C. If not, see . 19 | * 20 | * contact information: 21 | * email: TouchStone222@runbox.com 22 | * 23 | */ 24 | 25 | #ifndef _CRT_SECURE_NO_WARNINGS 26 | #define _CRT_SECURE_NO_WARNINGS 27 | #endif 28 | #include 29 | #include 30 | #include 31 | #include 32 | #ifdef TARGET_OS_WINDOWS 33 | # include 34 | #endif 35 | #ifdef HAVE_UNISTD_H 36 | # include 37 | # define _access access 38 | # define _isatty isatty 39 | # include 40 | #else 41 | # include 42 | extern "C" char* getcwd(char*, int); 43 | # ifdef BORLAND 44 | # define _isatty isatty 45 | # endif 46 | #endif 47 | 48 | #include "Utils.h" 49 | 50 | #include "CmdSwitch.h" 51 | #include "ToolChain.h" 52 | 53 | #include 54 | #include "version.h" 55 | #include 56 | 57 | void ToolChain::ShowBanner() 58 | { 59 | bool have_version = false; 60 | // no banner if they specify -!, this is also caught in the cmd switch module 61 | // so it is transparent to the proggy 62 | const char* modName = Utils::GetModuleName(); 63 | printf("%s (OrangeC) Version " STRING_VERSION "\n" COPYRIGHT "\n", Utils::ShortName(modName)); 64 | } 65 | void ToolChain::ShowVersion() 66 | { 67 | printf("\nCompile date: " __DATE__ " time: " __TIME__ "\n"); 68 | exit(0); 69 | } 70 | void ToolChain::Usage(const char* text, int exitVal) 71 | { 72 | 73 | int rows = 10000; 74 | #ifdef TARGET_OS_WINDOWS 75 | if (_isatty(fileno(stderr))) 76 | rows = ScreenHeight(); 77 | #else 78 | if (_isatty(STDERR_FILENO)) 79 | rows = ScreenHeight(); 80 | #endif 81 | const char* modName = Utils::GetModuleName(); 82 | fprintf(stderr, "\nUsage: %s ", Utils::ShortName(modName)); 83 | int left = rows - 4; 84 | std::string buf; 85 | while (GetLine(&text, buf)) 86 | { 87 | std::cerr << buf; 88 | if (--left == 0) 89 | { 90 | std::cerr << "Press to continue..."; 91 | char temp[512]; 92 | fgets(temp, sizeof(temp), stdin); 93 | left = rows - 1; 94 | } 95 | } 96 | exit(1); 97 | } 98 | CmdFiles ToolChain::StandardToolStartup(CmdSwitchParser& SwitchParser, int argc, char** argv, const char* usageText, 99 | const char* helpText, std::function noBanner) 100 | { 101 | CmdSwitchBool NoLogo(SwitchParser, '!', false, {"nologo"}); 102 | CmdSwitchBool ShowVersion(SwitchParser, 'v', false, {"version"}); 103 | CmdSwitchBool ShowHelp(SwitchParser, '?', false, {"help"}); 104 | CmdSwitchFile File(SwitchParser, '@'); 105 | CmdSwitchFile internalConfig(SwitchParser); 106 | 107 | Utils::SetEnvironmentToPathParent("ORANGEC"); 108 | std::string configName = Utils::QualifiedFile(argv[0], ".cfg"); 109 | if (access(configName.c_str(), 0) != 0) 110 | { 111 | configName = Utils::QualifiedFile(Utils::GetModuleName(), ".cfg"); 112 | } 113 | std::fstream configTest(configName, std::ios::in); 114 | if (!configTest.fail()) 115 | { 116 | configTest.close(); 117 | if (!internalConfig.Parse(configName.c_str())) 118 | Utils::Fatal("Corrupt configuration file"); 119 | } 120 | if (!SwitchParser.Parse(&argc, argv) && !ShowHelp.GetExists()) 121 | { 122 | if (!noBanner || !noBanner()) 123 | ToolChain::ShowBanner(); 124 | ToolChain::Usage(usageText); 125 | } 126 | if (noBanner && noBanner()) 127 | NoLogo.SetValue(true); 128 | if (!NoLogo.GetValue() || ShowVersion.GetValue()) 129 | ToolChain::ShowBanner(); 130 | if (ShowVersion.GetValue()) 131 | ToolChain::ShowVersion(); 132 | if (ShowHelp.GetExists()) 133 | ToolChain::Usage(helpText); 134 | auto rv = CmdFiles(argv); 135 | rv.Add(File); 136 | return rv; 137 | } 138 | 139 | int ToolChain::ScreenHeight() 140 | { 141 | #ifdef TARGET_OS_WINDOWS 142 | CONSOLE_SCREEN_BUFFER_INFO csbi; 143 | GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); 144 | return csbi.srWindow.Bottom - csbi.srWindow.Top + 1; 145 | #else 146 | struct winsize max; 147 | ioctl(0, TIOCGWINSZ, &max); 148 | return max.ws_row; 149 | #endif 150 | } 151 | bool ToolChain::GetLine(const char** text, std::string& buf) 152 | { 153 | if (!**text) 154 | return false; 155 | char const* start = *text; 156 | auto temp = (char*)strchr(*text, '\n'); 157 | if (!temp) 158 | { 159 | *text += strlen(*text); 160 | } 161 | else 162 | { 163 | *text = temp + 1; 164 | } 165 | buf = std::string(start, *text); 166 | return true; 167 | } 168 | -------------------------------------------------------------------------------- /netlink/ToolChain.h: -------------------------------------------------------------------------------- 1 | /* Software License Agreement 2 | * 3 | * Copyright(C) 1994-2023 David Lindauer, (LADSoft) 4 | * 5 | * This file is part of the Orange C Compiler package. 6 | * 7 | * The Orange C Compiler package is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * The Orange C Compiler package is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Orange C. If not, see . 19 | * 20 | * contact information: 21 | * email: TouchStone222@runbox.com 22 | * 23 | */ 24 | 25 | #ifndef TOOLCHAIN_H 26 | #define TOOLCHAIN_H 27 | #ifndef _CRT_SECURE_NO_WARNINGS 28 | # define _CRT_SECURE_NO_WARNINGS 29 | #endif 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include "Utils.h" 35 | #include "CmdFiles.h" 36 | #include 37 | 38 | #ifdef TARGET_OS_WINDOWS 39 | # define mysystem(x) winsystem(x) 40 | extern "C" int winsystem(const char*); 41 | #else 42 | # define mysystem(x) system(x) 43 | #endif 44 | 45 | class CmdSwitchParser; 46 | 47 | class ToolChain 48 | { 49 | public: 50 | static CmdFiles StandardToolStartup(CmdSwitchParser& SwitchParser, int argc, char** argv, const char* usageText, 51 | const char* helpText, std::function noBanner = nullptr); 52 | static void ShowBanner(); 53 | static void ShowVersion(); 54 | static void Usage(const char* text, int exitVal = 1); 55 | template 56 | static int ToolInvoke(const std::string& exeName, const char* with, const char* fmt, const Args... arg) 57 | { 58 | int size = snprintf(NULL, 0, fmt, arg...) + 260; 59 | char *buf = (char *)calloc(sizeof(char), size); 60 | buf[0] = '"'; 61 | strcpy(buf + 1, Utils::GetModuleName()); 62 | char* p = (char*)strrchr(buf, '/'); 63 | char* p1 = (char*)strrchr(buf, '\\'); 64 | if (p1 > p) 65 | p = p1; 66 | else if (!p) 67 | p = p1; 68 | if (p) 69 | { 70 | p++; 71 | } 72 | else 73 | { 74 | p = buf + 1; 75 | } 76 | *p = 0; 77 | strcat(p, exeName.c_str()); 78 | strcat(p, "\" "); 79 | sprintf(buf + strlen(buf), fmt, arg...); 80 | if (with) 81 | { 82 | printf("%s\n", buf); 83 | if (with[0]) 84 | printf(" with %s", with); 85 | } 86 | auto rv = mysystem(buf); 87 | free(buf); 88 | return rv; 89 | } 90 | 91 | private: 92 | static int ScreenHeight(); 93 | static bool GetLine(const char** text, std::string& buf); 94 | }; 95 | #endif -------------------------------------------------------------------------------- /netlink/Utils.h: -------------------------------------------------------------------------------- 1 | /* Software License Agreement 2 | * 3 | * Copyright(C) 1994-2023 David Lindauer, (LADSoft) 4 | * 5 | * This file is part of the Orange C Compiler package. 6 | * 7 | * The Orange C Compiler package is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * The Orange C Compiler package is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with Orange C. If not, see . 19 | * 20 | * contact information: 21 | * email: TouchStone222@runbox.com 22 | * 23 | */ 24 | 25 | #ifndef UTIL_H 26 | #define UTIL_H 27 | #ifndef _CRT_SECURE_NO_WARNINGS 28 | # define _CRT_SECURE_NO_WARNINGS 29 | #endif 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #ifdef TARGET_OS_WINDOWS 36 | # include "io.h" 37 | #endif 38 | 39 | class Utils 40 | { 41 | public: 42 | [[noreturn]] static void Fatal(const char* format) 43 | { 44 | fprintf(stderr, "Fatal error: "); 45 | fputs(format, stderr); 46 | if (cleanup) 47 | cleanup(); 48 | exit(1); 49 | } 50 | template // templates are MUCH more portable than varargs 51 | [[noreturn]] static void Fatal(const char* format, Args... arg) 52 | { 53 | fprintf(stderr, "Fatal error: "); 54 | fprintf(stderr, format, arg...); 55 | fputc('\n', stderr); 56 | if (cleanup) 57 | cleanup(); 58 | exit(1); 59 | } 60 | [[noreturn]] static void Fatal(const std::string& format) { Fatal(format.c_str()); } 61 | template 62 | [[noreturn]] static void Fatal(const std::string& format, Args... arg) 63 | { 64 | Fatal(format.c_str(), arg...); 65 | } 66 | static bool HasLocalExe(const std::string& exeName); 67 | static void SetCleanup(void(Cleanup)()) { cleanup = Cleanup; } 68 | static char* GetModuleName(); 69 | static void SetEnvironmentToPathParent(const char* name); 70 | static std::string FullPath(const std::string& path, const std::string& name); 71 | static std::string AbsolutePath(const std::string& name); 72 | static std::string QualifiedFile(const char* path, const char* ext); 73 | static char* FullQualify(char* string); 74 | static std::string SearchForFile(const std::string& path, const std::string& name); 75 | static std::string NumberToString(int num); 76 | static std::string NumberToStringHex(int num); 77 | static int StringToNumber(std::string str); 78 | static int StringToNumberHex(std::string str); 79 | static char* ShortName(const char* v); 80 | static bool iequal(const std::string& left, const std::string& right, int sz = -1); 81 | static FILE* TempName(std::string& name); 82 | static void AddExt(char* buffer, const char* ext); 83 | static void StripExt(char* buffer); 84 | static bool HasExt(const char* buffer, const char* ext); 85 | static bool FileExists(const char* buffer); 86 | static std::string FindOnPath(const std::string& name, const std::string& path); 87 | static std::vector split(const std::string& strToSplit, char delimeter = ';'); 88 | static void ReplaceAll(std::string& str, const std::string& from, const std::string& to); 89 | static std::string ConvertWStringToString(std::wstring str) 90 | { 91 | char intStr[256]; 92 | size_t sz = wcstombs(nullptr, str.c_str(), 256); 93 | sz = wcstombs(intStr, str.c_str(), sz); 94 | return std::string(intStr, sz); 95 | } 96 | static bool NamedPipe(int* fds, const std::string& name); 97 | static bool PipeWrite(int fileno, const std::string& data); 98 | static std::string PipeRead(int fileno); 99 | 100 | static unsigned PartialCRC32(unsigned crc, const unsigned char* data, size_t len); 101 | static unsigned CRC32(const unsigned char* data, size_t len) { return PartialCRC32(0, data, len); }; 102 | 103 | static unsigned Random(unsigned); 104 | 105 | static char* StrCpy(char* data, size_t len, const char* source) 106 | { 107 | strncpy(data, source, len); 108 | data[len - 1] = '\0'; 109 | return data; 110 | } 111 | template 112 | static char* StrCpy(char (&data)[len], const char* source) 113 | { 114 | return StrCpy(data, len, source); 115 | } 116 | static char* StrCat(char* data, size_t len, const char* source) 117 | { 118 | int num = (int)len - (int)strlen(data) - 1; 119 | if (num > 0) 120 | strncat(data, source, num); 121 | return data; 122 | } 123 | template 124 | static char* StrCat(char (&data)[len], const char* source) 125 | { 126 | return StrCat(data, len, source); 127 | } 128 | template 129 | static unsigned CRC32(const unsigned char (&data)[len]) 130 | { 131 | return CRC32(data, len); 132 | } 133 | template 134 | static unsigned PartialCRC32(unsigned crc, const unsigned char* data) 135 | { 136 | return PartialCRC32(crc, data, len); 137 | } 138 | static unsigned crctab[256]; 139 | 140 | private: 141 | static void (*cleanup)(); 142 | }; 143 | #endif -------------------------------------------------------------------------------- /netlink/dummy.cpp: -------------------------------------------------------------------------------- 1 | // placeholder to make build happy -------------------------------------------------------------------------------- /netlink/makefile: -------------------------------------------------------------------------------- 1 | # Software License Agreement (BSD License) 2 | # 3 | # Copyright (c) 1997-2009, David Lindauer, (LADSoft). 4 | # All rights reserved. 5 | # 6 | # Redistribution and use of this software in source and binary forms, 7 | # with or without modification, are permitted provided that the following 8 | # conditions are met: 9 | 10 | # * Redistributions of source code must retain the above 11 | # copyright notice, this list of conditions and the 12 | # following disclaimer. 13 | 14 | # * Redistributions in binary form must reproduce the above 15 | # copyright notice, this list of conditions and the 16 | # following disclaimer in the documentation and/or other 17 | # materials provided with the distribution. 18 | 19 | # * Neither the name of LADSoft nor the names of its 20 | # contributors may be used to endorse or promote products 21 | # derived from this software without specific prior 22 | # written permission of LADSoft. 23 | 24 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 26 | # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 27 | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 28 | # OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 31 | # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 32 | # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 33 | # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 34 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | # contact information: 37 | # email: TouchStone222@runbox.com 38 | NAME=netlink 39 | MAIN_FILE=NetLinkMain.cpp 40 | INCLUDES=..\ 41 | CPP_DEPENDENCIES=\ 42 | CmdFiles.cpp\ 43 | CmdSwitch.cpp\ 44 | Utils.cpp 45 | LIB_DEPENDENCIES=netlib 46 | 47 | compiler: 48 | @$(MAKE) /T 49 | copy netlink.exe ..\.. 50 | 51 | DISTRIBUTE: copyexe 52 | -------------------------------------------------------------------------------- /netlink/netlink.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /netlink/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /netlink/version.h: -------------------------------------------------------------------------------- 1 | #define STRING_VERSION "6.73.1" 2 | #define PRODUCT_VERSION 6,0,73,1 3 | #define CLIB_VERSION 6,0,73,1 4 | #define PRODUCT_STRING_VERSION STRING_VERSION 5 | #define PRODUCT_NAME "Orange C Compiler Package" 6 | #define CLIB_STRING_VERSION STRING_VERSION 7 | #define COPYRIGHT "Copyright (C) LADSoft 2006-2024" 8 | #define LIBRARY_COPYRIGHT "Copyright (C) LADSoft 1994-2024" 9 | -------------------------------------------------------------------------------- /sha1.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sha1.h 3 | * 4 | * Copyright (C) 1998, 2009 5 | * Paul E. Jones 6 | * All Rights Reserved 7 | * 8 | ***************************************************************************** 9 | * $Id: sha1.h 12 2009-06-22 19:34:25Z paulej $ 10 | ***************************************************************************** 11 | * 12 | * Description: 13 | * This class implements the Secure Hashing Standard as defined 14 | * in FIPS PUB 180-1 published April 17, 1995. 15 | * 16 | * Many of the variable names in the SHA1Context, especially the 17 | * single character names, were used because those were the names 18 | * used in the publication. 19 | * 20 | * Please read the file sha1.c for more information. 21 | * 22 | */ 23 | 24 | #ifndef _SHA1_H_ 25 | #define _SHA1_H_ 26 | 27 | namespace DotNetPELib { 28 | /* 29 | * This structure will hold context information for the hashing 30 | * operation 31 | */ 32 | typedef struct SHA1Context 33 | { 34 | unsigned Message_Digest[5]; /* Message Digest (output) */ 35 | 36 | unsigned Length_Low; /* Message length in bits */ 37 | unsigned Length_High; /* Message length in bits */ 38 | 39 | unsigned char Message_Block[64]; /* 512-bit message blocks */ 40 | int Message_Block_Index; /* Index into message block array */ 41 | 42 | int Computed; /* Is the digest computed? */ 43 | int Corrupted; /* Is the message digest corruped? */ 44 | } SHA1Context; 45 | 46 | /* 47 | * Function Prototypes 48 | */ 49 | void SHA1Reset(SHA1Context *); 50 | int SHA1Result(SHA1Context *); 51 | void SHA1Input( SHA1Context *, 52 | const unsigned char *, 53 | unsigned); 54 | 55 | } // NameSpace 56 | #endif 57 | -------------------------------------------------------------------------------- /targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /test/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /test/DumpMSCorLib.cpp: -------------------------------------------------------------------------------- 1 | // this is an example of how to use traversal to dump the public members of a .net assembly 2 | // instead of dumping them you could load them into a compiler's symbol table, for example.. 3 | #include "DotNetPELib.h" 4 | 5 | #include 6 | #include 7 | #include 8 | using namespace DotNetPELib; 9 | 10 | class Importer :public Callback 11 | { 12 | public: 13 | Importer() { } 14 | virtual ~Importer() { } 15 | 16 | virtual bool EnterAssembly(const AssemblyDef *) override; 17 | virtual bool ExitAssembly(const AssemblyDef *) override; 18 | virtual bool EnterNamespace(const Namespace *) override; 19 | virtual bool ExitNamespace(const Namespace *) override; 20 | virtual bool EnterClass(const Class *) override; 21 | virtual bool ExitClass(const Class *) override; 22 | virtual bool EnterEnum(const Enum *cls) override; 23 | virtual bool ExitEnum(const Enum *cls) override; 24 | virtual bool EnterMethod(const Method *) override; 25 | virtual bool EnterField(const Field *) override; 26 | virtual bool EnterProperty(const Property *) override; 27 | 28 | void diag(std::string header, std::string name) 29 | { 30 | 31 | for (int i = 0; i < names_.size(); i++) 32 | std::cout << "\t"; 33 | if (header.size()) 34 | std::cout << header << " "; 35 | for (int i = 0; i < names_.size(); i++) 36 | std::cout << names_[i] << "."; 37 | std::cout << name << std::endl; 38 | } 39 | private: 40 | std::deque names_; 41 | }; 42 | 43 | void main() 44 | { 45 | PELib lib("test", PELib::ilonly); 46 | 47 | if (!lib.LoadAssembly("mscorlib")) 48 | { 49 | Importer importer; 50 | lib.Traverse(importer); 51 | } 52 | } 53 | 54 | 55 | bool Importer::EnterAssembly(const AssemblyDef *assembly) 56 | { 57 | diag("Assembly", assembly->Name()); 58 | names_.push_back(assembly->Name()); 59 | return true; 60 | } 61 | bool Importer::ExitAssembly(const AssemblyDef *assembly) 62 | { 63 | names_.pop_back(); 64 | diag("Exit Assembly", assembly->Name()); 65 | return true; 66 | } 67 | bool Importer::EnterNamespace(const Namespace *nameSpace) 68 | { 69 | diag("Namespace", nameSpace->Name()); 70 | names_.push_back(nameSpace->Name()); 71 | return true; 72 | } 73 | bool Importer::ExitNamespace(const Namespace *nameSpace) 74 | { 75 | names_.pop_back(); 76 | diag("Exit Namespace", nameSpace->Name()); 77 | return true; 78 | } 79 | bool Importer::EnterClass(const Class *cls) 80 | { 81 | diag("Class", cls->Name()); 82 | names_.push_back(cls->Name()); 83 | return true; 84 | } 85 | bool Importer::ExitClass(const Class *cls) 86 | { 87 | names_.pop_back(); 88 | diag("Exit Class", cls->Name()); 89 | return true; 90 | } 91 | bool Importer::EnterEnum(const Enum *cls) 92 | { 93 | diag("Enum", cls->Name()); 94 | names_.push_back(cls->Name()); 95 | return true; 96 | } 97 | bool Importer::ExitEnum(const Enum *cls) 98 | { 99 | names_.pop_back(); 100 | diag("Exit Enum", cls->Name()); 101 | return true; 102 | } 103 | bool Importer::EnterMethod(const Method *method) 104 | { 105 | diag("Method", method->Signature()->Name()); 106 | return true; 107 | } 108 | bool Importer::EnterField(const Field *field) 109 | { 110 | diag("Field", field->Name()); 111 | return true; 112 | } 113 | bool Importer::EnterProperty(const Property *property) 114 | { 115 | diag("Property", property->Name()); 116 | return true; 117 | } -------------------------------------------------------------------------------- /test/DumpMSCorLib.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("testcsc")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Hewlett-Packard")] 12 | [assembly: AssemblyProduct("testcsc")] 13 | [assembly: AssemblyCopyright("Copyright © Hewlett-Packard 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("5be35f88-e1cb-4aaf-acc9-5227b5143b17")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /test/test.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /test/testcsc.cs: -------------------------------------------------------------------------------- 1 | namespace a.b.c 2 | { 3 | public class r 4 | { 5 | public class s 6 | { 7 | private static int _myprop; 8 | public static int zz = 5; 9 | public static int myprop { 10 | get { 11 | return _myprop + 11; 12 | } 13 | set { 14 | _myprop = value + 22; 15 | } 16 | } 17 | } 18 | } 19 | 20 | }; -------------------------------------------------------------------------------- /test/testcsc.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {5BE35F88-E1CB-4AAF-ACC9-5227B5143B17} 8 | Library 9 | Properties 10 | testcsc 11 | testcsc 12 | v4.8 13 | 512 14 | true 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | mkdir $(ProjectDir)$(ConfigurationName) 59 | copy $(TargetPath) $(ProjectDir)$(ConfigurationName) 60 | 61 | 68 | -------------------------------------------------------------------------------- /testcore/test.cpp: -------------------------------------------------------------------------------- 1 | #include "DotNetPELib.h" 2 | 3 | using namespace DotNetPELib; 4 | 5 | void build_dll(std::string assembly, PELib::CorFlags mode = PELib::cfnone) 6 | { 7 | NetCore core((PELib::CorFlags)(PELib::ilonly | mode)); 8 | PELib* libEntry = core.init(assembly); 9 | 10 | DataContainer* working = libEntry->WorkingAssembly(); 11 | 12 | Namespace* nmspc = libEntry->AllocateNamespace("nmspc"); 13 | working->Add(nmspc); 14 | Class* cls = libEntry->AllocateClass("cls", Qualifiers::Public | Qualifiers::Ansi | Qualifiers::Sealed, -1, -1); 15 | nmspc->Add(cls); 16 | 17 | MethodSignature* signatures = libEntry->AllocateMethodSignature("Start", MethodSignature::Managed, cls); 18 | signatures->ReturnType(libEntry->AllocateType(Type::Void, 0)); 19 | Param* parames1 = libEntry->AllocateParam("strn", libEntry->AllocateType(Type::string, 0)); 20 | signatures->AddParam(parames1); 21 | 22 | // add a reference to the assembly 23 | core.LoadAssembly("System.Runtime"); 24 | core.LoadAssembly("System.Console"); 25 | 26 | // create the function refernce to WriteLine 27 | // there is an argument matcher in the library, set up a vector of types describing 28 | // the arguments and it will try to find a matching overload. 29 | Type tp(Type::string, 0); 30 | std::vector typeList; 31 | typeList.push_back(&tp); 32 | Method* result = nullptr; 33 | MethodSignature* signaturep; 34 | if (libEntry->Find("System.Console.WriteLine", &result, typeList) == PELib::s_method) 35 | { 36 | signaturep = result->Signature(); 37 | } 38 | else 39 | { 40 | std::cout << "error" << std::endl; 41 | exit(1); 42 | } 43 | 44 | Method* start = libEntry->AllocateMethod(signatures, Qualifiers::Public | 45 | Qualifiers::Static | 46 | Qualifiers::HideBySig | 47 | Qualifiers::CIL | 48 | Qualifiers::Managed); 49 | start->AddInstruction(libEntry->AllocateInstruction(Instruction::i_ldarg, 50 | libEntry->AllocateOperand(parames1))); 51 | start->AddInstruction(libEntry->AllocateInstruction(Instruction::i_call, 52 | libEntry->AllocateOperand(libEntry->AllocateMethodName(signaturep)))); 53 | 54 | start->AddInstruction(libEntry->AllocateInstruction(Instruction::i_ldstr, 55 | libEntry->AllocateOperand("this is a string in Start()", true))); 56 | start->AddInstruction(libEntry->AllocateInstruction(Instruction::i_call, 57 | libEntry->AllocateOperand(libEntry->AllocateMethodName(signaturep)))); 58 | 59 | start->AddInstruction(libEntry->AllocateInstruction(Instruction::i_ret, nullptr)); 60 | 61 | try 62 | { 63 | start->Optimize(*libEntry); 64 | } 65 | catch (PELibError exc) 66 | { 67 | std::cout << "Optimizer error: " << exc.what() << std::endl; 68 | } 69 | cls->Add(start); 70 | 71 | core.DumpOutputFile(assembly + ".il", PELib::ilasm); 72 | core.DumpOutputFile(assembly + ".dll", PELib::pedll); 73 | 74 | } 75 | void build_exe(std::string assembly, std::string lib, PELib::CorFlags mode = PELib::cfnone) 76 | { 77 | NetCore core((PELib::CorFlags)(PELib::ilonly | mode)); 78 | PELib *libEntry = core.init(assembly); 79 | 80 | DataContainer* working = libEntry->WorkingAssembly(); 81 | Class* cls = libEntry->AllocateClass("Program", Qualifiers::Private | Qualifiers::Ansi | Qualifiers::Auto | Qualifiers::BeforeFieldInit, -1, -1); 82 | working->Add(cls); 83 | 84 | // add a reference to the assembly 85 | core.LoadAssembly("System.Runtime"); 86 | core.LoadAssembly(lib); 87 | 88 | MethodSignature* signaturem = libEntry->AllocateMethodSignature("
$", MethodSignature::Managed, working); 89 | signaturem->ReturnType(libEntry->AllocateType(Type::Void, 0)); 90 | Method* main = libEntry->AllocateMethod(signaturem, Qualifiers::Private | 91 | Qualifiers::Static | 92 | Qualifiers::HideBySig | 93 | Qualifiers::CIL | 94 | Qualifiers::Managed, true); 95 | cls->Add(main); 96 | 97 | Type tp(Type::string, 0); 98 | std::vector typeList; 99 | typeList.push_back(&tp); 100 | Method* result = nullptr; 101 | MethodSignature* signaturep; 102 | if (libEntry->Find("nmspc.cls.Start", &result, typeList) == PELib::s_method) 103 | { 104 | signaturep = result->Signature(); 105 | } 106 | else 107 | { 108 | std::cout << "error" << std::endl; 109 | exit(1); 110 | } 111 | // note the reference to the generic form of ldc.i4 ... it will be optimized 112 | // into an ldc.i4.s by the library 113 | main->AddInstruction(libEntry->AllocateInstruction(Instruction::i_ldstr, 114 | libEntry->AllocateOperand("this is a string in
$()", true))); 115 | main->AddInstruction(libEntry->AllocateInstruction(Instruction::i_call, 116 | libEntry->AllocateOperand(libEntry->AllocateMethodName(signaturep)))); 117 | main->AddInstruction(libEntry->AllocateInstruction(Instruction::i_ret, nullptr)); 118 | try 119 | { 120 | main->Optimize(*libEntry); 121 | } 122 | catch (PELibError exc) 123 | { 124 | std::cout << "Optimizer error: " << exc.what() << std::endl; 125 | } 126 | core.DumpOutputFile(assembly + ".il", PELib::ilasm); 127 | core.DumpOutputFile(assembly + ".exe", PELib::peexe); 128 | 129 | } 130 | int main() 131 | { 132 | for (int i = 5; i < 10; i++) 133 | { 134 | NetCore core(PELib::cfnone, false, i); 135 | std::cout << i << ": " << core.SupportsRuntime(i) << std::endl; 136 | } 137 | build_dll("libcore32", PELib::bits32); 138 | build_exe("testcore32", "libcore32", PELib::bits32); 139 | build_dll("libcore64"); 140 | build_exe("testcore64", "libcore64"); 141 | } -------------------------------------------------------------------------------- /testcore/testcore.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /util/dump.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LADSoft/DotNetPELib/8282f8a7ef7bc53ad5f443a9c382ce91d89c3aee/util/dump.c -------------------------------------------------------------------------------- /vcvars32.bat: -------------------------------------------------------------------------------- 1 | 2 | 3 | @call "%~dp0vcvarsall.bat" x86 %* 4 | --------------------------------------------------------------------------------