1// Copyright 2019 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "src/snapshot/embedded/platform-embedded-file-writer-base.h" 6 7#include <string> 8 9#include "src/base/platform/wrappers.h" 10#include "src/common/globals.h" 11#include "src/snapshot/embedded/platform-embedded-file-writer-aix.h" 12#include "src/snapshot/embedded/platform-embedded-file-writer-generic.h" 13#include "src/snapshot/embedded/platform-embedded-file-writer-mac.h" 14#include "src/snapshot/embedded/platform-embedded-file-writer-win.h" 15 16namespace v8 { 17namespace internal { 18 19DataDirective PointerSizeDirective() { 20 if (kSystemPointerSize == 8) { 21 return kQuad; 22 } else { 23 CHECK_EQ(4, kSystemPointerSize); 24 return kLong; 25 } 26} 27 28int PlatformEmbeddedFileWriterBase::HexLiteral(uint64_t value) { 29 return fprintf(fp_, "0x%" PRIx64, value); 30} 31 32int DataDirectiveSize(DataDirective directive) { 33 switch (directive) { 34 case kByte: 35 return 1; 36 case kLong: 37 return 4; 38 case kQuad: 39 return 8; 40 case kOcta: 41 return 16; 42 } 43 UNREACHABLE(); 44} 45 46int PlatformEmbeddedFileWriterBase::WriteByteChunk(const uint8_t* data) { 47 size_t kSize = DataDirectiveSize(ByteChunkDataDirective()); 48 size_t kHalfSize = kSize / 2; 49 uint64_t high = 0, low = 0; 50 51 switch (kSize) { 52 case 1: 53 low = *data; 54 break; 55 case 4: 56 low = *reinterpret_cast<const uint32_t*>(data); 57 break; 58 case 8: 59 low = *reinterpret_cast<const uint64_t*>(data); 60 break; 61 case 16: 62#ifdef V8_TARGET_BIG_ENDIAN 63 memcpy(&high, data, kHalfSize); 64 memcpy(&low, data + kHalfSize, kHalfSize); 65#else 66 memcpy(&high, data + kHalfSize, kHalfSize); 67 memcpy(&low, data, kHalfSize); 68#endif // V8_TARGET_BIG_ENDIAN 69 break; 70 default: 71 UNREACHABLE(); 72 } 73 74 if (high != 0) { 75 return fprintf(fp(), "0x%" PRIx64 "%016" PRIx64, high, low); 76 } else { 77 return fprintf(fp(), "0x%" PRIx64, low); 78 } 79} 80 81namespace { 82 83EmbeddedTargetArch DefaultEmbeddedTargetArch() { 84#if defined(V8_TARGET_ARCH_ARM) 85 return EmbeddedTargetArch::kArm; 86#elif defined(V8_TARGET_ARCH_ARM64) 87 return EmbeddedTargetArch::kArm64; 88#elif defined(V8_TARGET_ARCH_IA32) 89 return EmbeddedTargetArch::kIA32; 90#elif defined(V8_TARGET_ARCH_X64) 91 return EmbeddedTargetArch::kX64; 92#else 93 return EmbeddedTargetArch::kGeneric; 94#endif 95} 96 97EmbeddedTargetArch ToEmbeddedTargetArch(const char* s) { 98 if (s == nullptr) { 99 return DefaultEmbeddedTargetArch(); 100 } 101 102 std::string string(s); 103 if (string == "arm") { 104 return EmbeddedTargetArch::kArm; 105 } else if (string == "arm64") { 106 return EmbeddedTargetArch::kArm64; 107 } else if (string == "ia32") { 108 return EmbeddedTargetArch::kIA32; 109 } else if (string == "x64") { 110 return EmbeddedTargetArch::kX64; 111 } else { 112 return EmbeddedTargetArch::kGeneric; 113 } 114} 115 116EmbeddedTargetOs DefaultEmbeddedTargetOs() { 117#if defined(V8_OS_AIX) 118 return EmbeddedTargetOs::kAIX; 119#elif defined(V8_OS_DARWIN) 120 return EmbeddedTargetOs::kMac; 121#elif defined(V8_OS_WIN) 122 return EmbeddedTargetOs::kWin; 123#else 124 return EmbeddedTargetOs::kGeneric; 125#endif 126} 127 128EmbeddedTargetOs ToEmbeddedTargetOs(const char* s) { 129 if (s == nullptr) { 130 return DefaultEmbeddedTargetOs(); 131 } 132 133 std::string string(s); 134 if (string == "aix") { 135 return EmbeddedTargetOs::kAIX; 136 } else if (string == "chromeos") { 137 return EmbeddedTargetOs::kChromeOS; 138 } else if (string == "fuchsia") { 139 return EmbeddedTargetOs::kFuchsia; 140 } else if (string == "ios" || string == "mac") { 141 return EmbeddedTargetOs::kMac; 142 } else if (string == "win") { 143 return EmbeddedTargetOs::kWin; 144 } else if (string == "starboard") { 145 return EmbeddedTargetOs::kStarboard; 146 } else { 147 return EmbeddedTargetOs::kGeneric; 148 } 149} 150 151} // namespace 152 153std::unique_ptr<PlatformEmbeddedFileWriterBase> NewPlatformEmbeddedFileWriter( 154 const char* target_arch, const char* target_os) { 155 auto embedded_target_arch = ToEmbeddedTargetArch(target_arch); 156 auto embedded_target_os = ToEmbeddedTargetOs(target_os); 157 158 if (embedded_target_os == EmbeddedTargetOs::kStarboard) { 159 // target OS is "Starboard" for all starboard build so we need to 160 // use host OS macros to decide which writer to use. 161 // Cobalt also has Windows-based Posix target platform, 162 // in which case generic writer should be used. 163 switch (DefaultEmbeddedTargetOs()) { 164 case EmbeddedTargetOs::kMac: 165#if defined(V8_TARGET_OS_WIN) 166 case EmbeddedTargetOs::kWin: 167 // V8_TARGET_OS_WIN is used to enable WINDOWS-specific assembly code, 168 // for windows-hosted non-windows targets, we should still fallback to 169 // the generic writer. 170#endif 171 embedded_target_os = DefaultEmbeddedTargetOs(); 172 break; 173 default: 174 // In the block below, we will use WriterGeneric for other cases. 175 break; 176 } 177 } 178 179 if (embedded_target_os == EmbeddedTargetOs::kAIX) { 180 return std::make_unique<PlatformEmbeddedFileWriterAIX>(embedded_target_arch, 181 embedded_target_os); 182 } else if (embedded_target_os == EmbeddedTargetOs::kMac) { 183 return std::make_unique<PlatformEmbeddedFileWriterMac>(embedded_target_arch, 184 embedded_target_os); 185 } else if (embedded_target_os == EmbeddedTargetOs::kWin) { 186 return std::make_unique<PlatformEmbeddedFileWriterWin>(embedded_target_arch, 187 embedded_target_os); 188 } else { 189 return std::make_unique<PlatformEmbeddedFileWriterGeneric>( 190 embedded_target_arch, embedded_target_os); 191 } 192 193 UNREACHABLE(); 194} 195 196} // namespace internal 197} // namespace v8 198