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

Side by Side Diff: third_party/tcmalloc/chromium/src/base/elf_mem_image.cc

Issue 9666033: Experiment for updating the tcmalloc chromium branch to r144 (gperftools 2.0). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 9 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2008, Google Inc. 1 // Copyright (c) 2008, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer 11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the 12 // in the documentation and/or other materials provided with the
13 // distribution. 13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its 14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from 15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission. 16 // this software without specific prior written permission.
17 // 17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 29
30 // --- 30 // ---
31 // Author: Paul Pluzhnikov 31 // Author: Paul Pluzhnikov
32 // 32 //
33 // Allow dynamic symbol lookup in the kernel VDSO page. 33 // Allow dynamic symbol lookup in an in-memory Elf image.
34 //
35 // VDSOSupport -- a class representing kernel VDSO (if present).
36 // 34 //
37 35
38 #include "base/vdso_support.h" 36 #include "base/elf_mem_image.h"
39 37
40 #ifdef HAVE_VDSO_SUPPORT // defined in vdso_support.h 38 #ifdef HAVE_ELF_MEM_IMAGE // defined in elf_mem_image.h
41 39
42 #include <fcntl.h> 40 #include <stddef.h> // for size_t, ptrdiff_t
43 #include <stddef.h> // for std::ptrdiff_t
44
45 #include "base/atomicops.h" // for MemoryBarrier
46 #include "base/logging.h" 41 #include "base/logging.h"
47 #include "base/linux_syscall_support.h"
48 #include "base/dynamic_annotations.h"
49 #include "base/basictypes.h" // for COMPILE_ASSERT
50
51 using base::subtle::MemoryBarrier;
52
53 #ifndef AT_SYSINFO_EHDR
54 #define AT_SYSINFO_EHDR 33
55 #endif
56 42
57 // From binutils/include/elf/common.h (this doesn't appear to be documented 43 // From binutils/include/elf/common.h (this doesn't appear to be documented
58 // anywhere else). 44 // anywhere else).
59 // 45 //
60 // /* This flag appears in a Versym structure. It means that the symbol 46 // /* This flag appears in a Versym structure. It means that the symbol
61 // is hidden, and is only visible with an explicit version number. 47 // is hidden, and is only visible with an explicit version number.
62 // This is a GNU extension. */ 48 // This is a GNU extension. */
63 // #define VERSYM_HIDDEN 0x8000 49 // #define VERSYM_HIDDEN 0x8000
64 // 50 //
65 // /* This is the mask for the rest of the Versym information. */ 51 // /* This is the mask for the rest of the Versym information. */
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 const T* GetTableElement(const ElfW(Ehdr) *ehdr, 100 const T* GetTableElement(const ElfW(Ehdr) *ehdr,
115 ElfW(Off) table_offset, 101 ElfW(Off) table_offset,
116 ElfW(Word) element_size, 102 ElfW(Word) element_size,
117 size_t index) { 103 size_t index) {
118 return reinterpret_cast<const T*>(reinterpret_cast<const char *>(ehdr) 104 return reinterpret_cast<const T*>(reinterpret_cast<const char *>(ehdr)
119 + table_offset 105 + table_offset
120 + index * element_size); 106 + index * element_size);
121 } 107 }
122 } // namespace 108 } // namespace
123 109
124 const void *const VDSOSupport::kInvalidBase = 110 const void *const ElfMemImage::kInvalidBase =
125 reinterpret_cast<const void *>(~0L); 111 reinterpret_cast<const void *>(~0L);
126 112
127 const void *VDSOSupport::vdso_base_ = kInvalidBase; 113 ElfMemImage::ElfMemImage(const void *base) {
128 VDSOSupport::GetCpuFn VDSOSupport::getcpu_fn_ = &InitAndGetCPU;
129
130 VDSOSupport::ElfMemImage::ElfMemImage(const void *base) {
131 CHECK(base != kInvalidBase); 114 CHECK(base != kInvalidBase);
132 Init(base); 115 Init(base);
133 } 116 }
134 117
135 int VDSOSupport::ElfMemImage::GetNumSymbols() const { 118 int ElfMemImage::GetNumSymbols() const {
136 if (!hash_) { 119 if (!hash_) {
137 return 0; 120 return 0;
138 } 121 }
139 // See http://www.caldera.com/developers/gabi/latest/ch5.dynamic.html#hash 122 // See http://www.caldera.com/developers/gabi/latest/ch5.dynamic.html#hash
140 return hash_[1]; 123 return hash_[1];
141 } 124 }
142 125
143 const ElfW(Sym) *VDSOSupport::ElfMemImage::GetDynsym(int index) const { 126 const ElfW(Sym) *ElfMemImage::GetDynsym(int index) const {
144 CHECK_LT(index, GetNumSymbols()); 127 CHECK_LT(index, GetNumSymbols());
145 return dynsym_ + index; 128 return dynsym_ + index;
146 } 129 }
147 130
148 const ElfW(Versym) *VDSOSupport::ElfMemImage::GetVersym(int index) const { 131 const ElfW(Versym) *ElfMemImage::GetVersym(int index) const {
149 CHECK_LT(index, GetNumSymbols()); 132 CHECK_LT(index, GetNumSymbols());
150 return versym_ + index; 133 return versym_ + index;
151 } 134 }
152 135
153 const ElfW(Phdr) *VDSOSupport::ElfMemImage::GetPhdr(int index) const { 136 const ElfW(Phdr) *ElfMemImage::GetPhdr(int index) const {
154 CHECK_LT(index, ehdr_->e_phnum); 137 CHECK_LT(index, ehdr_->e_phnum);
155 return GetTableElement<ElfW(Phdr)>(ehdr_, 138 return GetTableElement<ElfW(Phdr)>(ehdr_,
156 ehdr_->e_phoff, 139 ehdr_->e_phoff,
157 ehdr_->e_phentsize, 140 ehdr_->e_phentsize,
158 index); 141 index);
159 } 142 }
160 143
161 const char *VDSOSupport::ElfMemImage::GetDynstr(ElfW(Word) offset) const { 144 const char *ElfMemImage::GetDynstr(ElfW(Word) offset) const {
162 CHECK_LT(offset, strsize_); 145 CHECK_LT(offset, strsize_);
163 return dynstr_ + offset; 146 return dynstr_ + offset;
164 } 147 }
165 148
166 const void *VDSOSupport::ElfMemImage::GetSymAddr(const ElfW(Sym) *sym) const { 149 const void *ElfMemImage::GetSymAddr(const ElfW(Sym) *sym) const {
167 if (sym->st_shndx == SHN_UNDEF || sym->st_shndx >= SHN_LORESERVE) { 150 if (sym->st_shndx == SHN_UNDEF || sym->st_shndx >= SHN_LORESERVE) {
168 // Symbol corresponds to "special" (e.g. SHN_ABS) section. 151 // Symbol corresponds to "special" (e.g. SHN_ABS) section.
169 return reinterpret_cast<const void *>(sym->st_value); 152 return reinterpret_cast<const void *>(sym->st_value);
170 } 153 }
171 CHECK_LT(link_base_, sym->st_value); 154 CHECK_LT(link_base_, sym->st_value);
172 return GetTableElement<char>(ehdr_, 0, 1, sym->st_value) - link_base_; 155 return GetTableElement<char>(ehdr_, 0, 1, sym->st_value) - link_base_;
173 } 156 }
174 157
175 const ElfW(Verdef) *VDSOSupport::ElfMemImage::GetVerdef(int index) const { 158 const ElfW(Verdef) *ElfMemImage::GetVerdef(int index) const {
176 CHECK_LE(index, verdefnum_); 159 CHECK_LE(index, verdefnum_);
177 const ElfW(Verdef) *version_definition = verdef_; 160 const ElfW(Verdef) *version_definition = verdef_;
178 while (version_definition->vd_ndx < index && version_definition->vd_next) { 161 while (version_definition->vd_ndx < index && version_definition->vd_next) {
179 const char *const version_definition_as_char = 162 const char *const version_definition_as_char =
180 reinterpret_cast<const char *>(version_definition); 163 reinterpret_cast<const char *>(version_definition);
181 version_definition = 164 version_definition =
182 reinterpret_cast<const ElfW(Verdef) *>(version_definition_as_char + 165 reinterpret_cast<const ElfW(Verdef) *>(version_definition_as_char +
183 version_definition->vd_next); 166 version_definition->vd_next);
184 } 167 }
185 return version_definition->vd_ndx == index ? version_definition : NULL; 168 return version_definition->vd_ndx == index ? version_definition : NULL;
186 } 169 }
187 170
188 const ElfW(Verdaux) *VDSOSupport::ElfMemImage::GetVerdefAux( 171 const ElfW(Verdaux) *ElfMemImage::GetVerdefAux(
189 const ElfW(Verdef) *verdef) const { 172 const ElfW(Verdef) *verdef) const {
190 return reinterpret_cast<const ElfW(Verdaux) *>(verdef+1); 173 return reinterpret_cast<const ElfW(Verdaux) *>(verdef+1);
191 } 174 }
192 175
193 const char *VDSOSupport::ElfMemImage::GetVerstr(ElfW(Word) offset) const { 176 const char *ElfMemImage::GetVerstr(ElfW(Word) offset) const {
194 CHECK_LT(offset, strsize_); 177 CHECK_LT(offset, strsize_);
195 return dynstr_ + offset; 178 return dynstr_ + offset;
196 } 179 }
197 180
198 void VDSOSupport::ElfMemImage::Init(const void *base) { 181 void ElfMemImage::Init(const void *base) {
199 ehdr_ = NULL; 182 ehdr_ = NULL;
200 dynsym_ = NULL; 183 dynsym_ = NULL;
201 dynstr_ = NULL; 184 dynstr_ = NULL;
202 versym_ = NULL; 185 versym_ = NULL;
203 verdef_ = NULL; 186 verdef_ = NULL;
204 hash_ = NULL; 187 hash_ = NULL;
205 strsize_ = 0; 188 strsize_ = 0;
206 verdefnum_ = 0; 189 verdefnum_ = 0;
207 link_base_ = ~0L; // Sentinel: PT_LOAD .p_vaddr can't possibly be this. 190 link_base_ = ~0L; // Sentinel: PT_LOAD .p_vaddr can't possibly be this.
208 if (!base) { 191 if (!base) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 break; 242 break;
260 } 243 }
261 } 244 }
262 if (link_base_ == ~0L || !dynamic_program_header) { 245 if (link_base_ == ~0L || !dynamic_program_header) {
263 RAW_DCHECK(~0L != link_base_, "no PT_LOADs in VDSO"); 246 RAW_DCHECK(~0L != link_base_, "no PT_LOADs in VDSO");
264 RAW_DCHECK(dynamic_program_header, "no PT_DYNAMIC in VDSO"); 247 RAW_DCHECK(dynamic_program_header, "no PT_DYNAMIC in VDSO");
265 // Mark this image as not present. Can not recur infinitely. 248 // Mark this image as not present. Can not recur infinitely.
266 Init(0); 249 Init(0);
267 return; 250 return;
268 } 251 }
269 std::ptrdiff_t relocation = 252 ptrdiff_t relocation =
270 base_as_char - reinterpret_cast<const char *>(link_base_); 253 base_as_char - reinterpret_cast<const char *>(link_base_);
271 ElfW(Dyn) *dynamic_entry = 254 ElfW(Dyn) *dynamic_entry =
272 reinterpret_cast<ElfW(Dyn) *>(dynamic_program_header->p_vaddr + 255 reinterpret_cast<ElfW(Dyn) *>(dynamic_program_header->p_vaddr +
273 relocation); 256 relocation);
274 for (; dynamic_entry->d_tag != DT_NULL; ++dynamic_entry) { 257 for (; dynamic_entry->d_tag != DT_NULL; ++dynamic_entry) {
275 ElfW(Xword) value = dynamic_entry->d_un.d_val; 258 ElfW(Xword) value = dynamic_entry->d_un.d_val;
276 if (fake_vdso) { 259 if (fake_vdso) {
277 // A complication: in the real VDSO, dynamic entries are not relocated 260 // A complication: in the real VDSO, dynamic entries are not relocated
278 // (it wasn't loaded by a dynamic loader). But when testing with a 261 // (it wasn't loaded by a dynamic loader). But when testing with a
279 // "fake" dlopen()ed vdso library, the loader relocates some (but 262 // "fake" dlopen()ed vdso library, the loader relocates some (but
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 RAW_DCHECK(versym_, "invalid VDSO (no DT_VERSYM)"); 305 RAW_DCHECK(versym_, "invalid VDSO (no DT_VERSYM)");
323 RAW_DCHECK(verdef_, "invalid VDSO (no DT_VERDEF)"); 306 RAW_DCHECK(verdef_, "invalid VDSO (no DT_VERDEF)");
324 RAW_DCHECK(verdefnum_, "invalid VDSO (no DT_VERDEFNUM)"); 307 RAW_DCHECK(verdefnum_, "invalid VDSO (no DT_VERDEFNUM)");
325 RAW_DCHECK(strsize_, "invalid VDSO (no DT_STRSZ)"); 308 RAW_DCHECK(strsize_, "invalid VDSO (no DT_STRSZ)");
326 // Mark this image as not present. Can not recur infinitely. 309 // Mark this image as not present. Can not recur infinitely.
327 Init(0); 310 Init(0);
328 return; 311 return;
329 } 312 }
330 } 313 }
331 314
332 VDSOSupport::VDSOSupport() 315 bool ElfMemImage::LookupSymbol(const char *name,
333 // If vdso_base_ is still set to kInvalidBase, we got here
334 // before VDSOSupport::Init has been called. Call it now.
335 : image_(vdso_base_ == kInvalidBase ? Init() : vdso_base_) {
336 }
337
338 // NOTE: we can't use GoogleOnceInit() below, because we can be
339 // called by tcmalloc, and none of the *once* stuff may be functional yet.
340 //
341 // In addition, we hope that the VDSOSupportHelper constructor
342 // causes this code to run before there are any threads, and before
343 // InitGoogle() has executed any chroot or setuid calls.
344 //
345 // Finally, even if there is a race here, it is harmless, because
346 // the operation should be idempotent.
347 const void *VDSOSupport::Init() {
348 if (vdso_base_ == kInvalidBase) {
349 // Valgrind zaps AT_SYSINFO_EHDR and friends from the auxv[]
350 // on stack, and so glibc works as if VDSO was not present.
351 // But going directly to kernel via /proc/self/auxv below bypasses
352 // Valgrind zapping. So we check for Valgrind separately.
353 if (RunningOnValgrind()) {
354 vdso_base_ = NULL;
355 getcpu_fn_ = &GetCPUViaSyscall;
356 return NULL;
357 }
358 int fd = open("/proc/self/auxv", O_RDONLY);
359 if (fd == -1) {
360 // Kernel too old to have a VDSO.
361 vdso_base_ = NULL;
362 getcpu_fn_ = &GetCPUViaSyscall;
363 return NULL;
364 }
365 ElfW(auxv_t) aux;
366 while (read(fd, &aux, sizeof(aux)) == sizeof(aux)) {
367 if (aux.a_type == AT_SYSINFO_EHDR) {
368 COMPILE_ASSERT(sizeof(vdso_base_) == sizeof(aux.a_un.a_val),
369 unexpected_sizeof_pointer_NE_sizeof_a_val);
370 vdso_base_ = reinterpret_cast<void *>(aux.a_un.a_val);
371 break;
372 }
373 }
374 close(fd);
375 if (vdso_base_ == kInvalidBase) {
376 // Didn't find AT_SYSINFO_EHDR in auxv[].
377 vdso_base_ = NULL;
378 }
379 }
380 GetCpuFn fn = &GetCPUViaSyscall; // default if VDSO not present.
381 if (vdso_base_) {
382 VDSOSupport vdso;
383 SymbolInfo info;
384 if (vdso.LookupSymbol("__vdso_getcpu", "LINUX_2.6", STT_FUNC, &info)) {
385 // Casting from an int to a pointer is not legal C++. To emphasize
386 // this, we use a C-style cast rather than a C++-style cast.
387 fn = (GetCpuFn)(info.address);
388 }
389 }
390 // Subtle: this code runs outside of any locks; prevent compiler
391 // from assigning to getcpu_fn_ more than once.
392 base::subtle::MemoryBarrier();
393 getcpu_fn_ = fn;
394 return vdso_base_;
395 }
396
397 const void *VDSOSupport::SetBase(const void *base) {
398 const void *old_base = vdso_base_;
399 vdso_base_ = base;
400 image_.Init(base);
401 // Also reset getcpu_fn_, so GetCPU could be tested with simulated VDSO.
402 getcpu_fn_ = &InitAndGetCPU;
403 return old_base;
404 }
405
406 bool VDSOSupport::LookupSymbol(const char *name,
407 const char *version, 316 const char *version,
408 int type, 317 int type,
409 SymbolInfo *info) const { 318 SymbolInfo *info) const {
410 for (SymbolIterator it = begin(); it != end(); ++it) { 319 for (SymbolIterator it = begin(); it != end(); ++it) {
411 if (strcmp(it->name, name) == 0 && strcmp(it->version, version) == 0 && 320 if (strcmp(it->name, name) == 0 && strcmp(it->version, version) == 0 &&
412 CurrentElfClass::ElfType(it->symbol) == type) { 321 CurrentElfClass::ElfType(it->symbol) == type) {
413 if (info) { 322 if (info) {
414 *info = *it; 323 *info = *it;
415 } 324 }
416 return true; 325 return true;
417 } 326 }
418 } 327 }
419 return false; 328 return false;
420 } 329 }
421 330
422 bool VDSOSupport::LookupSymbolByAddress(const void *address, 331 bool ElfMemImage::LookupSymbolByAddress(const void *address,
423 SymbolInfo *info_out) const { 332 SymbolInfo *info_out) const {
424 for (SymbolIterator it = begin(); it != end(); ++it) { 333 for (SymbolIterator it = begin(); it != end(); ++it) {
425 const char *const symbol_start = 334 const char *const symbol_start =
426 reinterpret_cast<const char *>(it->address); 335 reinterpret_cast<const char *>(it->address);
427 const char *const symbol_end = symbol_start + it->symbol->st_size; 336 const char *const symbol_end = symbol_start + it->symbol->st_size;
428 if (symbol_start <= address && address < symbol_end) { 337 if (symbol_start <= address && address < symbol_end) {
429 if (info_out) { 338 if (info_out) {
430 // Client wants to know details for that symbol (the usual case). 339 // Client wants to know details for that symbol (the usual case).
431 if (CurrentElfClass::ElfBind(it->symbol) == STB_GLOBAL) { 340 if (CurrentElfClass::ElfBind(it->symbol) == STB_GLOBAL) {
432 // Strong symbol; just return it. 341 // Strong symbol; just return it.
433 *info_out = *it; 342 *info_out = *it;
434 return true; 343 return true;
435 } else { 344 } else {
436 // Weak or local. Record it, but keep looking for a strong one. 345 // Weak or local. Record it, but keep looking for a strong one.
437 *info_out = *it; 346 *info_out = *it;
438 } 347 }
439 } else { 348 } else {
440 // Client only cares if there is an overlapping symbol. 349 // Client only cares if there is an overlapping symbol.
441 return true; 350 return true;
442 } 351 }
443 } 352 }
444 } 353 }
445 return false; 354 return false;
446 } 355 }
447 356
448 VDSOSupport::SymbolIterator::SymbolIterator(const void *const image, int index) 357 ElfMemImage::SymbolIterator::SymbolIterator(const void *const image, int index)
449 : index_(index), image_(image) { 358 : index_(index), image_(image) {
450 } 359 }
451 360
452 const VDSOSupport::SymbolInfo *VDSOSupport::SymbolIterator::operator->() const { 361 const ElfMemImage::SymbolInfo *ElfMemImage::SymbolIterator::operator->() const {
453 return &info_; 362 return &info_;
454 } 363 }
455 364
456 const VDSOSupport::SymbolInfo& VDSOSupport::SymbolIterator::operator*() const { 365 const ElfMemImage::SymbolInfo& ElfMemImage::SymbolIterator::operator*() const {
457 return info_; 366 return info_;
458 } 367 }
459 368
460 bool VDSOSupport::SymbolIterator::operator==(const SymbolIterator &rhs) const { 369 bool ElfMemImage::SymbolIterator::operator==(const SymbolIterator &rhs) const {
461 return this->image_ == rhs.image_ && this->index_ == rhs.index_; 370 return this->image_ == rhs.image_ && this->index_ == rhs.index_;
462 } 371 }
463 372
464 bool VDSOSupport::SymbolIterator::operator!=(const SymbolIterator &rhs) const { 373 bool ElfMemImage::SymbolIterator::operator!=(const SymbolIterator &rhs) const {
465 return !(*this == rhs); 374 return !(*this == rhs);
466 } 375 }
467 376
468 VDSOSupport::SymbolIterator &VDSOSupport::SymbolIterator::operator++() { 377 ElfMemImage::SymbolIterator &ElfMemImage::SymbolIterator::operator++() {
469 this->Update(1); 378 this->Update(1);
470 return *this; 379 return *this;
471 } 380 }
472 381
473 VDSOSupport::SymbolIterator VDSOSupport::begin() const { 382 ElfMemImage::SymbolIterator ElfMemImage::begin() const {
474 SymbolIterator it(&image_, 0); 383 SymbolIterator it(this, 0);
475 it.Update(0); 384 it.Update(0);
476 return it; 385 return it;
477 } 386 }
478 387
479 VDSOSupport::SymbolIterator VDSOSupport::end() const { 388 ElfMemImage::SymbolIterator ElfMemImage::end() const {
480 return SymbolIterator(&image_, image_.GetNumSymbols()); 389 return SymbolIterator(this, GetNumSymbols());
481 } 390 }
482 391
483 void VDSOSupport::SymbolIterator::Update(int increment) { 392 void ElfMemImage::SymbolIterator::Update(int increment) {
484 const ElfMemImage *image = reinterpret_cast<const ElfMemImage *>(image_); 393 const ElfMemImage *image = reinterpret_cast<const ElfMemImage *>(image_);
485 CHECK(image->IsPresent() || increment == 0); 394 CHECK(image->IsPresent() || increment == 0);
486 if (!image->IsPresent()) { 395 if (!image->IsPresent()) {
487 return; 396 return;
488 } 397 }
489 index_ += increment; 398 index_ += increment;
490 if (index_ >= image->GetNumSymbols()) { 399 if (index_ >= image->GetNumSymbols()) {
491 index_ = image->GetNumSymbols(); 400 index_ = image->GetNumSymbols();
492 return; 401 return;
493 } 402 }
(...skipping 18 matching lines...) Expand all
512 CHECK_LE(version_definition->vd_cnt, 2); 421 CHECK_LE(version_definition->vd_cnt, 2);
513 const ElfW(Verdaux) *version_aux = image->GetVerdefAux(version_definition); 422 const ElfW(Verdaux) *version_aux = image->GetVerdefAux(version_definition);
514 version_name = image->GetVerstr(version_aux->vda_name); 423 version_name = image->GetVerstr(version_aux->vda_name);
515 } 424 }
516 info_.name = symbol_name; 425 info_.name = symbol_name;
517 info_.version = version_name; 426 info_.version = version_name;
518 info_.address = image->GetSymAddr(symbol); 427 info_.address = image->GetSymAddr(symbol);
519 info_.symbol = symbol; 428 info_.symbol = symbol;
520 } 429 }
521 430
522 // NOLINT on 'long' because this routine mimics kernel api. 431 } // namespace base
523 long VDSOSupport::GetCPUViaSyscall(unsigned *cpu, void *, void *) { // NOLINT
524 #if defined(__NR_getcpu)
525 return sys_getcpu(cpu, NULL, NULL);
526 #else
527 // x86_64 never implemented sys_getcpu(), except as a VDSO call.
528 errno = ENOSYS;
529 return -1;
530 #endif
531 }
532 432
533 // Use fast __vdso_getcpu if available. 433 #endif // HAVE_ELF_MEM_IMAGE
534 long VDSOSupport::InitAndGetCPU(unsigned *cpu, void *x, void *y) { // NOLINT
535 Init();
536 CHECK_NE(getcpu_fn_, &InitAndGetCPU); // << "Init() did not set getcpu_fn_";
537 return (*getcpu_fn_)(cpu, x, y);
538 }
539
540 // This function must be very fast, and may be called from very
541 // low level (e.g. tcmalloc). Hence I avoid things like
542 // GoogleOnceInit() and ::operator new.
543 int GetCPU(void) {
544 unsigned cpu;
545 int ret_code = (*VDSOSupport::getcpu_fn_)(&cpu, NULL, NULL);
546 return ret_code == 0 ? cpu : ret_code;
547 }
548
549 // We need to make sure VDSOSupport::Init() is called before
550 // the main() runs, since it might do something like setuid or
551 // chroot. If VDSOSupport
552 // is used in any global constructor, this will happen, since
553 // VDSOSupport's constructor calls Init. But if not, we need to
554 // ensure it here, with a global constructor of our own. This
555 // is an allowed exception to the normal rule against non-trivial
556 // global constructors.
557 static class VDSOInitHelper {
558 public:
559 VDSOInitHelper() { VDSOSupport::Init(); }
560 } vdso_init_helper;
561 }
562
563 #endif // HAVE_VDSO_SUPPORT
OLDNEW
« 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