18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci#include <cstddef> 168bf80f4bSopenharmony_ci#include <string.h> 178bf80f4bSopenharmony_ci#include <inttypes.h> 188bf80f4bSopenharmony_ci#include <algorithm> 198bf80f4bSopenharmony_ci#include <string> 208bf80f4bSopenharmony_ci#include <string_view> 218bf80f4bSopenharmony_ci#include <vector> 228bf80f4bSopenharmony_ci#include <set> 238bf80f4bSopenharmony_ci#include "dir.h" 248bf80f4bSopenharmony_ci#include "coff.h" 258bf80f4bSopenharmony_ci#include "elf32.h" 268bf80f4bSopenharmony_ci#include "elf64.h" 278bf80f4bSopenharmony_ci 288bf80f4bSopenharmony_ci#ifdef __APPLE__ 298bf80f4bSopenharmony_ci#include <mach-o/loader.h> 308bf80f4bSopenharmony_ci#include <mach-o/nlist.h> 318bf80f4bSopenharmony_ci#include <mach-o/fat.h> 328bf80f4bSopenharmony_ci#endif 338bf80f4bSopenharmony_ci 348bf80f4bSopenharmony_cistruct fs_entry { 358bf80f4bSopenharmony_ci char fname[256]; 368bf80f4bSopenharmony_ci uint64_t offset; 378bf80f4bSopenharmony_ci uint64_t size; 388bf80f4bSopenharmony_ci}; 398bf80f4bSopenharmony_ci 408bf80f4bSopenharmony_cistd::vector<fs_entry> directory; 418bf80f4bSopenharmony_cistd::vector<uint8_t> bin; 428bf80f4bSopenharmony_cistd::vector<std::string_view> valid_exts; 438bf80f4bSopenharmony_ci 448bf80f4bSopenharmony_civoid append_file(const std::string& filename, const std::string& storename) 458bf80f4bSopenharmony_ci{ 468bf80f4bSopenharmony_ci std::string_view ext; 478bf80f4bSopenharmony_ci auto pos = filename.find_last_of("."); 488bf80f4bSopenharmony_ci if (pos != std::string::npos) { 498bf80f4bSopenharmony_ci // found it. 508bf80f4bSopenharmony_ci ext = std::string_view(filename).substr(pos); 518bf80f4bSopenharmony_ci } 528bf80f4bSopenharmony_ci bool valid = false; 538bf80f4bSopenharmony_ci for (const auto& e : valid_exts) { 548bf80f4bSopenharmony_ci if (ext.compare(e) == 0) { 558bf80f4bSopenharmony_ci valid = true; 568bf80f4bSopenharmony_ci break; 578bf80f4bSopenharmony_ci } 588bf80f4bSopenharmony_ci } 598bf80f4bSopenharmony_ci if (!valid) { 608bf80f4bSopenharmony_ci printf("Skipped %s\n", storename.c_str()); 618bf80f4bSopenharmony_ci return; 628bf80f4bSopenharmony_ci } 638bf80f4bSopenharmony_ci if (storename.size() > 255) { 648bf80f4bSopenharmony_ci printf("Filename too long [%s]\n", storename.c_str()); 658bf80f4bSopenharmony_ci exit(-1); 668bf80f4bSopenharmony_ci } 678bf80f4bSopenharmony_ci fs_entry tmp{}; 688bf80f4bSopenharmony_ci strcpy(tmp.fname, storename.c_str()); 698bf80f4bSopenharmony_ci#if _WIN32 708bf80f4bSopenharmony_ci struct _stat64 fileStat; 718bf80f4bSopenharmony_ci if (-1 == _stat64(filename.c_str(), &fileStat)) { 728bf80f4bSopenharmony_ci#else 738bf80f4bSopenharmony_ci struct stat fileStat; 748bf80f4bSopenharmony_ci if (-1 == stat(filename.c_str(), &fileStat)) { 758bf80f4bSopenharmony_ci#endif 768bf80f4bSopenharmony_ci printf("File [%s] not found\n", tmp.fname); 778bf80f4bSopenharmony_ci exit(-1); 788bf80f4bSopenharmony_ci } 798bf80f4bSopenharmony_ci tmp.size = fileStat.st_size; 808bf80f4bSopenharmony_ci auto padding = (8 - (bin.size() & 7)) & 7; 818bf80f4bSopenharmony_ci tmp.offset = bin.size() + padding; 828bf80f4bSopenharmony_ci directory.push_back(tmp); 838bf80f4bSopenharmony_ci FILE* f = fopen(filename.c_str(), "rb"); 848bf80f4bSopenharmony_ci if (f == NULL) { 858bf80f4bSopenharmony_ci printf("Could not open %s.\n", filename.c_str()); 868bf80f4bSopenharmony_ci exit(-1); 878bf80f4bSopenharmony_ci } 888bf80f4bSopenharmony_ci bin.resize((size_t)(bin.size() + padding + tmp.size)); 898bf80f4bSopenharmony_ci fread(bin.data() + tmp.offset, 1, (size_t)tmp.size, f); 908bf80f4bSopenharmony_ci fclose(f); 918bf80f4bSopenharmony_ci printf("Stored: %s [%" PRIu64 " , %" PRIu64 "]\n", tmp.fname, tmp.offset, tmp.size); 928bf80f4bSopenharmony_ci} 938bf80f4bSopenharmony_ci 948bf80f4bSopenharmony_civoid add_directory(const std::string& path, const std::string& outpath) 958bf80f4bSopenharmony_ci{ 968bf80f4bSopenharmony_ci struct dirent* pDirent = nullptr; 978bf80f4bSopenharmony_ci DIR* pDir = opendir(path.c_str()); 988bf80f4bSopenharmony_ci if (pDir == NULL) { 998bf80f4bSopenharmony_ci printf("Cannot open directory '%s'\n", path.c_str()); 1008bf80f4bSopenharmony_ci exit(1); 1018bf80f4bSopenharmony_ci } 1028bf80f4bSopenharmony_ci std::string p, op; 1038bf80f4bSopenharmony_ci p = path; 1048bf80f4bSopenharmony_ci if (!p.empty()) { 1058bf80f4bSopenharmony_ci if (p.back() != '/') { 1068bf80f4bSopenharmony_ci p += "/"; 1078bf80f4bSopenharmony_ci } 1088bf80f4bSopenharmony_ci } 1098bf80f4bSopenharmony_ci op = outpath; 1108bf80f4bSopenharmony_ci if (!op.empty()) { 1118bf80f4bSopenharmony_ci if (op.back() != '/') { 1128bf80f4bSopenharmony_ci op += "/"; 1138bf80f4bSopenharmony_ci } 1148bf80f4bSopenharmony_ci } 1158bf80f4bSopenharmony_ci 1168bf80f4bSopenharmony_ci // sort the readdir result 1178bf80f4bSopenharmony_ci auto alphaSort = [](dirent* x, dirent* y) { return std::string(x->d_name) < std::string(y->d_name); }; 1188bf80f4bSopenharmony_ci auto dirSet = std::set<dirent*, decltype(alphaSort)>(alphaSort); 1198bf80f4bSopenharmony_ci 1208bf80f4bSopenharmony_ci while ((pDirent = readdir(pDir)) != NULL) { 1218bf80f4bSopenharmony_ci // This structure may be statically allocated 1228bf80f4bSopenharmony_ci dirSet.insert(pDirent); 1238bf80f4bSopenharmony_ci } 1248bf80f4bSopenharmony_ci 1258bf80f4bSopenharmony_ci for (auto &d : dirSet) { 1268bf80f4bSopenharmony_ci if (d->d_type == DT_DIR) { 1278bf80f4bSopenharmony_ci if (d->d_name[0] == '.') { 1288bf80f4bSopenharmony_ci continue; 1298bf80f4bSopenharmony_ci } 1308bf80f4bSopenharmony_ci add_directory(p + d->d_name, op + d->d_name); 1318bf80f4bSopenharmony_ci continue; 1328bf80f4bSopenharmony_ci } 1338bf80f4bSopenharmony_ci append_file(p + d->d_name, op + d->d_name); 1348bf80f4bSopenharmony_ci } 1358bf80f4bSopenharmony_ci 1368bf80f4bSopenharmony_ci closedir(pDir); 1378bf80f4bSopenharmony_ci} 1388bf80f4bSopenharmony_ci/* 1398bf80f4bSopenharmony_ci * //Pseudo code for accessing files in blob 1408bf80f4bSopenharmony_ci * struct fs_entry 1418bf80f4bSopenharmony_ci * { 1428bf80f4bSopenharmony_ci * char fname[256]; 1438bf80f4bSopenharmony_ci * uint64_t offset; 1448bf80f4bSopenharmony_ci * uint64_t size; 1458bf80f4bSopenharmony_ci * }; 1468bf80f4bSopenharmony_ci * extern "C" uint64_t SizeOfDataForReadOnlyFileSystem; 1478bf80f4bSopenharmony_ci * extern "C" struct fs_entry BinaryDataForReadOnlyFileSystem[]; 1488bf80f4bSopenharmony_ci * void dump_files() 1498bf80f4bSopenharmony_ci * { 1508bf80f4bSopenharmony_ci * for (int i = 0; i < SizeOfDataForReadOnlyFileSystem; i++) 1518bf80f4bSopenharmony_ci * { 1528bf80f4bSopenharmony_ci * if (BinaryDataForReadOnlyFileSystem[i].fname[0] == 0) break; 1538bf80f4bSopenharmony_ci * printf("%s\n", BinaryDataForReadOnlyFileSystem[i].fname); 1548bf80f4bSopenharmony_ci * char* data = (char*)(BinaryDataForReadOnlyFileSystem[i].offset + 1558bf80f4bSopenharmony_ci * (uintptr_t)BinaryDataForReadOnlyFileSystem); printf("%lld\n", BinaryDataForReadOnlyFileSystem[i].offset); 1568bf80f4bSopenharmony_ci * } 1578bf80f4bSopenharmony_ci * } 1588bf80f4bSopenharmony_ci */ 1598bf80f4bSopenharmony_ci 1608bf80f4bSopenharmony_cistd::string gDataName = "BinaryDataForReadOnlyFileSystem"; 1618bf80f4bSopenharmony_cistd::string gSizeName = "SizeOfDataForReadOnlyFileSystem"; 1628bf80f4bSopenharmony_ci 1638bf80f4bSopenharmony_civoid write_obj(const std::string& fname, const std::string& secname, size_t size_of_data, const void* data, bool x64) 1648bf80f4bSopenharmony_ci{ 1658bf80f4bSopenharmony_ci size_t size_of_section = sizeof(uint64_t) + size_of_data; 1668bf80f4bSopenharmony_ci#pragma pack(push, 1) 1678bf80f4bSopenharmony_ci // Using headers and defines from winnt.h 1688bf80f4bSopenharmony_ci struct ObjFile { 1698bf80f4bSopenharmony_ci IMAGE_FILE_HEADER coffHead; 1708bf80f4bSopenharmony_ci IMAGE_SECTION_HEADER sections[1]; 1718bf80f4bSopenharmony_ci IMAGE_SYMBOL symtab[2]; 1728bf80f4bSopenharmony_ci } obj{}; 1738bf80f4bSopenharmony_ci#pragma pack(pop) 1748bf80f4bSopenharmony_ci 1758bf80f4bSopenharmony_ci // fill coff header. 1768bf80f4bSopenharmony_ci if (!x64) 1778bf80f4bSopenharmony_ci obj.coffHead.Machine = IMAGE_FILE_MACHINE_I386; 1788bf80f4bSopenharmony_ci else 1798bf80f4bSopenharmony_ci obj.coffHead.Machine = IMAGE_FILE_MACHINE_AMD64; 1808bf80f4bSopenharmony_ci obj.coffHead.NumberOfSections = sizeof(obj.sections) / sizeof(IMAGE_SECTION_HEADER); 1818bf80f4bSopenharmony_ci obj.coffHead.TimeDateStamp = 0; // duh. 1828bf80f4bSopenharmony_ci obj.coffHead.PointerToSymbolTable = offsetof(decltype(obj), symtab); 1838bf80f4bSopenharmony_ci obj.coffHead.NumberOfSymbols = sizeof(obj.symtab) / sizeof(IMAGE_SYMBOL); 1848bf80f4bSopenharmony_ci obj.coffHead.SizeOfOptionalHeader = 0; 1858bf80f4bSopenharmony_ci obj.coffHead.Characteristics = 0; // if x86 use IMAGE_FILE_32BIT_MACHINE ? 1868bf80f4bSopenharmony_ci 1878bf80f4bSopenharmony_ci // create stringtable 1888bf80f4bSopenharmony_ci char stringtable[256]{ 0 }; 1898bf80f4bSopenharmony_ci char* dst = stringtable; 1908bf80f4bSopenharmony_ci auto add_string = [&dst, &stringtable](std::string_view a) -> Elf32_Word { 1918bf80f4bSopenharmony_ci const auto offset = dst - stringtable; 1928bf80f4bSopenharmony_ci dst += a.copy(dst, 256u - offset); 1938bf80f4bSopenharmony_ci *dst++ = '\0'; 1948bf80f4bSopenharmony_ci return static_cast<uint32_t>(offset + 4); 1958bf80f4bSopenharmony_ci }; 1968bf80f4bSopenharmony_ci 1978bf80f4bSopenharmony_ci // obj.symtab[0].N.Name.Long = add_string("?BinaryDataForReadOnlyFileSystem@@3PAUfs_entry@@A");// 1988bf80f4bSopenharmony_ci // ?BinaryDataForReadOnlyFileSystem@@3PADA"); obj.symtab[1].N.Name.Long = 1998bf80f4bSopenharmony_ci // add_string("?SizeOfDataForReadOnlyFileSystem@@3KA"); 2008bf80f4bSopenharmony_ci if (!x64) { 2018bf80f4bSopenharmony_ci // in win32 the symbols have extra "_" ? 2028bf80f4bSopenharmony_ci std::string t = "_"; 2038bf80f4bSopenharmony_ci t += gDataName; 2048bf80f4bSopenharmony_ci std::string t2 = "_"; 2058bf80f4bSopenharmony_ci t2 += gSizeName; 2068bf80f4bSopenharmony_ci obj.symtab[1].N.Name.Long = add_string(t.c_str() /*"BinaryDataForReadOnlyFileSystem"*/); 2078bf80f4bSopenharmony_ci obj.symtab[0].N.Name.Long = add_string(t2.c_str() /*"SizeOfDataForReadOnlyFileSystem"*/); 2088bf80f4bSopenharmony_ci } else { 2098bf80f4bSopenharmony_ci obj.symtab[1].N.Name.Long = add_string(gDataName.c_str() /*"BinaryDataForReadOnlyFileSystem"*/); 2108bf80f4bSopenharmony_ci obj.symtab[0].N.Name.Long = add_string(gSizeName.c_str() /*"SizeOfDataForReadOnlyFileSystem"*/); 2118bf80f4bSopenharmony_ci } 2128bf80f4bSopenharmony_ci uint32_t stringTableSize = (uint32_t)((dst - stringtable) + 4); 2138bf80f4bSopenharmony_ci 2148bf80f4bSopenharmony_ci // fill the section. 2158bf80f4bSopenharmony_ci memcpy(&obj.sections[0].Name[0], secname.c_str(), secname.size()); 2168bf80f4bSopenharmony_ci obj.sections[0].Misc.VirtualSize = 0; 2178bf80f4bSopenharmony_ci obj.sections[0].VirtualAddress = 0; 2188bf80f4bSopenharmony_ci obj.sections[0].SizeOfRawData = (uint32_t)size_of_section; // sizeof the data on disk. 2198bf80f4bSopenharmony_ci obj.sections[0].PointerToRawData = 2208bf80f4bSopenharmony_ci ((sizeof(obj) + stringTableSize + 3) / 4) * 4; // DWORD align the data directly after the headers.. 2218bf80f4bSopenharmony_ci obj.sections[0].PointerToLinenumbers = 0; 2228bf80f4bSopenharmony_ci obj.sections[0].NumberOfRelocations = 0; 2238bf80f4bSopenharmony_ci obj.sections[0].NumberOfLinenumbers = 0; 2248bf80f4bSopenharmony_ci obj.sections[0].Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ; 2258bf80f4bSopenharmony_ci // fill symbols 2268bf80f4bSopenharmony_ci obj.symtab[1].Value = (uint32_t)sizeof(uint64_t); 2278bf80f4bSopenharmony_ci obj.symtab[1].SectionNumber = 1; // first section.. (one based) 2288bf80f4bSopenharmony_ci obj.symtab[1].Type = IMAGE_SYM_TYPE_CHAR | (IMAGE_SYM_DTYPE_ARRAY << 8); 2298bf80f4bSopenharmony_ci obj.symtab[1].StorageClass = IMAGE_SYM_CLASS_EXTERNAL; 2308bf80f4bSopenharmony_ci obj.symtab[1].NumberOfAuxSymbols = 0; 2318bf80f4bSopenharmony_ci 2328bf80f4bSopenharmony_ci obj.symtab[0].Value = (uint32_t)0; 2338bf80f4bSopenharmony_ci obj.symtab[0].SectionNumber = 1; // first section.. (one based) 2348bf80f4bSopenharmony_ci // obj.symtab[0].Type = IMAGE_SYM_TYPE_UINT; //(just use IMAGE_SYM_TYPE_NULL like mstools?) 2358bf80f4bSopenharmony_ci obj.symtab[0].StorageClass = IMAGE_SYM_CLASS_EXTERNAL; 2368bf80f4bSopenharmony_ci obj.symtab[0].NumberOfAuxSymbols = 0; 2378bf80f4bSopenharmony_ci 2388bf80f4bSopenharmony_ci FILE* d = fopen(fname.c_str(), "wb"); 2398bf80f4bSopenharmony_ci if (d == NULL) { 2408bf80f4bSopenharmony_ci printf("Could not open %s.\n", fname.c_str()); 2418bf80f4bSopenharmony_ci exit(-1); 2428bf80f4bSopenharmony_ci } 2438bf80f4bSopenharmony_ci // write headers 2448bf80f4bSopenharmony_ci fwrite(&obj, sizeof(obj), 1, d); 2458bf80f4bSopenharmony_ci // write string table 2468bf80f4bSopenharmony_ci fwrite(&stringTableSize, 1, sizeof(stringTableSize), d); 2478bf80f4bSopenharmony_ci fwrite(stringtable, 1, stringTableSize - 4, d); 2488bf80f4bSopenharmony_ci // write sections.. 2498bf80f4bSopenharmony_ci size_t p = ftell(d); 2508bf80f4bSopenharmony_ci uint32_t pad = 0; 2518bf80f4bSopenharmony_ci size_t padcount = obj.sections[0].PointerToRawData - p; 2528bf80f4bSopenharmony_ci fwrite(&pad, padcount, 1, d); 2538bf80f4bSopenharmony_ci fwrite(data, size_of_section, 1, d); 2548bf80f4bSopenharmony_ci fclose(d); 2558bf80f4bSopenharmony_ci#undef add_string 2568bf80f4bSopenharmony_ci} 2578bf80f4bSopenharmony_ci 2588bf80f4bSopenharmony_citemplate<class type> 2598bf80f4bSopenharmony_civoid write_elf( 2608bf80f4bSopenharmony_ci type o, uint8_t arch, const std::string& fname, const std::string& secname, size_t size_of_data, const void* data) 2618bf80f4bSopenharmony_ci{ 2628bf80f4bSopenharmony_ci size_t size_of_section = size_of_data + sizeof(uint64_t); 2638bf80f4bSopenharmony_ci char stringtable[256]; 2648bf80f4bSopenharmony_ci o.head.e_type = ET_REL; 2658bf80f4bSopenharmony_ci o.head.e_machine = arch; // machine id.. 2668bf80f4bSopenharmony_ci o.head.e_version = EV_CURRENT; 2678bf80f4bSopenharmony_ci o.head.e_ehsize = sizeof(o.head); 2688bf80f4bSopenharmony_ci o.head.e_shentsize = sizeof(o.sections[0]); 2698bf80f4bSopenharmony_ci o.head.e_shnum = sizeof(o.sections) / sizeof(o.sections[0]); 2708bf80f4bSopenharmony_ci o.head.e_shoff = sizeof(o.head); 2718bf80f4bSopenharmony_ci o.head.e_shstrndx = 1; 2728bf80f4bSopenharmony_ci 2738bf80f4bSopenharmony_ci // initialize stringtable. 2748bf80f4bSopenharmony_ci char* dst = stringtable; 2758bf80f4bSopenharmony_ci *dst = 0; 2768bf80f4bSopenharmony_ci dst++; 2778bf80f4bSopenharmony_ci auto add_string = [&dst, &stringtable](std::string_view a) -> Elf32_Word { 2788bf80f4bSopenharmony_ci const auto offset = dst - stringtable; 2798bf80f4bSopenharmony_ci dst += a.copy(dst, 256u - offset); 2808bf80f4bSopenharmony_ci *dst++ = '\0'; 2818bf80f4bSopenharmony_ci return static_cast<Elf32_Word>(offset); 2828bf80f4bSopenharmony_ci }; 2838bf80f4bSopenharmony_ci 2848bf80f4bSopenharmony_ci // create symbols 2858bf80f4bSopenharmony_ci o.symbs[2].st_name = add_string(gDataName); // ?BinaryDataForReadOnlyFileSystem@@3PADA"); 2868bf80f4bSopenharmony_ci o.symbs[2].st_value = sizeof(uint64_t); 2878bf80f4bSopenharmony_ci o.symbs[2].st_size = static_cast<Elf32_Word>(size_of_data); 2888bf80f4bSopenharmony_ci o.symbs[2].st_info = o.symbs[1].st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT); 2898bf80f4bSopenharmony_ci o.symbs[2].st_other = o.symbs[1].st_other = STV_HIDDEN; 2908bf80f4bSopenharmony_ci o.symbs[2].st_shndx = o.symbs[1].st_shndx = 3; 2918bf80f4bSopenharmony_ci 2928bf80f4bSopenharmony_ci o.symbs[1].st_name = add_string(gSizeName); 2938bf80f4bSopenharmony_ci o.symbs[1].st_value = 0; 2948bf80f4bSopenharmony_ci o.symbs[1].st_size = sizeof(uint64_t); 2958bf80f4bSopenharmony_ci 2968bf80f4bSopenharmony_ci o.sections[2].sh_name = add_string(".symtab"); 2978bf80f4bSopenharmony_ci o.sections[2].sh_type = SHT_SYMTAB; 2988bf80f4bSopenharmony_ci o.sections[2].sh_offset = offsetof(decltype(o), symbs); // sizeof(o) + size_of_section + stringtable_size; 2998bf80f4bSopenharmony_ci o.sections[2].sh_addralign = 8; 3008bf80f4bSopenharmony_ci o.sections[2].sh_size = sizeof(o.symbs); 3018bf80f4bSopenharmony_ci o.sections[2].sh_entsize = sizeof(o.symbs[0]); 3028bf80f4bSopenharmony_ci o.sections[2].sh_link = 1; 3038bf80f4bSopenharmony_ci o.sections[2].sh_info = 1; // index of first non-local symbol. 3048bf80f4bSopenharmony_ci 3058bf80f4bSopenharmony_ci std::string tmp = ".rodata."; 3068bf80f4bSopenharmony_ci tmp += secname; 3078bf80f4bSopenharmony_ci const char* sec; 3088bf80f4bSopenharmony_ci sec = tmp.c_str(); 3098bf80f4bSopenharmony_ci /*sec = ".rodata.rofs"*/ 3108bf80f4bSopenharmony_ci o.sections[3].sh_name = add_string(sec); 3118bf80f4bSopenharmony_ci o.sections[3].sh_type = SHT_PROGBITS; 3128bf80f4bSopenharmony_ci o.sections[3].sh_flags = SHF_ALLOC | SHF_MERGE; 3138bf80f4bSopenharmony_ci o.sections[3].sh_offset = sizeof(o); 3148bf80f4bSopenharmony_ci o.sections[3].sh_addralign = 8; 3158bf80f4bSopenharmony_ci o.sections[3].sh_size = static_cast<Elf32_Word>(size_of_section); 3168bf80f4bSopenharmony_ci 3178bf80f4bSopenharmony_ci o.sections[1].sh_name = add_string(".strtab"); 3188bf80f4bSopenharmony_ci o.sections[1].sh_type = SHT_STRTAB; 3198bf80f4bSopenharmony_ci o.sections[1].sh_offset = static_cast<Elf32_Off>(sizeof(o) + size_of_section); 3208bf80f4bSopenharmony_ci o.sections[1].sh_addralign = 1; 3218bf80f4bSopenharmony_ci o.sections[1].sh_size = static_cast<Elf32_Word>(dst - stringtable); 3228bf80f4bSopenharmony_ci 3238bf80f4bSopenharmony_ci FILE* e = fopen(fname.c_str(), "wb"); 3248bf80f4bSopenharmony_ci if (e == NULL) { 3258bf80f4bSopenharmony_ci printf("Could not open %s.\n", fname.c_str()); 3268bf80f4bSopenharmony_ci exit(-1); 3278bf80f4bSopenharmony_ci } 3288bf80f4bSopenharmony_ci fwrite(&o, sizeof(o), 1, e); 3298bf80f4bSopenharmony_ci fwrite(data, size_of_section, 1, e); 3308bf80f4bSopenharmony_ci fwrite(stringtable, (size_t)o.sections[1].sh_size, 1, e); 3318bf80f4bSopenharmony_ci fclose(e); 3328bf80f4bSopenharmony_ci} 3338bf80f4bSopenharmony_ci 3348bf80f4bSopenharmony_civoid write_macho(const std::string& fname, const std::string& secname, size_t size_of_data_, const void* data) 3358bf80f4bSopenharmony_ci{ 3368bf80f4bSopenharmony_ci#ifdef __APPLE__ 3378bf80f4bSopenharmony_ci // Write fat header for X64_64 and ARM64 object 3388bf80f4bSopenharmony_ci struct fat_header fathdr; 3398bf80f4bSopenharmony_ci fathdr.magic = FAT_CIGAM; 3408bf80f4bSopenharmony_ci fathdr.nfat_arch = htonl(2); // big-endian values in fat header 3418bf80f4bSopenharmony_ci 3428bf80f4bSopenharmony_ci struct fat_arch archs[2] = { 3438bf80f4bSopenharmony_ci { 3448bf80f4bSopenharmony_ci htonl(CPU_TYPE_X86_64), 3458bf80f4bSopenharmony_ci htonl(CPU_SUBTYPE_X86_64_ALL), 3468bf80f4bSopenharmony_ci 0, 3478bf80f4bSopenharmony_ci 0, // size of data TBD 3488bf80f4bSopenharmony_ci htonl(3) 3498bf80f4bSopenharmony_ci }, 3508bf80f4bSopenharmony_ci { 3518bf80f4bSopenharmony_ci htonl(CPU_TYPE_ARM64), 3528bf80f4bSopenharmony_ci htonl(CPU_SUBTYPE_ARM64_ALL), 3538bf80f4bSopenharmony_ci 0, // offset, 3548bf80f4bSopenharmony_ci 0, // size of data TBD 3558bf80f4bSopenharmony_ci htonl(3) 3568bf80f4bSopenharmony_ci }, 3578bf80f4bSopenharmony_ci }; 3588bf80f4bSopenharmony_ci 3598bf80f4bSopenharmony_ci size_t fpos = 0; // "file" offsets are actually relative to the architecture header 3608bf80f4bSopenharmony_ci archs[0].offset = htonl(sizeof(fathdr) + sizeof(archs)); 3618bf80f4bSopenharmony_ci 3628bf80f4bSopenharmony_ci size_t size_of_section = size_of_data_ + sizeof(uint64_t); 3638bf80f4bSopenharmony_ci 3648bf80f4bSopenharmony_ci struct mach_header_64 x64_header = { 3658bf80f4bSopenharmony_ci MH_MAGIC_64, 3668bf80f4bSopenharmony_ci CPU_TYPE_X86_64, 3678bf80f4bSopenharmony_ci CPU_SUBTYPE_X86_64_ALL, 3688bf80f4bSopenharmony_ci MH_OBJECT, 3698bf80f4bSopenharmony_ci 2, // ncmds 3708bf80f4bSopenharmony_ci sizeof(segment_command_64) + sizeof(section_64) + sizeof(symtab_command), // sizeofcmds 3718bf80f4bSopenharmony_ci 0, // flags 3728bf80f4bSopenharmony_ci 0 // reserved 3738bf80f4bSopenharmony_ci }; 3748bf80f4bSopenharmony_ci 3758bf80f4bSopenharmony_ci struct mach_header_64 arm64_header = { 3768bf80f4bSopenharmony_ci MH_MAGIC_64, 3778bf80f4bSopenharmony_ci CPU_TYPE_ARM64, 3788bf80f4bSopenharmony_ci CPU_SUBTYPE_ARM64_ALL, 3798bf80f4bSopenharmony_ci MH_OBJECT, 3808bf80f4bSopenharmony_ci 2, // ncmds 3818bf80f4bSopenharmony_ci sizeof(segment_command_64) + sizeof(section_64) + sizeof(symtab_command), // sizeofcmds 3828bf80f4bSopenharmony_ci 0, // flags 3838bf80f4bSopenharmony_ci 0 // reserved 3848bf80f4bSopenharmony_ci }; 3858bf80f4bSopenharmony_ci 3868bf80f4bSopenharmony_ci struct segment_command_64 data_seg = { 3878bf80f4bSopenharmony_ci LC_SEGMENT_64, 3888bf80f4bSopenharmony_ci sizeof(data_seg) + sizeof(section_64), 3898bf80f4bSopenharmony_ci "", // for object files name is empty 3908bf80f4bSopenharmony_ci 0, // vmaddress 3918bf80f4bSopenharmony_ci (size_of_section + 7) & ~7, // vmsize aligned to 8 bytes 3928bf80f4bSopenharmony_ci 0, // fileoffset = TBD 3938bf80f4bSopenharmony_ci size_of_section, // filesize = TBD 3948bf80f4bSopenharmony_ci VM_PROT_READ, // maxprot 3958bf80f4bSopenharmony_ci VM_PROT_READ, // initprot 3968bf80f4bSopenharmony_ci 1, // nsects 3978bf80f4bSopenharmony_ci SG_NORELOC // flags 3988bf80f4bSopenharmony_ci }; 3998bf80f4bSopenharmony_ci 4008bf80f4bSopenharmony_ci struct section_64 data_sect = { 4018bf80f4bSopenharmony_ci "__const", 4028bf80f4bSopenharmony_ci "__DATA", 4038bf80f4bSopenharmony_ci 0, // addr 4048bf80f4bSopenharmony_ci size_of_section, // vmsize aligned to 8 bytes 4058bf80f4bSopenharmony_ci 0, // offset = TBD 4068bf80f4bSopenharmony_ci 3, // alignment = 2^3 = 8 bytes 4078bf80f4bSopenharmony_ci 0, // reloff 4088bf80f4bSopenharmony_ci 0, // nreloc 4098bf80f4bSopenharmony_ci S_REGULAR, // flags 4108bf80f4bSopenharmony_ci 0, // reserved1 4118bf80f4bSopenharmony_ci 0, // reserved2 4128bf80f4bSopenharmony_ci }; 4138bf80f4bSopenharmony_ci 4148bf80f4bSopenharmony_ci std::string dataName = "_"; 4158bf80f4bSopenharmony_ci dataName += gDataName; 4168bf80f4bSopenharmony_ci std::string sizeName = "_"; 4178bf80f4bSopenharmony_ci sizeName += gSizeName; 4188bf80f4bSopenharmony_ci 4198bf80f4bSopenharmony_ci uint32_t string_size = dataName.size() + sizeName.size() + 3; // prepending plus two terminating nulls 4208bf80f4bSopenharmony_ci 4218bf80f4bSopenharmony_ci struct symtab_command symtab = { 4228bf80f4bSopenharmony_ci LC_SYMTAB, 4238bf80f4bSopenharmony_ci sizeof(symtab), 4248bf80f4bSopenharmony_ci 0, // symoff = TBD 4258bf80f4bSopenharmony_ci 2, // nsyms 4268bf80f4bSopenharmony_ci 0, // stroff = TBD 4278bf80f4bSopenharmony_ci string_size, // strsize 4288bf80f4bSopenharmony_ci }; 4298bf80f4bSopenharmony_ci 4308bf80f4bSopenharmony_ci fpos += sizeof(x64_header) + sizeof(data_seg) + sizeof(data_sect) + sizeof(symtab); 4318bf80f4bSopenharmony_ci 4328bf80f4bSopenharmony_ci data_seg.fileoff = static_cast<uint32_t>(fpos); 4338bf80f4bSopenharmony_ci data_sect.offset = static_cast<uint32_t>(fpos); 4348bf80f4bSopenharmony_ci fpos += size_of_section; 4358bf80f4bSopenharmony_ci 4368bf80f4bSopenharmony_ci size_t sectionAligned = (fpos + 7) & ~7; 4378bf80f4bSopenharmony_ci uint32_t sectionAlign = sectionAligned - fpos; 4388bf80f4bSopenharmony_ci fpos = sectionAligned; 4398bf80f4bSopenharmony_ci 4408bf80f4bSopenharmony_ci symtab.symoff = static_cast<uint32_t>(fpos); 4418bf80f4bSopenharmony_ci 4428bf80f4bSopenharmony_ci struct nlist_64 syms[2] = { 4438bf80f4bSopenharmony_ci { 4448bf80f4bSopenharmony_ci 1, // first string 4458bf80f4bSopenharmony_ci N_EXT | N_SECT, 4468bf80f4bSopenharmony_ci 1, // segment 4478bf80f4bSopenharmony_ci REFERENCE_FLAG_DEFINED, 4488bf80f4bSopenharmony_ci 0 4498bf80f4bSopenharmony_ci }, 4508bf80f4bSopenharmony_ci { 4518bf80f4bSopenharmony_ci static_cast<uint32_t>(sizeName.size() + 2), // second string 4528bf80f4bSopenharmony_ci N_EXT | N_SECT, 4538bf80f4bSopenharmony_ci 1, // segment 4548bf80f4bSopenharmony_ci REFERENCE_FLAG_DEFINED, 4558bf80f4bSopenharmony_ci 8 4568bf80f4bSopenharmony_ci } 4578bf80f4bSopenharmony_ci }; 4588bf80f4bSopenharmony_ci 4598bf80f4bSopenharmony_ci fpos += sizeof(syms); 4608bf80f4bSopenharmony_ci 4618bf80f4bSopenharmony_ci symtab.stroff = static_cast<uint32_t>(fpos); 4628bf80f4bSopenharmony_ci fpos += string_size; 4638bf80f4bSopenharmony_ci 4648bf80f4bSopenharmony_ci archs[0].size = htonl(fpos); 4658bf80f4bSopenharmony_ci 4668bf80f4bSopenharmony_ci size_t aligned = (fpos + 7) & ~7; 4678bf80f4bSopenharmony_ci uint32_t align = aligned - fpos; 4688bf80f4bSopenharmony_ci archs[1].offset = htonl(aligned + sizeof(fathdr) + sizeof(archs)); 4698bf80f4bSopenharmony_ci archs[1].size = archs[0].size; 4708bf80f4bSopenharmony_ci 4718bf80f4bSopenharmony_ci FILE* e = fopen(fname.c_str(), "wb"); 4728bf80f4bSopenharmony_ci if (e == NULL) { 4738bf80f4bSopenharmony_ci printf("Could not open %s.\n", fname.c_str()); 4748bf80f4bSopenharmony_ci exit(-1); 4758bf80f4bSopenharmony_ci } 4768bf80f4bSopenharmony_ci 4778bf80f4bSopenharmony_ci fwrite(&fathdr, sizeof(fathdr), 1, e); 4788bf80f4bSopenharmony_ci fwrite(&archs, sizeof(archs), 1, e); 4798bf80f4bSopenharmony_ci fwrite(&x64_header, sizeof(x64_header), 1, e); 4808bf80f4bSopenharmony_ci fwrite(&data_seg, sizeof(data_seg), 1, e); 4818bf80f4bSopenharmony_ci fwrite(&data_sect, sizeof(data_sect), 1, e); 4828bf80f4bSopenharmony_ci fwrite(&symtab, sizeof(symtab), 1, e); 4838bf80f4bSopenharmony_ci fwrite(data, size_of_section, 1, e); 4848bf80f4bSopenharmony_ci for(int i = 0; i < sectionAlign; i++) { 4858bf80f4bSopenharmony_ci fputc(0, e); // alignment byte to begin string table 8 byte boundary 4868bf80f4bSopenharmony_ci } 4878bf80f4bSopenharmony_ci fwrite(&syms, sizeof(syms), 1, e); 4888bf80f4bSopenharmony_ci fputc(0, e); // filler byte to begin string table as it starts indexing at 1 4898bf80f4bSopenharmony_ci fwrite(sizeName.c_str(), sizeName.size() + 1, 1, e); 4908bf80f4bSopenharmony_ci fwrite(dataName.c_str(), dataName.size() + 1, 1, e); 4918bf80f4bSopenharmony_ci 4928bf80f4bSopenharmony_ci for(int i = 0; i < align; i++) { 4938bf80f4bSopenharmony_ci fputc(0, e); // alignment byte to begin arm64 architecture at 8 byte boundary 4948bf80f4bSopenharmony_ci } 4958bf80f4bSopenharmony_ci 4968bf80f4bSopenharmony_ci fwrite(&arm64_header, sizeof(arm64_header), 1, e); 4978bf80f4bSopenharmony_ci fwrite(&data_seg, sizeof(data_seg), 1, e); 4988bf80f4bSopenharmony_ci fwrite(&data_sect, sizeof(data_sect), 1, e); 4998bf80f4bSopenharmony_ci fwrite(&symtab, sizeof(symtab), 1, e); 5008bf80f4bSopenharmony_ci fwrite(data, size_of_section, 1, e); 5018bf80f4bSopenharmony_ci for(int i = 0; i < sectionAlign; i++) { 5028bf80f4bSopenharmony_ci fputc(0, e); // alignment byte to begin string table 8 byte boundary 5038bf80f4bSopenharmony_ci } 5048bf80f4bSopenharmony_ci fwrite(&syms, sizeof(syms), 1, e); 5058bf80f4bSopenharmony_ci fputc(0, e); // filler byte to begin string table 5068bf80f4bSopenharmony_ci fwrite(sizeName.c_str(), sizeName.size() + 1, 1, e); 5078bf80f4bSopenharmony_ci fwrite(dataName.c_str(), dataName.size() + 1, 1, e); 5088bf80f4bSopenharmony_ci fclose(e); 5098bf80f4bSopenharmony_ci#endif 5108bf80f4bSopenharmony_ci} 5118bf80f4bSopenharmony_ci 5128bf80f4bSopenharmony_ciint main(int argc, char* argv[]) 5138bf80f4bSopenharmony_ci{ 5148bf80f4bSopenharmony_ci std::string obj32Name = "rofs_32.obj"; 5158bf80f4bSopenharmony_ci std::string obj64Name = "rofs_64.obj"; 5168bf80f4bSopenharmony_ci std::string o32Name = "rofs_32.o"; 5178bf80f4bSopenharmony_ci std::string o64Name = "rofs_64.o"; 5188bf80f4bSopenharmony_ci std::string x32Name = "rofs_x86.o"; 5198bf80f4bSopenharmony_ci std::string x64Name = "rofs_x64.o"; 5208bf80f4bSopenharmony_ci std::string macName = "rofs_mac.o"; 5218bf80f4bSopenharmony_ci std::string secName = "rofs"; 5228bf80f4bSopenharmony_ci 5238bf80f4bSopenharmony_ci bool buildX86 = true, buildX64 = true, buildV7 = true, buildV8 = true; 5248bf80f4bSopenharmony_ci bool buildWindows = true, buildAndroid = true, buildMac = true; 5258bf80f4bSopenharmony_ci 5268bf80f4bSopenharmony_ci std::string inPath = { "" }, roPath = { "" }; 5278bf80f4bSopenharmony_ci 5288bf80f4bSopenharmony_ci int baseArg = 0; 5298bf80f4bSopenharmony_ci if (argc >= 2) { 5308bf80f4bSopenharmony_ci if (argv[1][0] == '-') { 5318bf80f4bSopenharmony_ci buildAndroid = false; 5328bf80f4bSopenharmony_ci buildWindows = false; 5338bf80f4bSopenharmony_ci buildMac = false; 5348bf80f4bSopenharmony_ci buildX86 = buildX64 = buildV7 = buildV8 = false; 5358bf80f4bSopenharmony_ci } 5368bf80f4bSopenharmony_ci bool platset = false; 5378bf80f4bSopenharmony_ci for (;;) { 5388bf80f4bSopenharmony_ci if (baseArg + 1 >= argc) { 5398bf80f4bSopenharmony_ci printf("Invalid argument!\n"); 5408bf80f4bSopenharmony_ci return 0; 5418bf80f4bSopenharmony_ci } 5428bf80f4bSopenharmony_ci if (argv[baseArg + 1][0] != '-') 5438bf80f4bSopenharmony_ci break; 5448bf80f4bSopenharmony_ci if (strcmp(argv[baseArg + 1], "-linux") == 0) { 5458bf80f4bSopenharmony_ci platset = true; 5468bf80f4bSopenharmony_ci buildAndroid = true; 5478bf80f4bSopenharmony_ci baseArg++; 5488bf80f4bSopenharmony_ci } else if (strcmp(argv[baseArg + 1], "-android") == 0) { 5498bf80f4bSopenharmony_ci platset = true; 5508bf80f4bSopenharmony_ci buildAndroid = true; 5518bf80f4bSopenharmony_ci baseArg++; 5528bf80f4bSopenharmony_ci } else if (strcmp(argv[baseArg + 1], "-windows") == 0) { 5538bf80f4bSopenharmony_ci platset = true; 5548bf80f4bSopenharmony_ci buildWindows = true; 5558bf80f4bSopenharmony_ci baseArg++; 5568bf80f4bSopenharmony_ci } else if (strcmp(argv[baseArg + 1], "-mac") == 0) { 5578bf80f4bSopenharmony_ci platset = true; 5588bf80f4bSopenharmony_ci buildMac = true; 5598bf80f4bSopenharmony_ci baseArg++; 5608bf80f4bSopenharmony_ci } else if (strcmp(argv[baseArg + 1], "-x86") == 0) { 5618bf80f4bSopenharmony_ci buildX86 = true; 5628bf80f4bSopenharmony_ci baseArg++; 5638bf80f4bSopenharmony_ci } else if (strcmp(argv[baseArg + 1], "-x86_64") == 0) { 5648bf80f4bSopenharmony_ci buildAndroid = true; 5658bf80f4bSopenharmony_ci buildX64 = true; 5668bf80f4bSopenharmony_ci baseArg++; 5678bf80f4bSopenharmony_ci } else if (strcmp(argv[baseArg + 1], "-x64") == 0) { 5688bf80f4bSopenharmony_ci buildX64 = true; 5698bf80f4bSopenharmony_ci buildWindows = true; 5708bf80f4bSopenharmony_ci baseArg++; 5718bf80f4bSopenharmony_ci } else if (strcmp(argv[baseArg + 1], "-armeabi-v7a") == 0) { 5728bf80f4bSopenharmony_ci buildV7 = true; 5738bf80f4bSopenharmony_ci buildAndroid = true; 5748bf80f4bSopenharmony_ci platset = true; 5758bf80f4bSopenharmony_ci baseArg++; 5768bf80f4bSopenharmony_ci } else if (strcmp(argv[baseArg + 1], "-arm64-v8a") == 0) { 5778bf80f4bSopenharmony_ci buildV8 = true; 5788bf80f4bSopenharmony_ci buildAndroid = true; 5798bf80f4bSopenharmony_ci platset = true; 5808bf80f4bSopenharmony_ci baseArg++; 5818bf80f4bSopenharmony_ci } else if (strcmp(argv[baseArg + 1], "-extensions") == 0) { 5828bf80f4bSopenharmony_ci baseArg++; 5838bf80f4bSopenharmony_ci if (baseArg + 1 >= argc) { 5848bf80f4bSopenharmony_ci printf("Invalid argument!\n"); 5858bf80f4bSopenharmony_ci return 0; 5868bf80f4bSopenharmony_ci } 5878bf80f4bSopenharmony_ci auto exts = std::string_view(argv[baseArg + 1]); 5888bf80f4bSopenharmony_ci while (!exts.empty()) { 5898bf80f4bSopenharmony_ci auto pos = exts.find(';'); 5908bf80f4bSopenharmony_ci pos = std::min(pos, exts.size()); 5918bf80f4bSopenharmony_ci valid_exts.push_back(exts.substr(0, pos)); 5928bf80f4bSopenharmony_ci exts.remove_prefix(std::min(pos + 1, exts.size())); 5938bf80f4bSopenharmony_ci } 5948bf80f4bSopenharmony_ci baseArg++; 5958bf80f4bSopenharmony_ci } else { 5968bf80f4bSopenharmony_ci printf("Invalid argument!\n"); 5978bf80f4bSopenharmony_ci return 0; 5988bf80f4bSopenharmony_ci } 5998bf80f4bSopenharmony_ci } 6008bf80f4bSopenharmony_ci if (!platset) { 6018bf80f4bSopenharmony_ci buildWindows = true; 6028bf80f4bSopenharmony_ci buildAndroid = true; 6038bf80f4bSopenharmony_ci buildMac = true; 6048bf80f4bSopenharmony_ci } 6058bf80f4bSopenharmony_ci 6068bf80f4bSopenharmony_ci if (argc < baseArg + 3) { 6078bf80f4bSopenharmony_ci printf("invalid args"); 6088bf80f4bSopenharmony_ci return 0; 6098bf80f4bSopenharmony_ci } 6108bf80f4bSopenharmony_ci 6118bf80f4bSopenharmony_ci inPath = argv[baseArg + 1]; 6128bf80f4bSopenharmony_ci } else { 6138bf80f4bSopenharmony_ci printf("Not enough arguments!\n"); 6148bf80f4bSopenharmony_ci return 0; 6158bf80f4bSopenharmony_ci } 6168bf80f4bSopenharmony_ci if (argc >= baseArg + 3) { 6178bf80f4bSopenharmony_ci if (argv[baseArg + 2][0] == '/') { 6188bf80f4bSopenharmony_ci roPath = argv[baseArg + 2] + 1; 6198bf80f4bSopenharmony_ci } else { 6208bf80f4bSopenharmony_ci roPath = argv[baseArg + 2]; 6218bf80f4bSopenharmony_ci } 6228bf80f4bSopenharmony_ci } 6238bf80f4bSopenharmony_ci if (argc >= baseArg + 5) { 6248bf80f4bSopenharmony_ci gDataName = argv[baseArg + 3]; 6258bf80f4bSopenharmony_ci gSizeName = argv[baseArg + 4]; 6268bf80f4bSopenharmony_ci } 6278bf80f4bSopenharmony_ci if (argc == baseArg + 6) { 6288bf80f4bSopenharmony_ci secName = obj32Name = obj64Name = o32Name = o64Name = x32Name = x64Name = macName = argv[baseArg + 5]; 6298bf80f4bSopenharmony_ci obj32Name += "_32.obj"; 6308bf80f4bSopenharmony_ci obj64Name += "_64.obj"; 6318bf80f4bSopenharmony_ci o32Name += "_32.o"; 6328bf80f4bSopenharmony_ci o64Name += "_64.o"; 6338bf80f4bSopenharmony_ci x32Name += "_x86.o"; 6348bf80f4bSopenharmony_ci x64Name += "_x64.o"; 6358bf80f4bSopenharmony_ci macName += "_mac.o"; 6368bf80f4bSopenharmony_ci } 6378bf80f4bSopenharmony_ci add_directory(inPath, roPath); 6388bf80f4bSopenharmony_ci 6398bf80f4bSopenharmony_ci // fix offsets 6408bf80f4bSopenharmony_ci size_t base_offset = sizeof(fs_entry) * (directory.size() + 1); 6418bf80f4bSopenharmony_ci for (auto& d : directory) { 6428bf80f4bSopenharmony_ci d.offset += base_offset; 6438bf80f4bSopenharmony_ci } 6448bf80f4bSopenharmony_ci 6458bf80f4bSopenharmony_ci // add terminator 6468bf80f4bSopenharmony_ci directory.push_back({ { 0 }, 0, 0 }); 6478bf80f4bSopenharmony_ci 6488bf80f4bSopenharmony_ci const size_t size_of_dir = (sizeof(fs_entry) * directory.size()); 6498bf80f4bSopenharmony_ci const size_t size_of_data = bin.size() + size_of_dir; 6508bf80f4bSopenharmony_ci uint8_t* data = new uint8_t[size_of_data + sizeof(uint64_t)]; 6518bf80f4bSopenharmony_ci *(uint64_t*)(data) = size_of_data; 6528bf80f4bSopenharmony_ci memcpy(data + sizeof(uint64_t), directory.data(), size_of_dir); 6538bf80f4bSopenharmony_ci memcpy(data + sizeof(uint64_t) + size_of_dir, bin.data(), bin.size()); 6548bf80f4bSopenharmony_ci 6558bf80f4bSopenharmony_ci // Build obj 6568bf80f4bSopenharmony_ci if (buildWindows) { 6578bf80f4bSopenharmony_ci if (buildX86) { 6588bf80f4bSopenharmony_ci write_obj(obj32Name, secName, size_of_data, data, false); 6598bf80f4bSopenharmony_ci } 6608bf80f4bSopenharmony_ci if (buildX64) { 6618bf80f4bSopenharmony_ci write_obj(obj64Name, secName, size_of_data, data, true); 6628bf80f4bSopenharmony_ci } 6638bf80f4bSopenharmony_ci } 6648bf80f4bSopenharmony_ci // Create .elf (.o) 6658bf80f4bSopenharmony_ci if (buildAndroid) { 6668bf80f4bSopenharmony_ci struct { 6678bf80f4bSopenharmony_ci Elf32_Ehdr head{}; 6688bf80f4bSopenharmony_ci Elf32_Shdr sections[4]{}; 6698bf80f4bSopenharmony_ci Elf32_Sym symbs[3]{}; 6708bf80f4bSopenharmony_ci } o32; 6718bf80f4bSopenharmony_ci struct { 6728bf80f4bSopenharmony_ci Elf64_Ehdr head{}; 6738bf80f4bSopenharmony_ci Elf64_Shdr sections[4]{}; 6748bf80f4bSopenharmony_ci Elf64_Sym symbs[3]{}; 6758bf80f4bSopenharmony_ci } o64; 6768bf80f4bSopenharmony_ci if (buildV7) { 6778bf80f4bSopenharmony_ci write_elf(o32, EM_ARM, o32Name, secName, size_of_data, data); 6788bf80f4bSopenharmony_ci } 6798bf80f4bSopenharmony_ci if (buildV8) { 6808bf80f4bSopenharmony_ci write_elf(o64, EM_AARCH64, o64Name, secName, size_of_data, data); 6818bf80f4bSopenharmony_ci } 6828bf80f4bSopenharmony_ci if (buildX86) { 6838bf80f4bSopenharmony_ci write_elf(o32, EM_386, x32Name, secName, size_of_data, data); 6848bf80f4bSopenharmony_ci } 6858bf80f4bSopenharmony_ci if (buildX64) { 6868bf80f4bSopenharmony_ci write_elf(o64, EM_X86_64, x64Name, secName, size_of_data, data); 6878bf80f4bSopenharmony_ci } 6888bf80f4bSopenharmony_ci } 6898bf80f4bSopenharmony_ci // Create mach-o (.o) 6908bf80f4bSopenharmony_ci if (buildMac) { 6918bf80f4bSopenharmony_ci write_macho(macName, secName, size_of_data, data); 6928bf80f4bSopenharmony_ci } 6938bf80f4bSopenharmony_ci} 694