[gen_snapshot] Provide option to generate ELF libraries pre-stripped.

Change-Id: I13631e21e114296a268aeeaad570b8613273af10
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/105121
Commit-Queue: Siva Annamalai <asiva@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 6af098e..fbd41ce 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -119,17 +119,19 @@
   V(reused_instructions, reused_instructions_filename)                         \
   V(blobs_container_filename, blobs_container_filename)                        \
   V(assembly, assembly_filename)                                               \
+  V(elf, elf_filename)                                                         \
   V(load_compilation_trace, load_compilation_trace_filename)                   \
   V(load_type_feedback, load_type_feedback_filename)                           \
   V(save_obfuscation_map, obfuscation_map_filename)
 
 #define BOOL_OPTIONS_LIST(V)                                                   \
-  V(read_all_bytecode, read_all_bytecode)                                      \
   V(compile_all, compile_all)                                                  \
+  V(help, help)                                                                \
   V(obfuscate, obfuscate)                                                      \
+  V(read_all_bytecode, read_all_bytecode)                                      \
+  V(strip, strip)                                                              \
   V(verbose, verbose)                                                          \
-  V(version, version)                                                          \
-  V(help, help)
+  V(version, version)
 
 #define STRING_OPTION_DEFINITION(flag, variable)                               \
   static const char* variable = NULL;                                          \
@@ -188,6 +190,14 @@
 "[--save-obfuscation-map=<map-filename>]                                     \n"
 "<dart-kernel-file>                                                          \n"
 "                                                                            \n"
+"To create an AOT application snapshot as an ELF shared library:             \n"
+"--snapshot_kind=app-aot-elf                                                 \n"
+"--elf=<output-file>                                                         \n"
+"[--strip]                                                                   \n"
+"[--obfuscate]                                                               \n"
+"[--save-obfuscation-map=<map-filename>]                                     \n"
+"<dart-kernel-file>                                                          \n"
+"                                                                            \n"
 "AOT snapshots can be obfuscated: that is all identifiers will be renamed    \n"
 "during compilation. This mode is enabled with --obfuscate flag. Mapping     \n"
 "between original and obfuscated names can be serialized as a JSON array     \n"
@@ -317,16 +327,16 @@
       }
       break;
     }
-    case kAppAOTAssembly:
     case kAppAOTElf: {
-      if (assembly_filename == NULL) {
+      if (elf_filename == NULL) {
         Syslog::PrintErr(
             "Building an AOT snapshot as assembly requires specifying "
-            "an output file for --assembly.\n\n");
+            "an output file for --elf.\n\n");
         return -1;
       }
       break;
     }
+    case kAppAOTAssembly:
     case kVMAOTAssembly: {
       if (assembly_filename == NULL) {
         Syslog::PrintErr(
@@ -630,9 +640,15 @@
     result = Dart_CreateAppAOTSnapshotAsAssembly(StreamingWriteCallback, file);
     CHECK_RESULT(result);
   } else if (snapshot_kind == kAppAOTElf) {
-    File* file = OpenFile(assembly_filename);
+    if (strip) {
+      Syslog::PrintErr(
+          "Warning: Generating ELF library without DWARF debugging"
+          " information.\n");
+    }
+    File* file = OpenFile(elf_filename);
     RefCntReleaseScope<File> rs(file);
-    result = Dart_CreateAppAOTSnapshotAsElf(StreamingWriteCallback, file);
+    result =
+        Dart_CreateAppAOTSnapshotAsElf(StreamingWriteCallback, file, strip);
     CHECK_RESULT(result);
   } else if (snapshot_kind == kAppAOTBlobs) {
     const uint8_t* shared_data = NULL;
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index d1e4326..31a7d1b 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -3306,7 +3306,8 @@
  */
 DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle
 Dart_CreateAppAOTSnapshotAsElf(Dart_StreamingWriteCallback callback,
-                               void* callback_data);
+                               void* callback_data,
+                               bool stripped);
 
 /**
  *  Like Dart_CreateAppAOTSnapshotAsAssembly, but only includes
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 5f9a66b..4ebdac9 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -6065,7 +6065,8 @@
 
 DART_EXPORT Dart_Handle
 Dart_CreateAppAOTSnapshotAsElf(Dart_StreamingWriteCallback callback,
-                               void* callback_data) {
+                               void* callback_data,
+                               bool strip) {
 #if defined(TARGET_ARCH_IA32)
   return Api::NewError("AOT compilation is not supported on IA32.");
 #elif defined(TARGET_ARCH_DBC)
@@ -6089,8 +6090,12 @@
   NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
                                             "WriteAppAOTSnapshot"));
   StreamingWriteStream elf_stream(2 * MB, callback, callback_data);
+
   Elf* elf = new (Z) Elf(Z, &elf_stream);
-  Dwarf* dwarf = new (Z) Dwarf(Z, nullptr, elf);
+  Dwarf* dwarf = nullptr;
+  if (!strip) {
+    dwarf = new (Z) Dwarf(Z, nullptr, elf);
+  }
 
   BlobImageWriter vm_image_writer(T, &vm_snapshot_instructions_buffer,
                                   ApiReallocate, /* initial_size= */ 2 * MB,
@@ -6108,9 +6113,11 @@
                  writer.VmIsolateSnapshotSize());
   elf->AddROData("_kDartIsolateSnapshotData", isolate_snapshot_data_buffer,
                  writer.IsolateSnapshotSize());
-  // TODO(rmacnak): Generate .debug_frame / .eh_frame / .arm.exidx to
-  // providing unwinding information.
-  dwarf->Write();
+  if (!strip) {
+    // TODO(rmacnak): Generate .debug_frame / .eh_frame / .arm.exidx to
+    // provide unwinding information.
+    dwarf->Write();
+  }
   elf->Finalize();
 
   return Api::Success();
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index b3d16c8..460b148 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -540,7 +540,7 @@
 
 #ifdef DART_PRECOMPILER
     // Create a label for use by DWARF.
-    if (!code.IsNull()) {
+    if ((dwarf_ != nullptr) && !code.IsNull()) {
       const intptr_t dwarf_index = dwarf_->AddCode(code);
       assembly_stream_.Print(".Lcode%" Pd ":\n", dwarf_index);
     }
@@ -751,7 +751,7 @@
 
 #ifdef DART_PRECOMPILER
     const Code& code = *instructions_[i].code_;
-    if ((elf_ != nullptr) && !code.IsNull()) {
+    if ((elf_ != nullptr) && (dwarf_ != nullptr) && !code.IsNull()) {
       intptr_t segment_offset = instructions_blob_stream_.bytes_written() +
                                 Instructions::HeaderSize();
       dwarf_->AddCode(code, segment_base + segment_offset);
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index f3459d0..c67ae47 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -752,7 +752,7 @@
       args.add("--blobs_container_filename=$tempDir/out.aotsnapshot");
     } else if (_configuration.useElf) {
       args.add("--snapshot-kind=app-aot-elf");
-      args.add("--assembly=$tempDir/out.aotsnapshot");
+      args.add("--elf=$tempDir/out.aotsnapshot");
     } else {
       args.add("--snapshot-kind=app-aot-assembly");
       args.add("--assembly=$tempDir/out.S");