11cb0ef41Sopenharmony_ci// Copyright 2019 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/snapshot/embedded/platform-embedded-file-writer-base.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <string>
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci#include "src/base/platform/wrappers.h"
101cb0ef41Sopenharmony_ci#include "src/common/globals.h"
111cb0ef41Sopenharmony_ci#include "src/snapshot/embedded/platform-embedded-file-writer-aix.h"
121cb0ef41Sopenharmony_ci#include "src/snapshot/embedded/platform-embedded-file-writer-generic.h"
131cb0ef41Sopenharmony_ci#include "src/snapshot/embedded/platform-embedded-file-writer-mac.h"
141cb0ef41Sopenharmony_ci#include "src/snapshot/embedded/platform-embedded-file-writer-win.h"
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_cinamespace v8 {
171cb0ef41Sopenharmony_cinamespace internal {
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ciDataDirective PointerSizeDirective() {
201cb0ef41Sopenharmony_ci  if (kSystemPointerSize == 8) {
211cb0ef41Sopenharmony_ci    return kQuad;
221cb0ef41Sopenharmony_ci  } else {
231cb0ef41Sopenharmony_ci    CHECK_EQ(4, kSystemPointerSize);
241cb0ef41Sopenharmony_ci    return kLong;
251cb0ef41Sopenharmony_ci  }
261cb0ef41Sopenharmony_ci}
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ciint PlatformEmbeddedFileWriterBase::HexLiteral(uint64_t value) {
291cb0ef41Sopenharmony_ci  return fprintf(fp_, "0x%" PRIx64, value);
301cb0ef41Sopenharmony_ci}
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ciint DataDirectiveSize(DataDirective directive) {
331cb0ef41Sopenharmony_ci  switch (directive) {
341cb0ef41Sopenharmony_ci    case kByte:
351cb0ef41Sopenharmony_ci      return 1;
361cb0ef41Sopenharmony_ci    case kLong:
371cb0ef41Sopenharmony_ci      return 4;
381cb0ef41Sopenharmony_ci    case kQuad:
391cb0ef41Sopenharmony_ci      return 8;
401cb0ef41Sopenharmony_ci    case kOcta:
411cb0ef41Sopenharmony_ci      return 16;
421cb0ef41Sopenharmony_ci  }
431cb0ef41Sopenharmony_ci  UNREACHABLE();
441cb0ef41Sopenharmony_ci}
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ciint PlatformEmbeddedFileWriterBase::WriteByteChunk(const uint8_t* data) {
471cb0ef41Sopenharmony_ci  size_t kSize = DataDirectiveSize(ByteChunkDataDirective());
481cb0ef41Sopenharmony_ci  size_t kHalfSize = kSize / 2;
491cb0ef41Sopenharmony_ci  uint64_t high = 0, low = 0;
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci  switch (kSize) {
521cb0ef41Sopenharmony_ci    case 1:
531cb0ef41Sopenharmony_ci      low = *data;
541cb0ef41Sopenharmony_ci      break;
551cb0ef41Sopenharmony_ci    case 4:
561cb0ef41Sopenharmony_ci      low = *reinterpret_cast<const uint32_t*>(data);
571cb0ef41Sopenharmony_ci      break;
581cb0ef41Sopenharmony_ci    case 8:
591cb0ef41Sopenharmony_ci      low = *reinterpret_cast<const uint64_t*>(data);
601cb0ef41Sopenharmony_ci      break;
611cb0ef41Sopenharmony_ci    case 16:
621cb0ef41Sopenharmony_ci#ifdef V8_TARGET_BIG_ENDIAN
631cb0ef41Sopenharmony_ci      memcpy(&high, data, kHalfSize);
641cb0ef41Sopenharmony_ci      memcpy(&low, data + kHalfSize, kHalfSize);
651cb0ef41Sopenharmony_ci#else
661cb0ef41Sopenharmony_ci      memcpy(&high, data + kHalfSize, kHalfSize);
671cb0ef41Sopenharmony_ci      memcpy(&low, data, kHalfSize);
681cb0ef41Sopenharmony_ci#endif  // V8_TARGET_BIG_ENDIAN
691cb0ef41Sopenharmony_ci      break;
701cb0ef41Sopenharmony_ci    default:
711cb0ef41Sopenharmony_ci      UNREACHABLE();
721cb0ef41Sopenharmony_ci  }
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  if (high != 0) {
751cb0ef41Sopenharmony_ci    return fprintf(fp(), "0x%" PRIx64 "%016" PRIx64, high, low);
761cb0ef41Sopenharmony_ci  } else {
771cb0ef41Sopenharmony_ci    return fprintf(fp(), "0x%" PRIx64, low);
781cb0ef41Sopenharmony_ci  }
791cb0ef41Sopenharmony_ci}
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_cinamespace {
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ciEmbeddedTargetArch DefaultEmbeddedTargetArch() {
841cb0ef41Sopenharmony_ci#if defined(V8_TARGET_ARCH_ARM)
851cb0ef41Sopenharmony_ci  return EmbeddedTargetArch::kArm;
861cb0ef41Sopenharmony_ci#elif defined(V8_TARGET_ARCH_ARM64)
871cb0ef41Sopenharmony_ci  return EmbeddedTargetArch::kArm64;
881cb0ef41Sopenharmony_ci#elif defined(V8_TARGET_ARCH_IA32)
891cb0ef41Sopenharmony_ci  return EmbeddedTargetArch::kIA32;
901cb0ef41Sopenharmony_ci#elif defined(V8_TARGET_ARCH_X64)
911cb0ef41Sopenharmony_ci  return EmbeddedTargetArch::kX64;
921cb0ef41Sopenharmony_ci#else
931cb0ef41Sopenharmony_ci  return EmbeddedTargetArch::kGeneric;
941cb0ef41Sopenharmony_ci#endif
951cb0ef41Sopenharmony_ci}
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ciEmbeddedTargetArch ToEmbeddedTargetArch(const char* s) {
981cb0ef41Sopenharmony_ci  if (s == nullptr) {
991cb0ef41Sopenharmony_ci    return DefaultEmbeddedTargetArch();
1001cb0ef41Sopenharmony_ci  }
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci  std::string string(s);
1031cb0ef41Sopenharmony_ci  if (string == "arm") {
1041cb0ef41Sopenharmony_ci    return EmbeddedTargetArch::kArm;
1051cb0ef41Sopenharmony_ci  } else if (string == "arm64") {
1061cb0ef41Sopenharmony_ci    return EmbeddedTargetArch::kArm64;
1071cb0ef41Sopenharmony_ci  } else if (string == "ia32") {
1081cb0ef41Sopenharmony_ci    return EmbeddedTargetArch::kIA32;
1091cb0ef41Sopenharmony_ci  } else if (string == "x64") {
1101cb0ef41Sopenharmony_ci    return EmbeddedTargetArch::kX64;
1111cb0ef41Sopenharmony_ci  } else {
1121cb0ef41Sopenharmony_ci    return EmbeddedTargetArch::kGeneric;
1131cb0ef41Sopenharmony_ci  }
1141cb0ef41Sopenharmony_ci}
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ciEmbeddedTargetOs DefaultEmbeddedTargetOs() {
1171cb0ef41Sopenharmony_ci#if defined(V8_OS_AIX)
1181cb0ef41Sopenharmony_ci  return EmbeddedTargetOs::kAIX;
1191cb0ef41Sopenharmony_ci#elif defined(V8_OS_DARWIN)
1201cb0ef41Sopenharmony_ci  return EmbeddedTargetOs::kMac;
1211cb0ef41Sopenharmony_ci#elif defined(V8_OS_WIN)
1221cb0ef41Sopenharmony_ci  return EmbeddedTargetOs::kWin;
1231cb0ef41Sopenharmony_ci#else
1241cb0ef41Sopenharmony_ci  return EmbeddedTargetOs::kGeneric;
1251cb0ef41Sopenharmony_ci#endif
1261cb0ef41Sopenharmony_ci}
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ciEmbeddedTargetOs ToEmbeddedTargetOs(const char* s) {
1291cb0ef41Sopenharmony_ci  if (s == nullptr) {
1301cb0ef41Sopenharmony_ci    return DefaultEmbeddedTargetOs();
1311cb0ef41Sopenharmony_ci  }
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci  std::string string(s);
1341cb0ef41Sopenharmony_ci  if (string == "aix") {
1351cb0ef41Sopenharmony_ci    return EmbeddedTargetOs::kAIX;
1361cb0ef41Sopenharmony_ci  } else if (string == "chromeos") {
1371cb0ef41Sopenharmony_ci    return EmbeddedTargetOs::kChromeOS;
1381cb0ef41Sopenharmony_ci  } else if (string == "fuchsia") {
1391cb0ef41Sopenharmony_ci    return EmbeddedTargetOs::kFuchsia;
1401cb0ef41Sopenharmony_ci  } else if (string == "ios" || string == "mac") {
1411cb0ef41Sopenharmony_ci    return EmbeddedTargetOs::kMac;
1421cb0ef41Sopenharmony_ci  } else if (string == "win") {
1431cb0ef41Sopenharmony_ci    return EmbeddedTargetOs::kWin;
1441cb0ef41Sopenharmony_ci  } else if (string == "starboard") {
1451cb0ef41Sopenharmony_ci    return EmbeddedTargetOs::kStarboard;
1461cb0ef41Sopenharmony_ci  } else {
1471cb0ef41Sopenharmony_ci    return EmbeddedTargetOs::kGeneric;
1481cb0ef41Sopenharmony_ci  }
1491cb0ef41Sopenharmony_ci}
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci}  // namespace
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_cistd::unique_ptr<PlatformEmbeddedFileWriterBase> NewPlatformEmbeddedFileWriter(
1541cb0ef41Sopenharmony_ci    const char* target_arch, const char* target_os) {
1551cb0ef41Sopenharmony_ci  auto embedded_target_arch = ToEmbeddedTargetArch(target_arch);
1561cb0ef41Sopenharmony_ci  auto embedded_target_os = ToEmbeddedTargetOs(target_os);
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ci  if (embedded_target_os == EmbeddedTargetOs::kStarboard) {
1591cb0ef41Sopenharmony_ci    // target OS is "Starboard" for all starboard build so we need to
1601cb0ef41Sopenharmony_ci    // use host OS macros to decide which writer to use.
1611cb0ef41Sopenharmony_ci    // Cobalt also has Windows-based Posix target platform,
1621cb0ef41Sopenharmony_ci    // in which case generic writer should be used.
1631cb0ef41Sopenharmony_ci    switch (DefaultEmbeddedTargetOs()) {
1641cb0ef41Sopenharmony_ci      case EmbeddedTargetOs::kMac:
1651cb0ef41Sopenharmony_ci#if defined(V8_TARGET_OS_WIN)
1661cb0ef41Sopenharmony_ci      case EmbeddedTargetOs::kWin:
1671cb0ef41Sopenharmony_ci        // V8_TARGET_OS_WIN is used to enable WINDOWS-specific assembly code,
1681cb0ef41Sopenharmony_ci        // for windows-hosted non-windows targets, we should still fallback to
1691cb0ef41Sopenharmony_ci        // the generic writer.
1701cb0ef41Sopenharmony_ci#endif
1711cb0ef41Sopenharmony_ci        embedded_target_os = DefaultEmbeddedTargetOs();
1721cb0ef41Sopenharmony_ci        break;
1731cb0ef41Sopenharmony_ci      default:
1741cb0ef41Sopenharmony_ci        // In the block below, we will use WriterGeneric for other cases.
1751cb0ef41Sopenharmony_ci        break;
1761cb0ef41Sopenharmony_ci    }
1771cb0ef41Sopenharmony_ci  }
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ci  if (embedded_target_os == EmbeddedTargetOs::kAIX) {
1801cb0ef41Sopenharmony_ci    return std::make_unique<PlatformEmbeddedFileWriterAIX>(embedded_target_arch,
1811cb0ef41Sopenharmony_ci                                                           embedded_target_os);
1821cb0ef41Sopenharmony_ci  } else if (embedded_target_os == EmbeddedTargetOs::kMac) {
1831cb0ef41Sopenharmony_ci    return std::make_unique<PlatformEmbeddedFileWriterMac>(embedded_target_arch,
1841cb0ef41Sopenharmony_ci                                                           embedded_target_os);
1851cb0ef41Sopenharmony_ci  } else if (embedded_target_os == EmbeddedTargetOs::kWin) {
1861cb0ef41Sopenharmony_ci    return std::make_unique<PlatformEmbeddedFileWriterWin>(embedded_target_arch,
1871cb0ef41Sopenharmony_ci                                                           embedded_target_os);
1881cb0ef41Sopenharmony_ci  } else {
1891cb0ef41Sopenharmony_ci    return std::make_unique<PlatformEmbeddedFileWriterGeneric>(
1901cb0ef41Sopenharmony_ci        embedded_target_arch, embedded_target_os);
1911cb0ef41Sopenharmony_ci  }
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ci  UNREACHABLE();
1941cb0ef41Sopenharmony_ci}
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci}  // namespace internal
1971cb0ef41Sopenharmony_ci}  // namespace v8
198