Skip to content

Commit a5077aa

Browse files
iinozemtsevCommit Queue
authored andcommitted
Reland "Add gen_snapshot binaries, producing Linux ARM64/x64 snapshots"
This is a reland of commit e6d55c6 Reworks guards for 64-bit Windows unwinding support code so that it is not included in any 64-bit Windows gen_snapshot executable that targets a non-64-bit Windows platform. TEST=ci, build only Original change's description: > Add gen_snapshot binaries, producing Linux ARM64/x64 snapshots > > Inspired by `//runtime/bin:gen_snapshot_fuchsia`, required for go/dart-cross-compile. > > TEST=ci, build only > > Change-Id: Ie521c984a8f44d25f3f78d946af9416582a572dc > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/410402 > Reviewed-by: Ryan Macnak <[email protected]> > Commit-Queue: Ivan Inozemtsev <[email protected]> Change-Id: I4f1323ac8f7ab215c2dffeef188f70c466fb62ea Cq-Include-Trybots: luci.dart.try:vm-win-release-arm64-try,vm-win-release-ia32-try,vm-win-release-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/413402 Reviewed-by: Martin Kustermann <[email protected]> Reviewed-by: Ivan Inozemtsev <[email protected]> Commit-Queue: Ivan Inozemtsev <[email protected]>
1 parent 144fe2b commit a5077aa

File tree

11 files changed

+181
-50
lines changed

11 files changed

+181
-50
lines changed

runtime/BUILD.gn

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,26 @@ config("dart_os_fuchsia_config") {
128128
defines = [ "DART_TARGET_OS_FUCHSIA" ]
129129
}
130130

