Line data Source code
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 <algorithm>
8 : #include <cinttypes>
9 :
10 : #include "src/objects/code-inl.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 : // V8_CC_MSVC is true for both MSVC and clang on windows. clang can handle
16 : // __asm__-style inline assembly but MSVC cannot, and thus we need a more
17 : // precise compiler detection that can distinguish between the two. clang on
18 : // windows sets both __clang__ and _MSC_VER, MSVC sets only _MSC_VER.
19 : #if defined(_MSC_VER) && !defined(__clang__)
20 : #define V8_COMPILER_IS_MSVC
21 : #endif
22 :
23 : // MSVC uses MASM for x86 and x64, while it has a ARMASM for ARM32 and
24 : // ARMASM64 for ARM64. Since ARMASM and ARMASM64 accept a slightly tweaked
25 : // version of ARM assembly language, they are referred to together in Visual
26 : // Studio project files as MARMASM.
27 : //
28 : // ARM assembly language docs:
29 : // http://infocenter.arm.com/help/topic/com.arm.doc.dui0802b/index.html
30 : // Microsoft ARM assembler and assembly language docs:
31 : // https://docs.microsoft.com/en-us/cpp/assembler/arm/arm-assembler-reference
32 : #if defined(V8_COMPILER_IS_MSVC)
33 : #if defined(V8_TARGET_ARCH_ARM64) || defined(V8_TARGET_ARCH_ARM)
34 : #define V8_ASSEMBLER_IS_MARMASM
35 : #elif defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X64)
36 : #define V8_ASSEMBLER_IS_MASM
37 : #else
38 : #error Unknown Windows assembler target architecture.
39 : #endif
40 : #endif
41 :
42 : // Name mangling.
43 : // Symbols are prefixed with an underscore on 32-bit architectures.
44 : #if defined(V8_TARGET_OS_WIN) && !defined(V8_TARGET_ARCH_X64) && \
45 : !defined(V8_TARGET_ARCH_ARM64)
46 : #define SYMBOL_PREFIX "_"
47 : #else
48 : #define SYMBOL_PREFIX ""
49 : #endif
50 :
51 : // Platform-independent bits.
52 : // -----------------------------------------------------------------------------
53 :
54 : namespace {
55 :
56 : DataDirective PointerSizeDirective() {
57 : if (kSystemPointerSize == 8) {
58 : return kQuad;
59 : } else {
60 : CHECK_EQ(4, kSystemPointerSize);
61 : return kLong;
62 : }
63 : }
64 :
65 : } // namespace
66 :
67 45074 : const char* DirectiveAsString(DataDirective directive) {
68 : #if defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MASM)
69 : switch (directive) {
70 : case kByte:
71 : return "BYTE";
72 : case kLong:
73 : return "DWORD";
74 : case kQuad:
75 : return "QWORD";
76 : default:
77 : UNREACHABLE();
78 : }
79 : #elif defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MARMASM)
80 : switch (directive) {
81 : case kByte:
82 : return "DCB";
83 : case kLong:
84 : return "DCDU";
85 : case kQuad:
86 : return "DCQU";
87 : default:
88 : UNREACHABLE();
89 : }
90 : #elif defined(V8_OS_AIX)
91 : switch (directive) {
92 : case kByte:
93 : return ".byte";
94 : case kLong:
95 : return ".long";
96 : case kQuad:
97 : return ".llong";
98 : default:
99 : UNREACHABLE();
100 : }
101 : #else
102 45074 : switch (directive) {
103 : case kByte:
104 : return ".byte";
105 : case kLong:
106 1 : return ".long";
107 : case kQuad:
108 1 : return ".quad";
109 : case kOcta:
110 42479 : return ".octa";
111 : }
112 0 : UNREACHABLE();
113 : #endif
114 : }
115 :
116 1 : void EmbeddedFileWriter::PrepareBuiltinSourcePositionMap(Builtins* builtins) {
117 3031 : for (int i = 0; i < Builtins::builtin_count; i++) {
118 : // Retrieve the SourcePositionTable and copy it.
119 1515 : Code code = builtins->builtin(i);
120 : // Verify that the code object is still the "real code" and not a
121 : // trampoline (which wouldn't have source positions).
122 : DCHECK(!code->is_off_heap_trampoline());
123 : std::vector<unsigned char> data(
124 3030 : code->SourcePositionTable()->GetDataStartAddress(),
125 3030 : code->SourcePositionTable()->GetDataEndAddress());
126 1515 : source_positions_[i] = data;
127 : }
128 1 : }
129 :
130 : // V8_OS_MACOSX
131 : // Fuchsia target is explicitly excluded here for Mac hosts. This is to avoid
132 : // generating uncompilable assembly files for the Fuchsia target.
133 : // -----------------------------------------------------------------------------
134 :
135 : #if defined(V8_OS_MACOSX) && !defined(V8_TARGET_OS_FUCHSIA)
136 :
137 : void PlatformDependentEmbeddedFileWriter::SectionText() {
138 : fprintf(fp_, ".text\n");
139 : }
140 :
141 : void PlatformDependentEmbeddedFileWriter::SectionData() {
142 : fprintf(fp_, ".data\n");
143 : }
144 :
145 : void PlatformDependentEmbeddedFileWriter::SectionRoData() {
146 : fprintf(fp_, ".const_data\n");
147 : }
148 :
149 : void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
150 : uint32_t value) {
151 : DeclareSymbolGlobal(name);
152 : DeclareLabel(name);
153 : IndentedDataDirective(kLong);
154 : fprintf(fp_, "%d", value);
155 : Newline();
156 : }
157 :
158 : void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
159 : const char* name, const char* target) {
160 : DeclareSymbolGlobal(name);
161 : DeclareLabel(name);
162 : fprintf(fp_, " %s _%s\n", DirectiveAsString(PointerSizeDirective()), target);
163 : }
164 :
165 : void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
166 : const char* name) {
167 : // TODO(jgruber): Investigate switching to .globl. Using .private_extern
168 : // prevents something along the compilation chain from messing with the
169 : // embedded blob. Using .global here causes embedded blob hash verification
170 : // failures at runtime.
171 : fprintf(fp_, ".private_extern _%s\n", name);
172 : }
173 :
174 : void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
175 : fprintf(fp_, ".balign 32\n");
176 : }
177 :
178 : void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
179 : fprintf(fp_, ".balign 8\n");
180 : }
181 :
182 : void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
183 : fprintf(fp_, "// %s\n", string);
184 : }
185 :
186 : void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
187 : fprintf(fp_, "_%s:\n", name);
188 : }
189 :
190 : void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid,
191 : const char* filename,
192 : int line) {
193 : fprintf(fp_, ".loc %d %d\n", fileid, line);
194 : }
195 :
196 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
197 : const char* name) {
198 : DeclareLabel(name);
199 :
200 : // TODO(mvstanton): Investigate the proper incantations to mark the label as
201 : // a function on OSX.
202 : }
203 :
204 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
205 : }
206 :
207 : int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
208 : return fprintf(fp_, "0x%" PRIx64, value);
209 : }
210 :
211 : void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
212 :
213 : void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
214 : int fileid, const char* filename) {
215 : fprintf(fp_, ".file %d \"%s\"\n", fileid, filename);
216 : }
217 :
218 : void PlatformDependentEmbeddedFileWriter::FileEpilogue() {}
219 :
220 : int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
221 : DataDirective directive) {
222 : return fprintf(fp_, " %s ", DirectiveAsString(directive));
223 : }
224 :
225 : // V8_OS_AIX
226 : // -----------------------------------------------------------------------------
227 :
228 : #elif defined(V8_OS_AIX)
229 :
230 : void PlatformDependentEmbeddedFileWriter::SectionText() {
231 : fprintf(fp_, ".csect .text[PR]\n");
232 : }
233 :
234 : void PlatformDependentEmbeddedFileWriter::SectionData() {
235 : fprintf(fp_, ".csect .data[RW]\n");
236 : }
237 :
238 : void PlatformDependentEmbeddedFileWriter::SectionRoData() {
239 : fprintf(fp_, ".csect[RO]\n");
240 : }
241 :
242 : void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
243 : uint32_t value) {
244 : DeclareSymbolGlobal(name);
245 : fprintf(fp_, ".align 2\n");
246 : fprintf(fp_, "%s:\n", name);
247 : IndentedDataDirective(kLong);
248 : fprintf(fp_, "%d\n", value);
249 : Newline();
250 : }
251 :
252 : void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
253 : const char* name, const char* target) {
254 : AlignToCodeAlignment();
255 : DeclareLabel(name);
256 : fprintf(fp_, " %s %s\n", DirectiveAsString(PointerSizeDirective()), target);
257 : Newline();
258 : }
259 :
260 : void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
261 : const char* name) {
262 : fprintf(fp_, ".globl %s\n", name);
263 : }
264 :
265 : void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
266 : fprintf(fp_, ".align 5\n");
267 : }
268 :
269 : void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
270 : fprintf(fp_, ".align 3\n");
271 : }
272 :
273 : void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
274 : fprintf(fp_, "// %s\n", string);
275 : }
276 :
277 : void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
278 : DeclareSymbolGlobal(name);
279 : fprintf(fp_, "%s:\n", name);
280 : }
281 :
282 : void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid,
283 : const char* filename,
284 : int line) {
285 : fprintf(fp_, ".xline %d, \"%s\"\n", line, filename);
286 : }
287 :
288 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
289 : const char* name) {
290 : Newline();
291 : DeclareSymbolGlobal(name);
292 : fprintf(fp_, ".csect %s[DS]\n", name); // function descriptor
293 : fprintf(fp_, "%s:\n", name);
294 : fprintf(fp_, ".llong .%s, 0, 0\n", name);
295 : SectionText();
296 : fprintf(fp_, ".%s:\n", name);
297 : }
298 :
299 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
300 : }
301 :
302 : int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
303 : return fprintf(fp_, "0x%" PRIx64, value);
304 : }
305 :
306 : void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
307 :
308 : void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
309 : int fileid, const char* filename) {
310 : // File name cannot be declared with an identifier on AIX.
311 : // We use the SourceInfo method to emit debug info in
312 : //.xline <line-number> <file-name> format.
313 : }
314 :
315 : void PlatformDependentEmbeddedFileWriter::FileEpilogue() {}
316 :
317 : int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
318 : DataDirective directive) {
319 : return fprintf(fp_, " %s ", DirectiveAsString(directive));
320 : }
321 :
322 : // V8_TARGET_OS_WIN (MSVC)
323 : // -----------------------------------------------------------------------------
324 :
325 : #elif defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MASM)
326 :
327 : // For MSVC builds we emit assembly in MASM syntax.
328 : // See https://docs.microsoft.com/en-us/cpp/assembler/masm/directives-reference.
329 :
330 : void PlatformDependentEmbeddedFileWriter::SectionText() {
331 : fprintf(fp_, ".CODE\n");
332 : }
333 :
334 : void PlatformDependentEmbeddedFileWriter::SectionData() {
335 : fprintf(fp_, ".DATA\n");
336 : }
337 :
338 : void PlatformDependentEmbeddedFileWriter::SectionRoData() {
339 : fprintf(fp_, ".CONST\n");
340 : }
341 :
342 : void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
343 : uint32_t value) {
344 : DeclareSymbolGlobal(name);
345 : fprintf(fp_, "%s%s %s %d\n", SYMBOL_PREFIX, name, DirectiveAsString(kLong),
346 : value);
347 : }
348 :
349 : void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
350 : const char* name, const char* target) {
351 : DeclareSymbolGlobal(name);
352 : fprintf(fp_, "%s%s %s %s%s\n", SYMBOL_PREFIX, name,
353 : DirectiveAsString(PointerSizeDirective()), SYMBOL_PREFIX, target);
354 : }
355 :
356 : void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
357 : const char* name) {
358 : fprintf(fp_, "PUBLIC %s%s\n", SYMBOL_PREFIX, name);
359 : }
360 :
361 : void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
362 : // Diverges from other platforms due to compile error
363 : // 'invalid combination with segment alignment'.
364 : fprintf(fp_, "ALIGN 4\n");
365 : }
366 :
367 : void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
368 : fprintf(fp_, "ALIGN 4\n");
369 : }
370 :
371 : void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
372 : fprintf(fp_, "; %s\n", string);
373 : }
374 :
375 : void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
376 : fprintf(fp_, "%s%s LABEL %s\n", SYMBOL_PREFIX, name,
377 : DirectiveAsString(kByte));
378 : }
379 :
380 : void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid,
381 : const char* filename,
382 : int line) {
383 : // TODO(mvstanton): output source information for MSVC.
384 : // Its syntax is #line <line> "<filename>"
385 : }
386 :
387 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
388 : const char* name) {
389 : fprintf(fp_, "%s%s PROC\n", SYMBOL_PREFIX, name);
390 : }
391 :
392 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
393 : fprintf(fp_, "%s%s ENDP\n", SYMBOL_PREFIX, name);
394 : }
395 :
396 : int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
397 : return fprintf(fp_, "0%" PRIx64 "h", value);
398 : }
399 :
400 : void PlatformDependentEmbeddedFileWriter::FilePrologue() {
401 : #if !defined(V8_TARGET_ARCH_X64)
402 : fprintf(fp_, ".MODEL FLAT\n");
403 : #endif
404 : }
405 :
406 : void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
407 : int fileid, const char* filename) {}
408 :
409 : void PlatformDependentEmbeddedFileWriter::FileEpilogue() {
410 : fprintf(fp_, "END\n");
411 : }
412 :
413 : int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
414 : DataDirective directive) {
415 : return fprintf(fp_, " %s ", DirectiveAsString(directive));
416 : }
417 :
418 : #undef V8_ASSEMBLER_IS_MASM
419 :
420 : #elif defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MARMASM)
421 :
422 : // The the AARCH64 ABI requires instructions be 4-byte-aligned and Windows does
423 : // not have a stricter alignment requirement (see the TEXTAREA macro of
424 : // kxarm64.h in the Windows SDK), so code is 4-byte-aligned.
425 : // The data fields in the emitted assembly tend to be accessed with 8-byte
426 : // LDR instructions, so data is 8-byte-aligned.
427 : //
428 : // armasm64's warning A4228 states
429 : // Alignment value exceeds AREA alignment; alignment not guaranteed
430 : // To ensure that ALIGN directives are honored, their values are defined as
431 : // equal to their corresponding AREA's ALIGN attributes.
432 :
433 : #define ARM64_DATA_ALIGNMENT_POWER (3)
434 : #define ARM64_DATA_ALIGNMENT (1 << ARM64_DATA_ALIGNMENT_POWER)
435 : #define ARM64_CODE_ALIGNMENT_POWER (2)
436 : #define ARM64_CODE_ALIGNMENT (1 << ARM64_CODE_ALIGNMENT_POWER)
437 :
438 : void PlatformDependentEmbeddedFileWriter::SectionText() {
439 : fprintf(fp_, " AREA |.text|, CODE, ALIGN=%d, READONLY\n",
440 : ARM64_CODE_ALIGNMENT_POWER);
441 : }
442 :
443 : void PlatformDependentEmbeddedFileWriter::SectionData() {
444 : fprintf(fp_, " AREA |.data|, DATA, ALIGN=%d, READWRITE\n",
445 : ARM64_DATA_ALIGNMENT_POWER);
446 : }
447 :
448 : void PlatformDependentEmbeddedFileWriter::SectionRoData() {
449 : fprintf(fp_, " AREA |.rodata|, DATA, ALIGN=%d, READONLY\n",
450 : ARM64_DATA_ALIGNMENT_POWER);
451 : }
452 :
453 : void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
454 : uint32_t value) {
455 : DeclareSymbolGlobal(name);
456 : fprintf(fp_, "%s%s %s %d\n", SYMBOL_PREFIX, name, DirectiveAsString(kLong),
457 : value);
458 : }
459 :
460 : void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
461 : const char* name, const char* target) {
462 : DeclareSymbolGlobal(name);
463 : fprintf(fp_, "%s%s %s %s%s\n", SYMBOL_PREFIX, name,
464 : DirectiveAsString(PointerSizeDirective()), SYMBOL_PREFIX, target);
465 : }
466 :
467 : void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
468 : const char* name) {
469 : fprintf(fp_, " EXPORT %s%s\n", SYMBOL_PREFIX, name);
470 : }
471 :
472 : void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
473 : fprintf(fp_, " ALIGN %d\n", ARM64_CODE_ALIGNMENT);
474 : }
475 :
476 : void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
477 : fprintf(fp_, " ALIGN %d\n", ARM64_DATA_ALIGNMENT);
478 : }
479 :
480 : void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
481 : fprintf(fp_, "; %s\n", string);
482 : }
483 :
484 : void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
485 : fprintf(fp_, "%s%s\n", SYMBOL_PREFIX, name);
486 : }
487 :
488 : void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid,
489 : const char* filename,
490 : int line) {
491 : // TODO(mvstanton): output source information for MSVC.
492 : // Its syntax is #line <line> "<filename>"
493 : }
494 :
495 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
496 : const char* name) {
497 : fprintf(fp_, "%s%s FUNCTION\n", SYMBOL_PREFIX, name);
498 : }
499 :
500 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
501 : fprintf(fp_, " ENDFUNC\n");
502 : }
503 :
504 : int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
505 : return fprintf(fp_, "0x%" PRIx64, value);
506 : }
507 :
508 : void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
509 :
510 : void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
511 : int fileid, const char* filename) {}
512 :
513 : void PlatformDependentEmbeddedFileWriter::FileEpilogue() {
514 : fprintf(fp_, " END\n");
515 : }
516 :
517 : int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
518 : DataDirective directive) {
519 : return fprintf(fp_, " %s ", DirectiveAsString(directive));
520 : }
521 :
522 : #undef V8_ASSEMBLER_IS_MARMASM
523 : #undef ARM64_DATA_ALIGNMENT_POWER
524 : #undef ARM64_DATA_ALIGNMENT
525 : #undef ARM64_CODE_ALIGNMENT_POWER
526 : #undef ARM64_CODE_ALIGNMENT
527 :
528 : // Everything but AIX, Windows with MSVC, or OSX.
529 : // -----------------------------------------------------------------------------
530 :
531 : #else
532 :
533 1 : void PlatformDependentEmbeddedFileWriter::SectionText() {
534 : #ifdef OS_CHROMEOS
535 : fprintf(fp_, ".section .text.hot.embedded\n");
536 : #else
537 1 : fprintf(fp_, ".section .text\n");
538 : #endif
539 1 : }
540 :
541 1 : void PlatformDependentEmbeddedFileWriter::SectionData() {
542 1 : fprintf(fp_, ".section .data\n");
543 1 : }
544 :
545 1 : void PlatformDependentEmbeddedFileWriter::SectionRoData() {
546 : #if defined(V8_TARGET_OS_WIN)
547 : fprintf(fp_, ".section .rdata\n");
548 : #else
549 1 : fprintf(fp_, ".section .rodata\n");
550 : #endif
551 1 : }
552 :
553 1 : void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
554 : uint32_t value) {
555 : DeclareSymbolGlobal(name);
556 : DeclareLabel(name);
557 1 : IndentedDataDirective(kLong);
558 1 : fprintf(fp_, "%d", value);
559 : Newline();
560 1 : }
561 :
562 1 : void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
563 : const char* name, const char* target) {
564 : DeclareSymbolGlobal(name);
565 : DeclareLabel(name);
566 1 : fprintf(fp_, " %s %s%s\n", DirectiveAsString(PointerSizeDirective()),
567 : SYMBOL_PREFIX, target);
568 1 : }
569 :
570 0 : void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
571 : const char* name) {
572 2 : fprintf(fp_, ".global %s%s\n", SYMBOL_PREFIX, name);
573 0 : }
574 :
575 1 : void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
576 1 : fprintf(fp_, ".balign 32\n");
577 1 : }
578 :
579 2 : void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
580 : // On Windows ARM64, s390, PPC and possibly more platforms, aligned load
581 : // instructions are used to retrieve v8_Default_embedded_blob_ and/or
582 : // v8_Default_embedded_blob_size_. The generated instructions require the
583 : // load target to be aligned at 8 bytes (2^3).
584 2 : fprintf(fp_, ".balign 8\n");
585 2 : }
586 :
587 7 : void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
588 7 : fprintf(fp_, "// %s\n", string);
589 7 : }
590 :
591 1 : void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
592 1518 : fprintf(fp_, "%s%s:\n", SYMBOL_PREFIX, name);
593 1 : }
594 :
595 1077 : void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid,
596 : const char* filename,
597 : int line) {
598 1077 : fprintf(fp_, ".loc %d %d\n", fileid, line);
599 1077 : }
600 :
601 1515 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
602 : const char* name) {
603 : DeclareLabel(name);
604 :
605 : #if defined(V8_TARGET_OS_WIN)
606 : #if defined(V8_TARGET_ARCH_ARM64)
607 : // Windows ARM64 assembly is in GAS syntax, but ".type" is invalid directive
608 : // in PE/COFF for Windows.
609 : #else
610 : // The directives for inserting debugging information on Windows come
611 : // from the PE (Portable Executable) and COFF (Common Object File Format)
612 : // standards. Documented here:
613 : // https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format
614 : //
615 : // .scl 2 means StorageClass external.
616 : // .type 32 means Type Representation Function.
617 : fprintf(fp_, ".def %s%s; .scl 2; .type 32; .endef;\n", SYMBOL_PREFIX, name);
618 : #endif
619 : #elif defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_ARM64)
620 : // ELF format binaries on ARM use ".type <function name>, %function"
621 : // to create a DWARF subprogram entry.
622 : fprintf(fp_, ".type %s, %%function\n", name);
623 : #else
624 : // Other ELF Format binaries use ".type <function name>, @function"
625 : // to create a DWARF subprogram entry.
626 1515 : fprintf(fp_, ".type %s, @function\n", name);
627 : #endif
628 1515 : }
629 :
630 1515 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
631 1515 : }
632 :
633 31600 : int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
634 63200 : return fprintf(fp_, "0x%" PRIx64, value);
635 : }
636 :
637 1 : void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
638 :
639 65 : void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
640 : int fileid, const char* filename) {
641 : // Replace any Windows style paths (backslashes) with forward
642 : // slashes.
643 65 : std::string fixed_filename(filename);
644 : std::replace(fixed_filename.begin(), fixed_filename.end(), '\\', '/');
645 65 : fprintf(fp_, ".file %d \"%s\"\n", fileid, fixed_filename.c_str());
646 65 : }
647 :
648 1 : void PlatformDependentEmbeddedFileWriter::FileEpilogue() {}
649 :
650 45073 : int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
651 : DataDirective directive) {
652 90146 : return fprintf(fp_, " %s ", DirectiveAsString(directive));
653 : }
654 :
655 : #endif
656 :
657 : #undef SYMBOL_PREFIX
658 : #undef V8_COMPILER_IS_MSVC
659 :
660 : } // namespace internal
661 2 : } // namespace v8
|