Merge "Move GetFileSize() from symbolizer to base/file_utils.h"
diff --git a/Android.bp b/Android.bp
index 7827482..e104f17 100644
--- a/Android.bp
+++ b/Android.bp
@@ -7439,8 +7439,6 @@
     srcs: [
         "src/profiling/symbolizer/breakpad_parser.cc",
         "src/profiling/symbolizer/breakpad_symbolizer.cc",
-        "src/profiling/symbolizer/filesystem_posix.cc",
-        "src/profiling/symbolizer/filesystem_windows.cc",
         "src/profiling/symbolizer/local_symbolizer.cc",
         "src/profiling/symbolizer/scoped_read_mmap_posix.cc",
         "src/profiling/symbolizer/scoped_read_mmap_windows.cc",
diff --git a/BUILD b/BUILD
index 310f730..264030b 100644
--- a/BUILD
+++ b/BUILD
@@ -792,9 +792,6 @@
         "src/profiling/symbolizer/breakpad_symbolizer.cc",
         "src/profiling/symbolizer/breakpad_symbolizer.h",
         "src/profiling/symbolizer/elf.h",
-        "src/profiling/symbolizer/filesystem.h",
-        "src/profiling/symbolizer/filesystem_posix.cc",
-        "src/profiling/symbolizer/filesystem_windows.cc",
         "src/profiling/symbolizer/local_symbolizer.cc",
         "src/profiling/symbolizer/local_symbolizer.h",
         "src/profiling/symbolizer/scoped_read_mmap.h",
diff --git a/include/perfetto/ext/base/file_utils.h b/include/perfetto/ext/base/file_utils.h
index 17271da..5920196 100644
--- a/include/perfetto/ext/base/file_utils.h
+++ b/include/perfetto/ext/base/file_utils.h
@@ -27,6 +27,7 @@
 #include "perfetto/base/export.h"
 #include "perfetto/base/status.h"
 #include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/utils.h"
 
 namespace perfetto {
@@ -92,6 +93,9 @@
 base::Status ListFilesRecursive(const std::string& dir_path,
                                 std::vector<std::string>& output);
 
+// Returns the size of the file at `path` or nullopt in case of error.
+Optional<size_t> GetFileSize(const std::string& path);
+
 }  // namespace base
 }  // namespace perfetto
 
diff --git a/src/base/file_utils.cc b/src/base/file_utils.cc
index 4c06980..7ccbad4 100644
--- a/src/base/file_utils.cc
+++ b/src/base/file_utils.cc
@@ -292,5 +292,34 @@
   return filename.substr(ext_idx);
 }
 
+base::Optional<size_t> GetFileSize(const std::string& file_path) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  HANDLE file =
+      CreateFileA(file_path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr,
+                  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
+  if (file == INVALID_HANDLE_VALUE) {
+    return nullopt;
+  }
+  LARGE_INTEGER file_size;
+  file_size.QuadPart = 0;
+  BOOL ok = GetFileSizeEx(file, &file_size);
+  CloseHandle(file);
+  if (!ok) {
+    return nullopt;
+  }
+  return static_cast<size_t>(file_size.QuadPart);
+#else
+  base::ScopedFile fd(base::OpenFile(file_path, O_RDONLY | O_CLOEXEC));
+  if (!fd) {
+    return nullopt;
+  }
+  struct stat buf{};
+  if (fstat(*fd, &buf) == -1) {
+    return nullopt;
+  }
+  return static_cast<size_t>(buf.st_size);
+#endif
+}
+
 }  // namespace base
 }  // namespace perfetto
diff --git a/src/profiling/symbolizer/BUILD.gn b/src/profiling/symbolizer/BUILD.gn
index f16352a..70dc091 100644
--- a/src/profiling/symbolizer/BUILD.gn
+++ b/src/profiling/symbolizer/BUILD.gn
@@ -24,9 +24,6 @@
     "breakpad_symbolizer.cc",
     "breakpad_symbolizer.h",
     "elf.h",
-    "filesystem.h",
-    "filesystem_posix.cc",
-    "filesystem_windows.cc",
     "local_symbolizer.cc",
     "local_symbolizer.h",
     "scoped_read_mmap.h",
