• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 namespace v8 {
17 namespace internal {
18 
PointerSizeDirective()19 DataDirective PointerSizeDirective() {
20   if (kSystemPointerSize == 8) {
21     return kQuad;
22   } else {
23     CHECK_EQ(4, kSystemPointerSize);
24     return kLong;
25   }
26 }
27 
HexLiteral(uint64_t value)28 int PlatformEmbeddedFileWriterBase::HexLiteral(uint64_t value) {
29   return fprintf(fp_, "0x%" PRIx64, value);
30 }
31 
DataDirectiveSize(DataDirective directive)32 int 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 
WriteByteChunk(const uint8_t * data)46 int 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 
81 namespace {
82 
DefaultEmbeddedTargetArch()83 EmbeddedTargetArch 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 
ToEmbeddedTargetArch(const char * s)97 EmbeddedTargetArch 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 
DefaultEmbeddedTargetOs()116 EmbeddedTargetOs 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 
ToEmbeddedTargetOs(const char * s)128 EmbeddedTargetOs 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 
NewPlatformEmbeddedFileWriter(const char * target_arch,const char * target_os)153 std::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