Version 2.12.0-147.0.dev

Merge commit '739393b29096e7528df4ac655044e6b2c9475c6d' into 'dev'
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni
index 0d74966..96a32d4 100644
--- a/build/toolchain/gcc_toolchain.gni
+++ b/build/toolchain/gcc_toolchain.gni
@@ -204,7 +204,13 @@
         command += " && " + strip_command
       } else if (defined(invoker.llvm_objcopy)) {
         strip = invoker.llvm_objcopy
-        strip_command = "${strip} --strip-all $outfile $stripped_outfile"
+        if (defined(invoker.llvm_objcopy_extra_args)) {
+          extra_args = invoker.llvm_objcopy_extra_args
+        } else {
+          extra_args = ""
+        }
+        strip_command =
+            "${strip} --strip-all ${extra_args} $outfile $stripped_outfile"
         command += " && " + strip_command
       }
       if (defined(invoker.postlink)) {
diff --git a/build/toolchain/linux/BUILD.gn b/build/toolchain/linux/BUILD.gn
index 4692784..71038ed 100644
--- a/build/toolchain/linux/BUILD.gn
+++ b/build/toolchain/linux/BUILD.gn
@@ -52,6 +52,17 @@
   ld = cxx
   llvm_objcopy = "${prefix}/llvm-objcopy"
 
+  # When producing ARM builds we drop .ARM.exidx/extab sections. These sections
+  # don't contain any useful information (we don't use exceptions or
+  # unwind C++ frames and most of the dart binary is in fact not covered by
+  # them), however they have been seen to break dynamic linker in older glibc
+  # versions (pre 2.23) because .ARM.exidx ends up being positioned between
+  # .rel.dyn and .rel.plt sections while older versions of dynamic linker
+  # expect these two sections to appear one after another in the ELF file.
+  # See https://github.com/dart-lang/sdk/issues/41644.
+  llvm_objcopy_extra_args =
+      "--remove-section .ARM.exidx --remove-section .ARM.extab"
+
   toolchain_cpu = "arm"
   toolchain_os = "linux"
   is_clang = true
diff --git a/pkg/kernel/bin/size_breakdown.dart b/pkg/kernel/bin/size_breakdown.dart
index 01fec0f..298e1ec 100755
--- a/pkg/kernel/bin/size_breakdown.dart
+++ b/pkg/kernel/bin/size_breakdown.dart
@@ -62,9 +62,9 @@
     linkTableSize += byteOffset;
   }
 
-  Map<Uri, Source> readUriToSource() {
+  Map<Uri, Source> readUriToSource(bool readCoverage) {
     uriToSourceSize -= byteOffset;
-    var result = super.readUriToSource();
+    var result = super.readUriToSource(readCoverage);
     uriToSourceSize += byteOffset;
     return result;
   }
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index e4676d9..4a94b88 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -563,6 +563,8 @@
   }
 
   /// Deserializes the source and stores it in [component].
+  /// Note that the _coverage_ normally included in the source in the
+  /// uri-to-source mapping is _not_ included.
   ///
   /// The input bytes may contain multiple files concatenated.
   void readComponentSource(Component component) {
@@ -724,7 +726,7 @@
     _ComponentIndex index = _readComponentIndex(componentFileSize);
 
     _byteOffset = index.binaryOffsetForSourceTable;
-    Map<Uri, Source> uriToSource = readUriToSource();
+    Map<Uri, Source> uriToSource = readUriToSource(/* readCoverage = */ false);
     _mergeUriToSource(component.uriToSource, uriToSource);
 
     _byteOffset = _componentStartOffset + componentFileSize;
@@ -773,7 +775,7 @@
     _associateMetadata(component, _componentStartOffset);
 
     _byteOffset = index.binaryOffsetForSourceTable;
-    Map<Uri, Source> uriToSource = readUriToSource();
+    Map<Uri, Source> uriToSource = readUriToSource(/* readCoverage = */ true);
     _mergeUriToSource(component.uriToSource, uriToSource);
 
     _byteOffset = index.binaryOffsetForConstantTable;
@@ -821,7 +823,14 @@
     return strings;
   }
 
-  Map<Uri, Source> readUriToSource() {
+  /// Read the uri-to-source part of the binary.
+  /// Note that this can include coverage, but that it is only included if
+  /// [readCoverage] is true, otherwise coverage will be skipped. Note also that
+  /// if [readCoverage] is true, references are read and that the link table
+  /// thus has to be read first.
+  Map<Uri, Source> readUriToSource(bool readCoverage) {
+    assert(!readCoverage || (readCoverage && _linkTable != null));
+
     int length = readUint32();
 
     // Read data.
@@ -847,10 +856,16 @@
       Set<Reference> coverageConstructors;
       {
         int constructorCoverageCount = readUInt30();
-        coverageConstructors =
-            constructorCoverageCount == 0 ? null : new Set<Reference>();
-        for (int j = 0; j < constructorCoverageCount; ++j) {
-          coverageConstructors.add(readMemberReference());
+        if (readCoverage) {
+          coverageConstructors =
+              constructorCoverageCount == 0 ? null : new Set<Reference>();
+          for (int j = 0; j < constructorCoverageCount; ++j) {
+            coverageConstructors.add(readMemberReference());
+          }
+        } else {
+          for (int j = 0; j < constructorCoverageCount; ++j) {
+            skipMemberReference();
+          }
         }
       }
 
@@ -906,6 +921,10 @@
     }
   }
 
+  void skipCanonicalNameReference() {
+    readUInt30();
+  }
+
   CanonicalName readCanonicalNameReference() {
     int index = readUInt30();
     if (index == 0) return null;
@@ -937,6 +956,10 @@
     return name?.getReference();
   }
 
+  void skipMemberReference() {
+    skipCanonicalNameReference();
+  }
+
   Reference readMemberReference({bool allowNull: false}) {
     CanonicalName name = readCanonicalNameReference();
     if (name == null && !allowNull) {
diff --git a/pkg/kernel/test/binary/can_read_platform_test.dart b/pkg/kernel/test/binary/can_read_platform_test.dart
index 4984a0b..2b447bc 100644
--- a/pkg/kernel/test/binary/can_read_platform_test.dart
+++ b/pkg/kernel/test/binary/can_read_platform_test.dart
@@ -84,6 +84,9 @@
     int libs = component.libraries.length;
 
     component = new Component();
+    new BinaryBuilderWithMetadata(bytes).readComponentSource(component);
+
+    component = new Component();
     new BinaryBuilder(bytes).readComponent(component);
     if (libs != component.libraries.length) {
       throw "Didn't get the same number of libraries: $libs when reading with "
@@ -91,6 +94,9 @@
           "when reading with BinaryBuilder";
     }
 
+    component = new Component();
+    new BinaryBuilder(bytes).readComponentSource(component);
+
     return true;
   } catch (e, st) {
     print("Error for $dill:");
diff --git a/tools/VERSION b/tools/VERSION
index b0eadcc..a70c823 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 146
+PRERELEASE 147
 PRERELEASE_PATCH 0
\ No newline at end of file