Introduce allocator shim for Android

This is a follow-up to the work of crrev.com/1675143004 and ports the
shim layer to Android.
Conversely to Linux, on Android symbol interposition is not possible.
This is because Android processes are fork-ed from the Android zygote,
which pre-loads libc.so, and later native code gets dlopen-ed.
Therefore a different approach is used on Android, that is:
 - All linker units that depend on //base:allocator (via //base)
   get the --Wl,-wrap,malloc (& friends) linker flag.
 - Such linker flags causes all symbol references to malloc to be
   rewritten as references to __wrap_malloc.
- The __wrap_malloc & friends symbols are defined by
  allocator_shim_override_linker_wrapped_symbols.h. These symbols
  route the malloc calls inside the shim layer.
 - The shim layer ultimately dispatches the calls to the __real_malloc
   symbol.
 - The special __real_malloc symbols are resolved by the linker (as a
   result of -wrap) against what would have been the original "malloc"
   symbol.

In summary, this entire trickery is transparent to the dynamic loader,
which still sees undefined symbol references to malloc & friend symbols.
Those symbols will be resolved against libc.so (or whatever other weird
choice the Android OEM made) as usual.

An alternative approach would have been just redefining the malloc symbols
and use dlsym() to do the routing to bionic. This has the following
disadvantages:
 - More risky, as Chrome for Android has insane layers of complexity around
   loading (crazylinker pre M, relies on a special flavour of dlopen on M+).
 - Won't be possible to support component builds, as all components
   % libbase.so would resolve malloc against libc.so (unless violating ODR
   and redefining malloc & friends in every component, which smells bad++).

All this trickery is a noop when use_experimental_allocator_shim=false.
This CL does NOT enable the shim by default on Android. This will happen
separately in crrev.com/1875043003

Motivations of this work
------------------------
 - This allows the memory-infra heap-profiler to work on Android
   (design doc: https://goo.gl/UPfbF4).
 - This enables security checks (suicide on malloc()==null via
   the std::new_handler) on Android.
 - This fixes by accident crbug.com/598075 (Some Android device vendor
   forgot to implement posix_memalign on J, as mandated by the NDK,
   causing chrome to crash on startup).

Performance considerations
------------------------
Binary size diff (GN, arm, static, official build): 24k

I did a mixture of local and trybots run to estimate the perf impact
of this change. Didn't get any conclusive data, everything I tried
seems in the same ballpark, below noise levels. More in details:

cc_perftests.PrepareTiles on a Nexus 4.
Rationale of the choice: in a previous CL (crbug.com/593344), this
benchmark revealed the presence of two mfences in the malloc path.
Results: https://goo.gl/8VC3Jp in the same ballpark.

page-cycler on Nexus 9 via trybots:
Results: http://goo.gl/J3i50a seems to suggest that this CL improves
both warm and cold times in most cases. I doubt it, more likely it's
noise.

All the other perf trybots failed. The perf waterfall seems to be in a
bad state in these days.

BUG=550886,598075
TEST=base_unittests --gtest_filter=AllocatorShimTest.*

Review URL: https://codereview.chromium.org/1719433002

Cr-Commit-Position: refs/heads/master@{#386382}


CrOS-Libchrome-Original-Commit: 40b65c66b855b58cb2fda9228b7626f2904581a5
3 files changed
tree: 73b9808cef1a60f1e995f7b778b08a29fbf85412
  1. base/
  2. build/
  3. components/
  4. dbus/
  5. device/
  6. ipc/
  7. mojo/
  8. testing/
  9. third_party/
  10. ui/