remap_alloc.cc 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <stddef.h>
  5. #include <stdlib.h>
  6. #include "build/rust/std/immediate_crash.h"
  7. // When linking a final binary, rustc has to pick between either:
  8. // * The default Rust allocator
  9. // * Any #[global_allocator] defined in *any rlib in its dependency tree*
  10. // (https://doc.rust-lang.org/edition-guide/rust-2018/platform-and-target-support/global-allocators.html)
  11. //
  12. // In this latter case, this fact will be recorded in some of the metadata
  13. // within the .rlib file. (An .rlib file is just a .a file, but does have
  14. // additional metadata for use by rustc. This is, as far as I know, the only
  15. // such metadata we would ideally care about.)
  16. //
  17. // In all the linked rlibs,
  18. // * If 0 crates define a #[global_allocator], rustc uses its default allocator
  19. // * If 1 crate defines a #[global_allocator], rustc uses that
  20. // * If >1 crates define a #[global_allocator], rustc bombs out.
  21. //
  22. // Because rustc does these checks, it doesn't just have the __rust_alloc
  23. // symbols defined anywhere (neither in the stdlib nor in any of these
  24. // crates which have a #[global_allocator] defined.)
  25. //
  26. // Instead:
  27. // Rust's final linking stage invokes dynamic LLVM codegen to create symbols
  28. // for the basic heap allocation operations. It literally creates a
  29. // __rust_alloc symbol at link time. Unless any crate has specified a
  30. // #[global_allocator], it simply calls from __rust_alloc into
  31. // __rdl_alloc, which is the default Rust allocator. The same applies to a
  32. // few other symbols.
  33. //
  34. // We're not (always) using rustc for final linking. For cases where we're not
  35. // Rustc as the final linker, we'll define those symbols here instead.
  36. //
  37. // In future, we may wish to do something different from using the Rust
  38. // default allocator (e.g. explicitly redirect to PartitionAlloc). We could
  39. // do that here, or we could build a crate with a #[global_allocator] and
  40. // redirect these symbols to that crate instead. The advantage of the latter
  41. // is that it would work equally well for those cases where rustc is doing
  42. // the final linking.
  43. //
  44. // They're weak symbols, because this file will sometimes end up in targets
  45. // which are linked by rustc, and thus we would otherwise get duplicate
  46. // definitions. The following definitions will therefore only end up being
  47. // used in targets which are linked by our C++ toolchain.
  48. extern "C" {
  49. void* __rdl_alloc(size_t, size_t);
  50. void __rdl_dealloc(void*);
  51. void* __rdl_realloc(void*, size_t, size_t, size_t);
  52. void* __rdl_alloc_zeroed(size_t, size_t);
  53. void* __attribute__((weak)) __rust_alloc(size_t a, size_t b) {
  54. return __rdl_alloc(a, b);
  55. }
  56. void __attribute__((weak)) __rust_dealloc(void* a) {
  57. __rdl_dealloc(a);
  58. }
  59. void* __attribute__((weak))
  60. __rust_realloc(void* a, size_t b, size_t c, size_t d) {
  61. return __rdl_realloc(a, b, c, d);
  62. }
  63. void* __attribute__((weak)) __rust_alloc_zeroed(size_t a, size_t b) {
  64. return __rdl_alloc_zeroed(a, b);
  65. }
  66. void __attribute__((weak)) __rust_alloc_error_handler(size_t a, size_t b) {
  67. IMMEDIATE_CRASH();
  68. }
  69. extern const unsigned char __attribute__((weak))
  70. __rust_alloc_error_handler_should_panic = 0;
  71. } // extern "C"