diff --git a/src/profiling/symbolizer/filesystem.h b/src/profiling/symbolizer/filesystem.h
deleted file mode 100644
index 9d11233..0000000
--- a/src/profiling/symbolizer/filesystem.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_PROFILING_SYMBOLIZER_FILESYSTEM_H_
-#define SRC_PROFILING_SYMBOLIZER_FILESYSTEM_H_
-
-#include "src/profiling/symbolizer/local_symbolizer.h"
-
-namespace perfetto {
-namespace profiling {
-
-size_t GetFileSize(const std::string& file_path);
-
-}  // namespace profiling
-}  // namespace perfetto
-
-#endif  // SRC_PROFILING_SYMBOLIZER_FILESYSTEM_H_
diff --git a/src/profiling/symbolizer/filesystem_posix.cc b/src/profiling/symbolizer/filesystem_posix.cc
deleted file mode 100644
index 311f444..0000000
--- a/src/profiling/symbolizer/filesystem_posix.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/profiling/symbolizer/filesystem.h"
-
-#include "perfetto/base/build_config.h"
-
-#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-#if PERFETTO_BUILDFLAG(PERFETTO_LOCAL_SYMBOLIZER)
-#include <sys/stat.h>
-#endif
-
-#include <string>
-
-#include "perfetto/ext/base/file_utils.h"
-
-namespace perfetto {
-namespace profiling {
-#if PERFETTO_BUILDFLAG(PERFETTO_LOCAL_SYMBOLIZER)
-size_t GetFileSize(const std::string& file_path) {
-  base::ScopedFile fd(base::OpenFile(file_path, O_RDONLY | O_CLOEXEC));
-  if (!fd) {
-    PERFETTO_PLOG("Failed to get file size %s", file_path.c_str());
-    return 0;
-  }
-  struct stat buf;
-  if (fstat(*fd, &buf) == -1) {
-    return 0;
-  }
-  return static_cast<size_t>(buf.st_size);
-}
-#else
-size_t GetFileSize(const std::string&) {
-  return 0;
-}
-#endif
-
-}  // namespace profiling
-}  // namespace perfetto
-
-#endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
diff --git a/src/profiling/symbolizer/filesystem_windows.cc b/src/profiling/symbolizer/filesystem_windows.cc
deleted file mode 100644
index f7a381e..0000000
--- a/src/profiling/symbolizer/filesystem_windows.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/profiling/symbolizer/filesystem.h"
-
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-
-#include <Windows.h>
-
-namespace perfetto {
-namespace profiling {
-
-size_t GetFileSize(const std::string& file_path) {
-  HANDLE file =
-      CreateFileA(file_path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr,
-                  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
-  if (file == INVALID_HANDLE_VALUE) {
-    PERFETTO_PLOG("Failed to get file size %s", file_path.c_str());
-    return 0;
-  }
-  LARGE_INTEGER file_size;
-  file_size.QuadPart = 0;
-  if (!GetFileSizeEx(file, &file_size)) {
-    PERFETTO_PLOG("Failed to get file size %s", file_path.c_str());
-  }
-  CloseHandle(file);
-  return static_cast<size_t>(file_size.QuadPart);
-}
-
-}  // namespace profiling
-}  // namespace perfetto
-
-#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
diff --git a/src/profiling/symbolizer/local_symbolizer.cc b/src/profiling/symbolizer/local_symbolizer.cc
index 8970cca..bcacb37 100644
--- a/src/profiling/symbolizer/local_symbolizer.cc
+++ b/src/profiling/symbolizer/local_symbolizer.cc
@@ -32,7 +32,6 @@
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/string_utils.h"
 #include "src/profiling/symbolizer/elf.h"
-#include "src/profiling/symbolizer/filesystem.h"
 #include "src/profiling/symbolizer/scoped_read_mmap.h"
 
 namespace perfetto {
@@ -217,31 +216,36 @@
   uint64_t load_bias;
 };
 
-base::Optional<BuildIdAndLoadBias> GetBuildIdAndLoadBias(const std::string& fname) {
-  size_t size = GetFileSize(fname);
-  static_assert(EI_CLASS > EI_MAG3, "mem[EI_MAG?] accesses are in range.");
-  if (size <= EI_CLASS)
+base::Optional<BuildIdAndLoadBias> GetBuildIdAndLoadBias(
+    const std::string& fname) {
+  base::Optional<size_t> size = base::GetFileSize(fname);
+  if (!size.has_value()) {
+    PERFETTO_PLOG("Failed to get file size %s", fname.c_str());
     return base::nullopt;
-  ScopedReadMmap map(fname.c_str(), size);
+  }
+  static_assert(EI_CLASS > EI_MAG3, "mem[EI_MAG?] accesses are in range.");
+  if (*size <= EI_CLASS)
+    return base::nullopt;
+  ScopedReadMmap map(fname.c_str(), *size);
   if (!map.IsValid()) {
     PERFETTO_PLOG("mmap");
     return base::nullopt;
   }
   char* mem = static_cast<char*>(*map);
 
-  if (!IsElf(mem, size))
+  if (!IsElf(mem, *size))
     return base::nullopt;
 
   base::Optional<std::string> build_id;
   base::Optional<uint64_t> load_bias;
   switch (mem[EI_CLASS]) {
     case ELFCLASS32:
-      build_id = GetBuildId<Elf32>(mem, size);
-      load_bias = GetLoadBias<Elf32>(mem, size);
+      build_id = GetBuildId<Elf32>(mem, *size);
+      load_bias = GetLoadBias<Elf32>(mem, *size);
       break;
     case ELFCLASS64:
-      build_id = GetBuildId<Elf64>(mem, size);
-      load_bias = GetLoadBias<Elf64>(mem, size);
+      build_id = GetBuildId<Elf64>(mem, *size);
+      load_bias = GetLoadBias<Elf64>(mem, *size);
       break;
     default:
       return base::nullopt;