V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
embedded-file-writer.cc
1 // Copyright 2018 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-file-writer.h"
6 
7 #include <cinttypes>
8 
9 namespace v8 {
10 namespace internal {
11 
12 // V8_CC_MSVC is true for both MSVC and clang on windows. clang can handle
13 // __asm__-style inline assembly but MSVC cannot, and thus we need a more
14 // precise compiler detection that can distinguish between the two. clang on
15 // windows sets both __clang__ and _MSC_VER, MSVC sets only _MSC_VER.
16 #if defined(_MSC_VER) && !defined(__clang__)
17 #define V8_COMPILER_IS_MSVC
18 #endif
19 
20 // Name mangling.
21 // Symbols are prefixed with an underscore on 32-bit architectures.
22 #if defined(V8_OS_WIN) && !defined(V8_TARGET_ARCH_X64) && \
23  !defined(V8_TARGET_ARCH_ARM64)
24 #define SYMBOL_PREFIX "_"
25 #else
26 #define SYMBOL_PREFIX ""
27 #endif
28 
29 // Platform-independent bits.
30 // -----------------------------------------------------------------------------
31 
32 namespace {
33 
34 DataDirective PointerSizeDirective() {
35  if (kPointerSize == 8) {
36  return kQuad;
37  } else {
38  CHECK_EQ(4, kPointerSize);
39  return kLong;
40  }
41 }
42 
43 } // namespace
44 
45 const char* DirectiveAsString(DataDirective directive) {
46 #if defined(V8_OS_WIN) && defined(V8_COMPILER_IS_MSVC)
47  switch (directive) {
48  case kByte:
49  return "BYTE";
50  case kLong:
51  return "DWORD";
52  case kQuad:
53  return "QWORD";
54  default:
55  UNREACHABLE();
56  }
57 #else
58  switch (directive) {
59  case kByte:
60  return ".byte";
61  case kLong:
62  return ".long";
63  case kQuad:
64  return ".quad";
65  case kOcta:
66  return ".octa";
67  }
68  UNREACHABLE();
69 #endif
70 }
71 
72 // V8_OS_MACOSX
73 // -----------------------------------------------------------------------------
74 
75 #if defined(V8_OS_MACOSX)
76 
77 void PlatformDependentEmbeddedFileWriter::SectionText() {
78  fprintf(fp_, ".text\n");
79 }
80 
81 void PlatformDependentEmbeddedFileWriter::SectionData() {
82  fprintf(fp_, ".data\n");
83 }
84 
85 void PlatformDependentEmbeddedFileWriter::SectionRoData() {
86  fprintf(fp_, ".const_data\n");
87 }
88 
89 void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
90  uint32_t value) {
91  DeclareSymbolGlobal(name);
92  DeclareLabel(name);
93  IndentedDataDirective(kLong);
94  fprintf(fp_, "%d", value);
95  Newline();
96 }
97 
98 void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
99  const char* name, const char* target) {
100  DeclareSymbolGlobal(name);
101  DeclareLabel(name);
102  fprintf(fp_, " %s _%s\n", DirectiveAsString(PointerSizeDirective()), target);
103 }
104 
105 void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
106  const char* name) {
107  // TODO(jgruber): Investigate switching to .globl. Using .private_extern
108  // prevents something along the compilation chain from messing with the
109  // embedded blob. Using .global here causes embedded blob hash verification
110  // failures at runtime.
111  fprintf(fp_, ".private_extern _%s\n", name);
112 }
113 
114 void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
115  fprintf(fp_, ".balign 32\n");
116 }
117 
118 void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
119  fprintf(fp_, "// %s\n", string);
120 }
121 
122 void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
123  fprintf(fp_, "_%s:\n", name);
124 }
125 
126 void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
127  const char* name) {
128  DeclareLabel(name);
129 
130  // TODO(mvstanton): Investigate the proper incantations to mark the label as
131  // a function on OSX.
132 }
133 
134 void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
135 }
136 
137 int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
138  return fprintf(fp_, "0x%" PRIx64, value);
139 }
140 
141 void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
142 
143 void PlatformDependentEmbeddedFileWriter::FileEpilogue() {}
144 
145 int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
146  DataDirective directive) {
147  return fprintf(fp_, " %s ", DirectiveAsString(directive));
148 }
149 
150 // V8_OS_AIX
151 // -----------------------------------------------------------------------------
152 
153 #elif defined(V8_OS_AIX)
154 
155 // TODO(aix): Update custom logic previously contained in section header macros.
156 // See
157 // https://cs.chromium.org/chromium/src/v8/src/snapshot/macros.h?l=81&rcl=31b2546b348e864539ade15897eac971b3c0e402
158 
159 void PlatformDependentEmbeddedFileWriter::SectionText() {
160  fprintf(fp_, ".csect .text[PR]\n");
161 }
162 
163 void PlatformDependentEmbeddedFileWriter::SectionData() {
164  // TODO(aix): Confirm and update if needed.
165  fprintf(fp_, ".csect .data[RW]\n");
166 }
167 
168 void PlatformDependentEmbeddedFileWriter::SectionRoData() {
169  fprintf(fp_, ".csect[RO]\n");
170 }
171 
172 void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
173  uint32_t value) {
174  DeclareSymbolGlobal(name);
175  DeclareLabel(name);
176  IndentedDataDirective(kLong);
177  fprintf(fp_, "%d", value);
178  Newline();
179 }
180 
181 void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
182  const char* name, const char* target) {
183  DeclareSymbolGlobal(name);
184  DeclareLabel(name);
185  fprintf(fp_, " %s %s\n", DirectiveAsString(PointerSizeDirective()), target);
186  Newline();
187 }
188 
189 void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
190  const char* name) {
191  fprintf(fp_, ".globl %s\n", name);
192 }
193 
194 void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
195  fprintf(fp_, ".balign 32\n");
196 }
197 
198 void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
199  fprintf(fp_, "// %s\n", string);
200 }
201 
202 void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
203  fprintf(fp_, "%s:\n", name);
204 }
205 
206 void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
207  const char* name) {
208  DeclareLabel(name);
209 }
210 
211 void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
212 }
213 
214 int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
215  return fprintf(fp_, "0x%" PRIx64, value);
216 }
217 
218 void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
219 
220 void PlatformDependentEmbeddedFileWriter::FileEpilogue() {}
221 
222 int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
223  DataDirective directive) {
224  return fprintf(fp_, " %s ", DirectiveAsString(directive));
225 }
226 
227 // V8_OS_WIN (MSVC)
228 // -----------------------------------------------------------------------------
229 
230 #elif defined(V8_OS_WIN) && defined(V8_COMPILER_IS_MSVC)
231 
232 // For MSVC builds we emit assembly in MASM syntax.
233 // See https://docs.microsoft.com/en-us/cpp/assembler/masm/directives-reference.
234 
235 void PlatformDependentEmbeddedFileWriter::SectionText() {
236  fprintf(fp_, ".CODE\n");
237 }
238 
239 void PlatformDependentEmbeddedFileWriter::SectionData() {
240  fprintf(fp_, ".DATA\n");
241 }
242 
243 void PlatformDependentEmbeddedFileWriter::SectionRoData() {
244  fprintf(fp_, ".CONST\n");
245 }
246 
247 void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
248  uint32_t value) {
249  DeclareSymbolGlobal(name);
250  fprintf(fp_, "%s%s %s %d\n", SYMBOL_PREFIX, name, DirectiveAsString(kLong),
251  value);
252 }
253 
254 void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
255  const char* name, const char* target) {
256  DeclareSymbolGlobal(name);
257  fprintf(fp_, "%s%s %s %s%s\n", SYMBOL_PREFIX, name,
258  DirectiveAsString(PointerSizeDirective()), SYMBOL_PREFIX, target);
259 }
260 
261 void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
262  const char* name) {
263  fprintf(fp_, "PUBLIC %s%s\n", SYMBOL_PREFIX, name);
264 }
265 
266 void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
267  // Diverges from other platforms due to compile error
268  // 'invalid combination with segment alignment'.
269  fprintf(fp_, "ALIGN 4\n");
270 }
271 
272 void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
273  fprintf(fp_, "; %s\n", string);
274 }
275 
276 void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
277  fprintf(fp_, "%s%s LABEL %s\n", SYMBOL_PREFIX, name,
278  DirectiveAsString(kByte));
279 }
280 
281 void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
282  const char* name) {
283  fprintf(fp_, "%s%s PROC\n", SYMBOL_PREFIX, name);
284 }
285 
286 void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
287  fprintf(fp_, "%s%s ENDP\n", SYMBOL_PREFIX, name);
288 }
289 
290 int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
291  return fprintf(fp_, "0%" PRIx64 "h", value);
292 }
293 
294 void PlatformDependentEmbeddedFileWriter::FilePrologue() {
295 #if !defined(V8_TARGET_ARCH_X64) && !defined(V8_TARGET_ARCH_ARM64)
296  fprintf(fp_, ".MODEL FLAT\n");
297 #endif
298 }
299 
300 void PlatformDependentEmbeddedFileWriter::FileEpilogue() {
301  fprintf(fp_, "END\n");
302 }
303 
304 int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
305  DataDirective directive) {
306  return fprintf(fp_, " %s ", DirectiveAsString(directive));
307 }
308 
309 // Everything but AIX, Windows with MSVC, or OSX.
310 // -----------------------------------------------------------------------------
311 
312 #else
313 
314 void PlatformDependentEmbeddedFileWriter::SectionText() {
315 #ifdef OS_CHROMEOS
316  fprintf(fp_, ".section .text.hot.embedded\n");
317 #else
318  fprintf(fp_, ".section .text\n");
319 #endif
320 }
321 
322 void PlatformDependentEmbeddedFileWriter::SectionData() {
323  fprintf(fp_, ".section .data\n");
324 }
325 
326 void PlatformDependentEmbeddedFileWriter::SectionRoData() {
327  fprintf(fp_, ".section .rodata\n");
328 }
329 
330 void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
331  uint32_t value) {
332  DeclareSymbolGlobal(name);
333  DeclareLabel(name);
334  IndentedDataDirective(kLong);
335  fprintf(fp_, "%d", value);
336  Newline();
337 }
338 
339 void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
340  const char* name, const char* target) {
341  DeclareSymbolGlobal(name);
342  DeclareLabel(name);
343  fprintf(fp_, " %s %s%s\n", DirectiveAsString(PointerSizeDirective()),
344  SYMBOL_PREFIX, target);
345 }
346 
347 void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
348  const char* name) {
349  fprintf(fp_, ".global %s%s\n", SYMBOL_PREFIX, name);
350 }
351 
352 void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
353  fprintf(fp_, ".balign 32\n");
354 }
355 
356 void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
357  fprintf(fp_, "// %s\n", string);
358 }
359 
360 void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
361  fprintf(fp_, "%s%s:\n", SYMBOL_PREFIX, name);
362 }
363 
364 void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
365  const char* name) {
366  DeclareLabel(name);
367 
368 #if defined(V8_OS_WIN)
369  // The directives for inserting debugging information on Windows come
370  // from the PE (Portable Executable) and COFF (Common Object File Format)
371  // standards. Documented here:
372  // https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format
373  //
374  // .scl 2 means StorageClass external.
375  // .type 32 means Type Representation Function.
376  fprintf(fp_, ".def %s%s; .scl 2; .type 32; .endef;\n", SYMBOL_PREFIX, name);
377 #elif defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_ARM64)
378  // ELF format binaries on ARM use ".type <function name>, %function"
379  // to create a DWARF subprogram entry.
380  fprintf(fp_, ".type %s, %%function\n", name);
381 #else
382  // Other ELF Format binaries use ".type <function name>, @function"
383  // to create a DWARF subprogram entry.
384  fprintf(fp_, ".type %s, @function\n", name);
385 #endif
386 }
387 
388 void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
389 }
390 
391 int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
392  return fprintf(fp_, "0x%" PRIx64, value);
393 }
394 
395 void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
396 
397 void PlatformDependentEmbeddedFileWriter::FileEpilogue() {}
398 
399 int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
400  DataDirective directive) {
401  return fprintf(fp_, " %s ", DirectiveAsString(directive));
402 }
403 
404 #endif
405 
406 #undef SYMBOL_PREFIX
407 #undef V8_COMPILER_IS_MSVC
408 
409 } // namespace internal
410 } // namespace v8
Definition: libplatform.h:13