| // Copyright 2019 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/snapshot/embedded/platform-embedded-file-writer-base.h" |
| |
| #include <string> |
| |
| #include "src/base/platform/wrappers.h" |
| #include "src/common/globals.h" |
| #include "src/snapshot/embedded/platform-embedded-file-writer-aix.h" |
| #include "src/snapshot/embedded/platform-embedded-file-writer-generic.h" |
| #include "src/snapshot/embedded/platform-embedded-file-writer-mac.h" |
| #include "src/snapshot/embedded/platform-embedded-file-writer-win.h" |
| |
| namespace v8 { |
| namespace internal { |
| |
| DataDirective PointerSizeDirective() { |
| if (kSystemPointerSize == 8) { |
| return kQuad; |
| } else { |
| CHECK_EQ(4, kSystemPointerSize); |
| return kLong; |
| } |
| } |
| |
| int PlatformEmbeddedFileWriterBase::HexLiteral(uint64_t value) { |
| return fprintf(fp_, "0x%" PRIx64, value); |
| } |
| |
| int DataDirectiveSize(DataDirective directive) { |
| switch (directive) { |
| case kByte: |
| return 1; |
| case kLong: |
| return 4; |
| case kQuad: |
| return 8; |
| case kOcta: |
| return 16; |
| } |
| UNREACHABLE(); |
| } |
| |
| int PlatformEmbeddedFileWriterBase::WriteByteChunk(const uint8_t* data) { |
| size_t kSize = DataDirectiveSize(ByteChunkDataDirective()); |
| size_t kHalfSize = kSize / 2; |
| uint64_t high = 0, low = 0; |
| |
| switch (kSize) { |
| case 1: |
| low = *data; |
| break; |
| case 4: |
| low = *reinterpret_cast<const uint32_t*>(data); |
| break; |
| case 8: |
| low = *reinterpret_cast<const uint64_t*>(data); |
| break; |
| case 16: |
| #ifdef V8_TARGET_BIG_ENDIAN |
| memcpy(&high, data, kHalfSize); |
| memcpy(&low, data + kHalfSize, kHalfSize); |
| #else |
| memcpy(&high, data + kHalfSize, kHalfSize); |
| memcpy(&low, data, kHalfSize); |
| #endif // V8_TARGET_BIG_ENDIAN |
| break; |
| default: |
| UNREACHABLE(); |
| } |
| |
| if (high != 0) { |
| return fprintf(fp(), "0x%" PRIx64 "%016" PRIx64, high, low); |
| } else { |
| return fprintf(fp(), "0x%" PRIx64, low); |
| } |
| } |
| |
| namespace { |
| |
| EmbeddedTargetArch DefaultEmbeddedTargetArch() { |
| #if defined(V8_TARGET_ARCH_ARM) |
| return EmbeddedTargetArch::kArm; |
| #elif defined(V8_TARGET_ARCH_ARM64) |
| return EmbeddedTargetArch::kArm64; |
| #elif defined(V8_TARGET_ARCH_IA32) |
| return EmbeddedTargetArch::kIA32; |
| #elif defined(V8_TARGET_ARCH_X64) |
| return EmbeddedTargetArch::kX64; |
| #else |
| return EmbeddedTargetArch::kGeneric; |
| #endif |
| } |
| |
| EmbeddedTargetArch ToEmbeddedTargetArch(const char* s) { |
| if (s == nullptr) { |
| return DefaultEmbeddedTargetArch(); |
| } |
| |
| std::string string(s); |
| if (string == "arm") { |
| return EmbeddedTargetArch::kArm; |
| } else if (string == "arm64") { |
| return EmbeddedTargetArch::kArm64; |
| } else if (string == "ia32") { |
| return EmbeddedTargetArch::kIA32; |
| } else if (string == "x64") { |
| return EmbeddedTargetArch::kX64; |
| } else { |
| return EmbeddedTargetArch::kGeneric; |
| } |
| } |
| |
| EmbeddedTargetOs DefaultEmbeddedTargetOs() { |
| #if defined(V8_OS_AIX) |
| return EmbeddedTargetOs::kAIX; |
| #elif defined(V8_OS_MACOSX) |
| return EmbeddedTargetOs::kMac; |
| #elif defined(V8_OS_WIN) |
| return EmbeddedTargetOs::kWin; |
| #else |
| return EmbeddedTargetOs::kGeneric; |
| #endif |
| } |
| |
| EmbeddedTargetOs ToEmbeddedTargetOs(const char* s) { |
| if (s == nullptr) { |
| return DefaultEmbeddedTargetOs(); |
| } |
| |
| std::string string(s); |
| if (string == "aix") { |
| return EmbeddedTargetOs::kAIX; |
| } else if (string == "chromeos") { |
| return EmbeddedTargetOs::kChromeOS; |
| } else if (string == "fuchsia") { |
| return EmbeddedTargetOs::kFuchsia; |
| } else if (string == "ios" || string == "mac") { |
| return EmbeddedTargetOs::kMac; |
| } else if (string == "win") { |
| return EmbeddedTargetOs::kWin; |
| } else if (string == "starboard") { |
| return EmbeddedTargetOs::kStarboard; |
| } else { |
| return EmbeddedTargetOs::kGeneric; |
| } |
| } |
| |
| } // namespace |
| |
| std::unique_ptr<PlatformEmbeddedFileWriterBase> NewPlatformEmbeddedFileWriter( |
| const char* target_arch, const char* target_os) { |
| auto embedded_target_arch = ToEmbeddedTargetArch(target_arch); |
| auto embedded_target_os = ToEmbeddedTargetOs(target_os); |
| |
| if (embedded_target_os == EmbeddedTargetOs::kStarboard) { |
| // target OS is "Starboard" for all starboard build so we need to |
| // use host OS macros to decide which writer to use. |
| // Cobalt also has Windows-based Posix target platform, |
| // in which case generic writer should be used. |
| switch(DefaultEmbeddedTargetOs()) { |
| case EmbeddedTargetOs::kMac: |
| #if defined(V8_TARGET_OS_WIN) |
| case EmbeddedTargetOs::kWin: |
| // V8_TARGET_OS_WIN is used to enable WINDOWS-specific assembly code, |
| // for windows-hosted non-windows targets, we should still fallback to |
| // the generic writer. |
| #endif |
| embedded_target_os = DefaultEmbeddedTargetOs(); |
| break; |
| default: |
| // In the block below, we will use WriterGeneric for other cases. |
| break; |
| } |
| } |
| |
| if (embedded_target_os == EmbeddedTargetOs::kAIX) { |
| return std::make_unique<PlatformEmbeddedFileWriterAIX>(embedded_target_arch, |
| embedded_target_os); |
| } else if (embedded_target_os == EmbeddedTargetOs::kMac) { |
| return std::make_unique<PlatformEmbeddedFileWriterMac>(embedded_target_arch, |
| embedded_target_os); |
| } else if (embedded_target_os == EmbeddedTargetOs::kWin) { |
| return std::make_unique<PlatformEmbeddedFileWriterWin>(embedded_target_arch, |
| embedded_target_os); |
| } else { |
| return std::make_unique<PlatformEmbeddedFileWriterGeneric>( |
| embedded_target_arch, embedded_target_os); |
| } |
| |
| UNREACHABLE(); |
| } |
| |
| } // namespace internal |
| } // namespace v8 |