131+
# We need to build gen_snapshot targeting Linux ARM64 during a build
132+
# of the SDK. This configuration is used to unconditionally target
133+
# Linux ARM64. It should not be combined with dart_os_config and dart_arch_config.
134+
config("dart_linux_arm64_config") {
135+
defines = [
136+
"DART_TARGET_OS_LINUX",
137+
"TARGET_ARCH_ARM64",
138+
]
139+
}
140+
141+
# We need to build gen_snapshot targeting Linux ARM64 during a build
142+
# of the SDK. This configuration is used to unconditionally target
143+
# Linux ARM64. It should not be combined with dart_os_config and dart_arch_config.
144+
config("dart_linux_x64_config") {
145+
defines = [
146+
"DART_TARGET_OS_LINUX",
147+
"TARGET_ARCH_X64",
148+
]
149+
}
150+
131151
config("dart_arch_config") {
132152
defines = []
133153

runtime/bin/BUILD.gn

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,20 @@ build_libdart_builtin("libdart_builtin_product_host_targeting_host") {
107107
extra_configs = [ "..:dart_product_config" ]
108108
}
109109

110+
build_libdart_builtin("libdart_builtin_product_linux_x64") {
111+
extra_configs = [
112+
"..:dart_product_config",
113+
"..:dart_linux_x64_config",
114+
]
115+
}
116+
117+
build_libdart_builtin("libdart_builtin_product_linux_arm64") {
118+
extra_configs = [
119+
"..:dart_product_config",
120+
"..:dart_linux_arm64_config",
121+
]
122+
}
123+
110124
template("build_native_assets_api") {
111125
extra_configs = []
112126
if (defined(invoker.extra_configs)) {
@@ -330,6 +344,31 @@ build_gen_snapshot("gen_snapshot_product_fuchsia") {
330344
]
331345
}
332346

347+
build_gen_snapshot("gen_snapshot_product_linux_x64") {
348+
extra_configs = [
349+
"..:dart_product_config",
350+
"..:dart_linux_x64_config",
351+
]
352+
extra_deps = [
353+
":gen_snapshot_dart_io_product_linux_x64",
354+
":libdart_builtin_product_linux_x64",
355+
"..:libdart_precompiler_product_linux_x64",
356+
"../platform:libdart_platform_precompiler_product_linux_x64",
357+
]
358+
}
359+
360+
build_gen_snapshot("gen_snapshot_product_linux_arm64") {
361+
extra_configs = [
362+
"..:dart_product_config",
363+
"..:dart_linux_arm64_config",
364+
]
365+
extra_deps = [
366+
":gen_snapshot_dart_io_product_linux_arm64",
367+
":libdart_builtin_product_linux_arm64",
368+
"..:libdart_precompiler_product_linux_arm64",
369+
"../platform:libdart_platform_precompiler_product_linux_arm64",
370+
]
371+
}
333372
build_gen_snapshot("gen_snapshot_host_targeting_host") {
334373
extra_configs = [ "..:dart_maybe_product_config" ]
335374
extra_deps = [
@@ -434,6 +473,20 @@ build_gen_snapshot_dart_io("gen_snapshot_dart_io_product_fuchsia") {
434473
]
435474
}
436475

476+
build_gen_snapshot_dart_io("gen_snapshot_dart_io_product_linux_x64") {
477+
extra_configs = [
478+
"..:dart_product_config",
479+
"..:dart_linux_x64_config",
480+
]
481+
}
482+
483+
build_gen_snapshot_dart_io("gen_snapshot_dart_io_product_linux_arm64") {
484+
extra_configs = [
485+
"..:dart_product_config",
486+
"..:dart_linux_arm64_config",
487+
]
488+
}
489+
437490
# A source set for the implementation of 'dart:io' library.
438491
template("dart_io") {
439492
extra_configs = []

runtime/bin/elf_loader.cc

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,7 @@ class LoadedElf {
241241
const dart::elf::Symbol* dynamic_symbol_table_ = nullptr;
242242
uword dynamic_symbol_count_ = 0;
243243

244-
#if defined(DART_HOST_OS_WINDOWS) && \
245-
(defined(HOST_ARCH_X64) || defined(HOST_ARCH_ARM64))
244+
#if defined(DART_HOST_OS_WINDOWS) && defined(ARCH_IS_64_BIT)
246245
// Dynamic table for looking up unwinding exceptions info.
247246
// Initialized by LoadSegments as we load executable segment.
248247
MallocGrowableArray<void*> dynamic_runtime_function_tables_;
@@ -295,8 +294,7 @@ bool LoadedElf::Load() {
295294
}
296295

297296
LoadedElf::~LoadedElf() {
298-
#if defined(DART_HOST_OS_WINDOWS) && \
299-
(defined(HOST_ARCH_X64) || defined(HOST_ARCH_ARM64))
297+
#if defined(DART_HOST_OS_WINDOWS) && defined(ARCH_IS_64_BIT)
300298
for (intptr_t i = 0; i < dynamic_runtime_function_tables_.length(); i++) {
301299
UnwindingRecordsPlatform::UnregisterDynamicTable(
302300
dynamic_runtime_function_tables_[i]);
@@ -465,8 +463,7 @@ bool LoadedElf::LoadSegments() {
465463
CHECK_ERROR(memory != nullptr, "Could not map segment.");
466464
CHECK_ERROR(memory->address() == memory_start,
467465
"Mapping not at requested address.");
468-
#if defined(DART_HOST_OS_WINDOWS) && \
469-
(defined(HOST_ARCH_X64) || defined(HOST_ARCH_ARM64))
466+
#if defined(DART_HOST_OS_WINDOWS) && defined(ARCH_IS_64_BIT)
470467
// For executable pages register unwinding information that should be
471468
// present on the page.
472469
if (map_type == File::kReadExecute) {

runtime/configs.gni

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@ _precompiler_host_targeting_host_config =
6363
_precompiler_product_host_targeting_host_config =
6464
_base_host_targeting_host_config + _precompiler_base + _product
6565

66+
_precompiler_product_linux_x64_config =
67+
[
68+
"$_dart_runtime:dart_config",
69+
"$_dart_runtime:dart_linux_x64_config",
70+
] + _product + _precompiler_base
71+
72+
_precompiler_product_linux_arm64_config =
73+
[
74+
"$_dart_runtime:dart_config",
75+
"$_dart_runtime:dart_linux_arm64_config",
76+
] + _product + _precompiler_base
77+
6678
_all_configs = [
6779
{
6880
suffix = "_jit"
@@ -148,6 +160,20 @@ _all_configs = [
148160
compiler = true
149161
is_product = false
150162
},
163+
{
164+
suffix = "_precompiler_product_linux_x64"
165+
configs = _precompiler_product_linux_x64_config
166+
snapshot = false
167+
compiler = true
168+
is_product = true
169+
},
170+
{
171+
suffix = "_precompiler_product_linux_arm64"
172+
configs = _precompiler_product_linux_arm64_config
173+
snapshot = false
174+
compiler = true
175+
is_product = true
176+
},
151177
]
152178

153179
# This template creates a target for each of the configurations listed above.

runtime/platform/unwinding_records.cc

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,26 @@
77

88
namespace dart {
99

10-
#if (!defined(DART_TARGET_OS_WINDOWS) && !defined(DART_HOST_OS_WINDOWS)) || \
11-
(!defined(TARGET_ARCH_X64) && !defined(TARGET_ARCH_ARM64))
10+
#if !(defined(DART_TARGET_OS_WINDOWS) && defined(TARGET_ARCH_IS_64_BIT) || \
11+
defined(DART_HOST_OS_WINDOWS) && defined(ARCH_IS_64_BIT))
1212

1313
intptr_t UnwindingRecordsPlatform::SizeInBytes() {
1414
return 0;
1515
}
1616

17-
#endif // (!defined(DART_TARGET_OS_WINDOWS) && !defined(DART_HOST_OS_WINDOWS))
17+
#endif // !defined(DART_TARGET_OS_WINDOWS) && !defined(DART_HOST_OS_WINDOWS)
1818

19-
#if !defined(DART_HOST_OS_WINDOWS) || \
20-
(!defined(TARGET_ARCH_X64) && !defined(TARGET_ARCH_ARM64))
19+
// Also use empty definitions when running gen_snapshot on 64-bit Windows, as it
20+
// does not use the ELF loader, which is the client of these methods.
21+
#if !defined(DART_HOST_OS_WINDOWS) || !defined(ARCH_IS_64_BIT) || \
22+
(defined(DART_PRECOMPILER) && !defined(TESTING))
2123

2224
void UnwindingRecordsPlatform::RegisterExecutableMemory(
2325
void* start,
2426
intptr_t size,
2527
void** pp_dynamic_table) {}
2628
void UnwindingRecordsPlatform::UnregisterDynamicTable(void* p_dynamic_table) {}
2729

28-
#endif // !defined(DART_HOST_OS_WINDOWS) ...
30+
#endif // !defined(DART_HOST_OS_WINDOWS) || ...
2931

3032
} // namespace dart

runtime/platform/unwinding_records.h

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,25 @@ class UnwindingRecordsPlatform : public AllStatic {
2020
static void UnregisterDynamicTable(void* p_dynamic_table);
2121
};
2222

23-
#if (defined(DART_TARGET_OS_WINDOWS) || defined(DART_HOST_OS_WINDOWS)) && \
24-
defined(TARGET_ARCH_X64)
23+
// These definitions are only needed if targeting 64-bit Windows, or if the
24+
// ELF loader may be used on 64-bit Windows.
25+
//
26+
// More specifically, a 64-bit Windows gen_snapshot that does not target
27+
// 64-bit Windows does not need these definitions, as the generated snapshot
28+
// should not contain Windows-specific unwinding records and gen_snapshot
29+
// does not uses the ELF loader.
30+
#if (defined(DART_TARGET_OS_WINDOWS) && defined(TARGET_ARCH_IS_64_BIT)) || \
31+
(defined(DART_HOST_OS_WINDOWS) && defined(ARCH_IS_64_BIT) && \
32+
(!defined(DART_PRECOMPILER) || defined(TESTING)))
2533

2634
#pragma pack(push, 1)
35+
36+
#if !defined(DART_HOST_OS_WINDOWS) || !defined(HOST_ARCH_X64)
37+
typedef uint32_t ULONG;
38+
typedef uint32_t DWORD;
39+
#endif
40+
41+
#if defined(TARGET_ARCH_X64)
2742
//
2843
// Refer to https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64
2944
//
@@ -49,7 +64,6 @@ typedef struct _UNWIND_INFO {
4964
} UNWIND_INFO, *PUNWIND_INFO;
5065

5166
#if !defined(DART_HOST_OS_WINDOWS)
52-
typedef uint32_t ULONG;
5367
typedef struct _RUNTIME_FUNCTION {
5468
ULONG BeginAddress;
5569
ULONG EndAddress;
@@ -97,12 +111,7 @@ struct CodeRangeUnwindingRecord {
97111
RUNTIME_FUNCTION runtime_function[1];
98112
};
99113

100-
#pragma pack(pop)
101-
102-
#elif defined(TARGET_ARCH_ARM64) && \
103-
(defined(DART_TARGET_OS_WINDOWS) || defined(DART_HOST_OS_WINDOWS))
104-
105-
#pragma pack(push, 1)
114+
#elif defined(TARGET_ARCH_ARM64)
106115

107116
// ARM64 unwind codes are defined in below doc.
108117
// https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling#unwind-codes
@@ -139,12 +148,9 @@ struct UNWIND_INFO {
139148
uint32_t CodeWords : 5;
140149
};
141150

142-
#if !defined(DART_HOST_OS_WINDOWS)
143-
typedef uint32_t ULONG;
144-
typedef uint32_t DWORD;
151+
#if !defined(DART_HOST_OS_WINDOWS) || !defined(HOST_ARCH_ARM64)
145152
typedef struct _RUNTIME_FUNCTION {
146153
ULONG BeginAddress;
147-
ULONG EndAddress;
148154
ULONG UnwindData;
149155
} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
150156
#endif
@@ -231,9 +237,13 @@ struct CodeRangeUnwindingRecord {
231237
RUNTIME_FUNCTION runtime_function[kDefaultRuntimeFunctionCount];
232238
};
233239

240+
#else
241+
#error Unhandled Windows architecture.
242+
#endif
243+
234244
#pragma pack(pop)
235245

236-
#endif // (defined(DART_TARGET_OS_WINDOWS) || defined(DART_HOST_OS_WINDOWS))
246+
#endif // (defined(DART_TARGET_OS_WINDOWS) || ...
237247

238248
} // namespace dart
239249

runtime/platform/unwinding_records_win.cc

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,27 @@
99

1010
namespace dart {
1111

12-
#if (defined(DART_TARGET_OS_WINDOWS) || defined(DART_HOST_OS_WINDOWS)) && \
13-
(defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64))
12+
#if (defined(DART_TARGET_OS_WINDOWS) && defined(TARGET_ARCH_IS_64_BIT)) || \
13+
(defined(DART_HOST_OS_WINDOWS) && defined(ARCH_IS_64_BIT))
1414

1515
#if defined(TARGET_ARCH_X64)
1616
const intptr_t kReservedUnwindingRecordsSizeBytes = 64;
17-
#else
17+
#elif defined(TARGET_ARCH_ARM64)
1818
const intptr_t kReservedUnwindingRecordsSizeBytes = 4 * KB;
19+
#else
20+
#error Unhandled Windows architecture.
1921
#endif
2022

2123
intptr_t UnwindingRecordsPlatform::SizeInBytes() {
2224
return kReservedUnwindingRecordsSizeBytes;
2325
}
2426

25-
#endif // defined(DART_TARGET_OS_WINDOWS) || defined(DART_HOST_OS_WINDOWS)
27+
#endif // defined(DART_TARGET_OS_WINDOWS) ...
2628

27-
#if defined(DART_HOST_OS_WINDOWS) && \
28-
(defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64))
29+
// Only use these definitions when the ELF loader may be used on 64-bit Windows,
30+
// as it is the only client of these methods (e.g., _not_ in gen_snapshot).
31+
#if defined(DART_HOST_OS_WINDOWS) && defined(ARCH_IS_64_BIT) && \
32+
(!defined(DART_PRECOMPILER) || defined(TESTING))
2933

3034
void UnwindingRecordsPlatform::RegisterExecutableMemory(
3135
void* start,
@@ -54,6 +58,6 @@ void UnwindingRecordsPlatform::UnregisterDynamicTable(void* p_dynamic_table) {
5458
RtlDeleteGrowableFunctionTable(p_dynamic_table);
5559
}
5660

57-
#endif // defined(DART_HOST_OS_WINDOWS)
61+
#endif // defined(DART_HOST_OS_WINDOWS) ...
5862

5963
} // namespace dart

runtime/vm/elf.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,8 +1430,7 @@ void Elf::FinalizeEhFrame() {
14301430
// No text section added means no .eh_frame.
14311431
if (text_section == nullptr) return;
14321432

1433-
#if defined(DART_TARGET_OS_WINDOWS) && \
1434-
(defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64))
1433+
#if defined(DART_TARGET_OS_WINDOWS) && defined(TARGET_ARCH_IS_64_BIT)
14351434
// Append Windows unwinding instructions to the end of .text section.
14361435
{ // NOLINT
14371436
auto* const unwinding_instructions_frame = new (zone_) TextSection(type_);
@@ -1493,8 +1492,7 @@ void Elf::FinalizeEhFrame() {
14931492

14941493
// Emit an FDE covering each .text section.
14951494
for (const auto& portion : text_section->portions()) {
1496-
#if defined(DART_TARGET_OS_WINDOWS) && \
1497-
(defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64))
1495+
#if defined(DART_TARGET_OS_WINDOWS) && defined(TARGET_ARCH_IS_64_BIT)
14981496
if (portion.label == 0) {
14991497
// Unwinding instructions sections doesn't have label, doesn't dwarf
15001498
continue;

runtime/vm/unwinding_records.cc

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,23 @@
77

88
namespace dart {
99

10-
#if (!defined(DART_TARGET_OS_WINDOWS) && !defined(DART_HOST_OS_WINDOWS)) || \
11-
(!defined(TARGET_ARCH_X64) && !defined(TARGET_ARCH_ARM64))
10+
#if !defined(DART_TARGET_OS_WINDOWS) || !defined(TARGET_ARCH_IS_64_BIT)
1211

1312
const void* UnwindingRecords::GenerateRecordsInto(intptr_t offset,
1413
uint8_t* target_buffer) {
1514
return nullptr;
1615
}
1716

18-
#endif
17+
#endif // !defined(DART_TARGET_OS_WINDOWS)
1918

20-
#if !defined(DART_HOST_OS_WINDOWS) || \
21-
(!defined(TARGET_ARCH_X64) && !defined(TARGET_ARCH_ARM64))
19+
// Also use empty definitions when running gen_snapshot on 64-bit Windows, as
20+
// it does not use the ELF loader, which is the client of these methods.
21+
#if !defined(DART_HOST_OS_WINDOWS) || !defined(ARCH_IS_64_BIT) || \
22+
(defined(DART_PRECOMPILER) && !defined(TESTING))
2223

2324
void UnwindingRecords::RegisterExecutablePage(Page* page) {}
2425
void UnwindingRecords::UnregisterExecutablePage(Page* page) {}
2526

26-
#endif
27+
#endif // !defined(DART_HOST_OS_WINDOWS)
2728

2829
} // namespace dart

0 commit comments

Comments
 (0)