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_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 39642 : const char* DirectiveAsString(DataDirective directive) {
68 : #if defined(V8_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_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 39642 : 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 37194 : return ".octa";
111 : }
112 0 : UNREACHABLE();
113 : #endif
114 : }
115 :
116 1 : void EmbeddedFileWriter::PrepareBuiltinSourcePositionMap(Builtins* builtins) {
117 1506 : for (int i = 0; i < Builtins::builtin_count; i++) {
118 : // Retrieve the SourcePositionTable and copy it.
119 1505 : 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 : code->SourcePositionTable()->GetDataStartAddress(),
125 3010 : code->SourcePositionTable()->GetDataEndAddress());
126 1505 : 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, int line) {
191 : fprintf(fp_, ".loc %d %d\n", fileid, line);
192 : }
193 :
194 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
195 : const char* name) {
196 : DeclareLabel(name);
197 :
198 : // TODO(mvstanton): Investigate the proper incantations to mark the label as
199 : // a function on OSX.
200 : }
201 :
202 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
203 : }
204 :
205 : int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
206 : return fprintf(fp_, "0x%" PRIx64, value);
207 : }
208 :
209 : void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
210 :
211 : void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
212 : int fileid, const char* filename) {
213 : fprintf(fp_, ".file %d \"%s\"\n", fileid, filename);
214 : }
215 :
216 : void PlatformDependentEmbeddedFileWriter::FileEpilogue() {}
217 :
218 : int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
219 : DataDirective directive) {
220 : return fprintf(fp_, " %s ", DirectiveAsString(directive));
221 : }
222 :
223 : // V8_OS_AIX
224 : // -----------------------------------------------------------------------------
225 :
226 : #elif defined(V8_OS_AIX)
227 :
228 : void PlatformDependentEmbeddedFileWriter::SectionText() {
229 : fprintf(fp_, ".csect .text[PR]\n");
230 : }
231 :
232 : void PlatformDependentEmbeddedFileWriter::SectionData() {
233 : fprintf(fp_, ".csect .data[RW]\n");
234 : }
235 :
236 : void PlatformDependentEmbeddedFileWriter::SectionRoData() {
237 : fprintf(fp_, ".csect[RO]\n");
238 : }
239 :
240 : void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
241 : uint32_t value) {
242 : DeclareSymbolGlobal(name);
243 : fprintf(fp_, ".align 2\n");
244 : fprintf(fp_, "%s:\n", name);
245 : IndentedDataDirective(kLong);
246 : fprintf(fp_, "%d\n", value);
247 : Newline();
248 : }
249 :
250 : void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
251 : const char* name, const char* target) {
252 : AlignToCodeAlignment();
253 : DeclareLabel(name);
254 : fprintf(fp_, " %s %s\n", DirectiveAsString(PointerSizeDirective()), target);
255 : Newline();
256 : }
257 :
258 : void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
259 : const char* name) {
260 : fprintf(fp_, ".globl %s\n", name);
261 : }
262 :
263 : void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
264 : fprintf(fp_, ".align 5\n");
265 : }
266 :
267 : void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
268 : fprintf(fp_, ".align 3\n");
269 : }
270 :
271 : void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
272 : fprintf(fp_, "// %s\n", string);
273 : }
274 :
275 : void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
276 : DeclareSymbolGlobal(name);
277 : fprintf(fp_, "%s:\n", name);
278 : }
279 :
280 : void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid, int line) {
281 : fprintf(fp_, ".loc %d %d\n", fileid, line);
282 : }
283 :
284 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
285 : const char* name) {
286 : Newline();
287 : DeclareSymbolGlobal(name);
288 : fprintf(fp_, ".csect %s[DS]\n", name); // function descriptor
289 : fprintf(fp_, "%s:\n", name);
290 : fprintf(fp_, ".llong .%s, 0, 0\n", name);
291 : SectionText();
292 : fprintf(fp_, ".%s:\n", name);
293 : }
294 :
295 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
296 : }
297 :
298 : int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
299 : return fprintf(fp_, "0x%" PRIx64, value);
300 : }
301 :
302 : void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
303 :
304 : void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
305 : int fileid, const char* filename) {
306 : fprintf(fp_, ".file %d \"%s\"\n", fileid, filename);
307 : }
308 :
309 : void PlatformDependentEmbeddedFileWriter::FileEpilogue() {}
310 :
311 : int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
312 : DataDirective directive) {
313 : return fprintf(fp_, " %s ", DirectiveAsString(directive));
314 : }
315 :
316 : // V8_OS_WIN (MSVC)
317 : // -----------------------------------------------------------------------------
318 :
319 : #elif defined(V8_OS_WIN) && defined(V8_ASSEMBLER_IS_MASM)
320 :
321 : // For MSVC builds we emit assembly in MASM syntax.
322 : // See https://docs.microsoft.com/en-us/cpp/assembler/masm/directives-reference.
323 :
324 : void PlatformDependentEmbeddedFileWriter::SectionText() {
325 : fprintf(fp_, ".CODE\n");
326 : }
327 :
328 : void PlatformDependentEmbeddedFileWriter::SectionData() {
329 : fprintf(fp_, ".DATA\n");
330 : }
331 :
332 : void PlatformDependentEmbeddedFileWriter::SectionRoData() {
333 : fprintf(fp_, ".CONST\n");
334 : }
335 :
336 : void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
337 : uint32_t value) {
338 : DeclareSymbolGlobal(name);
339 : fprintf(fp_, "%s%s %s %d\n", SYMBOL_PREFIX, name, DirectiveAsString(kLong),
340 : value);
341 : }
342 :
343 : void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
344 : const char* name, const char* target) {
345 : DeclareSymbolGlobal(name);
346 : fprintf(fp_, "%s%s %s %s%s\n", SYMBOL_PREFIX, name,
347 : DirectiveAsString(PointerSizeDirective()), SYMBOL_PREFIX, target);
348 : }
349 :
350 : void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
351 : const char* name) {
352 : fprintf(fp_, "PUBLIC %s%s\n", SYMBOL_PREFIX, name);
353 : }
354 :
355 : void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
356 : // Diverges from other platforms due to compile error
357 : // 'invalid combination with segment alignment'.
358 : fprintf(fp_, "ALIGN 4\n");
359 : }
360 :
361 : void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
362 : fprintf(fp_, "ALIGN 4\n");
363 : }
364 :
365 : void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
366 : fprintf(fp_, "; %s\n", string);
367 : }
368 :
369 : void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
370 : fprintf(fp_, "%s%s LABEL %s\n", SYMBOL_PREFIX, name,
371 : DirectiveAsString(kByte));
372 : }
373 :
374 : void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid, int line) {
375 : // TODO(mvstanton): output source information for MSVC.
376 : // It's syntax is #line <line> "<filename>"
377 : }
378 :
379 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
380 : const char* name) {
381 : fprintf(fp_, "%s%s PROC\n", SYMBOL_PREFIX, name);
382 : }
383 :
384 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
385 : fprintf(fp_, "%s%s ENDP\n", SYMBOL_PREFIX, name);
386 : }
387 :
388 : int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
389 : return fprintf(fp_, "0%" PRIx64 "h", value);
390 : }
391 :
392 : void PlatformDependentEmbeddedFileWriter::FilePrologue() {
393 : #if !defined(V8_TARGET_ARCH_X64)
394 : fprintf(fp_, ".MODEL FLAT\n");
395 : #endif
396 : }
397 :
398 : void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
399 : int fileid, const char* filename) {}
400 :
401 : void PlatformDependentEmbeddedFileWriter::FileEpilogue() {
402 : fprintf(fp_, "END\n");
403 : }
404 :
405 : int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
406 : DataDirective directive) {
407 : return fprintf(fp_, " %s ", DirectiveAsString(directive));
408 : }
409 :
410 : #undef V8_ASSEMBLER_IS_MASM
411 :
412 : #elif defined(V8_OS_WIN) && defined(V8_ASSEMBLER_IS_MARMASM)
413 :
414 : // The the AARCH64 ABI requires instructions be 4-byte-aligned and Windows does
415 : // not have a stricter alignment requirement (see the TEXTAREA macro of
416 : // kxarm64.h in the Windows SDK), so code is 4-byte-aligned.
417 : // The data fields in the emitted assembly tend to be accessed with 8-byte
418 : // LDR instructions, so data is 8-byte-aligned.
419 : //
420 : // armasm64's warning A4228 states
421 : // Alignment value exceeds AREA alignment; alignment not guaranteed
422 : // To ensure that ALIGN directives are honored, their values are defined as
423 : // equal to their corresponding AREA's ALIGN attributes.
424 :
425 : #define ARM64_DATA_ALIGNMENT_POWER (3)
426 : #define ARM64_DATA_ALIGNMENT (1 << ARM64_DATA_ALIGNMENT_POWER)
427 : #define ARM64_CODE_ALIGNMENT_POWER (2)
428 : #define ARM64_CODE_ALIGNMENT (1 << ARM64_CODE_ALIGNMENT_POWER)
429 :
430 : void PlatformDependentEmbeddedFileWriter::SectionText() {
431 : fprintf(fp_, " AREA |.text|, CODE, ALIGN=%d, READONLY\n",
432 : ARM64_CODE_ALIGNMENT_POWER);
433 : }
434 :
435 : void PlatformDependentEmbeddedFileWriter::SectionData() {
436 : fprintf(fp_, " AREA |.data|, DATA, ALIGN=%d, READWRITE\n",
437 : ARM64_DATA_ALIGNMENT_POWER);
438 : }
439 :
440 : void PlatformDependentEmbeddedFileWriter::SectionRoData() {
441 : fprintf(fp_, " AREA |.rodata|, DATA, ALIGN=%d, READONLY\n",
442 : ARM64_DATA_ALIGNMENT_POWER);
443 : }
444 :
445 : void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
446 : uint32_t value) {
447 : DeclareSymbolGlobal(name);
448 : fprintf(fp_, "%s%s %s %d\n", SYMBOL_PREFIX, name, DirectiveAsString(kLong),
449 : value);
450 : }
451 :
452 : void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
453 : const char* name, const char* target) {
454 : DeclareSymbolGlobal(name);
455 : fprintf(fp_, "%s%s %s %s%s\n", SYMBOL_PREFIX, name,
456 : DirectiveAsString(PointerSizeDirective()), SYMBOL_PREFIX, target);
457 : }
458 :
459 : void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
460 : const char* name) {
461 : fprintf(fp_, " EXPORT %s%s\n", SYMBOL_PREFIX, name);
462 : }
463 :
464 : void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
465 : fprintf(fp_, " ALIGN %d\n", ARM64_CODE_ALIGNMENT);
466 : }
467 :
468 : void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
469 : fprintf(fp_, " ALIGN %d\n", ARM64_DATA_ALIGNMENT);
470 : }
471 :
472 : void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
473 : fprintf(fp_, "; %s\n", string);
474 : }
475 :
476 : void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
477 : fprintf(fp_, "%s%s\n", SYMBOL_PREFIX, name);
478 : }
479 :
480 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
481 : const char* name) {
482 : fprintf(fp_, "%s%s FUNCTION\n", SYMBOL_PREFIX, name);
483 : }
484 :
485 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
486 : fprintf(fp_, " ENDFUNC\n");
487 : }
488 :
489 : int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
490 : return fprintf(fp_, "0x%" PRIx64, value);
491 : }
492 :
493 : void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
494 :
495 : void PlatformDependentEmbeddedFileWriter::FileEpilogue() {
496 : fprintf(fp_, " END\n");
497 : }
498 :
499 : int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
500 : DataDirective directive) {
501 : return fprintf(fp_, " %s ", DirectiveAsString(directive));
502 : }
503 :
504 : #undef V8_ASSEMBLER_IS_MARMASM
505 : #undef ARM64_DATA_ALIGNMENT_POWER
506 : #undef ARM64_DATA_ALIGNMENT
507 : #undef ARM64_CODE_ALIGNMENT_POWER
508 : #undef ARM64_CODE_ALIGNMENT
509 :
510 : // Everything but AIX, Windows with MSVC, or OSX.
511 : // -----------------------------------------------------------------------------
512 :
513 : #else
514 :
515 1 : void PlatformDependentEmbeddedFileWriter::SectionText() {
516 : #ifdef OS_CHROMEOS
517 : fprintf(fp_, ".section .text.hot.embedded\n");
518 : #else
519 1 : fprintf(fp_, ".section .text\n");
520 : #endif
521 1 : }
522 :
523 1 : void PlatformDependentEmbeddedFileWriter::SectionData() {
524 1 : fprintf(fp_, ".section .data\n");
525 1 : }
526 :
527 1 : void PlatformDependentEmbeddedFileWriter::SectionRoData() {
528 : #if defined(V8_OS_WIN)
529 : fprintf(fp_, ".section .rdata\n");
530 : #else
531 1 : fprintf(fp_, ".section .rodata\n");
532 : #endif
533 1 : }
534 :
535 1 : void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
536 : uint32_t value) {
537 : DeclareSymbolGlobal(name);
538 : DeclareLabel(name);
539 1 : IndentedDataDirective(kLong);
540 1 : fprintf(fp_, "%d", value);
541 : Newline();
542 1 : }
543 :
544 1 : void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
545 : const char* name, const char* target) {
546 : DeclareSymbolGlobal(name);
547 : DeclareLabel(name);
548 : fprintf(fp_, " %s %s%s\n", DirectiveAsString(PointerSizeDirective()),
549 1 : SYMBOL_PREFIX, target);
550 1 : }
551 :
552 0 : void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
553 : const char* name) {
554 2 : fprintf(fp_, ".global %s%s\n", SYMBOL_PREFIX, name);
555 0 : }
556 :
557 1 : void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
558 1 : fprintf(fp_, ".balign 32\n");
559 1 : }
560 :
561 2 : void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
562 : // On Windows ARM64, s390, PPC and possibly more platforms, aligned load
563 : // instructions are used to retrieve v8_Default_embedded_blob_ and/or
564 : // v8_Default_embedded_blob_size_. The generated instructions require the
565 : // load target to be aligned at 8 bytes (2^3).
566 2 : fprintf(fp_, ".balign 8\n");
567 2 : }
568 :
569 7 : void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
570 7 : fprintf(fp_, "// %s\n", string);
571 7 : }
572 :
573 1 : void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
574 1508 : fprintf(fp_, "%s%s:\n", SYMBOL_PREFIX, name);
575 1 : }
576 :
577 940 : void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid, int line) {
578 940 : fprintf(fp_, ".loc %d %d\n", fileid, line);
579 940 : }
580 :
581 1505 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
582 : const char* name) {
583 : DeclareLabel(name);
584 :
585 : #if defined(V8_OS_WIN)
586 : #if defined(V8_TARGET_ARCH_ARM64)
587 : // Windows ARM64 assembly is in GAS syntax, but ".type" is invalid directive
588 : // in PE/COFF for Windows.
589 : #else
590 : // The directives for inserting debugging information on Windows come
591 : // from the PE (Portable Executable) and COFF (Common Object File Format)
592 : // standards. Documented here:
593 : // https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format
594 : //
595 : // .scl 2 means StorageClass external.
596 : // .type 32 means Type Representation Function.
597 : fprintf(fp_, ".def %s%s; .scl 2; .type 32; .endef;\n", SYMBOL_PREFIX, name);
598 : #endif
599 : #elif defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_ARM64)
600 : // ELF format binaries on ARM use ".type <function name>, %function"
601 : // to create a DWARF subprogram entry.
602 : fprintf(fp_, ".type %s, %%function\n", name);
603 : #else
604 : // Other ELF Format binaries use ".type <function name>, @function"
605 : // to create a DWARF subprogram entry.
606 1505 : fprintf(fp_, ".type %s, @function\n", name);
607 : #endif
608 1505 : }
609 :
610 1505 : void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
611 1505 : }
612 :
613 30656 : int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
614 61312 : return fprintf(fp_, "0x%" PRIx64, value);
615 : }
616 :
617 1 : void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
618 :
619 33 : void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
620 : int fileid, const char* filename) {
621 : // Replace any Windows style paths (backslashes) with forward
622 : // slashes.
623 33 : std::string fixed_filename(filename);
624 33 : std::replace(fixed_filename.begin(), fixed_filename.end(), '\\', '/');
625 33 : fprintf(fp_, ".file %d \"%s\"\n", fileid, fixed_filename.c_str());
626 33 : }
627 :
628 1 : void PlatformDependentEmbeddedFileWriter::FileEpilogue() {}
629 :
630 39641 : int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
631 : DataDirective directive) {
632 79282 : return fprintf(fp_, " %s ", DirectiveAsString(directive));
633 : }
634 :
635 : #endif
636 :
637 : #undef SYMBOL_PREFIX
638 : #undef V8_COMPILER_IS_MSVC
639 :
640 : } // namespace internal
641 3 : } // namespace v8
|