Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Unified Diff: third_party/tcmalloc/chromium/src/base/elf_mem_image.cc

Issue 9311003: Update the tcmalloc chromium branch to r144 (gperftools 2.0), and merge chromium-specific changes. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Rebasec Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/tcmalloc/chromium/src/base/elf_mem_image.cc
diff --git a/third_party/tcmalloc/chromium/src/base/vdso_support.cc b/third_party/tcmalloc/chromium/src/base/elf_mem_image.cc
similarity index 67%
copy from third_party/tcmalloc/chromium/src/base/vdso_support.cc
copy to third_party/tcmalloc/chromium/src/base/elf_mem_image.cc
index 444be26aa56f0f683ff641f1cc8f8c239b0d20a0..2949343700d57761480da81cfaf92847062768bd 100644
--- a/third_party/tcmalloc/chromium/src/base/vdso_support.cc
+++ b/third_party/tcmalloc/chromium/src/base/elf_mem_image.cc
@@ -1,10 +1,10 @@
// Copyright (c) 2008, Google Inc.
// All rights reserved.
-//
+//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
-//
+//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
@@ -14,7 +14,7 @@
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
-//
+//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -30,29 +30,15 @@
// ---
// Author: Paul Pluzhnikov
//
-// Allow dynamic symbol lookup in the kernel VDSO page.
+// Allow dynamic symbol lookup in an in-memory Elf image.
//
-// VDSOSupport -- a class representing kernel VDSO (if present).
-//
-
-#include "base/vdso_support.h"
-#ifdef HAVE_VDSO_SUPPORT // defined in vdso_support.h
+#include "base/elf_mem_image.h"
-#include <fcntl.h>
-#include <stddef.h> // for std::ptrdiff_t
+#ifdef HAVE_ELF_MEM_IMAGE // defined in elf_mem_image.h
-#include "base/atomicops.h" // for MemoryBarrier
+#include <stddef.h> // for size_t, ptrdiff_t
#include "base/logging.h"
-#include "base/linux_syscall_support.h"
-#include "base/dynamic_annotations.h"
-#include "base/basictypes.h" // for COMPILE_ASSERT
-
-using base::subtle::MemoryBarrier;
-
-#ifndef AT_SYSINFO_EHDR
-#define AT_SYSINFO_EHDR 33
-#endif
// From binutils/include/elf/common.h (this doesn't appear to be documented
// anywhere else).
@@ -121,18 +107,15 @@ const T* GetTableElement(const ElfW(Ehdr) *ehdr,
}
} // namespace
-const void *const VDSOSupport::kInvalidBase =
+const void *const ElfMemImage::kInvalidBase =
reinterpret_cast<const void *>(~0L);
-const void *VDSOSupport::vdso_base_ = kInvalidBase;
-VDSOSupport::GetCpuFn VDSOSupport::getcpu_fn_ = &InitAndGetCPU;
-
-VDSOSupport::ElfMemImage::ElfMemImage(const void *base) {
+ElfMemImage::ElfMemImage(const void *base) {
CHECK(base != kInvalidBase);
Init(base);
}
-int VDSOSupport::ElfMemImage::GetNumSymbols() const {
+int ElfMemImage::GetNumSymbols() const {
if (!hash_) {
return 0;
}
@@ -140,17 +123,17 @@ int VDSOSupport::ElfMemImage::GetNumSymbols() const {
return hash_[1];
}
-const ElfW(Sym) *VDSOSupport::ElfMemImage::GetDynsym(int index) const {
+const ElfW(Sym) *ElfMemImage::GetDynsym(int index) const {
CHECK_LT(index, GetNumSymbols());
return dynsym_ + index;
}
-const ElfW(Versym) *VDSOSupport::ElfMemImage::GetVersym(int index) const {
+const ElfW(Versym) *ElfMemImage::GetVersym(int index) const {
CHECK_LT(index, GetNumSymbols());
return versym_ + index;
}
-const ElfW(Phdr) *VDSOSupport::ElfMemImage::GetPhdr(int index) const {
+const ElfW(Phdr) *ElfMemImage::GetPhdr(int index) const {
CHECK_LT(index, ehdr_->e_phnum);
return GetTableElement<ElfW(Phdr)>(ehdr_,
ehdr_->e_phoff,
@@ -158,12 +141,12 @@ const ElfW(Phdr) *VDSOSupport::ElfMemImage::GetPhdr(int index) const {
index);
}
-const char *VDSOSupport::ElfMemImage::GetDynstr(ElfW(Word) offset) const {
+const char *ElfMemImage::GetDynstr(ElfW(Word) offset) const {
CHECK_LT(offset, strsize_);
return dynstr_ + offset;
}
-const void *VDSOSupport::ElfMemImage::GetSymAddr(const ElfW(Sym) *sym) const {
+const void *ElfMemImage::GetSymAddr(const ElfW(Sym) *sym) const {
if (sym->st_shndx == SHN_UNDEF || sym->st_shndx >= SHN_LORESERVE) {
// Symbol corresponds to "special" (e.g. SHN_ABS) section.
return reinterpret_cast<const void *>(sym->st_value);
@@ -172,7 +155,7 @@ const void *VDSOSupport::ElfMemImage::GetSymAddr(const ElfW(Sym) *sym) const {
return GetTableElement<char>(ehdr_, 0, 1, sym->st_value) - link_base_;
}
-const ElfW(Verdef) *VDSOSupport::ElfMemImage::GetVerdef(int index) const {
+const ElfW(Verdef) *ElfMemImage::GetVerdef(int index) const {
CHECK_LE(index, verdefnum_);
const ElfW(Verdef) *version_definition = verdef_;
while (version_definition->vd_ndx < index && version_definition->vd_next) {
@@ -185,17 +168,17 @@ const ElfW(Verdef) *VDSOSupport::ElfMemImage::GetVerdef(int index) const {
return version_definition->vd_ndx == index ? version_definition : NULL;
}
-const ElfW(Verdaux) *VDSOSupport::ElfMemImage::GetVerdefAux(
+const ElfW(Verdaux) *ElfMemImage::GetVerdefAux(
const ElfW(Verdef) *verdef) const {
return reinterpret_cast<const ElfW(Verdaux) *>(verdef+1);
}
-const char *VDSOSupport::ElfMemImage::GetVerstr(ElfW(Word) offset) const {
+const char *ElfMemImage::GetVerstr(ElfW(Word) offset) const {
CHECK_LT(offset, strsize_);
return dynstr_ + offset;
}
-void VDSOSupport::ElfMemImage::Init(const void *base) {
+void ElfMemImage::Init(const void *base) {
ehdr_ = NULL;
dynsym_ = NULL;
dynstr_ = NULL;
@@ -266,7 +249,7 @@ void VDSOSupport::ElfMemImage::Init(const void *base) {
Init(0);
return;
}
- std::ptrdiff_t relocation =
+ ptrdiff_t relocation =
base_as_char - reinterpret_cast<const char *>(link_base_);
ElfW(Dyn) *dynamic_entry =
reinterpret_cast<ElfW(Dyn) *>(dynamic_program_header->p_vaddr +
@@ -329,81 +312,7 @@ void VDSOSupport::ElfMemImage::Init(const void *base) {
}
}
-VDSOSupport::VDSOSupport()
- // If vdso_base_ is still set to kInvalidBase, we got here
- // before VDSOSupport::Init has been called. Call it now.
- : image_(vdso_base_ == kInvalidBase ? Init() : vdso_base_) {
-}
-
-// NOTE: we can't use GoogleOnceInit() below, because we can be
-// called by tcmalloc, and none of the *once* stuff may be functional yet.
-//
-// In addition, we hope that the VDSOSupportHelper constructor
-// causes this code to run before there are any threads, and before
-// InitGoogle() has executed any chroot or setuid calls.
-//
-// Finally, even if there is a race here, it is harmless, because
-// the operation should be idempotent.
-const void *VDSOSupport::Init() {
- if (vdso_base_ == kInvalidBase) {
- // Valgrind zaps AT_SYSINFO_EHDR and friends from the auxv[]
- // on stack, and so glibc works as if VDSO was not present.
- // But going directly to kernel via /proc/self/auxv below bypasses
- // Valgrind zapping. So we check for Valgrind separately.
- if (RunningOnValgrind()) {
- vdso_base_ = NULL;
- getcpu_fn_ = &GetCPUViaSyscall;
- return NULL;
- }
- int fd = open("/proc/self/auxv", O_RDONLY);
- if (fd == -1) {
- // Kernel too old to have a VDSO.
- vdso_base_ = NULL;
- getcpu_fn_ = &GetCPUViaSyscall;
- return NULL;
- }
- ElfW(auxv_t) aux;
- while (read(fd, &aux, sizeof(aux)) == sizeof(aux)) {
- if (aux.a_type == AT_SYSINFO_EHDR) {
- COMPILE_ASSERT(sizeof(vdso_base_) == sizeof(aux.a_un.a_val),
- unexpected_sizeof_pointer_NE_sizeof_a_val);
- vdso_base_ = reinterpret_cast<void *>(aux.a_un.a_val);
- break;
- }
- }
- close(fd);
- if (vdso_base_ == kInvalidBase) {
- // Didn't find AT_SYSINFO_EHDR in auxv[].
- vdso_base_ = NULL;
- }
- }
- GetCpuFn fn = &GetCPUViaSyscall; // default if VDSO not present.
- if (vdso_base_) {
- VDSOSupport vdso;
- SymbolInfo info;
- if (vdso.LookupSymbol("__vdso_getcpu", "LINUX_2.6", STT_FUNC, &info)) {
- // Casting from an int to a pointer is not legal C++. To emphasize
- // this, we use a C-style cast rather than a C++-style cast.
- fn = (GetCpuFn)(info.address);
- }
- }
- // Subtle: this code runs outside of any locks; prevent compiler
- // from assigning to getcpu_fn_ more than once.
- base::subtle::MemoryBarrier();
- getcpu_fn_ = fn;
- return vdso_base_;
-}
-
-const void *VDSOSupport::SetBase(const void *base) {
- const void *old_base = vdso_base_;
- vdso_base_ = base;
- image_.Init(base);
- // Also reset getcpu_fn_, so GetCPU could be tested with simulated VDSO.
- getcpu_fn_ = &InitAndGetCPU;
- return old_base;
-}
-
-bool VDSOSupport::LookupSymbol(const char *name,
+bool ElfMemImage::LookupSymbol(const char *name,
const char *version,
int type,
SymbolInfo *info) const {
@@ -419,7 +328,7 @@ bool VDSOSupport::LookupSymbol(const char *name,
return false;
}
-bool VDSOSupport::LookupSymbolByAddress(const void *address,
+bool ElfMemImage::LookupSymbolByAddress(const void *address,
SymbolInfo *info_out) const {
for (SymbolIterator it = begin(); it != end(); ++it) {
const char *const symbol_start =
@@ -445,42 +354,42 @@ bool VDSOSupport::LookupSymbolByAddress(const void *address,
return false;
}
-VDSOSupport::SymbolIterator::SymbolIterator(const void *const image, int index)
+ElfMemImage::SymbolIterator::SymbolIterator(const void *const image, int index)
: index_(index), image_(image) {
}
-const VDSOSupport::SymbolInfo *VDSOSupport::SymbolIterator::operator->() const {
+const ElfMemImage::SymbolInfo *ElfMemImage::SymbolIterator::operator->() const {
return &info_;
}
-const VDSOSupport::SymbolInfo& VDSOSupport::SymbolIterator::operator*() const {
+const ElfMemImage::SymbolInfo& ElfMemImage::SymbolIterator::operator*() const {
return info_;
}
-bool VDSOSupport::SymbolIterator::operator==(const SymbolIterator &rhs) const {
+bool ElfMemImage::SymbolIterator::operator==(const SymbolIterator &rhs) const {
return this->image_ == rhs.image_ && this->index_ == rhs.index_;
}
-bool VDSOSupport::SymbolIterator::operator!=(const SymbolIterator &rhs) const {
+bool ElfMemImage::SymbolIterator::operator!=(const SymbolIterator &rhs) const {
return !(*this == rhs);
}
-VDSOSupport::SymbolIterator &VDSOSupport::SymbolIterator::operator++() {
+ElfMemImage::SymbolIterator &ElfMemImage::SymbolIterator::operator++() {
this->Update(1);
return *this;
}
-VDSOSupport::SymbolIterator VDSOSupport::begin() const {
- SymbolIterator it(&image_, 0);
+ElfMemImage::SymbolIterator ElfMemImage::begin() const {
+ SymbolIterator it(this, 0);
it.Update(0);
return it;
}
-VDSOSupport::SymbolIterator VDSOSupport::end() const {
- return SymbolIterator(&image_, image_.GetNumSymbols());
+ElfMemImage::SymbolIterator ElfMemImage::end() const {
+ return SymbolIterator(this, GetNumSymbols());
}
-void VDSOSupport::SymbolIterator::Update(int increment) {
+void ElfMemImage::SymbolIterator::Update(int increment) {
const ElfMemImage *image = reinterpret_cast<const ElfMemImage *>(image_);
CHECK(image->IsPresent() || increment == 0);
if (!image->IsPresent()) {
@@ -519,45 +428,6 @@ void VDSOSupport::SymbolIterator::Update(int increment) {
info_.symbol = symbol;
}
-// NOLINT on 'long' because this routine mimics kernel api.
-long VDSOSupport::GetCPUViaSyscall(unsigned *cpu, void *, void *) { // NOLINT
-#if defined(__NR_getcpu)
- return sys_getcpu(cpu, NULL, NULL);
-#else
- // x86_64 never implemented sys_getcpu(), except as a VDSO call.
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-// Use fast __vdso_getcpu if available.
-long VDSOSupport::InitAndGetCPU(unsigned *cpu, void *x, void *y) { // NOLINT
- Init();
- CHECK_NE(getcpu_fn_, &InitAndGetCPU); // << "Init() did not set getcpu_fn_";
- return (*getcpu_fn_)(cpu, x, y);
-}
-
-// This function must be very fast, and may be called from very
-// low level (e.g. tcmalloc). Hence I avoid things like
-// GoogleOnceInit() and ::operator new.
-int GetCPU(void) {
- unsigned cpu;
- int ret_code = (*VDSOSupport::getcpu_fn_)(&cpu, NULL, NULL);
- return ret_code == 0 ? cpu : ret_code;
-}
-
-// We need to make sure VDSOSupport::Init() is called before
-// the main() runs, since it might do something like setuid or
-// chroot. If VDSOSupport
-// is used in any global constructor, this will happen, since
-// VDSOSupport's constructor calls Init. But if not, we need to
-// ensure it here, with a global constructor of our own. This
-// is an allowed exception to the normal rule against non-trivial
-// global constructors.
-static class VDSOInitHelper {
- public:
- VDSOInitHelper() { VDSOSupport::Init(); }
-} vdso_init_helper;
-}
+} // namespace base
-#endif // HAVE_VDSO_SUPPORT
+#endif // HAVE_ELF_MEM_IMAGE
« no previous file with comments | « third_party/tcmalloc/chromium/src/base/elf_mem_image.h ('k') | third_party/tcmalloc/chromium/src/base/googleinit.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698