[mksnapshot] Add abstract base class for platform embedded file writers

This is in preparation for better cross-compile support in mksnapshot.
Specifically, this CL series will introduce runtime switches to select
the target platform for generated embedded.S assembly.

Each platform writer will derive from the abstract base class
PlatformEmbeddedFileWriterBase. Currently, the code remains
functionally unmodified and was just moved to
PlatformEmbeddedFileWriterGeneric. This will be split up in future
CLs.

Bug: v8:9103
Change-Id: Ie7e29bb60ba5a8ff6c0c1edec676943b80a1781b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1622854
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Peter Marshall <petermarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61745}
This commit is contained in:
Jakob Gruber 2019-05-22 15:24:03 +02:00 committed by Commit Bot
parent 6908209dbb
commit a35e79ee58
7 changed files with 1021 additions and 810 deletions

View File

@ -3792,6 +3792,10 @@ if (v8_use_snapshot && current_toolchain == v8_snapshot_toolchain) {
sources = [
"src/snapshot/embedded-file-writer.cc",
"src/snapshot/embedded-file-writer.h",
"src/snapshot/embedded/platform-embedded-file-writer-base.cc",
"src/snapshot/embedded/platform-embedded-file-writer-base.h",
"src/snapshot/embedded/platform-embedded-file-writer-generic.cc",
"src/snapshot/embedded/platform-embedded-file-writer-generic.h",
"src/snapshot/mksnapshot.cc",
]

View File

@ -4,115 +4,16 @@
#include "src/snapshot/embedded-file-writer.h"
#include <algorithm>
#include <cinttypes>
#include "src/objects/code-inl.h"
// TODO(jgruber): Remove once windows-specific code is extracted.
#include "src/snapshot/embedded/platform-embedded-file-writer-generic.h"
namespace v8 {
namespace internal {
// V8_CC_MSVC is true for both MSVC and clang on windows. clang can handle
// __asm__-style inline assembly but MSVC cannot, and thus we need a more
// precise compiler detection that can distinguish between the two. clang on
// windows sets both __clang__ and _MSC_VER, MSVC sets only _MSC_VER.
#if defined(_MSC_VER) && !defined(__clang__)
#define V8_COMPILER_IS_MSVC
#endif
// MSVC uses MASM for x86 and x64, while it has a ARMASM for ARM32 and
// ARMASM64 for ARM64. Since ARMASM and ARMASM64 accept a slightly tweaked
// version of ARM assembly language, they are referred to together in Visual
// Studio project files as MARMASM.
//
// ARM assembly language docs:
// http://infocenter.arm.com/help/topic/com.arm.doc.dui0802b/index.html
// Microsoft ARM assembler and assembly language docs:
// https://docs.microsoft.com/en-us/cpp/assembler/arm/arm-assembler-reference
#if defined(V8_COMPILER_IS_MSVC)
#if defined(V8_TARGET_ARCH_ARM64) || defined(V8_TARGET_ARCH_ARM)
#define V8_ASSEMBLER_IS_MARMASM
#elif defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X64)
#define V8_ASSEMBLER_IS_MASM
#else
#error Unknown Windows assembler target architecture.
#endif
#endif
// Name mangling.
// Symbols are prefixed with an underscore on 32-bit architectures.
#if defined(V8_TARGET_OS_WIN) && !defined(V8_TARGET_ARCH_X64) && \
!defined(V8_TARGET_ARCH_ARM64)
#define SYMBOL_PREFIX "_"
#else
#define SYMBOL_PREFIX ""
#endif
// Platform-independent bits.
// -----------------------------------------------------------------------------
namespace {
DataDirective PointerSizeDirective() {
if (kSystemPointerSize == 8) {
return kQuad;
} else {
CHECK_EQ(4, kSystemPointerSize);
return kLong;
}
}
} // namespace
const char* DirectiveAsString(DataDirective directive) {
#if defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MASM)
switch (directive) {
case kByte:
return "BYTE";
case kLong:
return "DWORD";
case kQuad:
return "QWORD";
default:
UNREACHABLE();
}
#elif defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MARMASM)
switch (directive) {
case kByte:
return "DCB";
case kLong:
return "DCDU";
case kQuad:
return "DCQU";
default:
UNREACHABLE();
}
#elif defined(V8_OS_AIX)
switch (directive) {
case kByte:
return ".byte";
case kLong:
return ".long";
case kQuad:
return ".llong";
default:
UNREACHABLE();
}
#else
switch (directive) {
case kByte:
return ".byte";
case kLong:
return ".long";
case kQuad:
return ".quad";
case kOcta:
return ".octa";
}
UNREACHABLE();
#endif
}
void EmbeddedFileWriter::PrepareBuiltinSourcePositionMap(Builtins* builtins) {
for (int i = 0; i < Builtins::builtin_count; i++) {
// Retrieve the SourcePositionTable and copy it.
@ -141,45 +42,50 @@ void EmbeddedFileWriter::SetBuiltinUnwindData(
unwind_infos_[builtin_index] = unwind_info;
}
void EmbeddedFileWriter::WriteUnwindInfoEntry(
PlatformDependentEmbeddedFileWriter* w, uint64_t rva_start,
uint64_t rva_end) const {
w->DeclareRvaToSymbol(EmbeddedBlobDataSymbol().c_str(), rva_start);
w->DeclareRvaToSymbol(EmbeddedBlobDataSymbol().c_str(), rva_end);
w->DeclareRvaToSymbol(BuiltinsUnwindInfoLabel().c_str());
void EmbeddedFileWriter::WriteUnwindInfoEntry(PlatformEmbeddedFileWriterBase* w,
uint64_t rva_start,
uint64_t rva_end) const {
PlatformEmbeddedFileWriterGeneric* w_gen =
static_cast<PlatformEmbeddedFileWriterGeneric*>(w);
w_gen->DeclareRvaToSymbol(EmbeddedBlobDataSymbol().c_str(), rva_start);
w_gen->DeclareRvaToSymbol(EmbeddedBlobDataSymbol().c_str(), rva_end);
w_gen->DeclareRvaToSymbol(BuiltinsUnwindInfoLabel().c_str());
}
void EmbeddedFileWriter::WriteUnwindInfo(PlatformDependentEmbeddedFileWriter* w,
void EmbeddedFileWriter::WriteUnwindInfo(PlatformEmbeddedFileWriterBase* w,
const i::EmbeddedData* blob) const {
PlatformEmbeddedFileWriterGeneric* w_gen =
static_cast<PlatformEmbeddedFileWriterGeneric*>(w);
// Emit an UNWIND_INFO (XDATA) struct, which contains the unwinding
// information that is used for all builtin functions.
DCHECK(win64_unwindinfo::CanEmitUnwindInfoForBuiltins());
w->Comment("xdata for all the code in the embedded blob.");
w->DeclareExternalFunction(CRASH_HANDLER_FUNCTION_NAME_STRING);
w_gen->Comment("xdata for all the code in the embedded blob.");
w_gen->DeclareExternalFunction(CRASH_HANDLER_FUNCTION_NAME_STRING);
w->StartXdataSection();
w_gen->StartXdataSection();
{
w->DeclareLabel(BuiltinsUnwindInfoLabel().c_str());
w_gen->DeclareLabel(BuiltinsUnwindInfoLabel().c_str());
std::vector<uint8_t> xdata =
win64_unwindinfo::GetUnwindInfoForBuiltinFunctions();
WriteBinaryContentsAsInlineAssembly(w, xdata.data(),
WriteBinaryContentsAsInlineAssembly(w_gen, xdata.data(),
static_cast<uint32_t>(xdata.size()));
w->Comment(" ExceptionHandler");
w->DeclareRvaToSymbol(CRASH_HANDLER_FUNCTION_NAME_STRING);
w_gen->Comment(" ExceptionHandler");
w_gen->DeclareRvaToSymbol(CRASH_HANDLER_FUNCTION_NAME_STRING);
}
w->EndXdataSection();
w->Newline();
w_gen->EndXdataSection();
w_gen->Newline();
// Emit a RUNTIME_FUNCTION (PDATA) entry for each builtin function, as
// documented here:
// https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64.
w->Comment(
w_gen->Comment(
"pdata for all the code in the embedded blob (structs of type "
"RUNTIME_FUNCTION).");
w->Comment(" BeginAddress");
w->Comment(" EndAddress");
w->Comment(" UnwindInfoAddress");
w->StartPdataSection();
w_gen->Comment(" BeginAddress");
w_gen->Comment(" EndAddress");
w_gen->Comment(" UnwindInfoAddress");
w_gen->StartPdataSection();
{
Address prev_builtin_end_offset = 0;
for (int i = 0; i < Builtins::builtin_count; i++) {
@ -203,7 +109,7 @@ void EmbeddedFileWriter::WriteUnwindInfo(PlatformDependentEmbeddedFileWriter* w,
// a few bytes before the beginning of the function, if it does not
// overlap the end of the previous builtin.
WriteUnwindInfoEntry(
w,
w_gen,
std::max(prev_builtin_end_offset,
builtin_start_offset - win64_unwindinfo::kRbpPrefixLength),
builtin_start_offset + builtin_size);
@ -215,7 +121,7 @@ void EmbeddedFileWriter::WriteUnwindInfo(PlatformDependentEmbeddedFileWriter* w,
// we also emit a PDATA entry for the initial block of code up to the
// first 'push rbp', like in the case above.
if (xdata_desc[0] > 0) {
WriteUnwindInfoEntry(w,
WriteUnwindInfoEntry(w_gen,
std::max(prev_builtin_end_offset,
builtin_start_offset -
win64_unwindinfo::kRbpPrefixLength),
@ -226,614 +132,19 @@ void EmbeddedFileWriter::WriteUnwindInfo(PlatformDependentEmbeddedFileWriter* w,
int chunk_start = xdata_desc[j];
int chunk_end =
(j < xdata_desc.size() - 1) ? xdata_desc[j + 1] : builtin_size;
WriteUnwindInfoEntry(w, builtin_start_offset + chunk_start,
WriteUnwindInfoEntry(w_gen, builtin_start_offset + chunk_start,
builtin_start_offset + chunk_end);
}
}
prev_builtin_end_offset = builtin_start_offset + builtin_size;
w->Newline();
w_gen->Newline();
}
}
w->EndPdataSection();
w->Newline();
w_gen->EndPdataSection();
w_gen->Newline();
}
#endif
// V8_OS_MACOSX
// Fuchsia target is explicitly excluded here for Mac hosts. This is to avoid
// generating uncompilable assembly files for the Fuchsia target.
// -----------------------------------------------------------------------------
#if defined(V8_OS_MACOSX) && !defined(V8_TARGET_OS_FUCHSIA)
void PlatformDependentEmbeddedFileWriter::SectionText() {
fprintf(fp_, ".text\n");
}
void PlatformDependentEmbeddedFileWriter::SectionData() {
fprintf(fp_, ".data\n");
}
void PlatformDependentEmbeddedFileWriter::SectionRoData() {
fprintf(fp_, ".const_data\n");
}
void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
uint32_t value) {
DeclareSymbolGlobal(name);
DeclareLabel(name);
IndentedDataDirective(kLong);
fprintf(fp_, "%d", value);
Newline();
}
void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
const char* name, const char* target) {
DeclareSymbolGlobal(name);
DeclareLabel(name);
fprintf(fp_, " %s _%s\n", DirectiveAsString(PointerSizeDirective()), target);
}
void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
const char* name) {
// TODO(jgruber): Investigate switching to .globl. Using .private_extern
// prevents something along the compilation chain from messing with the
// embedded blob. Using .global here causes embedded blob hash verification
// failures at runtime.
fprintf(fp_, ".private_extern _%s\n", name);
}
void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
fprintf(fp_, ".balign 32\n");
}
void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
fprintf(fp_, ".balign 8\n");
}
void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
fprintf(fp_, "// %s\n", string);
}
void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
fprintf(fp_, "_%s:\n", name);
}
void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid,
const char* filename,
int line) {
fprintf(fp_, ".loc %d %d\n", fileid, line);
}
void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
const char* name) {
DeclareLabel(name);
// TODO(mvstanton): Investigate the proper incantations to mark the label as
// a function on OSX.
}
void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
}
int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
return fprintf(fp_, "0x%" PRIx64, value);
}
void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
int fileid, const char* filename) {
fprintf(fp_, ".file %d \"%s\"\n", fileid, filename);
}
void PlatformDependentEmbeddedFileWriter::FileEpilogue() {}
int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
DataDirective directive) {
return fprintf(fp_, " %s ", DirectiveAsString(directive));
}
// V8_OS_AIX
// -----------------------------------------------------------------------------
#elif defined(V8_OS_AIX)
void PlatformDependentEmbeddedFileWriter::SectionText() {
fprintf(fp_, ".csect .text[PR]\n");
}
void PlatformDependentEmbeddedFileWriter::SectionData() {
fprintf(fp_, ".csect .data[RW]\n");
}
void PlatformDependentEmbeddedFileWriter::SectionRoData() {
fprintf(fp_, ".csect[RO]\n");
}
void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
uint32_t value) {
DeclareSymbolGlobal(name);
fprintf(fp_, ".align 2\n");
fprintf(fp_, "%s:\n", name);
IndentedDataDirective(kLong);
fprintf(fp_, "%d\n", value);
Newline();
}
void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
const char* name, const char* target) {
AlignToCodeAlignment();
DeclareLabel(name);
fprintf(fp_, " %s %s\n", DirectiveAsString(PointerSizeDirective()), target);
Newline();
}
void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
const char* name) {
fprintf(fp_, ".globl %s\n", name);
}
void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
fprintf(fp_, ".align 5\n");
}
void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
fprintf(fp_, ".align 3\n");
}
void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
fprintf(fp_, "// %s\n", string);
}
void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
DeclareSymbolGlobal(name);
fprintf(fp_, "%s:\n", name);
}
void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid,
const char* filename,
int line) {
fprintf(fp_, ".xline %d, \"%s\"\n", line, filename);
}
void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
const char* name) {
Newline();
DeclareSymbolGlobal(name);
fprintf(fp_, ".csect %s[DS]\n", name); // function descriptor
fprintf(fp_, "%s:\n", name);
fprintf(fp_, ".llong .%s, 0, 0\n", name);
SectionText();
fprintf(fp_, ".%s:\n", name);
}
void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
}
int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
return fprintf(fp_, "0x%" PRIx64, value);
}
void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
int fileid, const char* filename) {
// File name cannot be declared with an identifier on AIX.
// We use the SourceInfo method to emit debug info in
//.xline <line-number> <file-name> format.
}
void PlatformDependentEmbeddedFileWriter::FileEpilogue() {}
int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
DataDirective directive) {
return fprintf(fp_, " %s ", DirectiveAsString(directive));
}
// V8_TARGET_OS_WIN (MSVC)
// -----------------------------------------------------------------------------
#elif defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MASM)
// For MSVC builds we emit assembly in MASM syntax.
// See https://docs.microsoft.com/en-us/cpp/assembler/masm/directives-reference.
void PlatformDependentEmbeddedFileWriter::SectionText() {
fprintf(fp_, ".CODE\n");
}
void PlatformDependentEmbeddedFileWriter::SectionData() {
fprintf(fp_, ".DATA\n");
}
void PlatformDependentEmbeddedFileWriter::SectionRoData() {
fprintf(fp_, ".CONST\n");
}
void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
uint32_t value) {
DeclareSymbolGlobal(name);
fprintf(fp_, "%s%s %s %d\n", SYMBOL_PREFIX, name, DirectiveAsString(kLong),
value);
}
void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
const char* name, const char* target) {
DeclareSymbolGlobal(name);
fprintf(fp_, "%s%s %s %s%s\n", SYMBOL_PREFIX, name,
DirectiveAsString(PointerSizeDirective()), SYMBOL_PREFIX, target);
}
#if defined(V8_OS_WIN_X64)
void PlatformDependentEmbeddedFileWriter::StartPdataSection() {
fprintf(fp_, "OPTION DOTNAME\n");
fprintf(fp_, ".pdata SEGMENT DWORD READ ''\n");
}
void PlatformDependentEmbeddedFileWriter::EndPdataSection() {
fprintf(fp_, ".pdata ENDS\n");
}
void PlatformDependentEmbeddedFileWriter::StartXdataSection() {
fprintf(fp_, "OPTION DOTNAME\n");
fprintf(fp_, ".xdata SEGMENT DWORD READ ''\n");
}
void PlatformDependentEmbeddedFileWriter::EndXdataSection() {
fprintf(fp_, ".xdata ENDS\n");
}
void PlatformDependentEmbeddedFileWriter::DeclareExternalFunction(
const char* name) {
fprintf(fp_, "EXTERN %s : PROC\n", name);
}
void PlatformDependentEmbeddedFileWriter::DeclareRvaToSymbol(const char* name,
uint64_t offset) {
if (offset > 0) {
fprintf(fp_, "DD IMAGEREL %s+%llu\n", name, offset);
} else {
fprintf(fp_, "DD IMAGEREL %s\n", name);
}
}
#endif // defined(V8_OS_WIN_X64)
void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
const char* name) {
fprintf(fp_, "PUBLIC %s%s\n", SYMBOL_PREFIX, name);
}
void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
// Diverges from other platforms due to compile error
// 'invalid combination with segment alignment'.
fprintf(fp_, "ALIGN 4\n");
}
void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
fprintf(fp_, "ALIGN 4\n");
}
void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
fprintf(fp_, "; %s\n", string);
}
void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
fprintf(fp_, "%s%s LABEL %s\n", SYMBOL_PREFIX, name,
DirectiveAsString(kByte));
}
void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid,
const char* filename,
int line) {
// TODO(mvstanton): output source information for MSVC.
// Its syntax is #line <line> "<filename>"
}
void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
const char* name) {
fprintf(fp_, "%s%s PROC\n", SYMBOL_PREFIX, name);
}
void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
fprintf(fp_, "%s%s ENDP\n", SYMBOL_PREFIX, name);
}
int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
return fprintf(fp_, "0%" PRIx64 "h", value);
}
void PlatformDependentEmbeddedFileWriter::FilePrologue() {
#if !defined(V8_TARGET_ARCH_X64)
fprintf(fp_, ".MODEL FLAT\n");
#endif
}
void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
int fileid, const char* filename) {}
void PlatformDependentEmbeddedFileWriter::FileEpilogue() {
fprintf(fp_, "END\n");
}
int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
DataDirective directive) {
return fprintf(fp_, " %s ", DirectiveAsString(directive));
}
#undef V8_ASSEMBLER_IS_MASM
#elif defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MARMASM)
// The the AARCH64 ABI requires instructions be 4-byte-aligned and Windows does
// not have a stricter alignment requirement (see the TEXTAREA macro of
// kxarm64.h in the Windows SDK), so code is 4-byte-aligned.
// The data fields in the emitted assembly tend to be accessed with 8-byte
// LDR instructions, so data is 8-byte-aligned.
//
// armasm64's warning A4228 states
// Alignment value exceeds AREA alignment; alignment not guaranteed
// To ensure that ALIGN directives are honored, their values are defined as
// equal to their corresponding AREA's ALIGN attributes.
#define ARM64_DATA_ALIGNMENT_POWER (3)
#define ARM64_DATA_ALIGNMENT (1 << ARM64_DATA_ALIGNMENT_POWER)
#define ARM64_CODE_ALIGNMENT_POWER (2)
#define ARM64_CODE_ALIGNMENT (1 << ARM64_CODE_ALIGNMENT_POWER)
void PlatformDependentEmbeddedFileWriter::SectionText() {
fprintf(fp_, " AREA |.text|, CODE, ALIGN=%d, READONLY\n",
ARM64_CODE_ALIGNMENT_POWER);
}
void PlatformDependentEmbeddedFileWriter::SectionData() {
fprintf(fp_, " AREA |.data|, DATA, ALIGN=%d, READWRITE\n",
ARM64_DATA_ALIGNMENT_POWER);
}
void PlatformDependentEmbeddedFileWriter::SectionRoData() {
fprintf(fp_, " AREA |.rodata|, DATA, ALIGN=%d, READONLY\n",
ARM64_DATA_ALIGNMENT_POWER);
}
void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
uint32_t value) {
DeclareSymbolGlobal(name);
fprintf(fp_, "%s%s %s %d\n", SYMBOL_PREFIX, name, DirectiveAsString(kLong),
value);
}
void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
const char* name, const char* target) {
DeclareSymbolGlobal(name);
fprintf(fp_, "%s%s %s %s%s\n", SYMBOL_PREFIX, name,
DirectiveAsString(PointerSizeDirective()), SYMBOL_PREFIX, target);
}
void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
const char* name) {
fprintf(fp_, " EXPORT %s%s\n", SYMBOL_PREFIX, name);
}
void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
fprintf(fp_, " ALIGN %d\n", ARM64_CODE_ALIGNMENT);
}
void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
fprintf(fp_, " ALIGN %d\n", ARM64_DATA_ALIGNMENT);
}
void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
fprintf(fp_, "; %s\n", string);
}
void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
fprintf(fp_, "%s%s\n", SYMBOL_PREFIX, name);
}
void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid,
const char* filename,
int line) {
// TODO(mvstanton): output source information for MSVC.
// Its syntax is #line <line> "<filename>"
}
void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
const char* name) {
fprintf(fp_, "%s%s FUNCTION\n", SYMBOL_PREFIX, name);
}
void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
fprintf(fp_, " ENDFUNC\n");
}
int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
return fprintf(fp_, "0x%" PRIx64, value);
}
void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
int fileid, const char* filename) {}
void PlatformDependentEmbeddedFileWriter::FileEpilogue() {
fprintf(fp_, " END\n");
}
int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
DataDirective directive) {
return fprintf(fp_, " %s ", DirectiveAsString(directive));
}
#undef V8_ASSEMBLER_IS_MARMASM
#undef ARM64_DATA_ALIGNMENT_POWER
#undef ARM64_DATA_ALIGNMENT
#undef ARM64_CODE_ALIGNMENT_POWER
#undef ARM64_CODE_ALIGNMENT
// Everything but AIX, Windows with MSVC, or OSX.
// -----------------------------------------------------------------------------
#else
void PlatformDependentEmbeddedFileWriter::SectionText() {
#if defined(V8_TARGET_OS_CHROMEOS)
fprintf(fp_, ".section .text.hot.embedded\n");
#else
fprintf(fp_, ".section .text\n");
#endif
}
void PlatformDependentEmbeddedFileWriter::SectionData() {
fprintf(fp_, ".section .data\n");
}
void PlatformDependentEmbeddedFileWriter::SectionRoData() {
if (i::FLAG_target_os == std::string("win"))
fprintf(fp_, ".section .rdata\n");
else
fprintf(fp_, ".section .rodata\n");
}
void PlatformDependentEmbeddedFileWriter::DeclareUint32(const char* name,
uint32_t value) {
DeclareSymbolGlobal(name);
DeclareLabel(name);
IndentedDataDirective(kLong);
fprintf(fp_, "%d", value);
Newline();
}
void PlatformDependentEmbeddedFileWriter::DeclarePointerToSymbol(
const char* name, const char* target) {
DeclareSymbolGlobal(name);
DeclareLabel(name);
fprintf(fp_, " %s %s%s\n", DirectiveAsString(PointerSizeDirective()),
SYMBOL_PREFIX, target);
}
#if defined(V8_OS_WIN_X64)
void PlatformDependentEmbeddedFileWriter::StartPdataSection() {
fprintf(fp_, ".section .pdata\n");
}
void PlatformDependentEmbeddedFileWriter::EndPdataSection() {}
void PlatformDependentEmbeddedFileWriter::StartXdataSection() {
fprintf(fp_, ".section .xdata\n");
}
void PlatformDependentEmbeddedFileWriter::EndXdataSection() {}
void PlatformDependentEmbeddedFileWriter::DeclareExternalFunction(
const char* name) {}
void PlatformDependentEmbeddedFileWriter::DeclareRvaToSymbol(const char* name,
uint64_t offset) {
if (offset > 0) {
fprintf(fp_, ".rva %s + %llu\n", name, offset);
} else {
fprintf(fp_, ".rva %s\n", name);
}
}
#endif // defined(V8_OS_WIN_X64)
void PlatformDependentEmbeddedFileWriter::DeclareSymbolGlobal(
const char* name) {
fprintf(fp_, ".global %s%s\n", SYMBOL_PREFIX, name);
}
void PlatformDependentEmbeddedFileWriter::AlignToCodeAlignment() {
fprintf(fp_, ".balign 32\n");
}
void PlatformDependentEmbeddedFileWriter::AlignToDataAlignment() {
// On Windows ARM64, s390, PPC and possibly more platforms, aligned load
// instructions are used to retrieve v8_Default_embedded_blob_ and/or
// v8_Default_embedded_blob_size_. The generated instructions require the
// load target to be aligned at 8 bytes (2^3).
fprintf(fp_, ".balign 8\n");
}
void PlatformDependentEmbeddedFileWriter::Comment(const char* string) {
fprintf(fp_, "// %s\n", string);
}
void PlatformDependentEmbeddedFileWriter::DeclareLabel(const char* name) {
fprintf(fp_, "%s%s:\n", SYMBOL_PREFIX, name);
}
void PlatformDependentEmbeddedFileWriter::SourceInfo(int fileid,
const char* filename,
int line) {
fprintf(fp_, ".loc %d %d\n", fileid, line);
}
void PlatformDependentEmbeddedFileWriter::DeclareFunctionBegin(
const char* name) {
DeclareLabel(name);
if (i::FLAG_target_os == std::string("win")) {
#if defined(V8_TARGET_ARCH_ARM64)
// Windows ARM64 assembly is in GAS syntax, but ".type" is invalid directive
// in PE/COFF for Windows.
#else
// The directives for inserting debugging information on Windows come
// from the PE (Portable Executable) and COFF (Common Object File Format)
// standards. Documented here:
// https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format
//
// .scl 2 means StorageClass external.
// .type 32 means Type Representation Function.
fprintf(fp_, ".def %s%s; .scl 2; .type 32; .endef;\n", SYMBOL_PREFIX, name);
#endif
} else {
#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_ARM64)
// ELF format binaries on ARM use ".type <function name>, %function"
// to create a DWARF subprogram entry.
fprintf(fp_, ".type %s, %%function\n", name);
#else
// Other ELF Format binaries use ".type <function name>, @function"
// to create a DWARF subprogram entry.
fprintf(fp_, ".type %s, @function\n", name);
#endif
}
}
void PlatformDependentEmbeddedFileWriter::DeclareFunctionEnd(const char* name) {
}
int PlatformDependentEmbeddedFileWriter::HexLiteral(uint64_t value) {
return fprintf(fp_, "0x%" PRIx64, value);
}
void PlatformDependentEmbeddedFileWriter::FilePrologue() {}
void PlatformDependentEmbeddedFileWriter::DeclareExternalFilename(
int fileid, const char* filename) {
// Replace any Windows style paths (backslashes) with forward
// slashes.
std::string fixed_filename(filename);
std::replace(fixed_filename.begin(), fixed_filename.end(), '\\', '/');
fprintf(fp_, ".file %d \"%s\"\n", fileid, fixed_filename.c_str());
}
void PlatformDependentEmbeddedFileWriter::FileEpilogue() {}
int PlatformDependentEmbeddedFileWriter::IndentedDataDirective(
DataDirective directive) {
return fprintf(fp_, " %s ", DirectiveAsString(directive));
}
#endif
#undef SYMBOL_PREFIX
#undef V8_COMPILER_IS_MSVC
} // namespace internal
} // namespace v8

