Staticlly allocate string buffers for realpath_fd()

Creating two huge buffers with std::vector, as it is now, is very
expensive, because it ends up being satisfied with mmap()/munmap().
Instead, we statically allocate a large string buffer while resizing
the other one to be a smaller and more appropriate size so that it can
be placed on the stack.

Note that this does mean that we increase linker data segment by 4KB
and that increases the overall system memory usage by about 400KB.
However, since that additional page is mostly zeroed with only some
ASCII text, it should be fairly easy to compress when it's swapped out
to ZRAM.

Test: Run with strace and observe no mmap/munmap around readlinkat().
Test: Measure average linker time of starting cameraserver on a Go
      device and see ~3% speed-up.
Bug: 132783386

Change-Id: I600cc7a92be316ef67440a9a28c05d18de229f6c
diff --git a/linker/linker.cpp b/linker/linker.cpp
index f68775c..bc62201 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -393,16 +393,23 @@
 }
 
 static bool realpath_fd(int fd, std::string* realpath) {
-  std::vector<char> buf(PATH_MAX), proc_self_fd(PATH_MAX);
-  async_safe_format_buffer(&proc_self_fd[0], proc_self_fd.size(), "/proc/self/fd/%d", fd);
-  if (readlink(&proc_self_fd[0], &buf[0], buf.size()) == -1) {
+  // proc_self_fd needs to be large enough to hold "/proc/self/fd/" plus an
+  // integer, plus the NULL terminator.
+  char proc_self_fd[32];
+  // We want to statically allocate this large buffer so that we don't grow
+  // the stack by too much.
+  static char buf[PATH_MAX];
+
+  async_safe_format_buffer(proc_self_fd, sizeof(proc_self_fd), "/proc/self/fd/%d", fd);
+  auto length = readlink(proc_self_fd, buf, sizeof(buf));
+  if (length == -1) {
     if (!is_first_stage_init()) {
-      PRINT("readlink(\"%s\") failed: %s [fd=%d]", &proc_self_fd[0], strerror(errno), fd);
+      PRINT("readlink(\"%s\") failed: %s [fd=%d]", proc_self_fd, strerror(errno), fd);
     }
     return false;
   }
 
-  *realpath = &buf[0];
+  realpath->assign(buf, length);
   return true;
 }