[Linux build] Add a linker version script to prevent symbol leaks

Bug 770264 was caused by accidentally leaking FreeType symbols from
Chrome.  This CL adds a linker version script to ensure new leaks do
not happen.  Any newly exported symbols must be explicitly added to
the version script.

BUG=770264
R=thestig@chromium.org
CC=pcc@chromium.org

Change-Id: I4241bd836c1d0b9a0a05c80daa66a9823bcd52d8
Reviewed-on: https://chromium-review.googlesource.com/736834
Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#511522}
diff --git a/build/linux/chrome.map b/build/linux/chrome.map
new file mode 100644
index 0000000..28ca6d4
--- /dev/null
+++ b/build/linux/chrome.map
@@ -0,0 +1,91 @@
+{
+global:
+  __bss_start;
+  __data_start;
+  data_start;
+  _edata;
+  _end;
+  _IO_stdin_used;
+
+  # Initialization and finalization functions for static global
+  # variables.
+  _fini;
+  _init;
+  __libc_csu_fini;
+  __libc_csu_init;
+
+  # Chrome's main function.  Exported for historical purposes.
+  ChromeMain;
+
+  # Program entry point.
+  _start;
+
+  # Memory allocation symbols.  We want chrome and any libraries to
+  # share the same heap, so it is correct to export these symbols.
+  calloc;
+  cfree;
+  free;
+  __free_hook;
+  __libc_calloc;
+  __libc_cfree;
+  __libc_free;
+  __libc_malloc;
+  __libc_memalign;
+  __libc_pvalloc;
+  __libc_realloc;
+  __libc_valloc;
+  mallinfo;
+  malloc;
+  __malloc_hook;
+  malloc_size;
+  malloc_stats;
+  malloc_usable_size;
+  mallopt;
+  memalign;
+  __memalign_hook;
+  __posix_memalign;
+  posix_memalign;
+  pvalloc;
+  realloc;
+  __realloc_hook;
+  __start_google_malloc;
+  __start_malloc_hook;
+  __stop_google_malloc;
+  __stop_malloc_hook;
+  valloc;
+
+  # Various flavors of operator new and operator delete.
+  _ZdaPv;
+  _ZdaPvm;
+  _ZdaPvmSt11align_val_t;
+  _ZdaPvRKSt9nothrow_t;
+  _ZdaPvSt11align_val_t;
+  _ZdaPvSt11align_val_tRKSt9nothrow_t;
+  _ZdlPv;
+  _ZdlPvm;
+  _ZdlPvmSt11align_val_t;
+  _ZdlPvRKSt9nothrow_t;
+  _ZdlPvSt11align_val_t;
+  _ZdlPvSt11align_val_tRKSt9nothrow_t;
+  _Znam;
+  _ZnamRKSt9nothrow_t;
+  _ZnamSt11align_val_t;
+  _ZnamSt11align_val_tRKSt9nothrow_t;
+  _Znwm;
+  _ZnwmRKSt9nothrow_t;
+  _ZnwmSt11align_val_t;
+  _ZnwmSt11align_val_tRKSt9nothrow_t;
+
+  # Various flavors of localtime().  These are exported by the chrome
+  # sandbox to intercept calls to localtime(), which would otherwise
+  # fail in untrusted processes that don't have permission to read
+  # /etc/localtime.  These overrides forward the request to the browser
+  # process, which uses dlsym(localtime) to make the real calls.
+  localtime;
+  localtime64;
+  localtime64_r;
+  localtime_r;
+
+local:
+  *;
+};
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index cbf9c96..1d850d8 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -272,6 +272,15 @@
           ldflags += [ "-Wl,--long-plt" ]
         }
 
+        if (!is_component_build && !using_sanitizer) {
+          version_script = "//build/linux/chrome.map"
+          inputs = [
+            version_script,
+          ]
+          ldflags += [ "-Wl,--version-script=" +
+                       rebase_path(version_script, root_build_dir) ]
+        }
+
         if (use_pangocairo) {
           # Needed for chrome_main.cc initialization of libraries.
           configs += [ "//build/config/linux/pangocairo" ]