View File

@ -11,7 +11,8 @@
#include "src/codegen/source-position-table.h"
#include "src/globals.h"
#include "src/snapshot/snapshot.h"
#include "src/snapshot/embedded-data.h"
#include "src/snapshot/embedded/platform-embedded-file-writer-base.h"
#if defined(V8_OS_WIN_X64)
#include "src/diagnostics/unwinding-info-win64.h"
@ -20,71 +21,8 @@
namespace v8 {
namespace internal {
enum DataDirective {
kByte,
kLong,
kQuad,
kOcta,
};
static constexpr char kDefaultEmbeddedVariant[] = "Default";
// The platform-dependent logic for emitting assembly code for the generated
// embedded.S file.
class EmbeddedFileWriter;
class PlatformDependentEmbeddedFileWriter final {
public:
void SetFile(FILE* fp) { fp_ = fp; }
void SectionText();
void SectionData();
void SectionRoData();
void AlignToCodeAlignment();
void AlignToDataAlignment();
void DeclareUint32(const char* name, uint32_t value);
void DeclarePointerToSymbol(const char* name, const char* target);
#if defined(V8_OS_WIN_X64)
void StartPdataSection();
void EndPdataSection();
void StartXdataSection();
void EndXdataSection();
void DeclareExternalFunction(const char* name);
// Emits an RVA (address relative to the module load address) specified as an
// offset from a given symbol.
void DeclareRvaToSymbol(const char* name, uint64_t offset = 0);
#endif
void DeclareLabel(const char* name);
void SourceInfo(int fileid, const char* filename, int line);
void DeclareFunctionBegin(const char* name);
void DeclareFunctionEnd(const char* name);
// Returns the number of printed characters.
int HexLiteral(uint64_t value);
void Comment(const char* string);
void Newline() { fprintf(fp_, "\n"); }
void FilePrologue();
void DeclareExternalFilename(int fileid, const char* filename);
void FileEpilogue();
int IndentedDataDirective(DataDirective directive);
FILE* fp() const { return fp_; }
private:
void DeclareSymbolGlobal(const char* name);
private:
FILE* fp_ = nullptr;
};
// When writing out compiled builtins to a file, we
// Detailed source-code information about builtins can only be obtained by
// registration on the isolate during compilation.
@ -173,14 +111,15 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
FILE* fp = GetFileDescriptorOrDie(embedded_src_path_);
PlatformDependentEmbeddedFileWriter writer;
writer.SetFile(fp);
std::unique_ptr<PlatformEmbeddedFileWriterBase> writer =
NewPlatformEmbeddedFileWriter(target_arch_, target_os_);
writer->SetFile(fp);
WriteFilePrologue(&writer);
WriteExternalFilenames(&writer);
WriteMetadataSection(&writer, blob);
WriteInstructionStreams(&writer, blob);
WriteFileEpilogue(&writer, blob);
WriteFilePrologue(writer.get());
WriteExternalFilenames(writer.get());
WriteMetadataSection(writer.get(), blob);
WriteInstructionStreams(writer.get(), blob);
WriteFileEpilogue(writer.get(), blob);
fclose(fp);
}
@ -194,13 +133,13 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
return fp;
}
void WriteFilePrologue(PlatformDependentEmbeddedFileWriter* w) const {
void WriteFilePrologue(PlatformEmbeddedFileWriterBase* w) const {
w->Comment("Autogenerated file. Do not edit.");
w->Newline();
w->FilePrologue();
}
void WriteExternalFilenames(PlatformDependentEmbeddedFileWriter* w) const {
void WriteExternalFilenames(PlatformEmbeddedFileWriterBase* w) const {
w->Comment(
"Source positions in the embedded blob refer to filenames by id.");
w->Comment("Assembly directives here map the id to a filename.");
@ -224,7 +163,7 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
return std::string{embedded_blob_data_symbol.begin()};
}
void WriteMetadataSection(PlatformDependentEmbeddedFileWriter* w,
void WriteMetadataSection(PlatformEmbeddedFileWriterBase* w,
const i::EmbeddedData* blob) const {
w->Comment("The embedded blob starts here. Metadata comes first, followed");
w->Comment("by builtin instruction streams.");
@ -236,7 +175,7 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
i::EmbeddedData::RawDataOffset());
}
void WriteBuiltin(PlatformDependentEmbeddedFileWriter* w,
void WriteBuiltin(PlatformEmbeddedFileWriterBase* w,
const i::EmbeddedData* blob, const int builtin_id) const {
const bool is_default_variant =
std::strcmp(embedded_variant_, kDefaultEmbeddedVariant) == 0;
@ -288,7 +227,7 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
w->DeclareFunctionEnd(builtin_symbol.begin());
}
void WriteInstructionStreams(PlatformDependentEmbeddedFileWriter* w,
void WriteInstructionStreams(PlatformEmbeddedFileWriterBase* w,
const i::EmbeddedData* blob) const {
for (int i = 0; i < i::Builtins::builtin_count; i++) {
if (!blob->ContainsBuiltin(i)) continue;
@ -298,7 +237,7 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
w->Newline();
}
void WriteFileEpilogue(PlatformDependentEmbeddedFileWriter* w,
void WriteFileEpilogue(PlatformEmbeddedFileWriterBase* w,
const i::EmbeddedData* blob) const {
{
i::EmbeddedVector<char, kTemporaryStringLength> embedded_blob_symbol;
@ -336,9 +275,9 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
#if defined(V8_OS_WIN_X64)
std::string BuiltinsUnwindInfoLabel() const;
void WriteUnwindInfo(PlatformDependentEmbeddedFileWriter* w,
void WriteUnwindInfo(PlatformEmbeddedFileWriterBase* w,
const i::EmbeddedData* blob) const;
void WriteUnwindInfoEntry(PlatformDependentEmbeddedFileWriter* w,
void WriteUnwindInfoEntry(PlatformEmbeddedFileWriterBase* w,
uint64_t rva_start, uint64_t rva_end) const;
#endif
@ -356,7 +295,7 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
static constexpr DataDirective kByteChunkDirective = kQuad;
static constexpr int kByteChunkSize = 8;
static int WriteByteChunk(PlatformDependentEmbeddedFileWriter* w,
static int WriteByteChunk(PlatformEmbeddedFileWriterBase* w,
int current_line_length, const uint8_t* data) {
const uint64_t* quad_ptr = reinterpret_cast<const uint64_t*>(data);
return current_line_length + w->HexLiteral(*quad_ptr);
@ -368,7 +307,7 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
static constexpr DataDirective kByteChunkDirective = kLong;
static constexpr int kByteChunkSize = 4;
static int WriteByteChunk(PlatformDependentEmbeddedFileWriter* w,
static int WriteByteChunk(PlatformEmbeddedFileWriterBase* w,
int current_line_length, const uint8_t* data) {
const uint32_t* long_ptr = reinterpret_cast<const uint32_t*>(data);
return current_line_length + w->HexLiteral(*long_ptr);
@ -378,7 +317,7 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
static constexpr DataDirective kByteChunkDirective = kOcta;
static constexpr int kByteChunkSize = 16;
static int WriteByteChunk(PlatformDependentEmbeddedFileWriter* w,
static int WriteByteChunk(PlatformEmbeddedFileWriterBase* w,
int current_line_length, const uint8_t* data) {
const size_t size = kInt64Size;
@ -403,7 +342,7 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
#endif // defined(V8_COMPILER_IS_MSVC) || defined(V8_OS_AIX)
#undef V8_COMPILER_IS_MSVC
static int WriteDirectiveOrSeparator(PlatformDependentEmbeddedFileWriter* w,
static int WriteDirectiveOrSeparator(PlatformEmbeddedFileWriterBase* w,
int current_line_length,
DataDirective directive) {
int printed_chars;
@ -417,7 +356,7 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
return current_line_length + printed_chars;
}
static int WriteLineEndIfNeeded(PlatformDependentEmbeddedFileWriter* w,
static int WriteLineEndIfNeeded(PlatformEmbeddedFileWriterBase* w,
int current_line_length, int write_size) {
static const int kTextWidth = 100;
// Check if adding ',0xFF...FF\n"' would force a line wrap. This doesn't use
@ -432,8 +371,7 @@ class EmbeddedFileWriter : public EmbeddedFileWriterInterface {
}
static void WriteBinaryContentsAsInlineAssembly(
PlatformDependentEmbeddedFileWriter* w, const uint8_t* data,
uint32_t size) {
PlatformEmbeddedFileWriterBase* w, const uint8_t* data, uint32_t size) {
int current_line_length = 0;
uint32_t i = 0;

View File

@ -0,0 +1,92 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/snapshot/embedded/platform-embedded-file-writer-base.h"
#include <string>
#include "src/snapshot/embedded/platform-embedded-file-writer-generic.h"
namespace v8 {
namespace internal {
namespace {
EmbeddedTargetArch DefaultEmbeddedTargetArch() {
#if defined(V8_TARGET_ARCH_ARM)
return EmbeddedTargetArch::kArm;
#elif defined(V8_TARGET_ARCH_ARM64)
return EmbeddedTargetArch::kArm64;
#elif defined(V8_TARGET_ARCH_IA32)
return EmbeddedTargetArch::kIA32;
#elif defined(V8_TARGET_ARCH_X64)
return EmbeddedTargetArch::kX64;
#else
return EmbeddedTargetArch::kGeneric;
#endif
}
EmbeddedTargetArch ToEmbeddedTargetArch(const char* s) {
if (s == nullptr) {
return DefaultEmbeddedTargetArch();
}
std::string string(s);
if (string == "arm") {
return EmbeddedTargetArch::kArm;
} else if (string == "arm64") {
return EmbeddedTargetArch::kArm64;
} else if (string == "ia32") {
return EmbeddedTargetArch::kIA32;
} else if (string == "x64") {
return EmbeddedTargetArch::kX64;
} else {
return EmbeddedTargetArch::kGeneric;
}
}
EmbeddedTargetOs DefaultEmbeddedTargetOs() {
#if defined(V8_OS_AIX)
return EmbeddedTargetOs::kAIX;
#elif defined(V8_OS_MACOSX)
return EmbeddedTargetOs::kMac;
#elif defined(V8_OS_WIN)
return EmbeddedTargetOs::kWin;
#else
return EmbeddedTargetOs::kGeneric;
#endif
}
EmbeddedTargetOs ToEmbeddedTargetOs(const char* s) {
if (s == nullptr) {
return DefaultEmbeddedTargetOs();
}
std::string string(s);
if (string == "aix") {
return EmbeddedTargetOs::kAIX;
} else if (string == "chromeos") {
return EmbeddedTargetOs::kChromeOS;
} else if (string == "fuchsia") {
return EmbeddedTargetOs::kFuchsia;
} else if (string == "mac") {
return EmbeddedTargetOs::kMac;
} else if (string == "win") {
return EmbeddedTargetOs::kWin;
} else {
return EmbeddedTargetOs::kGeneric;
}
}
} // namespace
std::unique_ptr<PlatformEmbeddedFileWriterBase> NewPlatformEmbeddedFileWriter(
const char* target_arch, const char* target_os) {
return std::unique_ptr<PlatformEmbeddedFileWriterGeneric>(
new PlatformEmbeddedFileWriterGeneric(ToEmbeddedTargetArch(target_arch),
ToEmbeddedTargetOs(target_os)));
}
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,87 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_BASE_H_
#define V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_BASE_H_
#include <cinttypes>
#include <cstdio> // For FILE.
#include <memory>
namespace v8 {
namespace internal {
enum DataDirective {
kByte,
kLong,
kQuad,
kOcta,
};
enum class EmbeddedTargetOs {
kAIX,
kChromeOS,
kFuchsia,
kMac,
kWin,
kGeneric, // Everything not covered above falls in here.
};
enum class EmbeddedTargetArch {
kArm,
kArm64,
kIA32,
kX64,
kGeneric, // Everything not covered above falls in here.
};
// The platform-dependent logic for emitting assembly code for the generated
// embedded.S file.
class PlatformEmbeddedFileWriterBase {
public:
virtual ~PlatformEmbeddedFileWriterBase() = default;
void SetFile(FILE* fp) { fp_ = fp; }
FILE* fp() const { return fp_; }
virtual void SectionText() = 0;
virtual void SectionData() = 0;
virtual void SectionRoData() = 0;
virtual void AlignToCodeAlignment() = 0;
virtual void AlignToDataAlignment() = 0;
virtual void DeclareUint32(const char* name, uint32_t value) = 0;
virtual void DeclarePointerToSymbol(const char* name, const char* target) = 0;
virtual void DeclareLabel(const char* name) = 0;
virtual void SourceInfo(int fileid, const char* filename, int line) = 0;
virtual void DeclareFunctionBegin(const char* name) = 0;
virtual void DeclareFunctionEnd(const char* name) = 0;
// Returns the number of printed characters.
virtual int HexLiteral(uint64_t value) = 0;
virtual void Comment(const char* string) = 0;
virtual void Newline() { fprintf(fp_, "\n"); }
virtual void FilePrologue() = 0;
virtual void DeclareExternalFilename(int fileid, const char* filename) = 0;
virtual void FileEpilogue() = 0;
virtual int IndentedDataDirective(DataDirective directive) = 0;
protected:
FILE* fp_ = nullptr;
};
// The factory function. Returns the appropriate platform-specific instance.
std::unique_ptr<PlatformEmbeddedFileWriterBase> NewPlatformEmbeddedFileWriter(
const char* target_arch, const char* target_os);
} // namespace internal
} // namespace v8
#endif // V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_BASE_H_

View File

@ -0,0 +1,700 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/snapshot/embedded/platform-embedded-file-writer-generic.h"
#include <algorithm>
#include <cinttypes>
#include "src/globals.h"
namespace v8 {
namespace internal {
// V8_CC_MSVC is true for both MSVC and clang on windows. clang can handle
// __asm__-style inline assembly but MSVC cannot, and thus we need a more
// precise compiler detection that can distinguish between the two. clang on
// windows sets both __clang__ and _MSC_VER, MSVC sets only _MSC_VER.
#if defined(_MSC_VER) && !defined(__clang__)
#define V8_COMPILER_IS_MSVC
#endif
// MSVC uses MASM for x86 and x64, while it has a ARMASM for ARM32 and
// ARMASM64 for ARM64. Since ARMASM and ARMASM64 accept a slightly tweaked
// version of ARM assembly language, they are referred to together in Visual
// Studio project files as MARMASM.
//
// ARM assembly language docs:
// http://infocenter.arm.com/help/topic/com.arm.doc.dui0802b/index.html
// Microsoft ARM assembler and assembly language docs:
// https://docs.microsoft.com/en-us/cpp/assembler/arm/arm-assembler-reference
#if defined(V8_COMPILER_IS_MSVC)
#if defined(V8_TARGET_ARCH_ARM64) || defined(V8_TARGET_ARCH_ARM)
#define V8_ASSEMBLER_IS_MARMASM
#elif defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X64)
#define V8_ASSEMBLER_IS_MASM
#else
#error Unknown Windows assembler target architecture.
#endif
#endif
// Name mangling.
// Symbols are prefixed with an underscore on 32-bit architectures.
#if defined(V8_TARGET_OS_WIN) && !defined(V8_TARGET_ARCH_X64) && \
!defined(V8_TARGET_ARCH_ARM64)
#define SYMBOL_PREFIX "_"
#else
#define SYMBOL_PREFIX ""
#endif
// Platform-independent bits.
// -----------------------------------------------------------------------------
namespace {
DataDirective PointerSizeDirective() {
if (kSystemPointerSize == 8) {
return kQuad;
} else {
CHECK_EQ(4, kSystemPointerSize);
return kLong;
}
}
} // namespace
const char* DirectiveAsString(DataDirective directive) {
#if defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MASM)
switch (directive) {
case kByte:
return "BYTE";
case kLong:
return "DWORD";
case kQuad:
return "QWORD";
default:
UNREACHABLE();
}
#elif defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MARMASM)
switch (directive) {
case kByte:
return "DCB";
case kLong:
return "DCDU";
case kQuad:
return "DCQU";
default:
UNREACHABLE();
}
#elif defined(V8_OS_AIX)
switch (directive) {
case kByte:
return ".byte";
case kLong:
return ".long";
case kQuad:
return ".llong";
default:
UNREACHABLE();
}
#else
switch (directive) {
case kByte:
return ".byte";
case kLong:
return ".long";
case kQuad:
return ".quad";
case kOcta:
return ".octa";
}
UNREACHABLE();
#endif
}
// V8_OS_MACOSX
// Fuchsia target is explicitly excluded here for Mac hosts. This is to avoid
// generating uncompilable assembly files for the Fuchsia target.
// -----------------------------------------------------------------------------
#if defined(V8_OS_MACOSX) && !defined(V8_TARGET_OS_FUCHSIA)
void PlatformEmbeddedFileWriterGeneric::SectionText() {
fprintf(fp_, ".text\n");
}
void PlatformEmbeddedFileWriterGeneric::SectionData() {
fprintf(fp_, ".data\n");
}
void PlatformEmbeddedFileWriterGeneric::SectionRoData() {
fprintf(fp_, ".const_data\n");
}
void PlatformEmbeddedFileWriterGeneric::DeclareUint32(const char* name,
uint32_t value) {
DeclareSymbolGlobal(name);
DeclareLabel(name);
IndentedDataDirective(kLong);
fprintf(fp_, "%d", value);
Newline();
}
void PlatformEmbeddedFileWriterGeneric::DeclarePointerToSymbol(
const char* name, const char* target) {
DeclareSymbolGlobal(name);
DeclareLabel(name);
fprintf(fp_, " %s _%s\n", DirectiveAsString(PointerSizeDirective()), target);
}
void PlatformEmbeddedFileWriterGeneric::DeclareSymbolGlobal(const char* name) {
// TODO(jgruber): Investigate switching to .globl. Using .private_extern
// prevents something along the compilation chain from messing with the
// embedded blob. Using .global here causes embedded blob hash verification
// failures at runtime.
fprintf(fp_, ".private_extern _%s\n", name);
}
void PlatformEmbeddedFileWriterGeneric::AlignToCodeAlignment() {
fprintf(fp_, ".balign 32\n");
}
void PlatformEmbeddedFileWriterGeneric::AlignToDataAlignment() {
fprintf(fp_, ".balign 8\n");
}
void PlatformEmbeddedFileWriterGeneric::Comment(const char* string) {
fprintf(fp_, "// %s\n", string);
}
void PlatformEmbeddedFileWriterGeneric::DeclareLabel(const char* name) {
fprintf(fp_, "_%s:\n", name);
}
void PlatformEmbeddedFileWriterGeneric::SourceInfo(int fileid,
const char* filename,
int line) {
fprintf(fp_, ".loc %d %d\n", fileid, line);
}
void PlatformEmbeddedFileWriterGeneric::DeclareFunctionBegin(const char* name) {
DeclareLabel(name);
// TODO(mvstanton): Investigate the proper incantations to mark the label as
// a function on OSX.
}
void PlatformEmbeddedFileWriterGeneric::DeclareFunctionEnd(const char* name) {}
int PlatformEmbeddedFileWriterGeneric::HexLiteral(uint64_t value) {
return fprintf(fp_, "0x%" PRIx64, value);
}
void PlatformEmbeddedFileWriterGeneric::FilePrologue() {}
void PlatformEmbeddedFileWriterGeneric::DeclareExternalFilename(
int fileid, const char* filename) {
fprintf(fp_, ".file %d \"%s\"\n", fileid, filename);
}
void PlatformEmbeddedFileWriterGeneric::FileEpilogue() {}
int PlatformEmbeddedFileWriterGeneric::IndentedDataDirective(
DataDirective directive) {
return fprintf(fp_, " %s ", DirectiveAsString(directive));
}
// V8_OS_AIX
// -----------------------------------------------------------------------------
#elif defined(V8_OS_AIX)
void PlatformEmbeddedFileWriterGeneric::SectionText() {
fprintf(fp_, ".csect .text[PR]\n");
}
void PlatformEmbeddedFileWriterGeneric::SectionData() {
fprintf(fp_, ".csect .data[RW]\n");
}
void PlatformEmbeddedFileWriterGeneric::SectionRoData() {
fprintf(fp_, ".csect[RO]\n");
}
void PlatformEmbeddedFileWriterGeneric::DeclareUint32(const char* name,
uint32_t value) {
DeclareSymbolGlobal(name);
fprintf(fp_, ".align 2\n");
fprintf(fp_, "%s:\n", name);
IndentedDataDirective(kLong);
fprintf(fp_, "%d\n", value);
Newline();
}
void PlatformEmbeddedFileWriterGeneric::DeclarePointerToSymbol(
const char* name, const char* target) {
AlignToCodeAlignment();
DeclareLabel(name);
fprintf(fp_, " %s %s\n", DirectiveAsString(PointerSizeDirective()), target);
Newline();
}
void PlatformEmbeddedFileWriterGeneric::DeclareSymbolGlobal(const char* name) {
fprintf(fp_, ".globl %s\n", name);
}
void PlatformEmbeddedFileWriterGeneric::AlignToCodeAlignment() {
fprintf(fp_, ".align 5\n");
}
void PlatformEmbeddedFileWriterGeneric::AlignToDataAlignment() {
fprintf(fp_, ".align 3\n");
}
void PlatformEmbeddedFileWriterGeneric::Comment(const char* string) {
fprintf(fp_, "// %s\n", string);
}
void PlatformEmbeddedFileWriterGeneric::DeclareLabel(const char* name) {
DeclareSymbolGlobal(name);
fprintf(fp_, "%s:\n", name);
}
void PlatformEmbeddedFileWriterGeneric::SourceInfo(int fileid,
const char* filename,
int line) {
fprintf(fp_, ".xline %d, \"%s\"\n", line, filename);
}
void PlatformEmbeddedFileWriterGeneric::DeclareFunctionBegin(const char* name) {
Newline();
DeclareSymbolGlobal(name);
fprintf(fp_, ".csect %s[DS]\n", name); // function descriptor
fprintf(fp_, "%s:\n", name);
fprintf(fp_, ".llong .%s, 0, 0\n", name);
SectionText();
fprintf(fp_, ".%s:\n", name);
}
void PlatformEmbeddedFileWriterGeneric::DeclareFunctionEnd(const char* name) {}
int PlatformEmbeddedFileWriterGeneric::HexLiteral(uint64_t value) {
return fprintf(fp_, "0x%" PRIx64, value);
}
void PlatformEmbeddedFileWriterGeneric::FilePrologue() {}
void PlatformEmbeddedFileWriterGeneric::DeclareExternalFilename(
int fileid, const char* filename) {
// File name cannot be declared with an identifier on AIX.
// We use the SourceInfo method to emit debug info in
//.xline <line-number> <file-name> format.
}
void PlatformEmbeddedFileWriterGeneric::FileEpilogue() {}
int PlatformEmbeddedFileWriterGeneric::IndentedDataDirective(
DataDirective directive) {
return fprintf(fp_, " %s ", DirectiveAsString(directive));
}
// V8_TARGET_OS_WIN (MSVC)
// -----------------------------------------------------------------------------
#elif defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MASM)
// For MSVC builds we emit assembly in MASM syntax.
// See https://docs.microsoft.com/en-us/cpp/assembler/masm/directives-reference.
void PlatformEmbeddedFileWriterGeneric::SectionText() {
fprintf(fp_, ".CODE\n");
}
void PlatformEmbeddedFileWriterGeneric::SectionData() {
fprintf(fp_, ".DATA\n");
}
void PlatformEmbeddedFileWriterGeneric::SectionRoData() {
fprintf(fp_, ".CONST\n");
}
void PlatformEmbeddedFileWriterGeneric::DeclareUint32(const char* name,
uint32_t value) {
DeclareSymbolGlobal(name);
fprintf(fp_, "%s%s %s %d\n", SYMBOL_PREFIX, name, DirectiveAsString(kLong),
value);
}
void PlatformEmbeddedFileWriterGeneric::DeclarePointerToSymbol(
const char* name, const char* target) {
DeclareSymbolGlobal(name);
fprintf(fp_, "%s%s %s %s%s\n", SYMBOL_PREFIX, name,
DirectiveAsString(PointerSizeDirective()), SYMBOL_PREFIX, target);
}
#if defined(V8_OS_WIN_X64)
void PlatformEmbeddedFileWriterGeneric::StartPdataSection() {
fprintf(fp_, "OPTION DOTNAME\n");
fprintf(fp_, ".pdata SEGMENT DWORD READ ''\n");
}
void PlatformEmbeddedFileWriterGeneric::EndPdataSection() {
fprintf(fp_, ".pdata ENDS\n");
}
void PlatformEmbeddedFileWriterGeneric::StartXdataSection() {
fprintf(fp_, "OPTION DOTNAME\n");
fprintf(fp_, ".xdata SEGMENT DWORD READ ''\n");
}
void PlatformEmbeddedFileWriterGeneric::EndXdataSection() {
fprintf(fp_, ".xdata ENDS\n");
}
void PlatformEmbeddedFileWriterGeneric::DeclareExternalFunction(
const char* name) {
fprintf(fp_, "EXTERN %s : PROC\n", name);
}
void PlatformEmbeddedFileWriterGeneric::DeclareRvaToSymbol(const char* name,
uint64_t offset) {
if (offset > 0) {
fprintf(fp_, "DD IMAGEREL %s+%llu\n", name, offset);
} else {
fprintf(fp_, "DD IMAGEREL %s\n", name);
}
}
#endif // defined(V8_OS_WIN_X64)
void PlatformEmbeddedFileWriterGeneric::DeclareSymbolGlobal(const char* name) {
fprintf(fp_, "PUBLIC %s%s\n", SYMBOL_PREFIX, name);
}
void PlatformEmbeddedFileWriterGeneric::AlignToCodeAlignment() {
// Diverges from other platforms due to compile error
// 'invalid combination with segment alignment'.
fprintf(fp_, "ALIGN 4\n");
}
void PlatformEmbeddedFileWriterGeneric::AlignToDataAlignment() {
fprintf(fp_, "ALIGN 4\n");
}
void PlatformEmbeddedFileWriterGeneric::Comment(const char* string) {
fprintf(fp_, "; %s\n", string);
}
void PlatformEmbeddedFileWriterGeneric::DeclareLabel(const char* name) {
fprintf(fp_, "%s%s LABEL %s\n", SYMBOL_PREFIX, name,
DirectiveAsString(kByte));
}
void PlatformEmbeddedFileWriterGeneric::SourceInfo(int fileid,
const char* filename,
int line) {
// TODO(mvstanton): output source information for MSVC.
// Its syntax is #line <line> "<filename>"
}
void PlatformEmbeddedFileWriterGeneric::DeclareFunctionBegin(const char* name) {
fprintf(fp_, "%s%s PROC\n", SYMBOL_PREFIX, name);
}
void PlatformEmbeddedFileWriterGeneric::DeclareFunctionEnd(const char* name) {
fprintf(fp_, "%s%s ENDP\n", SYMBOL_PREFIX, name);
}
int PlatformEmbeddedFileWriterGeneric::HexLiteral(uint64_t value) {
return fprintf(fp_, "0%" PRIx64 "h", value);
}
void PlatformEmbeddedFileWriterGeneric::FilePrologue() {
#if !defined(V8_TARGET_ARCH_X64)
fprintf(fp_, ".MODEL FLAT\n");
#endif
}
void PlatformEmbeddedFileWriterGeneric::DeclareExternalFilename(
int fileid, const char* filename) {}
void PlatformEmbeddedFileWriterGeneric::FileEpilogue() {
fprintf(fp_, "END\n");
}
int PlatformEmbeddedFileWriterGeneric::IndentedDataDirective(
DataDirective directive) {
return fprintf(fp_, " %s ", DirectiveAsString(directive));
}
#undef V8_ASSEMBLER_IS_MASM
#elif defined(V8_TARGET_OS_WIN) && defined(V8_ASSEMBLER_IS_MARMASM)
// The the AARCH64 ABI requires instructions be 4-byte-aligned and Windows does
// not have a stricter alignment requirement (see the TEXTAREA macro of
// kxarm64.h in the Windows SDK), so code is 4-byte-aligned.
// The data fields in the emitted assembly tend to be accessed with 8-byte
// LDR instructions, so data is 8-byte-aligned.
//
// armasm64's warning A4228 states
// Alignment value exceeds AREA alignment; alignment not guaranteed
// To ensure that ALIGN directives are honored, their values are defined as
// equal to their corresponding AREA's ALIGN attributes.
#define ARM64_DATA_ALIGNMENT_POWER (3)
#define ARM64_DATA_ALIGNMENT (1 << ARM64_DATA_ALIGNMENT_POWER)
#define ARM64_CODE_ALIGNMENT_POWER (2)
#define ARM64_CODE_ALIGNMENT (1 << ARM64_CODE_ALIGNMENT_POWER)
void PlatformEmbeddedFileWriterGeneric::SectionText() {
fprintf(fp_, " AREA |.text|, CODE, ALIGN=%d, READONLY\n",
ARM64_CODE_ALIGNMENT_POWER);
}
void PlatformEmbeddedFileWriterGeneric::SectionData() {
fprintf(fp_, " AREA |.data|, DATA, ALIGN=%d, READWRITE\n",
ARM64_DATA_ALIGNMENT_POWER);
}
void PlatformEmbeddedFileWriterGeneric::SectionRoData() {
fprintf(fp_, " AREA |.rodata|, DATA, ALIGN=%d, READONLY\n",
ARM64_DATA_ALIGNMENT_POWER);
}
void PlatformEmbeddedFileWriterGeneric::DeclareUint32(const char* name,
uint32_t value) {
DeclareSymbolGlobal(name);
fprintf(fp_, "%s%s %s %d\n", SYMBOL_PREFIX, name, DirectiveAsString(kLong),
value);
}
void PlatformEmbeddedFileWriterGeneric::DeclarePointerToSymbol(
const char* name, const char* target) {
DeclareSymbolGlobal(name);
fprintf(fp_, "%s%s %s %s%s\n", SYMBOL_PREFIX, name,
DirectiveAsString(PointerSizeDirective()), SYMBOL_PREFIX, target);
}
void PlatformEmbeddedFileWriterGeneric::DeclareSymbolGlobal(const char* name) {
fprintf(fp_, " EXPORT %s%s\n", SYMBOL_PREFIX, name);
}
void PlatformEmbeddedFileWriterGeneric::AlignToCodeAlignment() {
fprintf(fp_, " ALIGN %d\n", ARM64_CODE_ALIGNMENT);
}
void PlatformEmbeddedFileWriterGeneric::AlignToDataAlignment() {
fprintf(fp_, " ALIGN %d\n", ARM64_DATA_ALIGNMENT);
}
void PlatformEmbeddedFileWriterGeneric::Comment(const char* string) {
fprintf(fp_, "; %s\n", string);
}
void PlatformEmbeddedFileWriterGeneric::DeclareLabel(const char* name) {
fprintf(fp_, "%s%s\n", SYMBOL_PREFIX, name);
}
void PlatformEmbeddedFileWriterGeneric::SourceInfo(int fileid,
const char* filename,
int line) {
// TODO(mvstanton): output source information for MSVC.
// Its syntax is #line <line> "<filename>"
}
void PlatformEmbeddedFileWriterGeneric::DeclareFunctionBegin(const char* name) {
fprintf(fp_, "%s%s FUNCTION\n", SYMBOL_PREFIX, name);
}
void PlatformEmbeddedFileWriterGeneric::DeclareFunctionEnd(const char* name) {
fprintf(fp_, " ENDFUNC\n");
}
int PlatformEmbeddedFileWriterGeneric::HexLiteral(uint64_t value) {
return fprintf(fp_, "0x%" PRIx64, value);
}
void PlatformEmbeddedFileWriterGeneric::FilePrologue() {}
void PlatformEmbeddedFileWriterGeneric::DeclareExternalFilename(
int fileid, const char* filename) {}
void PlatformEmbeddedFileWriterGeneric::FileEpilogue() {
fprintf(fp_, " END\n");
}
int PlatformEmbeddedFileWriterGeneric::IndentedDataDirective(
DataDirective directive) {
return fprintf(fp_, " %s ", DirectiveAsString(directive));
}
#undef V8_ASSEMBLER_IS_MARMASM
#undef ARM64_DATA_ALIGNMENT_POWER
#undef ARM64_DATA_ALIGNMENT
#undef ARM64_CODE_ALIGNMENT_POWER
#undef ARM64_CODE_ALIGNMENT
// Everything but AIX, Windows with MSVC, or OSX.
// -----------------------------------------------------------------------------
#else
void PlatformEmbeddedFileWriterGeneric::SectionText() {
#if defined(V8_TARGET_OS_CHROMEOS)
fprintf(fp_, ".section .text.hot.embedded\n");
#else
fprintf(fp_, ".section .text\n");
#endif
}
void PlatformEmbeddedFileWriterGeneric::SectionData() {
fprintf(fp_, ".section .data\n");
}
void PlatformEmbeddedFileWriterGeneric::SectionRoData() {
if (target_os_ == EmbeddedTargetOs::kWin) {
fprintf(fp_, ".section .rdata\n");
} else {
fprintf(fp_, ".section .rodata\n");
}
}
void PlatformEmbeddedFileWriterGeneric::DeclareUint32(const char* name,
uint32_t value) {
DeclareSymbolGlobal(name);
DeclareLabel(name);
IndentedDataDirective(kLong);
fprintf(fp_, "%d", value);
Newline();
}
void PlatformEmbeddedFileWriterGeneric::DeclarePointerToSymbol(
const char* name, const char* target) {
DeclareSymbolGlobal(name);
DeclareLabel(name);
fprintf(fp_, " %s %s%s\n", DirectiveAsString(PointerSizeDirective()),
SYMBOL_PREFIX, target);
}
#if defined(V8_OS_WIN_X64)
void PlatformEmbeddedFileWriterGeneric::StartPdataSection() {
fprintf(fp_, ".section .pdata\n");
}
void PlatformEmbeddedFileWriterGeneric::EndPdataSection() {}
void PlatformEmbeddedFileWriterGeneric::StartXdataSection() {
fprintf(fp_, ".section .xdata\n");
}
void PlatformEmbeddedFileWriterGeneric::EndXdataSection() {}
void PlatformEmbeddedFileWriterGeneric::DeclareExternalFunction(
const char* name) {}
void PlatformEmbeddedFileWriterGeneric::DeclareRvaToSymbol(const char* name,
uint64_t offset) {
if (offset > 0) {
fprintf(fp_, ".rva %s + %llu\n", name, offset);
} else {
fprintf(fp_, ".rva %s\n", name);
}
}
#endif // defined(V8_OS_WIN_X64)
void PlatformEmbeddedFileWriterGeneric::DeclareSymbolGlobal(const char* name) {
fprintf(fp_, ".global %s%s\n", SYMBOL_PREFIX, name);
}
void PlatformEmbeddedFileWriterGeneric::AlignToCodeAlignment() {
fprintf(fp_, ".balign 32\n");
}
void PlatformEmbeddedFileWriterGeneric::AlignToDataAlignment() {
// On Windows ARM64, s390, PPC and possibly more platforms, aligned load
// instructions are used to retrieve v8_Default_embedded_blob_ and/or
// v8_Default_embedded_blob_size_. The generated instructions require the
// load target to be aligned at 8 bytes (2^3).
fprintf(fp_, ".balign 8\n");
}
void PlatformEmbeddedFileWriterGeneric::Comment(const char* string) {
fprintf(fp_, "// %s\n", string);
}
void PlatformEmbeddedFileWriterGeneric::DeclareLabel(const char* name) {
fprintf(fp_, "%s%s:\n", SYMBOL_PREFIX, name);
}
void PlatformEmbeddedFileWriterGeneric::SourceInfo(int fileid,
const char* filename,
int line) {
fprintf(fp_, ".loc %d %d\n", fileid, line);
}
void PlatformEmbeddedFileWriterGeneric::DeclareFunctionBegin(const char* name) {
DeclareLabel(name);
if (target_os_ == EmbeddedTargetOs::kWin) {
#if defined(V8_TARGET_ARCH_ARM64)
// Windows ARM64 assembly is in GAS syntax, but ".type" is invalid directive
// in PE/COFF for Windows.
#else
// The directives for inserting debugging information on Windows come
// from the PE (Portable Executable) and COFF (Common Object File Format)
// standards. Documented here:
// https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format
//
// .scl 2 means StorageClass external.
// .type 32 means Type Representation Function.
fprintf(fp_, ".def %s%s; .scl 2; .type 32; .endef;\n", SYMBOL_PREFIX, name);
#endif
} else {
#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_ARM64)
// ELF format binaries on ARM use ".type <function name>, %function"
// to create a DWARF subprogram entry.
fprintf(fp_, ".type %s, %%function\n", name);
#else
// Other ELF Format binaries use ".type <function name>, @function"
// to create a DWARF subprogram entry.
fprintf(fp_, ".type %s, @function\n", name);
#endif
}
}
void PlatformEmbeddedFileWriterGeneric::DeclareFunctionEnd(const char* name) {}
int PlatformEmbeddedFileWriterGeneric::HexLiteral(uint64_t value) {
return fprintf(fp_, "0x%" PRIx64, value);
}
void PlatformEmbeddedFileWriterGeneric::FilePrologue() {}
void PlatformEmbeddedFileWriterGeneric::DeclareExternalFilename(
int fileid, const char* filename) {
// Replace any Windows style paths (backslashes) with forward
// slashes.
std::string fixed_filename(filename);
std::replace(fixed_filename.begin(), fixed_filename.end(), '\\', '/');
fprintf(fp_, ".file %d \"%s\"\n", fileid, fixed_filename.c_str());
}
void PlatformEmbeddedFileWriterGeneric::FileEpilogue() {}
int PlatformEmbeddedFileWriterGeneric::IndentedDataDirective(
DataDirective directive) {
return fprintf(fp_, " %s ", DirectiveAsString(directive));
}
#endif
#undef SYMBOL_PREFIX
#undef V8_COMPILER_IS_MSVC
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,79 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_GENERIC_H_
#define V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_GENERIC_H_
#include <cinttypes>
#include <cstdio> // For FILE.
#include "src/base/macros.h"
#include "src/globals.h" // For V8_OS_WIN_X64
#include "src/snapshot/embedded/platform-embedded-file-writer-base.h"
namespace v8 {
namespace internal {
class PlatformEmbeddedFileWriterGeneric
: public PlatformEmbeddedFileWriterBase {
public:
PlatformEmbeddedFileWriterGeneric(EmbeddedTargetArch target_arch,
EmbeddedTargetOs target_os)
: target_arch_(target_arch), target_os_(target_os) {
// TODO(jgruber): Remove these once platforms have been split off.
USE(target_arch_);
USE(target_os_);
}
void SectionText() override;
void SectionData() override;
void SectionRoData() override;
void AlignToCodeAlignment() override;
void AlignToDataAlignment() override;
void DeclareUint32(const char* name, uint32_t value) override;
void DeclarePointerToSymbol(const char* name, const char* target) override;
void DeclareLabel(const char* name) override;
void SourceInfo(int fileid, const char* filename, int line) override;
void DeclareFunctionBegin(const char* name) override;
void DeclareFunctionEnd(const char* name) override;
int HexLiteral(uint64_t value) override;
void Comment(const char* string) override;
void FilePrologue() override;
void DeclareExternalFilename(int fileid, const char* filename) override;
void FileEpilogue() override;
int IndentedDataDirective(DataDirective directive) override;
#if defined(V8_OS_WIN_X64)
// TODO(jgruber): Move these to the windows-specific writer.
void StartPdataSection();
void EndPdataSection();
void StartXdataSection();
void EndXdataSection();
void DeclareExternalFunction(const char* name);
// Emits an RVA (address relative to the module load address) specified as an
// offset from a given symbol.
void DeclareRvaToSymbol(const char* name, uint64_t offset = 0);
#endif // defined(V8_OS_WIN_X64)
private:
void DeclareSymbolGlobal(const char* name);
private:
const EmbeddedTargetArch target_arch_;
const EmbeddedTargetOs target_os_;
};
} // namespace internal
} // namespace v8
#endif // V8_SNAPSHOT_EMBEDDED_PLATFORM_EMBEDDED_FILE_WRITER_GENERIC_H_