sanitizer_linux.cc revision 6985085c4860bf945358f227ddba26511ae770e9
1ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov//===-- sanitizer_linux.cc ------------------------------------------------===//
2ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov//
3ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov//                     The LLVM Compiler Infrastructure
4ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov//
5ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov// This file is distributed under the University of Illinois Open Source
6ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov// License. See LICENSE.TXT for details.
7ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov//
8ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov//===----------------------------------------------------------------------===//
9ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov//
10ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov// This file is shared between AddressSanitizer and ThreadSanitizer
11ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov// run-time libraries and implements linux-specific functions from
12ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov// sanitizer_libc.h.
13ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov//===----------------------------------------------------------------------===//
14ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov#ifdef __linux__
15ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov
166895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov#include "sanitizer_common.h"
1794b5036ee6ba866e1702848855b6d687d1e70afaAlexey Samsonov#include "sanitizer_internal_defs.h"
18ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov#include "sanitizer_libc.h"
196895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov#include "sanitizer_procmaps.h"
20ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov
21c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov#include <fcntl.h>
22e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov#include <pthread.h>
230969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov#include <sched.h>
24ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov#include <sys/mman.h>
25e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov#include <sys/resource.h>
26c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov#include <sys/stat.h>
27ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov#include <sys/syscall.h>
28e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov#include <sys/time.h>
29ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov#include <sys/types.h>
30ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov#include <unistd.h>
31ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov
32ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonovnamespace __sanitizer {
33ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov
34e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov// --------------- sanitizer_libc.h
35ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonovvoid *internal_mmap(void *addr, uptr length, int prot, int flags,
36ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov                    int fd, u64 offset) {
37ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov#if __WORDSIZE == 64
38ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov  return (void *)syscall(__NR_mmap, addr, length, prot, flags, fd, offset);
39ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov#else
40ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov  return (void *)syscall(__NR_mmap2, addr, length, prot, flags, fd, offset);
41ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov#endif
42ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov}
43ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov
441f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonovint internal_munmap(void *addr, uptr length) {
451f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov  return syscall(__NR_munmap, addr, length);
461f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov}
471f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov
48a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonovint internal_close(fd_t fd) {
49a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov  return syscall(__NR_close, fd);
50a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov}
51a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov
52c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonovfd_t internal_open(const char *filename, bool write) {
53c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov  return syscall(__NR_open, filename,
549b8a9c1b1ce4659457178ff4c0838ac1b35ca9dcKostya Serebryany      write ? O_WRONLY | O_CREAT /*| O_CLOEXEC*/ : O_RDONLY, 0660);
55c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov}
56c5d465136b911bf925f2a631e2b79f1c03e8a1b0Alexey Samsonov
57a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonovuptr internal_read(fd_t fd, void *buf, uptr count) {
58a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov  return (uptr)syscall(__NR_read, fd, buf, count);
59a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov}
60a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov
61a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonovuptr internal_write(fd_t fd, const void *buf, uptr count) {
62a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov  return (uptr)syscall(__NR_write, fd, buf, count);
63a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov}
64a56aefd2e01940fcf88d1426f9de3d5e4b1ee203Alexey Samsonov
658e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonovuptr internal_filesize(fd_t fd) {
668e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonov  struct stat st = {};
678e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonov  if (syscall(__NR_fstat, fd, &st))
688e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonov    return -1;
698e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonov  return (uptr)st.st_size;
708e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonov}
718e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonov
728e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonovint internal_dup2(int oldfd, int newfd) {
738e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonov  return syscall(__NR_dup2, oldfd, newfd);
748e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonov}
758e820fcf7aafeb8101322182d742fcf99255d972Alexey Samsonov
760969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonovint internal_sched_yield() {
770969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov  return syscall(__NR_sched_yield);
780969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov}
790969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov
80e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov// ----------------- sanitizer_common.h
81ed996f79710f532bf231537e44d5c8c9c9d57e8dAlexey Samsonovvoid GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
82e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov                                uptr *stack_bottom) {
83e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov  static const uptr kMaxThreadStackSize = 256 * (1 << 20);  // 256M
84e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov  CHECK(stack_top);
85e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov  CHECK(stack_bottom);
86ed996f79710f532bf231537e44d5c8c9c9d57e8dAlexey Samsonov  if (at_initialization) {
87e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    // This is the main thread. Libpthread may not be initialized yet.
88e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    struct rlimit rl;
896985085c4860bf945358f227ddba26511ae770e9Kostya Serebryany    CHECK_EQ(getrlimit(RLIMIT_STACK, &rl), 0);
90e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov
91e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    // Find the mapping that contains a stack variable.
92e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    ProcessMaps proc_maps;
93e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    uptr start, end, offset;
94e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    uptr prev_end = 0;
95e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    while (proc_maps.Next(&start, &end, &offset, 0, 0)) {
96e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov      if ((uptr)&rl < end)
97e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov        break;
98e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov      prev_end = end;
99e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    }
100e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    CHECK((uptr)&rl >= start && (uptr)&rl < end);
101e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov
102e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    // Get stacksize from rlimit, but clip it so that it does not overlap
103e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    // with other mappings.
104e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    uptr stacksize = rl.rlim_cur;
105e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    if (stacksize > end - prev_end)
106e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov      stacksize = end - prev_end;
107e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    // When running with unlimited stack size, we still want to set some limit.
108e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    // The unlimited stack size is caused by 'ulimit -s unlimited'.
109e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    // Also, for some reason, GNU make spawns subprocesses with unlimited stack.
110e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    if (stacksize > kMaxThreadStackSize)
111e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov      stacksize = kMaxThreadStackSize;
112e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    *stack_top = end;
113e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    *stack_bottom = end - stacksize;
114e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov    return;
115e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov  }
116e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov  pthread_attr_t attr;
1176985085c4860bf945358f227ddba26511ae770e9Kostya Serebryany  CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0);
118e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov  uptr stacksize = 0;
119e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov  void *stackaddr = 0;
120e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov  pthread_attr_getstack(&attr, &stackaddr, (size_t*)&stacksize);
121e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov  pthread_attr_destroy(&attr);
122e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov
123e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov  *stack_top = (uptr)stackaddr + stacksize;
124e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov  *stack_bottom = (uptr)stackaddr;
125e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov  CHECK(stacksize < kMaxThreadStackSize);  // Sanity check.
126e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov}
127e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov
1283dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov// Like getenv, but reads env directly from /proc and does not use libc.
1293dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov// This function should be called first inside __asan_init.
1303dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonovconst char *GetEnv(const char *name) {
1313dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov  static char *environ;
1323dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov  static uptr len;
1333dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov  static bool inited;
1343dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov  if (!inited) {
1353dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov    inited = true;
1363dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov    uptr environ_size;
1373dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov    len = ReadFileToBuffer("/proc/self/environ",
1383dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov                           &environ, &environ_size, 1 << 26);
1393dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov  }
1403dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov  if (!environ || len == 0) return 0;
1413dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov  uptr namelen = internal_strlen(name);
1423dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov  const char *p = environ;
1433dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov  while (*p != '\0') {  // will happen at the \0\0 that terminates the buffer
1443dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov    // proc file has the format NAME=value\0NAME=value\0NAME=value\0...
1453dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov    const char* endp =
1463dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov        (char*)internal_memchr(p, '\0', len - (p - environ));
1473dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov    if (endp == 0)  // this entry isn't NUL terminated
1483dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov      return 0;
1493dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov    else if (!internal_memcmp(p, name, namelen) && p[namelen] == '=')  // Match.
1503dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov      return p + namelen + 1;  // point after =
1513dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov    p = endp + 1;
1523dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov  }
1533dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov  return 0;  // Not found.
1543dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov}
1553dbeabb3446f203156ae03d957de9bdf50933ae4Alexey Samsonov
156e5931fd7d2a74fd7fb60bd8d7f644cca51a24364Alexey Samsonov// ----------------- sanitizer_procmaps.h
1576895adc39c4e09371154c8037366ad4464163ed0Alexey SamsonovProcessMaps::ProcessMaps() {
1586895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  proc_self_maps_buff_len_ =
1596895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov      ReadFileToBuffer("/proc/self/maps", &proc_self_maps_buff_,
1606895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov                       &proc_self_maps_buff_mmaped_size_, 1 << 26);
1616985085c4860bf945358f227ddba26511ae770e9Kostya Serebryany  CHECK_GT(proc_self_maps_buff_len_, 0);
1626895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  // internal_write(2, proc_self_maps_buff_, proc_self_maps_buff_len_);
1636895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  Reset();
1646895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov}
1656895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov
1666895adc39c4e09371154c8037366ad4464163ed0Alexey SamsonovProcessMaps::~ProcessMaps() {
1676895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  UnmapOrDie(proc_self_maps_buff_, proc_self_maps_buff_mmaped_size_);
1686895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov}
1696895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov
1706895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonovvoid ProcessMaps::Reset() {
1716895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  current_ = proc_self_maps_buff_;
1726895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov}
1736895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov
1746895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonovbool ProcessMaps::Next(uptr *start, uptr *end, uptr *offset,
1756895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov                       char filename[], uptr filename_size) {
1766895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  char *last = proc_self_maps_buff_ + proc_self_maps_buff_len_;
1776895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  if (current_ >= last) return false;
1786895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  int consumed = 0;
1796895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  char flags[10];
1806895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  int major, minor;
1816895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  uptr inode;
1826895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  uptr dummy;
1836895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  if (!start) start = &dummy;
1846895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  if (!end) end = &dummy;
1856895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  if (!offset) offset = &dummy;
1866895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  char *next_line = (char*)internal_memchr(current_, '\n', last - current_);
1876895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  if (next_line == 0)
1886895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov    next_line = last;
1896895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  if (internal_sscanf(current_, "%lx-%lx %4s %lx %x:%x %ld %n",
1906895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov                      start, end, flags, offset, &major, &minor,
1916895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov                      &inode, &consumed) != 7)
1926895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov    return false;
1936895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  current_ += consumed;
1946895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  // Skip spaces.
1956895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  while (current_ < next_line && *current_ == ' ')
1966895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov    current_++;
1976895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  // Fill in the filename.
1986895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  uptr i = 0;
1996895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  while (current_ < next_line) {
2006895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov    if (filename && i < filename_size - 1)
2016895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov      filename[i++] = *current_;
2026895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov    current_++;
2036895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  }
2046895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  if (filename && i < filename_size)
2056895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov    filename[i] = 0;
2066895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  current_ = next_line + 1;
2076895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  return true;
2086895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov}
2096895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov
2106895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov// Gets the object name and the offset by walking ProcessMaps.
2116895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonovbool ProcessMaps::GetObjectNameAndOffset(uptr addr, uptr *offset,
2126895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov                                         char filename[],
2136895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov                                         uptr filename_size) {
2146895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov  return IterateForObjectNameAndOffset(addr, offset, filename, filename_size);
2156895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov}
2166895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov
217ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov}  // namespace __sanitizer
218ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov
219ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov#endif  // __linux__
220