diff options
author | Moonchild <mcwerewolf@gmail.com> | 2018-05-04 09:09:10 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-04 09:09:10 +0200 |
commit | 4a2aeb152e48c44efa57c140660e99792f4dd350 (patch) | |
tree | 7b786de2b175122814a53232268b1147a8bd0bfb /security/sandbox/chromium/base | |
parent | 20532e13937ab5fc8efcb2bfc4c0070dace40cd1 (diff) | |
parent | f265784e8cabaff17f4554cf2bd2c30217b6ec0f (diff) | |
download | UXP-4a2aeb152e48c44efa57c140660e99792f4dd350.tar UXP-4a2aeb152e48c44efa57c140660e99792f4dd350.tar.gz UXP-4a2aeb152e48c44efa57c140660e99792f4dd350.tar.lz UXP-4a2aeb152e48c44efa57c140660e99792f4dd350.tar.xz UXP-4a2aeb152e48c44efa57c140660e99792f4dd350.zip |
Merge pull request #323 from MoonchildProductions/nuke-sandbox
Nuke sandbox
Diffstat (limited to 'security/sandbox/chromium/base')
151 files changed, 0 insertions, 37083 deletions
diff --git a/security/sandbox/chromium/base/at_exit.cc b/security/sandbox/chromium/base/at_exit.cc deleted file mode 100644 index 0fba35569..000000000 --- a/security/sandbox/chromium/base/at_exit.cc +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/at_exit.h" - -#include <stddef.h> -#include <ostream> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/logging.h" - -namespace base { - -// Keep a stack of registered AtExitManagers. We always operate on the most -// recent, and we should never have more than one outside of testing (for a -// statically linked version of this library). Testing may use the shadow -// version of the constructor, and if we are building a dynamic library we may -// end up with multiple AtExitManagers on the same process. We don't protect -// this for thread-safe access, since it will only be modified in testing. -static AtExitManager* g_top_manager = NULL; - -AtExitManager::AtExitManager() : next_manager_(g_top_manager) { -// If multiple modules instantiate AtExitManagers they'll end up living in this -// module... they have to coexist. -#if !defined(COMPONENT_BUILD) - DCHECK(!g_top_manager); -#endif - g_top_manager = this; -} - -AtExitManager::~AtExitManager() { - if (!g_top_manager) { - NOTREACHED() << "Tried to ~AtExitManager without an AtExitManager"; - return; - } - DCHECK_EQ(this, g_top_manager); - - ProcessCallbacksNow(); - g_top_manager = next_manager_; -} - -// static -void AtExitManager::RegisterCallback(AtExitCallbackType func, void* param) { - DCHECK(func); - RegisterTask(base::Bind(func, param)); -} - -// static -void AtExitManager::RegisterTask(base::Closure task) { - if (!g_top_manager) { - NOTREACHED() << "Tried to RegisterCallback without an AtExitManager"; - return; - } - - AutoLock lock(g_top_manager->lock_); - g_top_manager->stack_.push(task); -} - -// static -void AtExitManager::ProcessCallbacksNow() { - if (!g_top_manager) { - NOTREACHED() << "Tried to ProcessCallbacksNow without an AtExitManager"; - return; - } - - AutoLock lock(g_top_manager->lock_); - - while (!g_top_manager->stack_.empty()) { - base::Closure task = g_top_manager->stack_.top(); - task.Run(); - g_top_manager->stack_.pop(); - } -} - -AtExitManager::AtExitManager(bool shadow) : next_manager_(g_top_manager) { - DCHECK(shadow || !g_top_manager); - g_top_manager = this; -} - -} // namespace base diff --git a/security/sandbox/chromium/base/at_exit.h b/security/sandbox/chromium/base/at_exit.h deleted file mode 100644 index 04e3f7642..000000000 --- a/security/sandbox/chromium/base/at_exit.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_AT_EXIT_H_ -#define BASE_AT_EXIT_H_ - -#include <stack> - -#include "base/base_export.h" -#include "base/callback.h" -#include "base/macros.h" -#include "base/synchronization/lock.h" - -namespace base { - -// This class provides a facility similar to the CRT atexit(), except that -// we control when the callbacks are executed. Under Windows for a DLL they -// happen at a really bad time and under the loader lock. This facility is -// mostly used by base::Singleton. -// -// The usage is simple. Early in the main() or WinMain() scope create an -// AtExitManager object on the stack: -// int main(...) { -// base::AtExitManager exit_manager; -// -// } -// When the exit_manager object goes out of scope, all the registered -// callbacks and singleton destructors will be called. - -class BASE_EXPORT AtExitManager { - public: - typedef void (*AtExitCallbackType)(void*); - - AtExitManager(); - - // The dtor calls all the registered callbacks. Do not try to register more - // callbacks after this point. - ~AtExitManager(); - - // Registers the specified function to be called at exit. The prototype of - // the callback function is void func(void*). - static void RegisterCallback(AtExitCallbackType func, void* param); - - // Registers the specified task to be called at exit. - static void RegisterTask(base::Closure task); - - // Calls the functions registered with RegisterCallback in LIFO order. It - // is possible to register new callbacks after calling this function. - static void ProcessCallbacksNow(); - - protected: - // This constructor will allow this instance of AtExitManager to be created - // even if one already exists. This should only be used for testing! - // AtExitManagers are kept on a global stack, and it will be removed during - // destruction. This allows you to shadow another AtExitManager. - explicit AtExitManager(bool shadow); - - private: - base::Lock lock_; - std::stack<base::Closure> stack_; - AtExitManager* next_manager_; // Stack of managers to allow shadowing. - - DISALLOW_COPY_AND_ASSIGN(AtExitManager); -}; - -#if defined(UNIT_TEST) -class ShadowingAtExitManager : public AtExitManager { - public: - ShadowingAtExitManager() : AtExitManager(true) {} -}; -#endif // defined(UNIT_TEST) - -} // namespace base - -#endif // BASE_AT_EXIT_H_ diff --git a/security/sandbox/chromium/base/atomic_ref_count.h b/security/sandbox/chromium/base/atomic_ref_count.h deleted file mode 100644 index 2ab724200..000000000 --- a/security/sandbox/chromium/base/atomic_ref_count.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This is a low level implementation of atomic semantics for reference -// counting. Please use base/memory/ref_counted.h directly instead. - -#ifndef BASE_ATOMIC_REF_COUNT_H_ -#define BASE_ATOMIC_REF_COUNT_H_ - -#include "base/atomicops.h" - -namespace base { - -typedef subtle::Atomic32 AtomicRefCount; - -// Increment a reference count by "increment", which must exceed 0. -inline void AtomicRefCountIncN(volatile AtomicRefCount *ptr, - AtomicRefCount increment) { - subtle::NoBarrier_AtomicIncrement(ptr, increment); -} - -// Decrement a reference count by "decrement", which must exceed 0, -// and return whether the result is non-zero. -// Insert barriers to ensure that state written before the reference count -// became zero will be visible to a thread that has just made the count zero. -inline bool AtomicRefCountDecN(volatile AtomicRefCount *ptr, - AtomicRefCount decrement) { - bool res = (subtle::Barrier_AtomicIncrement(ptr, -decrement) != 0); - return res; -} - -// Increment a reference count by 1. -inline void AtomicRefCountInc(volatile AtomicRefCount *ptr) { - base::AtomicRefCountIncN(ptr, 1); -} - -// Decrement a reference count by 1 and return whether the result is non-zero. -// Insert barriers to ensure that state written before the reference count -// became zero will be visible to a thread that has just made the count zero. -inline bool AtomicRefCountDec(volatile AtomicRefCount *ptr) { - return base::AtomicRefCountDecN(ptr, 1); -} - -// Return whether the reference count is one. If the reference count is used -// in the conventional way, a refrerence count of 1 implies that the current -// thread owns the reference and no other thread shares it. This call performs -// the test for a reference count of one, and performs the memory barrier -// needed for the owning thread to act on the object, knowing that it has -// exclusive access to the object. -inline bool AtomicRefCountIsOne(volatile AtomicRefCount *ptr) { - bool res = (subtle::Acquire_Load(ptr) == 1); - return res; -} - -// Return whether the reference count is zero. With conventional object -// referencing counting, the object will be destroyed, so the reference count -// should never be zero. Hence this is generally used for a debug check. -inline bool AtomicRefCountIsZero(volatile AtomicRefCount *ptr) { - bool res = (subtle::Acquire_Load(ptr) == 0); - return res; -} - -} // namespace base - -#endif // BASE_ATOMIC_REF_COUNT_H_ diff --git a/security/sandbox/chromium/base/atomic_sequence_num.h b/security/sandbox/chromium/base/atomic_sequence_num.h deleted file mode 100644 index 59b0d2551..000000000 --- a/security/sandbox/chromium/base/atomic_sequence_num.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_ATOMIC_SEQUENCE_NUM_H_ -#define BASE_ATOMIC_SEQUENCE_NUM_H_ - -#include "base/atomicops.h" -#include "base/macros.h" - -namespace base { - -class AtomicSequenceNumber; - -// Static (POD) AtomicSequenceNumber that MUST be used in global scope (or -// non-function scope) ONLY. This implementation does not generate any static -// initializer. Note that it does not implement any constructor which means -// that its fields are not initialized except when it is stored in the global -// data section (.data in ELF). If you want to allocate an atomic sequence -// number on the stack (or heap), please use the AtomicSequenceNumber class -// declared below. -class StaticAtomicSequenceNumber { - public: - inline int GetNext() { - return static_cast<int>( - base::subtle::NoBarrier_AtomicIncrement(&seq_, 1) - 1); - } - - private: - friend class AtomicSequenceNumber; - - inline void Reset() { - base::subtle::Release_Store(&seq_, 0); - } - - base::subtle::Atomic32 seq_; -}; - -// AtomicSequenceNumber that can be stored and used safely (i.e. its fields are -// always initialized as opposed to StaticAtomicSequenceNumber declared above). -// Please use StaticAtomicSequenceNumber if you want to declare an atomic -// sequence number in the global scope. -class AtomicSequenceNumber { - public: - AtomicSequenceNumber() { - seq_.Reset(); - } - - inline int GetNext() { - return seq_.GetNext(); - } - - private: - StaticAtomicSequenceNumber seq_; - DISALLOW_COPY_AND_ASSIGN(AtomicSequenceNumber); -}; - -} // namespace base - -#endif // BASE_ATOMIC_SEQUENCE_NUM_H_ diff --git a/security/sandbox/chromium/base/atomicops.h b/security/sandbox/chromium/base/atomicops.h deleted file mode 100644 index 3428fe87a..000000000 --- a/security/sandbox/chromium/base/atomicops.h +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// For atomic operations on reference counts, see atomic_refcount.h. -// For atomic operations on sequence numbers, see atomic_sequence_num.h. - -// The routines exported by this module are subtle. If you use them, even if -// you get the code right, it will depend on careful reasoning about atomicity -// and memory ordering; it will be less readable, and harder to maintain. If -// you plan to use these routines, you should have a good reason, such as solid -// evidence that performance would otherwise suffer, or there being no -// alternative. You should assume only properties explicitly guaranteed by the -// specifications in this file. You are almost certainly _not_ writing code -// just for the x86; if you assume x86 semantics, x86 hardware bugs and -// implementations on other archtectures will cause your code to break. If you -// do not know what you are doing, avoid these routines, and use a Mutex. -// -// It is incorrect to make direct assignments to/from an atomic variable. -// You should use one of the Load or Store routines. The NoBarrier -// versions are provided when no barriers are needed: -// NoBarrier_Store() -// NoBarrier_Load() -// Although there are currently no compiler enforcement, you are encouraged -// to use these. -// - -#ifndef BASE_ATOMICOPS_H_ -#define BASE_ATOMICOPS_H_ - -#include <stdint.h> - -// Small C++ header which defines implementation specific macros used to -// identify the STL implementation. -// - libc++: captures __config for _LIBCPP_VERSION -// - libstdc++: captures bits/c++config.h for __GLIBCXX__ -#include <cstddef> - -#include "base/base_export.h" -#include "build/build_config.h" - -#if defined(OS_WIN) && defined(ARCH_CPU_64_BITS) -// windows.h #defines this (only on x64). This causes problems because the -// public API also uses MemoryBarrier at the public name for this fence. So, on -// X64, undef it, and call its documented -// (http://msdn.microsoft.com/en-us/library/windows/desktop/ms684208.aspx) -// implementation directly. -#undef MemoryBarrier -#endif - -namespace base { -namespace subtle { - -typedef int32_t Atomic32; -#ifdef ARCH_CPU_64_BITS -// We need to be able to go between Atomic64 and AtomicWord implicitly. This -// means Atomic64 and AtomicWord should be the same type on 64-bit. -#if defined(__ILP32__) || defined(OS_NACL) -// NaCl's intptr_t is not actually 64-bits on 64-bit! -// http://code.google.com/p/nativeclient/issues/detail?id=1162 -typedef int64_t Atomic64; -#else -typedef intptr_t Atomic64; -#endif -#endif - -// Use AtomicWord for a machine-sized pointer. It will use the Atomic32 or -// Atomic64 routines below, depending on your architecture. -typedef intptr_t AtomicWord; - -// Atomically execute: -// result = *ptr; -// if (*ptr == old_value) -// *ptr = new_value; -// return result; -// -// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value". -// Always return the old value of "*ptr" -// -// This routine implies no memory barriers. -Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, - Atomic32 old_value, - Atomic32 new_value); - -// Atomically store new_value into *ptr, returning the previous value held in -// *ptr. This routine implies no memory barriers. -Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value); - -// Atomically increment *ptr by "increment". Returns the new value of -// *ptr with the increment applied. This routine implies no memory barriers. -Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment); - -Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, - Atomic32 increment); - -// These following lower-level operations are typically useful only to people -// implementing higher-level synchronization operations like spinlocks, -// mutexes, and condition-variables. They combine CompareAndSwap(), a load, or -// a store with appropriate memory-ordering instructions. "Acquire" operations -// ensure that no later memory access can be reordered ahead of the operation. -// "Release" operations ensure that no previous memory access can be reordered -// after the operation. "Barrier" operations have both "Acquire" and "Release" -// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory -// access. -Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, - Atomic32 old_value, - Atomic32 new_value); -Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, - Atomic32 old_value, - Atomic32 new_value); - -void MemoryBarrier(); -void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value); -void Acquire_Store(volatile Atomic32* ptr, Atomic32 value); -void Release_Store(volatile Atomic32* ptr, Atomic32 value); - -Atomic32 NoBarrier_Load(volatile const Atomic32* ptr); -Atomic32 Acquire_Load(volatile const Atomic32* ptr); -Atomic32 Release_Load(volatile const Atomic32* ptr); - -// 64-bit atomic operations (only available on 64-bit processors). -#ifdef ARCH_CPU_64_BITS -Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, - Atomic64 old_value, - Atomic64 new_value); -Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value); -Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); -Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment); - -Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, - Atomic64 old_value, - Atomic64 new_value); -Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, - Atomic64 old_value, - Atomic64 new_value); -void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value); -void Acquire_Store(volatile Atomic64* ptr, Atomic64 value); -void Release_Store(volatile Atomic64* ptr, Atomic64 value); -Atomic64 NoBarrier_Load(volatile const Atomic64* ptr); -Atomic64 Acquire_Load(volatile const Atomic64* ptr); -Atomic64 Release_Load(volatile const Atomic64* ptr); -#endif // ARCH_CPU_64_BITS - -} // namespace subtle -} // namespace base - -#if defined(OS_WIN) -// TODO(jfb): The MSVC header includes windows.h, which other files end up -// relying on. Fix this as part of crbug.com/559247. -# include "base/atomicops_internals_x86_msvc.h" -#else -# include "base/atomicops_internals_portable.h" -#endif - -// On some platforms we need additional declarations to make -// AtomicWord compatible with our other Atomic* types. -#if defined(OS_MACOSX) || defined(OS_OPENBSD) -#include "base/atomicops_internals_atomicword_compat.h" -#endif - -#endif // BASE_ATOMICOPS_H_ diff --git a/security/sandbox/chromium/base/atomicops_internals_portable.h b/security/sandbox/chromium/base/atomicops_internals_portable.h deleted file mode 100644 index ee034dee1..000000000 --- a/security/sandbox/chromium/base/atomicops_internals_portable.h +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright (c) 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file is an internal atomic implementation, use atomicops.h instead. -// -// This implementation uses C++11 atomics' member functions. The code base is -// currently written assuming atomicity revolves around accesses instead of -// C++11's memory locations. The burden is on the programmer to ensure that all -// memory locations accessed atomically are never accessed non-atomically (tsan -// should help with this). -// -// TODO(jfb) Modify the atomicops.h API and user code to declare atomic -// locations as truly atomic. See the static_assert below. -// -// Of note in this implementation: -// * All NoBarrier variants are implemented as relaxed. -// * All Barrier variants are implemented as sequentially-consistent. -// * Compare exchange's failure ordering is always the same as the success one -// (except for release, which fails as relaxed): using a weaker ordering is -// only valid under certain uses of compare exchange. -// * Acquire store doesn't exist in the C11 memory model, it is instead -// implemented as a relaxed store followed by a sequentially consistent -// fence. -// * Release load doesn't exist in the C11 memory model, it is instead -// implemented as sequentially consistent fence followed by a relaxed load. -// * Atomic increment is expected to return the post-incremented value, whereas -// C11 fetch add returns the previous value. The implementation therefore -// needs to increment twice (which the compiler should be able to detect and -// optimize). - -#ifndef BASE_ATOMICOPS_INTERNALS_PORTABLE_H_ -#define BASE_ATOMICOPS_INTERNALS_PORTABLE_H_ - -#include <atomic> - -#include "build/build_config.h" - -namespace base { -namespace subtle { - -// This implementation is transitional and maintains the original API for -// atomicops.h. This requires casting memory locations to the atomic types, and -// assumes that the API and the C++11 implementation are layout-compatible, -// which isn't true for all implementations or hardware platforms. The static -// assertion should detect this issue, were it to fire then this header -// shouldn't be used. -// -// TODO(jfb) If this header manages to stay committed then the API should be -// modified, and all call sites updated. -typedef volatile std::atomic<Atomic32>* AtomicLocation32; -static_assert(sizeof(*(AtomicLocation32) nullptr) == sizeof(Atomic32), - "incompatible 32-bit atomic layout"); - -inline void MemoryBarrier() { -#if defined(__GLIBCXX__) - // Work around libstdc++ bug 51038 where atomic_thread_fence was declared but - // not defined, leading to the linker complaining about undefined references. - __atomic_thread_fence(std::memory_order_seq_cst); -#else - std::atomic_thread_fence(std::memory_order_seq_cst); -#endif -} - -inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, - Atomic32 old_value, - Atomic32 new_value) { - ((AtomicLocation32)ptr) - ->compare_exchange_strong(old_value, - new_value, - std::memory_order_relaxed, - std::memory_order_relaxed); - return old_value; -} - -inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, - Atomic32 new_value) { - return ((AtomicLocation32)ptr) - ->exchange(new_value, std::memory_order_relaxed); -} - -inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, - Atomic32 increment) { - return increment + - ((AtomicLocation32)ptr) - ->fetch_add(increment, std::memory_order_relaxed); -} - -inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, - Atomic32 increment) { - return increment + ((AtomicLocation32)ptr)->fetch_add(increment); -} - -inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, - Atomic32 old_value, - Atomic32 new_value) { - ((AtomicLocation32)ptr) - ->compare_exchange_strong(old_value, - new_value, - std::memory_order_acquire, - std::memory_order_acquire); - return old_value; -} - -inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, - Atomic32 old_value, - Atomic32 new_value) { - ((AtomicLocation32)ptr) - ->compare_exchange_strong(old_value, - new_value, - std::memory_order_release, - std::memory_order_relaxed); - return old_value; -} - -inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { - ((AtomicLocation32)ptr)->store(value, std::memory_order_relaxed); -} - -inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { - ((AtomicLocation32)ptr)->store(value, std::memory_order_relaxed); - MemoryBarrier(); -} - -inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { - ((AtomicLocation32)ptr)->store(value, std::memory_order_release); -} - -inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { - return ((AtomicLocation32)ptr)->load(std::memory_order_relaxed); -} - -inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { - return ((AtomicLocation32)ptr)->load(std::memory_order_acquire); -} - -inline Atomic32 Release_Load(volatile const Atomic32* ptr) { - MemoryBarrier(); - return ((AtomicLocation32)ptr)->load(std::memory_order_relaxed); -} - -#if defined(ARCH_CPU_64_BITS) - -typedef volatile std::atomic<Atomic64>* AtomicLocation64; -static_assert(sizeof(*(AtomicLocation64) nullptr) == sizeof(Atomic64), - "incompatible 64-bit atomic layout"); - -inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, - Atomic64 old_value, - Atomic64 new_value) { - ((AtomicLocation64)ptr) - ->compare_exchange_strong(old_value, - new_value, - std::memory_order_relaxed, - std::memory_order_relaxed); - return old_value; -} - -inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, - Atomic64 new_value) { - return ((AtomicLocation64)ptr) - ->exchange(new_value, std::memory_order_relaxed); -} - -inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, - Atomic64 increment) { - return increment + - ((AtomicLocation64)ptr) - ->fetch_add(increment, std::memory_order_relaxed); -} - -inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, - Atomic64 increment) { - return increment + ((AtomicLocation64)ptr)->fetch_add(increment); -} - -inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, - Atomic64 old_value, - Atomic64 new_value) { - ((AtomicLocation64)ptr) - ->compare_exchange_strong(old_value, - new_value, - std::memory_order_acquire, - std::memory_order_acquire); - return old_value; -} - -inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, - Atomic64 old_value, - Atomic64 new_value) { - ((AtomicLocation64)ptr) - ->compare_exchange_strong(old_value, - new_value, - std::memory_order_release, - std::memory_order_relaxed); - return old_value; -} - -inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { - ((AtomicLocation64)ptr)->store(value, std::memory_order_relaxed); -} - -inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { - ((AtomicLocation64)ptr)->store(value, std::memory_order_relaxed); - MemoryBarrier(); -} - -inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { - ((AtomicLocation64)ptr)->store(value, std::memory_order_release); -} - -inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { - return ((AtomicLocation64)ptr)->load(std::memory_order_relaxed); -} - -inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { - return ((AtomicLocation64)ptr)->load(std::memory_order_acquire); -} - -inline Atomic64 Release_Load(volatile const Atomic64* ptr) { - MemoryBarrier(); - return ((AtomicLocation64)ptr)->load(std::memory_order_relaxed); -} - -#endif // defined(ARCH_CPU_64_BITS) -} // namespace subtle -} // namespace base - -#endif // BASE_ATOMICOPS_INTERNALS_PORTABLE_H_ diff --git a/security/sandbox/chromium/base/atomicops_internals_x86_msvc.h b/security/sandbox/chromium/base/atomicops_internals_x86_msvc.h deleted file mode 100644 index 9f05b7e78..000000000 --- a/security/sandbox/chromium/base/atomicops_internals_x86_msvc.h +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file is an internal atomic implementation, use base/atomicops.h instead. - -#ifndef BASE_ATOMICOPS_INTERNALS_X86_MSVC_H_ -#define BASE_ATOMICOPS_INTERNALS_X86_MSVC_H_ - -#include <windows.h> - -#include <intrin.h> - -#include "base/macros.h" -#include "build/build_config.h" - -#if defined(ARCH_CPU_64_BITS) -// windows.h #defines this (only on x64). This causes problems because the -// public API also uses MemoryBarrier at the public name for this fence. So, on -// X64, undef it, and call its documented -// (http://msdn.microsoft.com/en-us/library/windows/desktop/ms684208.aspx) -// implementation directly. -#undef MemoryBarrier -#endif - -namespace base { -namespace subtle { - -inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, - Atomic32 old_value, - Atomic32 new_value) { - LONG result = _InterlockedCompareExchange( - reinterpret_cast<volatile LONG*>(ptr), - static_cast<LONG>(new_value), - static_cast<LONG>(old_value)); - return static_cast<Atomic32>(result); -} - -inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, - Atomic32 new_value) { - LONG result = _InterlockedExchange( - reinterpret_cast<volatile LONG*>(ptr), - static_cast<LONG>(new_value)); - return static_cast<Atomic32>(result); -} - -inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, - Atomic32 increment) { - return _InterlockedExchangeAdd( - reinterpret_cast<volatile LONG*>(ptr), - static_cast<LONG>(increment)) + increment; -} - -inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, - Atomic32 increment) { - return Barrier_AtomicIncrement(ptr, increment); -} - -inline void MemoryBarrier() { -#if defined(ARCH_CPU_64_BITS) - // See #undef and note at the top of this file. - __faststorefence(); -#else - // We use MemoryBarrier from WinNT.h - ::MemoryBarrier(); -#endif -} - -inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, - Atomic32 old_value, - Atomic32 new_value) { - return NoBarrier_CompareAndSwap(ptr, old_value, new_value); -} - -inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, - Atomic32 old_value, - Atomic32 new_value) { - return NoBarrier_CompareAndSwap(ptr, old_value, new_value); -} - -inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { - *ptr = value; -} - -inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { - NoBarrier_AtomicExchange(ptr, value); - // acts as a barrier in this implementation -} - -inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { - *ptr = value; // works w/o barrier for current Intel chips as of June 2005 - // See comments in Atomic64 version of Release_Store() below. -} - -inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { - return *ptr; -} - -inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { - Atomic32 value = *ptr; - return value; -} - -inline Atomic32 Release_Load(volatile const Atomic32* ptr) { - MemoryBarrier(); - return *ptr; -} - -#if defined(_WIN64) - -// 64-bit low-level operations on 64-bit platform. - -static_assert(sizeof(Atomic64) == sizeof(PVOID), "atomic word is atomic"); - -inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, - Atomic64 old_value, - Atomic64 new_value) { - PVOID result = InterlockedCompareExchangePointer( - reinterpret_cast<volatile PVOID*>(ptr), - reinterpret_cast<PVOID>(new_value), reinterpret_cast<PVOID>(old_value)); - return reinterpret_cast<Atomic64>(result); -} - -inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, - Atomic64 new_value) { - PVOID result = InterlockedExchangePointer( - reinterpret_cast<volatile PVOID*>(ptr), - reinterpret_cast<PVOID>(new_value)); - return reinterpret_cast<Atomic64>(result); -} - -inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, - Atomic64 increment) { - return InterlockedExchangeAdd64( - reinterpret_cast<volatile LONGLONG*>(ptr), - static_cast<LONGLONG>(increment)) + increment; -} - -inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, - Atomic64 increment) { - return Barrier_AtomicIncrement(ptr, increment); -} - -inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { - *ptr = value; -} - -inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { - NoBarrier_AtomicExchange(ptr, value); - // acts as a barrier in this implementation -} - -inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { - *ptr = value; // works w/o barrier for current Intel chips as of June 2005 - - // When new chips come out, check: - // IA-32 Intel Architecture Software Developer's Manual, Volume 3: - // System Programming Guide, Chatper 7: Multiple-processor management, - // Section 7.2, Memory Ordering. - // Last seen at: - // http://developer.intel.com/design/pentium4/manuals/index_new.htm -} - -inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { - return *ptr; -} - -inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { - Atomic64 value = *ptr; - return value; -} - -inline Atomic64 Release_Load(volatile const Atomic64* ptr) { - MemoryBarrier(); - return *ptr; -} - -inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, - Atomic64 old_value, - Atomic64 new_value) { - return NoBarrier_CompareAndSwap(ptr, old_value, new_value); -} - -inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, - Atomic64 old_value, - Atomic64 new_value) { - return NoBarrier_CompareAndSwap(ptr, old_value, new_value); -} - - -#endif // defined(_WIN64) - -} // namespace subtle -} // namespace base - -#endif // BASE_ATOMICOPS_INTERNALS_X86_MSVC_H_ diff --git a/security/sandbox/chromium/base/base_export.h b/security/sandbox/chromium/base/base_export.h deleted file mode 100644 index cf7ebd781..000000000 --- a/security/sandbox/chromium/base/base_export.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_BASE_EXPORT_H_ -#define BASE_BASE_EXPORT_H_ - -#if defined(COMPONENT_BUILD) -#if defined(WIN32) - -#if defined(BASE_IMPLEMENTATION) -#define BASE_EXPORT __declspec(dllexport) -#else -#define BASE_EXPORT __declspec(dllimport) -#endif // defined(BASE_IMPLEMENTATION) - -#else // defined(WIN32) -#if defined(BASE_IMPLEMENTATION) -#define BASE_EXPORT __attribute__((visibility("default"))) -#else -#define BASE_EXPORT -#endif // defined(BASE_IMPLEMENTATION) -#endif - -#else // defined(COMPONENT_BUILD) -#define BASE_EXPORT -#endif - -#endif // BASE_BASE_EXPORT_H_ diff --git a/security/sandbox/chromium/base/base_paths.h b/security/sandbox/chromium/base/base_paths.h deleted file mode 100644 index 26b2fd4c9..000000000 --- a/security/sandbox/chromium/base/base_paths.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_BASE_PATHS_H_ -#define BASE_BASE_PATHS_H_ - -// This file declares path keys for the base module. These can be used with -// the PathService to access various special directories and files. - -#include "build/build_config.h" - -#if defined(OS_WIN) -#include "base/base_paths_win.h" -#elif defined(OS_MACOSX) -#include "base/base_paths_mac.h" -#elif defined(OS_ANDROID) -#include "base/base_paths_android.h" -#endif - -#if defined(OS_POSIX) -#include "base/base_paths_posix.h" -#endif - -namespace base { - -enum BasePathKey { - PATH_START = 0, - - DIR_CURRENT, // Current directory. - DIR_EXE, // Directory containing FILE_EXE. - DIR_MODULE, // Directory containing FILE_MODULE. - DIR_TEMP, // Temporary directory. - DIR_HOME, // User's root home directory. On Windows this will look - // like "C:\Users\you" (or on XP - // "C:\Document and Settings\you") which isn't necessarily - // a great place to put files. - FILE_EXE, // Path and filename of the current executable. - FILE_MODULE, // Path and filename of the module containing the code for - // the PathService (which could differ from FILE_EXE if the - // PathService were compiled into a shared object, for - // example). - DIR_SOURCE_ROOT, // Returns the root of the source tree. This key is useful - // for tests that need to locate various resources. It - // should not be used outside of test code. - DIR_USER_DESKTOP, // The current user's Desktop. - - DIR_TEST_DATA, // Used only for testing. - - PATH_END -}; - -} // namespace base - -#endif // BASE_BASE_PATHS_H_ diff --git a/security/sandbox/chromium/base/base_paths_win.h b/security/sandbox/chromium/base/base_paths_win.h deleted file mode 100644 index d9dbc39f9..000000000 --- a/security/sandbox/chromium/base/base_paths_win.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_BASE_PATHS_WIN_H_ -#define BASE_BASE_PATHS_WIN_H_ - -// This file declares windows-specific path keys for the base module. -// These can be used with the PathService to access various special -// directories and files. - -namespace base { - -enum { - PATH_WIN_START = 100, - - DIR_WINDOWS, // Windows directory, usually "c:\windows" - DIR_SYSTEM, // Usually c:\windows\system32" - // 32-bit 32-bit on 64-bit 64-bit on 64-bit - // DIR_PROGRAM_FILES 1 2 1 - // DIR_PROGRAM_FILESX86 1 2 2 - // DIR_PROGRAM_FILES6432 1 1 1 - // 1 - C:\Program Files 2 - C:\Program Files (x86) - DIR_PROGRAM_FILES, // See table above. - DIR_PROGRAM_FILESX86, // See table above. - DIR_PROGRAM_FILES6432, // See table above. - - DIR_IE_INTERNET_CACHE, // Temporary Internet Files directory. - DIR_COMMON_START_MENU, // Usually "C:\Documents and Settings\All Users\ - // Start Menu\Programs" - DIR_START_MENU, // Usually "C:\Documents and Settings\<user>\ - // Start Menu\Programs" - DIR_APP_DATA, // Application Data directory under the user profile. - DIR_LOCAL_APP_DATA, // "Local Settings\Application Data" directory under - // the user profile. - DIR_COMMON_APP_DATA, // W2K, XP, W2K3: "C:\Documents and Settings\ - // All Users\Application Data". - // Vista, W2K8 and above: "C:\ProgramData". - DIR_APP_SHORTCUTS, // Where tiles on the start screen are stored, only - // for Windows 8. Maps to "Local\AppData\Microsoft\ - // Windows\Application Shortcuts\". - DIR_COMMON_DESKTOP, // Directory for the common desktop (visible - // on all user's Desktop). - DIR_USER_QUICK_LAUNCH, // Directory for the quick launch shortcuts. - DIR_TASKBAR_PINS, // Directory for the shortcuts pinned to taskbar - // (Win7-8) via base::win::PinShortcutToTaskbar(). - DIR_WINDOWS_FONTS, // Usually C:\Windows\Fonts. - - PATH_WIN_END -}; - -} // namespace base - -#endif // BASE_BASE_PATHS_WIN_H_ diff --git a/security/sandbox/chromium/base/base_switches.cc b/security/sandbox/chromium/base/base_switches.cc deleted file mode 100644 index 02b222988..000000000 --- a/security/sandbox/chromium/base/base_switches.cc +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/base_switches.h" -#include "build/build_config.h" - -namespace switches { - -// Disables the crash reporting. -const char kDisableBreakpad[] = "disable-breakpad"; - -// Indicates that crash reporting should be enabled. On platforms where helper -// processes cannot access to files needed to make this decision, this flag is -// generated internally. -const char kEnableCrashReporter[] = "enable-crash-reporter"; - -// Makes memory allocators keep track of their allocations and context, so a -// detailed breakdown of memory usage can be presented in chrome://tracing when -// the memory-infra category is enabled. -const char kEnableHeapProfiling[] = "enable-heap-profiling"; - -// Generates full memory crash dump. -const char kFullMemoryCrashReport[] = "full-memory-crash-report"; - -// Force low-end device mode when set. -const char kEnableLowEndDeviceMode[] = "enable-low-end-device-mode"; - -// Force disabling of low-end device mode when set. -const char kDisableLowEndDeviceMode[] = "disable-low-end-device-mode"; - -// This option can be used to force field trials when testing changes locally. -// The argument is a list of name and value pairs, separated by slashes. If a -// trial name is prefixed with an asterisk, that trial will start activated. -// For example, the following argument defines two trials, with the second one -// activated: "GoogleNow/Enable/*MaterialDesignNTP/Default/" This option can -// also be used by the browser process to send the list of trials to a -// non-browser process, using the same format. See -// FieldTrialList::CreateTrialsFromString() in field_trial.h for details. -const char kForceFieldTrials[] = "force-fieldtrials"; - -// Suppresses all error dialogs when present. -const char kNoErrorDialogs[] = "noerrdialogs"; - -// When running certain tests that spawn child processes, this switch indicates -// to the test framework that the current process is a child process. -const char kTestChildProcess[] = "test-child-process"; - -// Gives the default maximal active V-logging level; 0 is the default. -// Normally positive values are used for V-logging levels. -const char kV[] = "v"; - -// Gives the per-module maximal V-logging levels to override the value -// given by --v. E.g. "my_module=2,foo*=3" would change the logging -// level for all code in source files "my_module.*" and "foo*.*" -// ("-inl" suffixes are also disregarded for this matching). -// -// Any pattern containing a forward or backward slash will be tested -// against the whole pathname and not just the module. E.g., -// "*/foo/bar/*=2" would change the logging level for all code in -// source files under a "foo/bar" directory. -const char kVModule[] = "vmodule"; - -// Will wait for 60 seconds for a debugger to come to attach to the process. -const char kWaitForDebugger[] = "wait-for-debugger"; - -// Sends trace events from these categories to a file. -// --trace-to-file on its own sends to default categories. -const char kTraceToFile[] = "trace-to-file"; - -// Specifies the file name for --trace-to-file. If unspecified, it will -// go to a default file name. -const char kTraceToFileName[] = "trace-to-file-name"; - -// Configure whether chrome://profiler will contain timing information. This -// option is enabled by default. A value of "0" will disable profiler timing, -// while all other values will enable it. -const char kProfilerTiming[] = "profiler-timing"; -// Value of the --profiler-timing flag that will disable timing information for -// chrome://profiler. -const char kProfilerTimingDisabledValue[] = "0"; - -#if defined(OS_WIN) -// Disables the USB keyboard detection for blocking the OSK on Win8+. -const char kDisableUsbKeyboardDetect[] = "disable-usb-keyboard-detect"; -#endif - -#if defined(OS_POSIX) -// Used for turning on Breakpad crash reporting in a debug environment where -// crash reporting is typically compiled but disabled. -const char kEnableCrashReporterForTesting[] = - "enable-crash-reporter-for-testing"; -#endif - -} // namespace switches diff --git a/security/sandbox/chromium/base/base_switches.h b/security/sandbox/chromium/base/base_switches.h deleted file mode 100644 index c97a629d9..000000000 --- a/security/sandbox/chromium/base/base_switches.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Defines all the "base" command-line switches. - -#ifndef BASE_BASE_SWITCHES_H_ -#define BASE_BASE_SWITCHES_H_ - -#include "build/build_config.h" - -namespace switches { - -extern const char kDisableBreakpad[]; -extern const char kDisableLowEndDeviceMode[]; -extern const char kEnableCrashReporter[]; -extern const char kEnableHeapProfiling[]; -extern const char kEnableLowEndDeviceMode[]; -extern const char kForceFieldTrials[]; -extern const char kFullMemoryCrashReport[]; -extern const char kNoErrorDialogs[]; -extern const char kProfilerTiming[]; -extern const char kProfilerTimingDisabledValue[]; -extern const char kTestChildProcess[]; -extern const char kTraceToFile[]; -extern const char kTraceToFileName[]; -extern const char kV[]; -extern const char kVModule[]; -extern const char kWaitForDebugger[]; - -#if defined(OS_WIN) -extern const char kDisableUsbKeyboardDetect[]; -#endif - -#if defined(OS_POSIX) -extern const char kEnableCrashReporterForTesting[]; -#endif - -} // namespace switches - -#endif // BASE_BASE_SWITCHES_H_ diff --git a/security/sandbox/chromium/base/bind.h b/security/sandbox/chromium/base/bind.h deleted file mode 100644 index 770e45706..000000000 --- a/security/sandbox/chromium/base/bind.h +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_BIND_H_ -#define BASE_BIND_H_ - -#include "base/bind_internal.h" -#include "base/callback_internal.h" - -// ----------------------------------------------------------------------------- -// Usage documentation -// ----------------------------------------------------------------------------- -// -// See base/callback.h for documentation. -// -// -// ----------------------------------------------------------------------------- -// Implementation notes -// ----------------------------------------------------------------------------- -// -// If you're reading the implementation, before proceeding further, you should -// read the top comment of base/bind_internal.h for a definition of common -// terms and concepts. -// -// RETURN TYPES -// -// Though Bind()'s result is meant to be stored in a Callback<> type, it -// cannot actually return the exact type without requiring a large amount -// of extra template specializations. The problem is that in order to -// discern the correct specialization of Callback<>, Bind would need to -// unwrap the function signature to determine the signature's arity, and -// whether or not it is a method. -// -// Each unique combination of (arity, function_type, num_prebound) where -// function_type is one of {function, method, const_method} would require -// one specialization. We eventually have to do a similar number of -// specializations anyways in the implementation (see the Invoker<>, -// classes). However, it is avoidable in Bind if we return the result -// via an indirection like we do below. -// -// TODO(ajwong): We might be able to avoid this now, but need to test. -// -// It is possible to move most of the static_assert into BindState<>, but it -// feels a little nicer to have the asserts here so people do not need to crack -// open bind_internal.h. On the other hand, it makes Bind() harder to read. - -namespace base { - -template <typename Functor, typename... Args> -base::Callback< - typename internal::BindState< - typename internal::FunctorTraits<Functor>::RunnableType, - typename internal::FunctorTraits<Functor>::RunType, - typename internal::CallbackParamTraits<Args>::StorageType...> - ::UnboundRunType> -Bind(Functor functor, const Args&... args) { - // Type aliases for how to store and run the functor. - using RunnableType = typename internal::FunctorTraits<Functor>::RunnableType; - using RunType = typename internal::FunctorTraits<Functor>::RunType; - - // Use RunnableType::RunType instead of RunType above because our - // checks below for bound references need to know what the actual - // functor is going to interpret the argument as. - using BoundRunType = typename RunnableType::RunType; - - using BoundArgs = - internal::TakeTypeListItem<sizeof...(Args), - internal::ExtractArgs<BoundRunType>>; - - // Do not allow binding a non-const reference parameter. Non-const reference - // parameters are disallowed by the Google style guide. Also, binding a - // non-const reference parameter can make for subtle bugs because the - // invoked function will receive a reference to the stored copy of the - // argument and not the original. - static_assert(!internal::HasNonConstReferenceItem<BoundArgs>::value, - "do not bind functions with nonconst ref"); - - const bool is_method = internal::HasIsMethodTag<RunnableType>::value; - - // For methods, we need to be careful for parameter 1. We do not require - // a scoped_refptr because BindState<> itself takes care of AddRef() for - // methods. We also disallow binding of an array as the method's target - // object. - static_assert(!internal::BindsArrayToFirstArg<is_method, Args...>::value, - "first bound argument to method cannot be array"); - static_assert( - !internal::HasRefCountedParamAsRawPtr<is_method, Args...>::value, - "a parameter is a refcounted type and needs scoped_refptr"); - - using BindState = internal::BindState< - RunnableType, RunType, - typename internal::CallbackParamTraits<Args>::StorageType...>; - - return Callback<typename BindState::UnboundRunType>( - new BindState(internal::MakeRunnable(functor), args...)); -} - -} // namespace base - -#endif // BASE_BIND_H_ diff --git a/security/sandbox/chromium/base/bind_helpers.h b/security/sandbox/chromium/base/bind_helpers.h deleted file mode 100644 index 2add755b4..000000000 --- a/security/sandbox/chromium/base/bind_helpers.h +++ /dev/null @@ -1,658 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This defines a set of argument wrappers and related factory methods that -// can be used specify the refcounting and reference semantics of arguments -// that are bound by the Bind() function in base/bind.h. -// -// It also defines a set of simple functions and utilities that people want -// when using Callback<> and Bind(). -// -// -// ARGUMENT BINDING WRAPPERS -// -// The wrapper functions are base::Unretained(), base::Owned(), base::Passed(), -// base::ConstRef(), and base::IgnoreResult(). -// -// Unretained() allows Bind() to bind a non-refcounted class, and to disable -// refcounting on arguments that are refcounted objects. -// -// Owned() transfers ownership of an object to the Callback resulting from -// bind; the object will be deleted when the Callback is deleted. -// -// Passed() is for transferring movable-but-not-copyable types (eg. scoped_ptr) -// through a Callback. Logically, this signifies a destructive transfer of -// the state of the argument into the target function. Invoking -// Callback::Run() twice on a Callback that was created with a Passed() -// argument will CHECK() because the first invocation would have already -// transferred ownership to the target function. -// -// ConstRef() allows binding a constant reference to an argument rather -// than a copy. -// -// IgnoreResult() is used to adapt a function or Callback with a return type to -// one with a void return. This is most useful if you have a function with, -// say, a pesky ignorable bool return that you want to use with PostTask or -// something else that expect a Callback with a void return. -// -// EXAMPLE OF Unretained(): -// -// class Foo { -// public: -// void func() { cout << "Foo:f" << endl; } -// }; -// -// // In some function somewhere. -// Foo foo; -// Closure foo_callback = -// Bind(&Foo::func, Unretained(&foo)); -// foo_callback.Run(); // Prints "Foo:f". -// -// Without the Unretained() wrapper on |&foo|, the above call would fail -// to compile because Foo does not support the AddRef() and Release() methods. -// -// -// EXAMPLE OF Owned(): -// -// void foo(int* arg) { cout << *arg << endl } -// -// int* pn = new int(1); -// Closure foo_callback = Bind(&foo, Owned(pn)); -// -// foo_callback.Run(); // Prints "1" -// foo_callback.Run(); // Prints "1" -// *n = 2; -// foo_callback.Run(); // Prints "2" -// -// foo_callback.Reset(); // |pn| is deleted. Also will happen when -// // |foo_callback| goes out of scope. -// -// Without Owned(), someone would have to know to delete |pn| when the last -// reference to the Callback is deleted. -// -// -// EXAMPLE OF ConstRef(): -// -// void foo(int arg) { cout << arg << endl } -// -// int n = 1; -// Closure no_ref = Bind(&foo, n); -// Closure has_ref = Bind(&foo, ConstRef(n)); -// -// no_ref.Run(); // Prints "1" -// has_ref.Run(); // Prints "1" -// -// n = 2; -// no_ref.Run(); // Prints "1" -// has_ref.Run(); // Prints "2" -// -// Note that because ConstRef() takes a reference on |n|, |n| must outlive all -// its bound callbacks. -// -// -// EXAMPLE OF IgnoreResult(): -// -// int DoSomething(int arg) { cout << arg << endl; } -// -// // Assign to a Callback with a void return type. -// Callback<void(int)> cb = Bind(IgnoreResult(&DoSomething)); -// cb->Run(1); // Prints "1". -// -// // Prints "1" on |ml|. -// ml->PostTask(FROM_HERE, Bind(IgnoreResult(&DoSomething), 1); -// -// -// EXAMPLE OF Passed(): -// -// void TakesOwnership(scoped_ptr<Foo> arg) { } -// scoped_ptr<Foo> CreateFoo() { return scoped_ptr<Foo>(new Foo()); } -// -// scoped_ptr<Foo> f(new Foo()); -// -// // |cb| is given ownership of Foo(). |f| is now NULL. -// // You can use std::move(f) in place of &f, but it's more verbose. -// Closure cb = Bind(&TakesOwnership, Passed(&f)); -// -// // Run was never called so |cb| still owns Foo() and deletes -// // it on Reset(). -// cb.Reset(); -// -// // |cb| is given a new Foo created by CreateFoo(). -// cb = Bind(&TakesOwnership, Passed(CreateFoo())); -// -// // |arg| in TakesOwnership() is given ownership of Foo(). |cb| -// // no longer owns Foo() and, if reset, would not delete Foo(). -// cb.Run(); // Foo() is now transferred to |arg| and deleted. -// cb.Run(); // This CHECK()s since Foo() already been used once. -// -// Passed() is particularly useful with PostTask() when you are transferring -// ownership of an argument into a task, but don't necessarily know if the -// task will always be executed. This can happen if the task is cancellable -// or if it is posted to a TaskRunner. -// -// -// SIMPLE FUNCTIONS AND UTILITIES. -// -// DoNothing() - Useful for creating a Closure that does nothing when called. -// DeletePointer<T>() - Useful for creating a Closure that will delete a -// pointer when invoked. Only use this when necessary. -// In most cases MessageLoop::DeleteSoon() is a better -// fit. - -#ifndef BASE_BIND_HELPERS_H_ -#define BASE_BIND_HELPERS_H_ - -#include <stddef.h> - -#include <type_traits> -#include <utility> - -#include "base/callback.h" -#include "base/memory/weak_ptr.h" -#include "base/template_util.h" -#include "build/build_config.h" - -namespace base { -namespace internal { - -// Use the Substitution Failure Is Not An Error (SFINAE) trick to inspect T -// for the existence of AddRef() and Release() functions of the correct -// signature. -// -// http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error -// http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence -// http://stackoverflow.com/questions/4358584/sfinae-approach-comparison -// http://stackoverflow.com/questions/1966362/sfinae-to-check-for-inherited-member-functions -// -// The last link in particular show the method used below. -// -// For SFINAE to work with inherited methods, we need to pull some extra tricks -// with multiple inheritance. In the more standard formulation, the overloads -// of Check would be: -// -// template <typename C> -// Yes NotTheCheckWeWant(Helper<&C::TargetFunc>*); -// -// template <typename C> -// No NotTheCheckWeWant(...); -// -// static const bool value = sizeof(NotTheCheckWeWant<T>(0)) == sizeof(Yes); -// -// The problem here is that template resolution will not match -// C::TargetFunc if TargetFunc does not exist directly in C. That is, if -// TargetFunc in inherited from an ancestor, &C::TargetFunc will not match, -// |value| will be false. This formulation only checks for whether or -// not TargetFunc exist directly in the class being introspected. -// -// To get around this, we play a dirty trick with multiple inheritance. -// First, We create a class BaseMixin that declares each function that we -// want to probe for. Then we create a class Base that inherits from both T -// (the class we wish to probe) and BaseMixin. Note that the function -// signature in BaseMixin does not need to match the signature of the function -// we are probing for; thus it's easiest to just use void(). -// -// Now, if TargetFunc exists somewhere in T, then &Base::TargetFunc has an -// ambiguous resolution between BaseMixin and T. This lets us write the -// following: -// -// template <typename C> -// No GoodCheck(Helper<&C::TargetFunc>*); -// -// template <typename C> -// Yes GoodCheck(...); -// -// static const bool value = sizeof(GoodCheck<Base>(0)) == sizeof(Yes); -// -// Notice here that the variadic version of GoodCheck() returns Yes here -// instead of No like the previous one. Also notice that we calculate |value| -// by specializing GoodCheck() on Base instead of T. -// -// We've reversed the roles of the variadic, and Helper overloads. -// GoodCheck(Helper<&C::TargetFunc>*), when C = Base, fails to be a valid -// substitution if T::TargetFunc exists. Thus GoodCheck<Base>(0) will resolve -// to the variadic version if T has TargetFunc. If T::TargetFunc does not -// exist, then &C::TargetFunc is not ambiguous, and the overload resolution -// will prefer GoodCheck(Helper<&C::TargetFunc>*). -// -// This method of SFINAE will correctly probe for inherited names, but it cannot -// typecheck those names. It's still a good enough sanity check though. -// -// Works on gcc-4.2, gcc-4.4, and Visual Studio 2008. -// -// TODO(ajwong): Move to ref_counted.h or template_util.h when we've vetted -// this works well. -// -// TODO(ajwong): Make this check for Release() as well. -// See http://crbug.com/82038. -template <typename T> -class SupportsAddRefAndRelease { - using Yes = char[1]; - using No = char[2]; - - struct BaseMixin { - void AddRef(); - }; - -// MSVC warns when you try to use Base if T has a private destructor, the -// common pattern for refcounted types. It does this even though no attempt to -// instantiate Base is made. We disable the warning for this definition. -#if defined(OS_WIN) -#pragma warning(push) -#pragma warning(disable:4624) -#endif - struct Base : public T, public BaseMixin { - }; -#if defined(OS_WIN) -#pragma warning(pop) -#endif - - template <void(BaseMixin::*)()> struct Helper {}; - - template <typename C> - static No& Check(Helper<&C::AddRef>*); - - template <typename > - static Yes& Check(...); - - public: - enum { value = sizeof(Check<Base>(0)) == sizeof(Yes) }; -}; - -// Helpers to assert that arguments of a recounted type are bound with a -// scoped_refptr. -template <bool IsClasstype, typename T> -struct UnsafeBindtoRefCountedArgHelper : false_type { -}; - -template <typename T> -struct UnsafeBindtoRefCountedArgHelper<true, T> - : integral_constant<bool, SupportsAddRefAndRelease<T>::value> { -}; - -template <typename T> -struct UnsafeBindtoRefCountedArg : false_type { -}; - -template <typename T> -struct UnsafeBindtoRefCountedArg<T*> - : UnsafeBindtoRefCountedArgHelper<is_class<T>::value, T> { -}; - -template <typename T> -class HasIsMethodTag { - using Yes = char[1]; - using No = char[2]; - - template <typename U> - static Yes& Check(typename U::IsMethod*); - - template <typename U> - static No& Check(...); - - public: - enum { value = sizeof(Check<T>(0)) == sizeof(Yes) }; -}; - -template <typename T> -class UnretainedWrapper { - public: - explicit UnretainedWrapper(T* o) : ptr_(o) {} - T* get() const { return ptr_; } - private: - T* ptr_; -}; - -template <typename T> -class ConstRefWrapper { - public: - explicit ConstRefWrapper(const T& o) : ptr_(&o) {} - const T& get() const { return *ptr_; } - private: - const T* ptr_; -}; - -template <typename T> -struct IgnoreResultHelper { - explicit IgnoreResultHelper(T functor) : functor_(functor) {} - - T functor_; -}; - -template <typename T> -struct IgnoreResultHelper<Callback<T> > { - explicit IgnoreResultHelper(const Callback<T>& functor) : functor_(functor) {} - - const Callback<T>& functor_; -}; - -// An alternate implementation is to avoid the destructive copy, and instead -// specialize ParamTraits<> for OwnedWrapper<> to change the StorageType to -// a class that is essentially a scoped_ptr<>. -// -// The current implementation has the benefit though of leaving ParamTraits<> -// fully in callback_internal.h as well as avoiding type conversions during -// storage. -template <typename T> -class OwnedWrapper { - public: - explicit OwnedWrapper(T* o) : ptr_(o) {} - ~OwnedWrapper() { delete ptr_; } - T* get() const { return ptr_; } - OwnedWrapper(const OwnedWrapper& other) { - ptr_ = other.ptr_; - other.ptr_ = NULL; - } - - private: - mutable T* ptr_; -}; - -// PassedWrapper is a copyable adapter for a scoper that ignores const. -// -// It is needed to get around the fact that Bind() takes a const reference to -// all its arguments. Because Bind() takes a const reference to avoid -// unnecessary copies, it is incompatible with movable-but-not-copyable -// types; doing a destructive "move" of the type into Bind() would violate -// the const correctness. -// -// This conundrum cannot be solved without either C++11 rvalue references or -// a O(2^n) blowup of Bind() templates to handle each combination of regular -// types and movable-but-not-copyable types. Thus we introduce a wrapper type -// that is copyable to transmit the correct type information down into -// BindState<>. Ignoring const in this type makes sense because it is only -// created when we are explicitly trying to do a destructive move. -// -// Two notes: -// 1) PassedWrapper supports any type that has a move constructor, however -// the type will need to be specifically whitelisted in order for it to be -// bound to a Callback. We guard this explicitly at the call of Passed() -// to make for clear errors. Things not given to Passed() will be forwarded -// and stored by value which will not work for general move-only types. -// 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL" -// scoper to a Callback and allow the Callback to execute once. -template <typename T> -class PassedWrapper { - public: - explicit PassedWrapper(T&& scoper) - : is_valid_(true), scoper_(std::move(scoper)) {} - PassedWrapper(const PassedWrapper& other) - : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {} - T Pass() const { - CHECK(is_valid_); - is_valid_ = false; - return std::move(scoper_); - } - - private: - mutable bool is_valid_; - mutable T scoper_; -}; - -// Unwrap the stored parameters for the wrappers above. -template <typename T> -struct UnwrapTraits { - using ForwardType = const T&; - static ForwardType Unwrap(const T& o) { return o; } -}; - -template <typename T> -struct UnwrapTraits<UnretainedWrapper<T> > { - using ForwardType = T*; - static ForwardType Unwrap(UnretainedWrapper<T> unretained) { - return unretained.get(); - } -}; - -template <typename T> -struct UnwrapTraits<ConstRefWrapper<T> > { - using ForwardType = const T&; - static ForwardType Unwrap(ConstRefWrapper<T> const_ref) { - return const_ref.get(); - } -}; - -template <typename T> -struct UnwrapTraits<scoped_refptr<T> > { - using ForwardType = T*; - static ForwardType Unwrap(const scoped_refptr<T>& o) { return o.get(); } -}; - -template <typename T> -struct UnwrapTraits<WeakPtr<T> > { - using ForwardType = const WeakPtr<T>&; - static ForwardType Unwrap(const WeakPtr<T>& o) { return o; } -}; - -template <typename T> -struct UnwrapTraits<OwnedWrapper<T> > { - using ForwardType = T*; - static ForwardType Unwrap(const OwnedWrapper<T>& o) { - return o.get(); - } -}; - -template <typename T> -struct UnwrapTraits<PassedWrapper<T> > { - using ForwardType = T; - static T Unwrap(PassedWrapper<T>& o) { - return o.Pass(); - } -}; - -// Utility for handling different refcounting semantics in the Bind() -// function. -template <bool is_method, typename... T> -struct MaybeScopedRefPtr; - -template <bool is_method> -struct MaybeScopedRefPtr<is_method> { - MaybeScopedRefPtr() {} -}; - -template <typename T, typename... Rest> -struct MaybeScopedRefPtr<false, T, Rest...> { - MaybeScopedRefPtr(const T&, const Rest&...) {} -}; - -template <typename T, size_t n, typename... Rest> -struct MaybeScopedRefPtr<false, T[n], Rest...> { - MaybeScopedRefPtr(const T*, const Rest&...) {} -}; - -template <typename T, typename... Rest> -struct MaybeScopedRefPtr<true, T, Rest...> { - MaybeScopedRefPtr(const T& o, const Rest&...) {} -}; - -template <typename T, typename... Rest> -struct MaybeScopedRefPtr<true, T*, Rest...> { - MaybeScopedRefPtr(T* o, const Rest&...) : ref_(o) {} - scoped_refptr<T> ref_; -}; - -// No need to additionally AddRef() and Release() since we are storing a -// scoped_refptr<> inside the storage object already. -template <typename T, typename... Rest> -struct MaybeScopedRefPtr<true, scoped_refptr<T>, Rest...> { - MaybeScopedRefPtr(const scoped_refptr<T>&, const Rest&...) {} -}; - -template <typename T, typename... Rest> -struct MaybeScopedRefPtr<true, const T*, Rest...> { - MaybeScopedRefPtr(const T* o, const Rest&...) : ref_(o) {} - scoped_refptr<const T> ref_; -}; - -// IsWeakMethod is a helper that determine if we are binding a WeakPtr<> to a -// method. It is used internally by Bind() to select the correct -// InvokeHelper that will no-op itself in the event the WeakPtr<> for -// the target object is invalidated. -// -// The first argument should be the type of the object that will be received by -// the method. -template <bool IsMethod, typename... Args> -struct IsWeakMethod : public false_type {}; - -template <typename T, typename... Args> -struct IsWeakMethod<true, WeakPtr<T>, Args...> : public true_type {}; - -template <typename T, typename... Args> -struct IsWeakMethod<true, ConstRefWrapper<WeakPtr<T>>, Args...> - : public true_type {}; - - -// Packs a list of types to hold them in a single type. -template <typename... Types> -struct TypeList {}; - -// Used for DropTypeListItem implementation. -template <size_t n, typename List> -struct DropTypeListItemImpl; - -// Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. -template <size_t n, typename T, typename... List> -struct DropTypeListItemImpl<n, TypeList<T, List...>> - : DropTypeListItemImpl<n - 1, TypeList<List...>> {}; - -template <typename T, typename... List> -struct DropTypeListItemImpl<0, TypeList<T, List...>> { - using Type = TypeList<T, List...>; -}; - -template <> -struct DropTypeListItemImpl<0, TypeList<>> { - using Type = TypeList<>; -}; - -// A type-level function that drops |n| list item from given TypeList. -template <size_t n, typename List> -using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type; - -// Used for TakeTypeListItem implementation. -template <size_t n, typename List, typename... Accum> -struct TakeTypeListItemImpl; - -// Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure. -template <size_t n, typename T, typename... List, typename... Accum> -struct TakeTypeListItemImpl<n, TypeList<T, List...>, Accum...> - : TakeTypeListItemImpl<n - 1, TypeList<List...>, Accum..., T> {}; - -template <typename T, typename... List, typename... Accum> -struct TakeTypeListItemImpl<0, TypeList<T, List...>, Accum...> { - using Type = TypeList<Accum...>; -}; - -template <typename... Accum> -struct TakeTypeListItemImpl<0, TypeList<>, Accum...> { - using Type = TypeList<Accum...>; -}; - -// A type-level function that takes first |n| list item from given TypeList. -// E.g. TakeTypeListItem<3, TypeList<A, B, C, D>> is evaluated to -// TypeList<A, B, C>. -template <size_t n, typename List> -using TakeTypeListItem = typename TakeTypeListItemImpl<n, List>::Type; - -// Used for ConcatTypeLists implementation. -template <typename List1, typename List2> -struct ConcatTypeListsImpl; - -template <typename... Types1, typename... Types2> -struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> { - using Type = TypeList<Types1..., Types2...>; -}; - -// A type-level function that concats two TypeLists. -template <typename List1, typename List2> -using ConcatTypeLists = typename ConcatTypeListsImpl<List1, List2>::Type; - -// Used for MakeFunctionType implementation. -template <typename R, typename ArgList> -struct MakeFunctionTypeImpl; - -template <typename R, typename... Args> -struct MakeFunctionTypeImpl<R, TypeList<Args...>> { - // MSVC 2013 doesn't support Type Alias of function types. - // Revisit this after we update it to newer version. - typedef R Type(Args...); -}; - -// A type-level function that constructs a function type that has |R| as its -// return type and has TypeLists items as its arguments. -template <typename R, typename ArgList> -using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type; - -// Used for ExtractArgs. -template <typename Signature> -struct ExtractArgsImpl; - -template <typename R, typename... Args> -struct ExtractArgsImpl<R(Args...)> { - using Type = TypeList<Args...>; -}; - -// A type-level function that extracts function arguments into a TypeList. -// E.g. ExtractArgs<R(A, B, C)> is evaluated to TypeList<A, B, C>. -template <typename Signature> -using ExtractArgs = typename ExtractArgsImpl<Signature>::Type; - -} // namespace internal - -template <typename T> -static inline internal::UnretainedWrapper<T> Unretained(T* o) { - return internal::UnretainedWrapper<T>(o); -} - -template <typename T> -static inline internal::ConstRefWrapper<T> ConstRef(const T& o) { - return internal::ConstRefWrapper<T>(o); -} - -template <typename T> -static inline internal::OwnedWrapper<T> Owned(T* o) { - return internal::OwnedWrapper<T>(o); -} - -// We offer 2 syntaxes for calling Passed(). The first takes an rvalue and -// is best suited for use with the return value of a function or other temporary -// rvalues. The second takes a pointer to the scoper and is just syntactic sugar -// to avoid having to write Passed(std::move(scoper)). -// -// Both versions of Passed() prevent T from being an lvalue reference. The first -// via use of enable_if, and the second takes a T* which will not bind to T&. -template <typename T, - typename std::enable_if<internal::IsMoveOnlyType<T>::value && - !std::is_lvalue_reference<T>::value>::type* = - nullptr> -static inline internal::PassedWrapper<T> Passed(T&& scoper) { - return internal::PassedWrapper<T>(std::move(scoper)); -} -template <typename T, - typename std::enable_if<internal::IsMoveOnlyType<T>::value>::type* = - nullptr> -static inline internal::PassedWrapper<T> Passed(T* scoper) { - return internal::PassedWrapper<T>(std::move(*scoper)); -} - -template <typename T> -static inline internal::IgnoreResultHelper<T> IgnoreResult(T data) { - return internal::IgnoreResultHelper<T>(data); -} - -template <typename T> -static inline internal::IgnoreResultHelper<Callback<T> > -IgnoreResult(const Callback<T>& data) { - return internal::IgnoreResultHelper<Callback<T> >(data); -} - -BASE_EXPORT void DoNothing(); - -template<typename T> -void DeletePointer(T* obj) { - delete obj; -} - -} // namespace base - -#endif // BASE_BIND_HELPERS_H_ diff --git a/security/sandbox/chromium/base/bind_internal.h b/security/sandbox/chromium/base/bind_internal.h deleted file mode 100644 index ac7cd0098..000000000 --- a/security/sandbox/chromium/base/bind_internal.h +++ /dev/null @@ -1,425 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_BIND_INTERNAL_H_ -#define BASE_BIND_INTERNAL_H_ - -#include <stddef.h> - -#include <type_traits> - -#include "base/bind_helpers.h" -#include "base/callback_internal.h" -#include "base/memory/raw_scoped_refptr_mismatch_checker.h" -#include "base/memory/weak_ptr.h" -#include "base/template_util.h" -#include "base/tuple.h" -#include "build/build_config.h" - -#if defined(OS_WIN) -#include "base/bind_internal_win.h" -#endif - -namespace base { -namespace internal { - -// See base/callback.h for user documentation. -// -// -// CONCEPTS: -// Runnable -- A type (really a type class) that has a single Run() method -// and a RunType typedef that corresponds to the type of Run(). -// A Runnable can declare that it should treated like a method -// call by including a typedef named IsMethod. The value of -// this typedef is NOT inspected, only the existence. When a -// Runnable declares itself a method, Bind() will enforce special -// refcounting + WeakPtr handling semantics for the first -// parameter which is expected to be an object. -// Functor -- A copyable type representing something that should be called. -// All function pointers, Callback<>, and Runnables are functors -// even if the invocation syntax differs. -// RunType -- A function type (as opposed to function _pointer_ type) for -// a Run() function. Usually just a convenience typedef. -// (Bound)Args -- A set of types that stores the arguments. -// -// Types: -// RunnableAdapter<> -- Wraps the various "function" pointer types into an -// object that adheres to the Runnable interface. -// ForceVoidReturn<> -- Helper class for translating function signatures to -// equivalent forms with a "void" return type. -// FunctorTraits<> -- Type traits used determine the correct RunType and -// RunnableType for a Functor. This is where function -// signature adapters are applied. -// MakeRunnable<> -- Takes a Functor and returns an object in the Runnable -// type class that represents the underlying Functor. -// InvokeHelper<> -- Take a Runnable + arguments and actully invokes it. -// Handle the differing syntaxes needed for WeakPtr<> -// support, and for ignoring return values. This is separate -// from Invoker to avoid creating multiple version of -// Invoker<>. -// Invoker<> -- Unwraps the curried parameters and executes the Runnable. -// BindState<> -- Stores the curried parameters, and is the main entry point -// into the Bind() system, doing most of the type resolution. -// There are ARITY BindState types. - -// HasNonConstReferenceParam selects true_type when any of the parameters in -// |Sig| is a non-const reference. -// Implementation note: This non-specialized case handles zero-arity case only. -// Non-zero-arity cases should be handled by the specialization below. -template <typename List> -struct HasNonConstReferenceItem : false_type {}; - -// Implementation note: Select true_type if the first parameter is a non-const -// reference. Otherwise, skip the first parameter and check rest of parameters -// recursively. -template <typename T, typename... Args> -struct HasNonConstReferenceItem<TypeList<T, Args...>> - : std::conditional<is_non_const_reference<T>::value, - true_type, - HasNonConstReferenceItem<TypeList<Args...>>>::type {}; - -// HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw -// pointer to a RefCounted type. -// Implementation note: This non-specialized case handles zero-arity case only. -// Non-zero-arity cases should be handled by the specialization below. -template <typename... Args> -struct HasRefCountedTypeAsRawPtr : false_type {}; - -// Implementation note: Select true_type if the first parameter is a raw pointer -// to a RefCounted type. Otherwise, skip the first parameter and check rest of -// parameters recursively. -template <typename T, typename... Args> -struct HasRefCountedTypeAsRawPtr<T, Args...> - : std::conditional<NeedsScopedRefptrButGetsRawPtr<T>::value, - true_type, - HasRefCountedTypeAsRawPtr<Args...>>::type {}; - -// BindsArrayToFirstArg selects true_type when |is_method| is true and the first -// item of |Args| is an array type. -// Implementation note: This non-specialized case handles !is_method case and -// zero-arity case only. Other cases should be handled by the specialization -// below. -template <bool is_method, typename... Args> -struct BindsArrayToFirstArg : false_type {}; - -template <typename T, typename... Args> -struct BindsArrayToFirstArg<true, T, Args...> : is_array<T> {}; - -// HasRefCountedParamAsRawPtr is the same to HasRefCountedTypeAsRawPtr except -// when |is_method| is true HasRefCountedParamAsRawPtr skips the first argument. -// Implementation note: This non-specialized case handles !is_method case and -// zero-arity case only. Other cases should be handled by the specialization -// below. -template <bool is_method, typename... Args> -struct HasRefCountedParamAsRawPtr : HasRefCountedTypeAsRawPtr<Args...> {}; - -template <typename T, typename... Args> -struct HasRefCountedParamAsRawPtr<true, T, Args...> - : HasRefCountedTypeAsRawPtr<Args...> {}; - -// RunnableAdapter<> -// -// The RunnableAdapter<> templates provide a uniform interface for invoking -// a function pointer, method pointer, or const method pointer. The adapter -// exposes a Run() method with an appropriate signature. Using this wrapper -// allows for writing code that supports all three pointer types without -// undue repetition. Without it, a lot of code would need to be repeated 3 -// times. -// -// For method pointers and const method pointers the first argument to Run() -// is considered to be the received of the method. This is similar to STL's -// mem_fun(). -// -// This class also exposes a RunType typedef that is the function type of the -// Run() function. -// -// If and only if the wrapper contains a method or const method pointer, an -// IsMethod typedef is exposed. The existence of this typedef (NOT the value) -// marks that the wrapper should be considered a method wrapper. - -template <typename Functor> -class RunnableAdapter; - -// Function. -template <typename R, typename... Args> -class RunnableAdapter<R(*)(Args...)> { - public: - // MSVC 2013 doesn't support Type Alias of function types. - // Revisit this after we update it to newer version. - typedef R RunType(Args...); - - explicit RunnableAdapter(R(*function)(Args...)) - : function_(function) { - } - - R Run(typename CallbackParamTraits<Args>::ForwardType... args) { - return function_(CallbackForward(args)...); - } - - private: - R (*function_)(Args...); -}; - -// Method. -template <typename R, typename T, typename... Args> -class RunnableAdapter<R(T::*)(Args...)> { - public: - // MSVC 2013 doesn't support Type Alias of function types. - // Revisit this after we update it to newer version. - typedef R RunType(T*, Args...); - using IsMethod = true_type; - - explicit RunnableAdapter(R(T::*method)(Args...)) - : method_(method) { - } - - R Run(T* object, typename CallbackParamTraits<Args>::ForwardType... args) { - return (object->*method_)(CallbackForward(args)...); - } - - private: - R (T::*method_)(Args...); -}; - -// Const Method. -template <typename R, typename T, typename... Args> -class RunnableAdapter<R(T::*)(Args...) const> { - public: - using RunType = R(const T*, Args...); - using IsMethod = true_type; - - explicit RunnableAdapter(R(T::*method)(Args...) const) - : method_(method) { - } - - R Run(const T* object, - typename CallbackParamTraits<Args>::ForwardType... args) { - return (object->*method_)(CallbackForward(args)...); - } - - private: - R (T::*method_)(Args...) const; -}; - - -// ForceVoidReturn<> -// -// Set of templates that support forcing the function return type to void. -template <typename Sig> -struct ForceVoidReturn; - -template <typename R, typename... Args> -struct ForceVoidReturn<R(Args...)> { - // MSVC 2013 doesn't support Type Alias of function types. - // Revisit this after we update it to newer version. - typedef void RunType(Args...); -}; - - -// FunctorTraits<> -// -// See description at top of file. -template <typename T> -struct FunctorTraits { - using RunnableType = RunnableAdapter<T>; - using RunType = typename RunnableType::RunType; -}; - -template <typename T> -struct FunctorTraits<IgnoreResultHelper<T>> { - using RunnableType = typename FunctorTraits<T>::RunnableType; - using RunType = - typename ForceVoidReturn<typename RunnableType::RunType>::RunType; -}; - -template <typename T> -struct FunctorTraits<Callback<T>> { - using RunnableType = Callback<T> ; - using RunType = typename Callback<T>::RunType; -}; - - -// MakeRunnable<> -// -// Converts a passed in functor to a RunnableType using type inference. - -template <typename T> -typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) { - return RunnableAdapter<T>(t); -} - -template <typename T> -typename FunctorTraits<T>::RunnableType -MakeRunnable(const IgnoreResultHelper<T>& t) { - return MakeRunnable(t.functor_); -} - -template <typename T> -const typename FunctorTraits<Callback<T>>::RunnableType& -MakeRunnable(const Callback<T>& t) { - DCHECK(!t.is_null()); - return t; -} - - -// InvokeHelper<> -// -// There are 3 logical InvokeHelper<> specializations: normal, void-return, -// WeakCalls. -// -// The normal type just calls the underlying runnable. -// -// We need a InvokeHelper to handle void return types in order to support -// IgnoreResult(). Normally, if the Runnable's RunType had a void return, -// the template system would just accept "return functor.Run()" ignoring -// the fact that a void function is being used with return. This piece of -// sugar breaks though when the Runnable's RunType is not void. Thus, we -// need a partial specialization to change the syntax to drop the "return" -// from the invocation call. -// -// WeakCalls similarly need special syntax that is applied to the first -// argument to check if they should no-op themselves. -template <bool IsWeakCall, typename ReturnType, typename Runnable, - typename ArgsType> -struct InvokeHelper; - -template <typename ReturnType, typename Runnable, typename... Args> -struct InvokeHelper<false, ReturnType, Runnable, TypeList<Args...>> { - static ReturnType MakeItSo(Runnable runnable, Args... args) { - return runnable.Run(CallbackForward(args)...); - } -}; - -template <typename Runnable, typename... Args> -struct InvokeHelper<false, void, Runnable, TypeList<Args...>> { - static void MakeItSo(Runnable runnable, Args... args) { - runnable.Run(CallbackForward(args)...); - } -}; - -template <typename Runnable, typename BoundWeakPtr, typename... Args> -struct InvokeHelper<true, void, Runnable, TypeList<BoundWeakPtr, Args...>> { - static void MakeItSo(Runnable runnable, BoundWeakPtr weak_ptr, Args... args) { - if (!weak_ptr.get()) { - return; - } - runnable.Run(weak_ptr.get(), CallbackForward(args)...); - } -}; - -#if !defined(_MSC_VER) - -template <typename ReturnType, typename Runnable, typename ArgsType> -struct InvokeHelper<true, ReturnType, Runnable, ArgsType> { - // WeakCalls are only supported for functions with a void return type. - // Otherwise, the function result would be undefined if the the WeakPtr<> - // is invalidated. - static_assert(is_void<ReturnType>::value, - "weak_ptrs can only bind to methods without return values"); -}; - -#endif - -// Invoker<> -// -// See description at the top of the file. -template <typename BoundIndices, - typename StorageType, typename Unwrappers, - typename InvokeHelperType, typename UnboundForwardRunType> -struct Invoker; - -template <size_t... bound_indices, - typename StorageType, - typename... Unwrappers, - typename InvokeHelperType, - typename R, - typename... UnboundForwardArgs> -struct Invoker<IndexSequence<bound_indices...>, - StorageType, TypeList<Unwrappers...>, - InvokeHelperType, R(UnboundForwardArgs...)> { - static R Run(BindStateBase* base, - UnboundForwardArgs... unbound_args) { - StorageType* storage = static_cast<StorageType*>(base); - // Local references to make debugger stepping easier. If in a debugger, - // you really want to warp ahead and step through the - // InvokeHelper<>::MakeItSo() call below. - return InvokeHelperType::MakeItSo( - storage->runnable_, - Unwrappers::Unwrap(get<bound_indices>(storage->bound_args_))..., - CallbackForward(unbound_args)...); - } -}; - - -// BindState<> -// -// This stores all the state passed into Bind() and is also where most -// of the template resolution magic occurs. -// -// Runnable is the functor we are binding arguments to. -// RunType is type of the Run() function that the Invoker<> should use. -// Normally, this is the same as the RunType of the Runnable, but it can -// be different if an adapter like IgnoreResult() has been used. -// -// BoundArgs contains the storage type for all the bound arguments. -template <typename Runnable, typename RunType, typename... BoundArgs> -struct BindState; - -template <typename Runnable, - typename R, - typename... Args, - typename... BoundArgs> -struct BindState<Runnable, R(Args...), BoundArgs...> final - : public BindStateBase { - private: - using StorageType = BindState<Runnable, R(Args...), BoundArgs...>; - using RunnableType = Runnable; - - // true_type if Runnable is a method invocation and the first bound argument - // is a WeakPtr. - using IsWeakCall = - IsWeakMethod<HasIsMethodTag<Runnable>::value, BoundArgs...>; - - using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>; - using Unwrappers = TypeList<UnwrapTraits<BoundArgs>...>; - using UnboundForwardArgs = DropTypeListItem< - sizeof...(BoundArgs), - TypeList<typename CallbackParamTraits<Args>::ForwardType...>>; - using UnboundForwardRunType = MakeFunctionType<R, UnboundForwardArgs>; - - using InvokeHelperArgs = ConcatTypeLists< - TypeList<typename UnwrapTraits<BoundArgs>::ForwardType...>, - UnboundForwardArgs>; - using InvokeHelperType = - InvokeHelper<IsWeakCall::value, R, Runnable, InvokeHelperArgs>; - - using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>; - - public: - using InvokerType = Invoker<BoundIndices, StorageType, Unwrappers, - InvokeHelperType, UnboundForwardRunType>; - using UnboundRunType = MakeFunctionType<R, UnboundArgs>; - - BindState(const Runnable& runnable, const BoundArgs&... bound_args) - : BindStateBase(&Destroy), - runnable_(runnable), - ref_(bound_args...), - bound_args_(bound_args...) {} - - RunnableType runnable_; - MaybeScopedRefPtr<HasIsMethodTag<Runnable>::value, BoundArgs...> ref_; - Tuple<BoundArgs...> bound_args_; - - private: - ~BindState() {} - - static void Destroy(BindStateBase* self) { - delete static_cast<BindState*>(self); - } -}; - -} // namespace internal -} // namespace base - -#endif // BASE_BIND_INTERNAL_H_ diff --git a/security/sandbox/chromium/base/bind_internal_win.h b/security/sandbox/chromium/base/bind_internal_win.h deleted file mode 100644 index 2ee12ef21..000000000 --- a/security/sandbox/chromium/base/bind_internal_win.h +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Specializations of RunnableAdapter<> for Windows specific calling -// conventions. Please see base/bind_internal.h for more info. - -#ifndef BASE_BIND_INTERNAL_WIN_H_ -#define BASE_BIND_INTERNAL_WIN_H_ - -#include "build/build_config.h" - -// In the x64 architecture in Windows, __fastcall, __stdcall, etc, are all -// the same as __cdecl which would turn the following specializations into -// multiple definitions. -#if !defined(ARCH_CPU_X86_64) - -namespace base { -namespace internal { - -template <typename Functor> -class RunnableAdapter; - -// __stdcall Function. -template <typename R, typename... Args> -class RunnableAdapter<R(__stdcall *)(Args...)> { - public: - // MSVC 2013 doesn't support Type Alias of function types. - // Revisit this after we update it to newer version. - typedef R RunType(Args...); - - explicit RunnableAdapter(R(__stdcall *function)(Args...)) - : function_(function) { - } - - R Run(typename CallbackParamTraits<Args>::ForwardType... args) { - return function_(args...); - } - - private: - R (__stdcall *function_)(Args...); -}; - -// __fastcall Function. -template <typename R, typename... Args> -class RunnableAdapter<R(__fastcall *)(Args...)> { - public: - // MSVC 2013 doesn't support Type Alias of function types. - // Revisit this after we update it to newer version. - typedef R RunType(Args...); - - explicit RunnableAdapter(R(__fastcall *function)(Args...)) - : function_(function) { - } - - R Run(typename CallbackParamTraits<Args>::ForwardType... args) { - return function_(args...); - } - - private: - R (__fastcall *function_)(Args...); -}; - -} // namespace internal -} // namespace base - -#endif // !defined(ARCH_CPU_X86_64) - -#endif // BASE_BIND_INTERNAL_WIN_H_ diff --git a/security/sandbox/chromium/base/bit_cast.h b/security/sandbox/chromium/base/bit_cast.h deleted file mode 100644 index b548467e7..000000000 --- a/security/sandbox/chromium/base/bit_cast.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_BIT_CAST_H_ -#define BASE_BIT_CAST_H_ - -#include <string.h> - -// bit_cast<Dest,Source> is a template function that implements the equivalent -// of "*reinterpret_cast<Dest*>(&source)". We need this in very low-level -// functions like the protobuf library and fast math support. -// -// float f = 3.14159265358979; -// int i = bit_cast<int32_t>(f); -// // i = 0x40490fdb -// -// The classical address-casting method is: -// -// // WRONG -// float f = 3.14159265358979; // WRONG -// int i = * reinterpret_cast<int*>(&f); // WRONG -// -// The address-casting method actually produces undefined behavior according to -// the ISO C++98 specification, section 3.10 ("basic.lval"), paragraph 15. -// (This did not substantially change in C++11.) Roughly, this section says: if -// an object in memory has one type, and a program accesses it with a different -// type, then the result is undefined behavior for most values of "different -// type". -// -// This is true for any cast syntax, either *(int*)&f or -// *reinterpret_cast<int*>(&f). And it is particularly true for conversions -// between integral lvalues and floating-point lvalues. -// -// The purpose of this paragraph is to allow optimizing compilers to assume that -// expressions with different types refer to different memory. Compilers are -// known to take advantage of this. So a non-conforming program quietly -// produces wildly incorrect output. -// -// The problem is not the use of reinterpret_cast. The problem is type punning: -// holding an object in memory of one type and reading its bits back using a -// different type. -// -// The C++ standard is more subtle and complex than this, but that is the basic -// idea. -// -// Anyways ... -// -// bit_cast<> calls memcpy() which is blessed by the standard, especially by the -// example in section 3.9 . Also, of course, bit_cast<> wraps up the nasty -// logic in one place. -// -// Fortunately memcpy() is very fast. In optimized mode, compilers replace -// calls to memcpy() with inline object code when the size argument is a -// compile-time constant. On a 32-bit system, memcpy(d,s,4) compiles to one -// load and one store, and memcpy(d,s,8) compiles to two loads and two stores. -// -// WARNING: if Dest or Source is a non-POD type, the result of the memcpy -// is likely to surprise you. - -template <class Dest, class Source> -inline Dest bit_cast(const Source& source) { - static_assert(sizeof(Dest) == sizeof(Source), - "bit_cast requires source and destination to be the same size"); - - Dest dest; - memcpy(&dest, &source, sizeof(dest)); - return dest; -} - -#endif // BASE_BIT_CAST_H_ diff --git a/security/sandbox/chromium/base/callback.h b/security/sandbox/chromium/base/callback.h deleted file mode 100644 index 3bf0008b6..000000000 --- a/security/sandbox/chromium/base/callback.h +++ /dev/null @@ -1,405 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_CALLBACK_H_ -#define BASE_CALLBACK_H_ - -#include "base/callback_forward.h" -#include "base/callback_internal.h" -#include "base/template_util.h" - -// NOTE: Header files that do not require the full definition of Callback or -// Closure should #include "base/callback_forward.h" instead of this file. - -// ----------------------------------------------------------------------------- -// Introduction -// ----------------------------------------------------------------------------- -// -// The templated Callback class is a generalized function object. Together -// with the Bind() function in bind.h, they provide a type-safe method for -// performing partial application of functions. -// -// Partial application (or "currying") is the process of binding a subset of -// a function's arguments to produce another function that takes fewer -// arguments. This can be used to pass around a unit of delayed execution, -// much like lexical closures are used in other languages. For example, it -// is used in Chromium code to schedule tasks on different MessageLoops. -// -// A callback with no unbound input parameters (base::Callback<void()>) -// is called a base::Closure. Note that this is NOT the same as what other -// languages refer to as a closure -- it does not retain a reference to its -// enclosing environment. -// -// MEMORY MANAGEMENT AND PASSING -// -// The Callback objects themselves should be passed by const-reference, and -// stored by copy. They internally store their state via a refcounted class -// and thus do not need to be deleted. -// -// The reason to pass via a const-reference is to avoid unnecessary -// AddRef/Release pairs to the internal state. -// -// -// ----------------------------------------------------------------------------- -// Quick reference for basic stuff -// ----------------------------------------------------------------------------- -// -// BINDING A BARE FUNCTION -// -// int Return5() { return 5; } -// base::Callback<int()> func_cb = base::Bind(&Return5); -// LOG(INFO) << func_cb.Run(); // Prints 5. -// -// BINDING A CLASS METHOD -// -// The first argument to bind is the member function to call, the second is -// the object on which to call it. -// -// class Ref : public base::RefCountedThreadSafe<Ref> { -// public: -// int Foo() { return 3; } -// void PrintBye() { LOG(INFO) << "bye."; } -// }; -// scoped_refptr<Ref> ref = new Ref(); -// base::Callback<void()> ref_cb = base::Bind(&Ref::Foo, ref); -// LOG(INFO) << ref_cb.Run(); // Prints out 3. -// -// By default the object must support RefCounted or you will get a compiler -// error. If you're passing between threads, be sure it's -// RefCountedThreadSafe! See "Advanced binding of member functions" below if -// you don't want to use reference counting. -// -// RUNNING A CALLBACK -// -// Callbacks can be run with their "Run" method, which has the same -// signature as the template argument to the callback. -// -// void DoSomething(const base::Callback<void(int, std::string)>& callback) { -// callback.Run(5, "hello"); -// } -// -// Callbacks can be run more than once (they don't get deleted or marked when -// run). However, this precludes using base::Passed (see below). -// -// void DoSomething(const base::Callback<double(double)>& callback) { -// double myresult = callback.Run(3.14159); -// myresult += callback.Run(2.71828); -// } -// -// PASSING UNBOUND INPUT PARAMETERS -// -// Unbound parameters are specified at the time a callback is Run(). They are -// specified in the Callback template type: -// -// void MyFunc(int i, const std::string& str) {} -// base::Callback<void(int, const std::string&)> cb = base::Bind(&MyFunc); -// cb.Run(23, "hello, world"); -// -// PASSING BOUND INPUT PARAMETERS -// -// Bound parameters are specified when you create thee callback as arguments -// to Bind(). They will be passed to the function and the Run()ner of the -// callback doesn't see those values or even know that the function it's -// calling. -// -// void MyFunc(int i, const std::string& str) {} -// base::Callback<void()> cb = base::Bind(&MyFunc, 23, "hello world"); -// cb.Run(); -// -// A callback with no unbound input parameters (base::Callback<void()>) -// is called a base::Closure. So we could have also written: -// -// base::Closure cb = base::Bind(&MyFunc, 23, "hello world"); -// -// When calling member functions, bound parameters just go after the object -// pointer. -// -// base::Closure cb = base::Bind(&MyClass::MyFunc, this, 23, "hello world"); -// -// PARTIAL BINDING OF PARAMETERS -// -// You can specify some parameters when you create the callback, and specify -// the rest when you execute the callback. -// -// void MyFunc(int i, const std::string& str) {} -// base::Callback<void(const std::string&)> cb = base::Bind(&MyFunc, 23); -// cb.Run("hello world"); -// -// When calling a function bound parameters are first, followed by unbound -// parameters. -// -// -// ----------------------------------------------------------------------------- -// Quick reference for advanced binding -// ----------------------------------------------------------------------------- -// -// BINDING A CLASS METHOD WITH WEAK POINTERS -// -// base::Bind(&MyClass::Foo, GetWeakPtr()); -// -// The callback will not be run if the object has already been destroyed. -// DANGER: weak pointers are not threadsafe, so don't use this -// when passing between threads! -// -// BINDING A CLASS METHOD WITH MANUAL LIFETIME MANAGEMENT -// -// base::Bind(&MyClass::Foo, base::Unretained(this)); -// -// This disables all lifetime management on the object. You're responsible -// for making sure the object is alive at the time of the call. You break it, -// you own it! -// -// BINDING A CLASS METHOD AND HAVING THE CALLBACK OWN THE CLASS -// -// MyClass* myclass = new MyClass; -// base::Bind(&MyClass::Foo, base::Owned(myclass)); -// -// The object will be deleted when the callback is destroyed, even if it's -// not run (like if you post a task during shutdown). Potentially useful for -// "fire and forget" cases. -// -// IGNORING RETURN VALUES -// -// Sometimes you want to call a function that returns a value in a callback -// that doesn't expect a return value. -// -// int DoSomething(int arg) { cout << arg << endl; } -// base::Callback<void(int)> cb = -// base::Bind(base::IgnoreResult(&DoSomething)); -// -// -// ----------------------------------------------------------------------------- -// Quick reference for binding parameters to Bind() -// ----------------------------------------------------------------------------- -// -// Bound parameters are specified as arguments to Bind() and are passed to the -// function. A callback with no parameters or no unbound parameters is called a -// Closure (base::Callback<void()> and base::Closure are the same thing). -// -// PASSING PARAMETERS OWNED BY THE CALLBACK -// -// void Foo(int* arg) { cout << *arg << endl; } -// int* pn = new int(1); -// base::Closure foo_callback = base::Bind(&foo, base::Owned(pn)); -// -// The parameter will be deleted when the callback is destroyed, even if it's -// not run (like if you post a task during shutdown). -// -// PASSING PARAMETERS AS A scoped_ptr -// -// void TakesOwnership(scoped_ptr<Foo> arg) {} -// scoped_ptr<Foo> f(new Foo); -// // f becomes null during the following call. -// base::Closure cb = base::Bind(&TakesOwnership, base::Passed(&f)); -// -// Ownership of the parameter will be with the callback until the it is run, -// when ownership is passed to the callback function. This means the callback -// can only be run once. If the callback is never run, it will delete the -// object when it's destroyed. -// -// PASSING PARAMETERS AS A scoped_refptr -// -// void TakesOneRef(scoped_refptr<Foo> arg) {} -// scoped_refptr<Foo> f(new Foo) -// base::Closure cb = base::Bind(&TakesOneRef, f); -// -// This should "just work." The closure will take a reference as long as it -// is alive, and another reference will be taken for the called function. -// -// PASSING PARAMETERS BY REFERENCE -// -// Const references are *copied* unless ConstRef is used. Example: -// -// void foo(const int& arg) { printf("%d %p\n", arg, &arg); } -// int n = 1; -// base::Closure has_copy = base::Bind(&foo, n); -// base::Closure has_ref = base::Bind(&foo, base::ConstRef(n)); -// n = 2; -// foo(n); // Prints "2 0xaaaaaaaaaaaa" -// has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb" -// has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa" -// -// Normally parameters are copied in the closure. DANGER: ConstRef stores a -// const reference instead, referencing the original parameter. This means -// that you must ensure the object outlives the callback! -// -// -// ----------------------------------------------------------------------------- -// Implementation notes -// ----------------------------------------------------------------------------- -// -// WHERE IS THIS DESIGN FROM: -// -// The design Callback and Bind is heavily influenced by C++'s -// tr1::function/tr1::bind, and by the "Google Callback" system used inside -// Google. -// -// -// HOW THE IMPLEMENTATION WORKS: -// -// There are three main components to the system: -// 1) The Callback classes. -// 2) The Bind() functions. -// 3) The arguments wrappers (e.g., Unretained() and ConstRef()). -// -// The Callback classes represent a generic function pointer. Internally, -// it stores a refcounted piece of state that represents the target function -// and all its bound parameters. Each Callback specialization has a templated -// constructor that takes an BindState<>*. In the context of the constructor, -// the static type of this BindState<> pointer uniquely identifies the -// function it is representing, all its bound parameters, and a Run() method -// that is capable of invoking the target. -// -// Callback's constructor takes the BindState<>* that has the full static type -// and erases the target function type as well as the types of the bound -// parameters. It does this by storing a pointer to the specific Run() -// function, and upcasting the state of BindState<>* to a -// BindStateBase*. This is safe as long as this BindStateBase pointer -// is only used with the stored Run() pointer. -// -// To BindState<> objects are created inside the Bind() functions. -// These functions, along with a set of internal templates, are responsible for -// -// - Unwrapping the function signature into return type, and parameters -// - Determining the number of parameters that are bound -// - Creating the BindState storing the bound parameters -// - Performing compile-time asserts to avoid error-prone behavior -// - Returning an Callback<> with an arity matching the number of unbound -// parameters and that knows the correct refcounting semantics for the -// target object if we are binding a method. -// -// The Bind functions do the above using type-inference, and template -// specializations. -// -// By default Bind() will store copies of all bound parameters, and attempt -// to refcount a target object if the function being bound is a class method. -// These copies are created even if the function takes parameters as const -// references. (Binding to non-const references is forbidden, see bind.h.) -// -// To change this behavior, we introduce a set of argument wrappers -// (e.g., Unretained(), and ConstRef()). These are simple container templates -// that are passed by value, and wrap a pointer to argument. See the -// file-level comment in base/bind_helpers.h for more info. -// -// These types are passed to the Unwrap() functions, and the MaybeRefcount() -// functions respectively to modify the behavior of Bind(). The Unwrap() -// and MaybeRefcount() functions change behavior by doing partial -// specialization based on whether or not a parameter is a wrapper type. -// -// ConstRef() is similar to tr1::cref. Unretained() is specific to Chromium. -// -// -// WHY NOT TR1 FUNCTION/BIND? -// -// Direct use of tr1::function and tr1::bind was considered, but ultimately -// rejected because of the number of copy constructors invocations involved -// in the binding of arguments during construction, and the forwarding of -// arguments during invocation. These copies will no longer be an issue in -// C++0x because C++0x will support rvalue reference allowing for the compiler -// to avoid these copies. However, waiting for C++0x is not an option. -// -// Measured with valgrind on gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5), the -// tr1::bind call itself will invoke a non-trivial copy constructor three times -// for each bound parameter. Also, each when passing a tr1::function, each -// bound argument will be copied again. -// -// In addition to the copies taken at binding and invocation, copying a -// tr1::function causes a copy to be made of all the bound parameters and -// state. -// -// Furthermore, in Chromium, it is desirable for the Callback to take a -// reference on a target object when representing a class method call. This -// is not supported by tr1. -// -// Lastly, tr1::function and tr1::bind has a more general and flexible API. -// This includes things like argument reordering by use of -// tr1::bind::placeholder, support for non-const reference parameters, and some -// limited amount of subtyping of the tr1::function object (e.g., -// tr1::function<int(int)> is convertible to tr1::function<void(int)>). -// -// These are not features that are required in Chromium. Some of them, such as -// allowing for reference parameters, and subtyping of functions, may actually -// become a source of errors. Removing support for these features actually -// allows for a simpler implementation, and a terser Currying API. -// -// -// WHY NOT GOOGLE CALLBACKS? -// -// The Google callback system also does not support refcounting. Furthermore, -// its implementation has a number of strange edge cases with respect to type -// conversion of its arguments. In particular, the argument's constness must -// at times match exactly the function signature, or the type-inference might -// break. Given the above, writing a custom solution was easier. -// -// -// MISSING FUNCTIONALITY -// - Invoking the return of Bind. Bind(&foo).Run() does not work; -// - Binding arrays to functions that take a non-const pointer. -// Example: -// void Foo(const char* ptr); -// void Bar(char* ptr); -// Bind(&Foo, "test"); -// Bind(&Bar, "test"); // This fails because ptr is not const. - -namespace base { - -// First, we forward declare the Callback class template. This informs the -// compiler that the template only has 1 type parameter which is the function -// signature that the Callback is representing. -// -// After this, create template specializations for 0-7 parameters. Note that -// even though the template typelist grows, the specialization still -// only has one type: the function signature. -// -// If you are thinking of forward declaring Callback in your own header file, -// please include "base/callback_forward.h" instead. - -namespace internal { -template <typename Runnable, typename RunType, typename... BoundArgsType> -struct BindState; -} // namespace internal - -template <typename R, typename... Args> -class Callback<R(Args...)> : public internal::CallbackBase { - public: - // MSVC 2013 doesn't support Type Alias of function types. - // Revisit this after we update it to newer version. - typedef R RunType(Args...); - - Callback() : CallbackBase(nullptr) { } - - template <typename Runnable, typename BindRunType, typename... BoundArgsType> - explicit Callback( - internal::BindState<Runnable, BindRunType, BoundArgsType...>* bind_state) - : CallbackBase(bind_state) { - // Force the assignment to a local variable of PolymorphicInvoke - // so the compiler will typecheck that the passed in Run() method has - // the correct type. - PolymorphicInvoke invoke_func = - &internal::BindState<Runnable, BindRunType, BoundArgsType...> - ::InvokerType::Run; - polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func); - } - - bool Equals(const Callback& other) const { - return CallbackBase::Equals(other); - } - - R Run(typename internal::CallbackParamTraits<Args>::ForwardType... args) - const { - PolymorphicInvoke f = - reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_); - - return f(bind_state_.get(), internal::CallbackForward(args)...); - } - - private: - using PolymorphicInvoke = - R(*)(internal::BindStateBase*, - typename internal::CallbackParamTraits<Args>::ForwardType...); -}; - -} // namespace base - -#endif // BASE_CALLBACK_H_ diff --git a/security/sandbox/chromium/base/callback_forward.h b/security/sandbox/chromium/base/callback_forward.h deleted file mode 100644 index a9a263a50..000000000 --- a/security/sandbox/chromium/base/callback_forward.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_CALLBACK_FORWARD_H_ -#define BASE_CALLBACK_FORWARD_H_ - -namespace base { - -template <typename Sig> -class Callback; - -// Syntactic sugar to make Callback<void()> easier to declare since it -// will be used in a lot of APIs with delayed execution. -using Closure = Callback<void()>; - -} // namespace base - -#endif // BASE_CALLBACK_FORWARD_H_ diff --git a/security/sandbox/chromium/base/callback_internal.cc b/security/sandbox/chromium/base/callback_internal.cc deleted file mode 100644 index 2553fe7e1..000000000 --- a/security/sandbox/chromium/base/callback_internal.cc +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/callback_internal.h" - -#include "base/logging.h" - -namespace base { -namespace internal { - -void BindStateBase::AddRef() { - AtomicRefCountInc(&ref_count_); -} - -void BindStateBase::Release() { - if (!AtomicRefCountDec(&ref_count_)) - destructor_(this); -} - -CallbackBase::CallbackBase(const CallbackBase& c) = default; -CallbackBase& CallbackBase::operator=(const CallbackBase& c) = default; - -void CallbackBase::Reset() { - polymorphic_invoke_ = NULL; - // NULL the bind_state_ last, since it may be holding the last ref to whatever - // object owns us, and we may be deleted after that. - bind_state_ = NULL; -} - -bool CallbackBase::Equals(const CallbackBase& other) const { - return bind_state_.get() == other.bind_state_.get() && - polymorphic_invoke_ == other.polymorphic_invoke_; -} - -CallbackBase::CallbackBase(BindStateBase* bind_state) - : bind_state_(bind_state), - polymorphic_invoke_(NULL) { - DCHECK(!bind_state_.get() || bind_state_->ref_count_ == 1); -} - -CallbackBase::~CallbackBase() { -} - -} // namespace internal -} // namespace base diff --git a/security/sandbox/chromium/base/callback_internal.h b/security/sandbox/chromium/base/callback_internal.h deleted file mode 100644 index d1d8ab8ec..000000000 --- a/security/sandbox/chromium/base/callback_internal.h +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file contains utility functions and classes that help the -// implementation, and management of the Callback objects. - -#ifndef BASE_CALLBACK_INTERNAL_H_ -#define BASE_CALLBACK_INTERNAL_H_ - -#include <stddef.h> -#include <memory> -#include <type_traits> - -#include "base/atomic_ref_count.h" -#include "base/base_export.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/template_util.h" - -namespace base { -namespace internal { -class CallbackBase; - -// BindStateBase is used to provide an opaque handle that the Callback -// class can use to represent a function object with bound arguments. It -// behaves as an existential type that is used by a corresponding -// DoInvoke function to perform the function execution. This allows -// us to shield the Callback class from the types of the bound argument via -// "type erasure." -// At the base level, the only task is to add reference counting data. Don't use -// RefCountedThreadSafe since it requires the destructor to be a virtual method. -// Creating a vtable for every BindState template instantiation results in a lot -// of bloat. Its only task is to call the destructor which can be done with a -// function pointer. -class BindStateBase { - protected: - explicit BindStateBase(void (*destructor)(BindStateBase*)) - : ref_count_(0), destructor_(destructor) {} - ~BindStateBase() = default; - - private: - friend class scoped_refptr<BindStateBase>; - friend class CallbackBase; - - void AddRef(); - void Release(); - - AtomicRefCount ref_count_; - - // Pointer to a function that will properly destroy |this|. - void (*destructor_)(BindStateBase*); - - DISALLOW_COPY_AND_ASSIGN(BindStateBase); -}; - -// Holds the Callback methods that don't require specialization to reduce -// template bloat. -class BASE_EXPORT CallbackBase { - public: - CallbackBase(const CallbackBase& c); - CallbackBase& operator=(const CallbackBase& c); - - // Returns true if Callback is null (doesn't refer to anything). - bool is_null() const { return bind_state_.get() == NULL; } - - // Returns the Callback into an uninitialized state. - void Reset(); - - protected: - // In C++, it is safe to cast function pointers to function pointers of - // another type. It is not okay to use void*. We create a InvokeFuncStorage - // that that can store our function pointer, and then cast it back to - // the original type on usage. - using InvokeFuncStorage = void(*)(); - - // Returns true if this callback equals |other|. |other| may be null. - bool Equals(const CallbackBase& other) const; - - // Allow initializing of |bind_state_| via the constructor to avoid default - // initialization of the scoped_refptr. We do not also initialize - // |polymorphic_invoke_| here because doing a normal assignment in the - // derived Callback templates makes for much nicer compiler errors. - explicit CallbackBase(BindStateBase* bind_state); - - // Force the destructor to be instantiated inside this translation unit so - // that our subclasses will not get inlined versions. Avoids more template - // bloat. - ~CallbackBase(); - - scoped_refptr<BindStateBase> bind_state_; - InvokeFuncStorage polymorphic_invoke_; -}; - -// A helper template to determine if given type is non-const move-only-type, -// i.e. if a value of the given type should be passed via std::move() in a -// destructive way. Types are considered to be move-only if they have a -// sentinel MoveOnlyTypeForCPP03 member: a class typically gets this from using -// the DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND macro. -// It would be easy to generalize this trait to all move-only types... but this -// confuses template deduction in VS2013 with certain types such as -// std::unique_ptr. -// TODO(dcheng): Revisit this when Windows switches to VS2015 by default. -template <typename T> struct IsMoveOnlyType { - template <typename U> - static YesType Test(const typename U::MoveOnlyTypeForCPP03*); - - template <typename U> - static NoType Test(...); - - static const bool value = sizeof((Test<T>(0))) == sizeof(YesType) && - !is_const<T>::value; -}; - -// Specialization of IsMoveOnlyType so that std::unique_ptr is still considered -// move-only, even without the sentinel member. -template <typename T> -struct IsMoveOnlyType<std::unique_ptr<T>> : std::true_type {}; - -template <typename> -struct CallbackParamTraitsForMoveOnlyType; - -template <typename> -struct CallbackParamTraitsForNonMoveOnlyType; - -// TODO(tzik): Use a default parameter once MSVS supports variadic templates -// with default values. -// http://connect.microsoft.com/VisualStudio/feedbackdetail/view/957801/compilation-error-with-variadic-templates -// -// This is a typetraits object that's used to take an argument type, and -// extract a suitable type for storing and forwarding arguments. -// -// In particular, it strips off references, and converts arrays to -// pointers for storage; and it avoids accidentally trying to create a -// "reference of a reference" if the argument is a reference type. -// -// This array type becomes an issue for storage because we are passing bound -// parameters by const reference. In this case, we end up passing an actual -// array type in the initializer list which C++ does not allow. This will -// break passing of C-string literals. -template <typename T> -struct CallbackParamTraits - : std::conditional<IsMoveOnlyType<T>::value, - CallbackParamTraitsForMoveOnlyType<T>, - CallbackParamTraitsForNonMoveOnlyType<T>>::type { -}; - -template <typename T> -struct CallbackParamTraitsForNonMoveOnlyType { - using ForwardType = const T&; - using StorageType = T; -}; - -// The Storage should almost be impossible to trigger unless someone manually -// specifies type of the bind parameters. However, in case they do, -// this will guard against us accidentally storing a reference parameter. -// -// The ForwardType should only be used for unbound arguments. -template <typename T> -struct CallbackParamTraitsForNonMoveOnlyType<T&> { - using ForwardType = T&; - using StorageType = T; -}; - -// Note that for array types, we implicitly add a const in the conversion. This -// means that it is not possible to bind array arguments to functions that take -// a non-const pointer. Trying to specialize the template based on a "const -// T[n]" does not seem to match correctly, so we are stuck with this -// restriction. -template <typename T, size_t n> -struct CallbackParamTraitsForNonMoveOnlyType<T[n]> { - using ForwardType = const T*; - using StorageType = const T*; -}; - -// See comment for CallbackParamTraits<T[n]>. -template <typename T> -struct CallbackParamTraitsForNonMoveOnlyType<T[]> { - using ForwardType = const T*; - using StorageType = const T*; -}; - -// Parameter traits for movable-but-not-copyable scopers. -// -// Callback<>/Bind() understands movable-but-not-copyable semantics where -// the type cannot be copied but can still have its state destructively -// transferred (aka. moved) to another instance of the same type by calling a -// helper function. When used with Bind(), this signifies transferal of the -// object's state to the target function. -// -// For these types, the ForwardType must not be a const reference, or a -// reference. A const reference is inappropriate, and would break const -// correctness, because we are implementing a destructive move. A non-const -// reference cannot be used with temporaries which means the result of a -// function or a cast would not be usable with Callback<> or Bind(). -template <typename T> -struct CallbackParamTraitsForMoveOnlyType { - using ForwardType = T; - using StorageType = T; -}; - -// CallbackForward() is a very limited simulation of C++11's std::forward() -// used by the Callback/Bind system for a set of movable-but-not-copyable -// types. It is needed because forwarding a movable-but-not-copyable -// argument to another function requires us to invoke the proper move -// operator to create a rvalue version of the type. The supported types are -// whitelisted below as overloads of the CallbackForward() function. The -// default template compiles out to be a no-op. -// -// In C++11, std::forward would replace all uses of this function. However, it -// is impossible to implement a general std::forward without C++11 due to a lack -// of rvalue references. -// -// In addition to Callback/Bind, this is used by PostTaskAndReplyWithResult to -// simulate std::forward() and forward the result of one Callback as a -// parameter to another callback. This is to support Callbacks that return -// the movable-but-not-copyable types whitelisted above. -template <typename T> -typename std::enable_if<!IsMoveOnlyType<T>::value, T>::type& CallbackForward( - T& t) { - return t; -} - -template <typename T> -typename std::enable_if<IsMoveOnlyType<T>::value, T>::type CallbackForward( - T& t) { - return std::move(t); -} - -} // namespace internal -} // namespace base - -#endif // BASE_CALLBACK_INTERNAL_H_ diff --git a/security/sandbox/chromium/base/compiler_specific.h b/security/sandbox/chromium/base/compiler_specific.h deleted file mode 100644 index 339e9b74e..000000000 --- a/security/sandbox/chromium/base/compiler_specific.h +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_COMPILER_SPECIFIC_H_ -#define BASE_COMPILER_SPECIFIC_H_ - -#include "build/build_config.h" - -#if defined(COMPILER_MSVC) - -// For _Printf_format_string_. -#include <sal.h> - -// Macros for suppressing and disabling warnings on MSVC. -// -// Warning numbers are enumerated at: -// http://msdn.microsoft.com/en-us/library/8x5x43k7(VS.80).aspx -// -// The warning pragma: -// http://msdn.microsoft.com/en-us/library/2c8f766e(VS.80).aspx -// -// Using __pragma instead of #pragma inside macros: -// http://msdn.microsoft.com/en-us/library/d9x1s805.aspx - -// MSVC_SUPPRESS_WARNING disables warning |n| for the remainder of the line and -// for the next line of the source file. -#define MSVC_SUPPRESS_WARNING(n) __pragma(warning(suppress:n)) - -// MSVC_PUSH_DISABLE_WARNING pushes |n| onto a stack of warnings to be disabled. -// The warning remains disabled until popped by MSVC_POP_WARNING. -#define MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \ - __pragma(warning(disable:n)) - -// MSVC_PUSH_WARNING_LEVEL pushes |n| as the global warning level. The level -// remains in effect until popped by MSVC_POP_WARNING(). Use 0 to disable all -// warnings. -#define MSVC_PUSH_WARNING_LEVEL(n) __pragma(warning(push, n)) - -// Pop effects of innermost MSVC_PUSH_* macro. -#define MSVC_POP_WARNING() __pragma(warning(pop)) - -#define MSVC_DISABLE_OPTIMIZE() __pragma(optimize("", off)) -#define MSVC_ENABLE_OPTIMIZE() __pragma(optimize("", on)) - -// Allows exporting a class that inherits from a non-exported base class. -// This uses suppress instead of push/pop because the delimiter after the -// declaration (either "," or "{") has to be placed before the pop macro. -// -// Example usage: -// class EXPORT_API Foo : NON_EXPORTED_BASE(public Bar) { -// -// MSVC Compiler warning C4275: -// non dll-interface class 'Bar' used as base for dll-interface class 'Foo'. -// Note that this is intended to be used only when no access to the base class' -// static data is done through derived classes or inline methods. For more info, -// see http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx -#define NON_EXPORTED_BASE(code) MSVC_SUPPRESS_WARNING(4275) \ - code - -#else // Not MSVC - -#define _Printf_format_string_ -#define MSVC_SUPPRESS_WARNING(n) -#define MSVC_PUSH_DISABLE_WARNING(n) -#define MSVC_PUSH_WARNING_LEVEL(n) -#define MSVC_POP_WARNING() -#define MSVC_DISABLE_OPTIMIZE() -#define MSVC_ENABLE_OPTIMIZE() -#define NON_EXPORTED_BASE(code) code - -#endif // COMPILER_MSVC - - -// Annotate a variable indicating it's ok if the variable is not used. -// (Typically used to silence a compiler warning when the assignment -// is important for some other reason.) -// Use like: -// int x = ...; -// ALLOW_UNUSED_LOCAL(x); -#define ALLOW_UNUSED_LOCAL(x) false ? (void)x : (void)0 - -// Annotate a typedef or function indicating it's ok if it's not used. -// Use like: -// typedef Foo Bar ALLOW_UNUSED_TYPE; -#if defined(COMPILER_GCC) || defined(__clang__) -#define ALLOW_UNUSED_TYPE __attribute__((unused)) -#else -#define ALLOW_UNUSED_TYPE -#endif - -// Annotate a function indicating it should not be inlined. -// Use like: -// NOINLINE void DoStuff() { ... } -#if defined(COMPILER_GCC) -#define NOINLINE __attribute__((noinline)) -#elif defined(COMPILER_MSVC) -#define NOINLINE __declspec(noinline) -#else -#define NOINLINE -#endif - -// Specify memory alignment for structs, classes, etc. -// Use like: -// class ALIGNAS(16) MyClass { ... } -// ALIGNAS(16) int array[4]; -#if defined(COMPILER_MSVC) -#define ALIGNAS(byte_alignment) __declspec(align(byte_alignment)) -#elif defined(COMPILER_GCC) -#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) -#endif - -// Return the byte alignment of the given type (available at compile time). -// Use like: -// ALIGNOF(int32_t) // this would be 4 -#if defined(COMPILER_MSVC) -#define ALIGNOF(type) __alignof(type) -#elif defined(COMPILER_GCC) -#define ALIGNOF(type) __alignof__(type) -#endif - -// Annotate a function indicating the caller must examine the return value. -// Use like: -// int foo() WARN_UNUSED_RESULT; -// To explicitly ignore a result, see |ignore_result()| in base/macros.h. -#undef WARN_UNUSED_RESULT -#if defined(COMPILER_GCC) || defined(__clang__) -#define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -#define WARN_UNUSED_RESULT -#endif - -// Tell the compiler a function is using a printf-style format string. -// |format_param| is the one-based index of the format string parameter; -// |dots_param| is the one-based index of the "..." parameter. -// For v*printf functions (which take a va_list), pass 0 for dots_param. -// (This is undocumented but matches what the system C headers do.) -#if defined(COMPILER_GCC) -#define PRINTF_FORMAT(format_param, dots_param) \ - __attribute__((format(printf, format_param, dots_param))) -#else -#define PRINTF_FORMAT(format_param, dots_param) -#endif - -// WPRINTF_FORMAT is the same, but for wide format strings. -// This doesn't appear to yet be implemented in any compiler. -// See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38308 . -#define WPRINTF_FORMAT(format_param, dots_param) -// If available, it would look like: -// __attribute__((format(wprintf, format_param, dots_param))) - -// MemorySanitizer annotations. -#if defined(MEMORY_SANITIZER) && !defined(OS_NACL) -#include <sanitizer/msan_interface.h> - -// Mark a memory region fully initialized. -// Use this to annotate code that deliberately reads uninitialized data, for -// example a GC scavenging root set pointers from the stack. -#define MSAN_UNPOISON(p, size) __msan_unpoison(p, size) - -// Check a memory region for initializedness, as if it was being used here. -// If any bits are uninitialized, crash with an MSan report. -// Use this to sanitize data which MSan won't be able to track, e.g. before -// passing data to another process via shared memory. -#define MSAN_CHECK_MEM_IS_INITIALIZED(p, size) \ - __msan_check_mem_is_initialized(p, size) -#else // MEMORY_SANITIZER -#define MSAN_UNPOISON(p, size) -#define MSAN_CHECK_MEM_IS_INITIALIZED(p, size) -#endif // MEMORY_SANITIZER - -// Macro useful for writing cross-platform function pointers. -#if !defined(CDECL) -#if defined(OS_WIN) -#define CDECL __cdecl -#else // defined(OS_WIN) -#define CDECL -#endif // defined(OS_WIN) -#endif // !defined(CDECL) - -// Macro for hinting that an expression is likely to be false. -#if !defined(UNLIKELY) -#if defined(COMPILER_GCC) -#define UNLIKELY(x) __builtin_expect(!!(x), 0) -#else -#define UNLIKELY(x) (x) -#endif // defined(COMPILER_GCC) -#endif // !defined(UNLIKELY) - -#endif // BASE_COMPILER_SPECIFIC_H_ diff --git a/security/sandbox/chromium/base/containers/hash_tables.h b/security/sandbox/chromium/base/containers/hash_tables.h deleted file mode 100644 index c421dddf3..000000000 --- a/security/sandbox/chromium/base/containers/hash_tables.h +++ /dev/null @@ -1,281 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// -// Deal with the differences between Microsoft and GNU implemenations -// of hash_map. Allows all platforms to use |base::hash_map| and -// |base::hash_set|. -// eg: -// base::hash_map<int> my_map; -// base::hash_set<int> my_set; -// -// NOTE: It is an explicit non-goal of this class to provide a generic hash -// function for pointers. If you want to hash a pointers to a particular class, -// please define the template specialization elsewhere (for example, in its -// header file) and keep it specific to just pointers to that class. This is -// because identity hashes are not desirable for all types that might show up -// in containers as pointers. - -#ifndef BASE_CONTAINERS_HASH_TABLES_H_ -#define BASE_CONTAINERS_HASH_TABLES_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <utility> - -#include "base/strings/string16.h" -#include "build/build_config.h" - -#if defined(COMPILER_MSVC) -#include <unordered_map> -#include <unordered_set> - -#define BASE_HASH_NAMESPACE std - -#elif defined(COMPILER_GCC) - -#define BASE_HASH_NAMESPACE base_hash - -// This is a hack to disable the gcc 4.4 warning about hash_map and hash_set -// being deprecated. We can get rid of this when we upgrade to VS2008 and we -// can use <tr1/unordered_map> and <tr1/unordered_set>. -#ifdef __DEPRECATED -#define CHROME_OLD__DEPRECATED __DEPRECATED -#undef __DEPRECATED -#endif - -#include <ext/hash_map> -#include <ext/hash_set> -#define BASE_HASH_IMPL_NAMESPACE __gnu_cxx - -#include <string> - -#ifdef CHROME_OLD__DEPRECATED -#define __DEPRECATED CHROME_OLD__DEPRECATED -#undef CHROME_OLD__DEPRECATED -#endif - -namespace BASE_HASH_NAMESPACE { - -// The pre-standard hash behaves like C++11's std::hash, except around pointers. -// const char* is specialized to hash the C string and hash functions for -// general T* are missing. Define a BASE_HASH_NAMESPACE::hash which aligns with -// the C++11 behavior. - -template<typename T> -struct hash { - std::size_t operator()(const T& value) const { - return BASE_HASH_IMPL_NAMESPACE::hash<T>()(value); - } -}; - -template<typename T> -struct hash<T*> { - std::size_t operator()(T* value) const { - return BASE_HASH_IMPL_NAMESPACE::hash<uintptr_t>()( - reinterpret_cast<uintptr_t>(value)); - } -}; - -// The GNU C++ library provides identity hash functions for many integral types, -// but not for |long long|. This hash function will truncate if |size_t| is -// narrower than |long long|. This is probably good enough for what we will -// use it for. - -#define DEFINE_TRIVIAL_HASH(integral_type) \ - template<> \ - struct hash<integral_type> { \ - std::size_t operator()(integral_type value) const { \ - return static_cast<std::size_t>(value); \ - } \ - } - -DEFINE_TRIVIAL_HASH(long long); -DEFINE_TRIVIAL_HASH(unsigned long long); - -#undef DEFINE_TRIVIAL_HASH - -// Implement string hash functions so that strings of various flavors can -// be used as keys in STL maps and sets. The hash algorithm comes from the -// GNU C++ library, in <tr1/functional>. It is duplicated here because GCC -// versions prior to 4.3.2 are unable to compile <tr1/functional> when RTTI -// is disabled, as it is in our build. - -#define DEFINE_STRING_HASH(string_type) \ - template<> \ - struct hash<string_type> { \ - std::size_t operator()(const string_type& s) const { \ - std::size_t result = 0; \ - for (string_type::const_iterator i = s.begin(); i != s.end(); ++i) \ - result = (result * 131) + *i; \ - return result; \ - } \ - } - -DEFINE_STRING_HASH(std::string); -DEFINE_STRING_HASH(base::string16); - -#undef DEFINE_STRING_HASH - -} // namespace BASE_HASH_NAMESPACE - -#else // COMPILER -#error define BASE_HASH_NAMESPACE for your compiler -#endif // COMPILER - -namespace base { - -// On MSVC, use the C++11 containers. -#if defined(COMPILER_MSVC) - -template<class Key, class T, - class Hash = std::hash<Key>, - class Pred = std::equal_to<Key>, - class Alloc = std::allocator<std::pair<const Key, T>>> -using hash_map = std::unordered_map<Key, T, Hash, Pred, Alloc>; - -template<class Key, class T, - class Hash = std::hash<Key>, - class Pred = std::equal_to<Key>, - class Alloc = std::allocator<std::pair<const Key, T>>> -using hash_multimap = std::unordered_multimap<Key, T, Hash, Pred, Alloc>; - -template<class Key, - class Hash = std::hash<Key>, - class Pred = std::equal_to<Key>, - class Alloc = std::allocator<Key>> -using hash_multiset = std::unordered_multiset<Key, Hash, Pred, Alloc>; - -template<class Key, - class Hash = std::hash<Key>, - class Pred = std::equal_to<Key>, - class Alloc = std::allocator<Key>> -using hash_set = std::unordered_set<Key, Hash, Pred, Alloc>; - -#else // !COMPILER_MSVC - -// Otherwise, use the pre-standard ones, but override the default hash to match -// C++11. -template<class Key, class T, - class Hash = BASE_HASH_NAMESPACE::hash<Key>, - class Pred = std::equal_to<Key>, - class Alloc = std::allocator<std::pair<const Key, T>>> -using hash_map = BASE_HASH_IMPL_NAMESPACE::hash_map<Key, T, Hash, Pred, Alloc>; - -template<class Key, class T, - class Hash = BASE_HASH_NAMESPACE::hash<Key>, - class Pred = std::equal_to<Key>, - class Alloc = std::allocator<std::pair<const Key, T>>> -using hash_multimap = - BASE_HASH_IMPL_NAMESPACE::hash_multimap<Key, T, Hash, Pred, Alloc>; - -template<class Key, - class Hash = BASE_HASH_NAMESPACE::hash<Key>, - class Pred = std::equal_to<Key>, - class Alloc = std::allocator<Key>> -using hash_multiset = - BASE_HASH_IMPL_NAMESPACE::hash_multiset<Key, Hash, Pred, Alloc>; - -template<class Key, - class Hash = BASE_HASH_NAMESPACE::hash<Key>, - class Pred = std::equal_to<Key>, - class Alloc = std::allocator<Key>> -using hash_set = BASE_HASH_IMPL_NAMESPACE::hash_set<Key, Hash, Pred, Alloc>; - -#undef BASE_HASH_IMPL_NAMESPACE - -#endif // COMPILER_MSVC - -// Implement hashing for pairs of at-most 32 bit integer values. -// When size_t is 32 bits, we turn the 64-bit hash code into 32 bits by using -// multiply-add hashing. This algorithm, as described in -// Theorem 4.3.3 of the thesis "Ãœber die Komplexität der Multiplikation in -// eingeschränkten Branchingprogrammmodellen" by Woelfel, is: -// -// h32(x32, y32) = (h64(x32, y32) * rand_odd64 + rand16 * 2^16) % 2^64 / 2^32 -// -// Contact danakj@chromium.org for any questions. -inline std::size_t HashInts32(uint32_t value1, uint32_t value2) { - uint64_t value1_64 = value1; - uint64_t hash64 = (value1_64 << 32) | value2; - - if (sizeof(std::size_t) >= sizeof(uint64_t)) - return static_cast<std::size_t>(hash64); - - uint64_t odd_random = 481046412LL << 32 | 1025306955LL; - uint32_t shift_random = 10121U << 16; - - hash64 = hash64 * odd_random + shift_random; - std::size_t high_bits = static_cast<std::size_t>( - hash64 >> (8 * (sizeof(uint64_t) - sizeof(std::size_t)))); - return high_bits; -} - -// Implement hashing for pairs of up-to 64-bit integer values. -// We use the compound integer hash method to produce a 64-bit hash code, by -// breaking the two 64-bit inputs into 4 32-bit values: -// http://opendatastructures.org/versions/edition-0.1d/ods-java/node33.html#SECTION00832000000000000000 -// Then we reduce our result to 32 bits if required, similar to above. -inline std::size_t HashInts64(uint64_t value1, uint64_t value2) { - uint32_t short_random1 = 842304669U; - uint32_t short_random2 = 619063811U; - uint32_t short_random3 = 937041849U; - uint32_t short_random4 = 3309708029U; - - uint32_t value1a = static_cast<uint32_t>(value1 & 0xffffffff); - uint32_t value1b = static_cast<uint32_t>((value1 >> 32) & 0xffffffff); - uint32_t value2a = static_cast<uint32_t>(value2 & 0xffffffff); - uint32_t value2b = static_cast<uint32_t>((value2 >> 32) & 0xffffffff); - - uint64_t product1 = static_cast<uint64_t>(value1a) * short_random1; - uint64_t product2 = static_cast<uint64_t>(value1b) * short_random2; - uint64_t product3 = static_cast<uint64_t>(value2a) * short_random3; - uint64_t product4 = static_cast<uint64_t>(value2b) * short_random4; - - uint64_t hash64 = product1 + product2 + product3 + product4; - - if (sizeof(std::size_t) >= sizeof(uint64_t)) - return static_cast<std::size_t>(hash64); - - uint64_t odd_random = 1578233944LL << 32 | 194370989LL; - uint32_t shift_random = 20591U << 16; - - hash64 = hash64 * odd_random + shift_random; - std::size_t high_bits = static_cast<std::size_t>( - hash64 >> (8 * (sizeof(uint64_t) - sizeof(std::size_t)))); - return high_bits; -} - -template<typename T1, typename T2> -inline std::size_t HashPair(T1 value1, T2 value2) { - // This condition is expected to be compile-time evaluated and optimised away - // in release builds. - if (sizeof(T1) > sizeof(uint32_t) || (sizeof(T2) > sizeof(uint32_t))) - return HashInts64(value1, value2); - - return HashInts32(value1, value2); -} - -} // namespace base - -namespace BASE_HASH_NAMESPACE { - -// Implement methods for hashing a pair of integers, so they can be used as -// keys in STL containers. - -template<typename Type1, typename Type2> -struct hash<std::pair<Type1, Type2> > { - std::size_t operator()(std::pair<Type1, Type2> value) const { - return base::HashPair(value.first, value.second); - } -}; - -} // namespace BASE_HASH_NAMESPACE - -#undef DEFINE_PAIR_HASH_FUNCTION_START -#undef DEFINE_PAIR_HASH_FUNCTION_END - -#endif // BASE_CONTAINERS_HASH_TABLES_H_ diff --git a/security/sandbox/chromium/base/cpu.cc b/security/sandbox/chromium/base/cpu.cc deleted file mode 100644 index 713544566..000000000 --- a/security/sandbox/chromium/base/cpu.cc +++ /dev/null @@ -1,296 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/cpu.h" - -#include <limits.h> -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> - -#include <algorithm> - -#include "base/macros.h" -#include "base/strings/string_piece.h" -#include "build/build_config.h" - -#if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX)) -#include "base/files/file_util.h" -#include "base/lazy_instance.h" -#endif - -#if defined(ARCH_CPU_X86_FAMILY) -#if defined(_MSC_VER) -#include <intrin.h> -#include <immintrin.h> // For _xgetbv() -#endif -#endif - -namespace base { - -CPU::CPU() - : signature_(0), - type_(0), - family_(0), - model_(0), - stepping_(0), - ext_model_(0), - ext_family_(0), - has_mmx_(false), - has_sse_(false), - has_sse2_(false), - has_sse3_(false), - has_ssse3_(false), - has_sse41_(false), - has_sse42_(false), - has_avx_(false), - has_avx2_(false), - has_aesni_(false), - has_non_stop_time_stamp_counter_(false), - has_broken_neon_(false), - cpu_vendor_("unknown") { - Initialize(); -} - -namespace { - -#if defined(ARCH_CPU_X86_FAMILY) -#ifndef _MSC_VER - -#if defined(__pic__) && defined(__i386__) - -void __cpuid(int cpu_info[4], int info_type) { - __asm__ volatile ( - "mov %%ebx, %%edi\n" - "cpuid\n" - "xchg %%edi, %%ebx\n" - : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) - : "a"(info_type) - ); -} - -#else - -void __cpuid(int cpu_info[4], int info_type) { - __asm__ volatile ( - "cpuid\n" - : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) - : "a"(info_type) - ); -} - -#endif - -// _xgetbv returns the value of an Intel Extended Control Register (XCR). -// Currently only XCR0 is defined by Intel so |xcr| should always be zero. -uint64_t _xgetbv(uint32_t xcr) { - uint32_t eax, edx; - - __asm__ volatile ( - "xgetbv" : "=a"(eax), "=d"(edx) : "c"(xcr)); - return (static_cast<uint64_t>(edx) << 32) | eax; -} - -#endif // !_MSC_VER -#endif // ARCH_CPU_X86_FAMILY - -#if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX)) -class LazyCpuInfoValue { - public: - LazyCpuInfoValue() : has_broken_neon_(false) { - // This function finds the value from /proc/cpuinfo under the key "model - // name" or "Processor". "model name" is used in Linux 3.8 and later (3.7 - // and later for arm64) and is shown once per CPU. "Processor" is used in - // earler versions and is shown only once at the top of /proc/cpuinfo - // regardless of the number CPUs. - const char kModelNamePrefix[] = "model name\t: "; - const char kProcessorPrefix[] = "Processor\t: "; - - // This function also calculates whether we believe that this CPU has a - // broken NEON unit based on these fields from cpuinfo: - unsigned implementer = 0, architecture = 0, variant = 0, part = 0, - revision = 0; - const struct { - const char key[17]; - unsigned int* result; - } kUnsignedValues[] = { - {"CPU implementer", &implementer}, - {"CPU architecture", &architecture}, - {"CPU variant", &variant}, - {"CPU part", &part}, - {"CPU revision", &revision}, - }; - - std::string contents; - ReadFileToString(FilePath("/proc/cpuinfo"), &contents); - DCHECK(!contents.empty()); - if (contents.empty()) { - return; - } - - std::istringstream iss(contents); - std::string line; - while (std::getline(iss, line)) { - if (brand_.empty() && - (line.compare(0, strlen(kModelNamePrefix), kModelNamePrefix) == 0 || - line.compare(0, strlen(kProcessorPrefix), kProcessorPrefix) == 0)) { - brand_.assign(line.substr(strlen(kModelNamePrefix))); - } - - for (size_t i = 0; i < arraysize(kUnsignedValues); i++) { - const char *key = kUnsignedValues[i].key; - const size_t len = strlen(key); - - if (line.compare(0, len, key) == 0 && - line.size() >= len + 1 && - (line[len] == '\t' || line[len] == ' ' || line[len] == ':')) { - size_t colon_pos = line.find(':', len); - if (colon_pos == std::string::npos) { - continue; - } - - const StringPiece line_sp(line); - StringPiece value_sp = line_sp.substr(colon_pos + 1); - while (!value_sp.empty() && - (value_sp[0] == ' ' || value_sp[0] == '\t')) { - value_sp = value_sp.substr(1); - } - - // The string may have leading "0x" or not, so we use strtoul to - // handle that. - char* endptr; - std::string value(value_sp.as_string()); - unsigned long int result = strtoul(value.c_str(), &endptr, 0); - if (*endptr == 0 && result <= UINT_MAX) { - *kUnsignedValues[i].result = result; - } - } - } - } - - has_broken_neon_ = - implementer == 0x51 && - architecture == 7 && - variant == 1 && - part == 0x4d && - revision == 0; - } - - const std::string& brand() const { return brand_; } - bool has_broken_neon() const { return has_broken_neon_; } - - private: - std::string brand_; - bool has_broken_neon_; - DISALLOW_COPY_AND_ASSIGN(LazyCpuInfoValue); -}; - -base::LazyInstance<LazyCpuInfoValue>::Leaky g_lazy_cpuinfo = - LAZY_INSTANCE_INITIALIZER; - -#endif // defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || - // defined(OS_LINUX)) - -} // anonymous namespace - -void CPU::Initialize() { -#if defined(ARCH_CPU_X86_FAMILY) - int cpu_info[4] = {-1}; - char cpu_string[48]; - - // __cpuid with an InfoType argument of 0 returns the number of - // valid Ids in CPUInfo[0] and the CPU identification string in - // the other three array elements. The CPU identification string is - // not in linear order. The code below arranges the information - // in a human readable form. The human readable order is CPUInfo[1] | - // CPUInfo[3] | CPUInfo[2]. CPUInfo[2] and CPUInfo[3] are swapped - // before using memcpy to copy these three array elements to cpu_string. - __cpuid(cpu_info, 0); - int num_ids = cpu_info[0]; - std::swap(cpu_info[2], cpu_info[3]); - memcpy(cpu_string, &cpu_info[1], 3 * sizeof(cpu_info[1])); - cpu_vendor_.assign(cpu_string, 3 * sizeof(cpu_info[1])); - - // Interpret CPU feature information. - if (num_ids > 0) { - int cpu_info7[4] = {0}; - __cpuid(cpu_info, 1); - if (num_ids >= 7) { - __cpuid(cpu_info7, 7); - } - signature_ = cpu_info[0]; - stepping_ = cpu_info[0] & 0xf; - model_ = ((cpu_info[0] >> 4) & 0xf) + ((cpu_info[0] >> 12) & 0xf0); - family_ = (cpu_info[0] >> 8) & 0xf; - type_ = (cpu_info[0] >> 12) & 0x3; - ext_model_ = (cpu_info[0] >> 16) & 0xf; - ext_family_ = (cpu_info[0] >> 20) & 0xff; - has_mmx_ = (cpu_info[3] & 0x00800000) != 0; - has_sse_ = (cpu_info[3] & 0x02000000) != 0; - has_sse2_ = (cpu_info[3] & 0x04000000) != 0; - has_sse3_ = (cpu_info[2] & 0x00000001) != 0; - has_ssse3_ = (cpu_info[2] & 0x00000200) != 0; - has_sse41_ = (cpu_info[2] & 0x00080000) != 0; - has_sse42_ = (cpu_info[2] & 0x00100000) != 0; - // AVX instructions will generate an illegal instruction exception unless - // a) they are supported by the CPU, - // b) XSAVE is supported by the CPU and - // c) XSAVE is enabled by the kernel. - // See http://software.intel.com/en-us/blogs/2011/04/14/is-avx-enabled - // - // In addition, we have observed some crashes with the xgetbv instruction - // even after following Intel's example code. (See crbug.com/375968.) - // Because of that, we also test the XSAVE bit because its description in - // the CPUID documentation suggests that it signals xgetbv support. - has_avx_ = - (cpu_info[2] & 0x10000000) != 0 && - (cpu_info[2] & 0x04000000) != 0 /* XSAVE */ && - (cpu_info[2] & 0x08000000) != 0 /* OSXSAVE */ && - (_xgetbv(0) & 6) == 6 /* XSAVE enabled by kernel */; - has_aesni_ = (cpu_info[2] & 0x02000000) != 0; - has_avx2_ = has_avx_ && (cpu_info7[1] & 0x00000020) != 0; - } - - // Get the brand string of the cpu. - __cpuid(cpu_info, 0x80000000); - const int parameter_end = 0x80000004; - int max_parameter = cpu_info[0]; - - if (cpu_info[0] >= parameter_end) { - char* cpu_string_ptr = cpu_string; - - for (int parameter = 0x80000002; parameter <= parameter_end && - cpu_string_ptr < &cpu_string[sizeof(cpu_string)]; parameter++) { - __cpuid(cpu_info, parameter); - memcpy(cpu_string_ptr, cpu_info, sizeof(cpu_info)); - cpu_string_ptr += sizeof(cpu_info); - } - cpu_brand_.assign(cpu_string, cpu_string_ptr - cpu_string); - } - - const int parameter_containing_non_stop_time_stamp_counter = 0x80000007; - if (max_parameter >= parameter_containing_non_stop_time_stamp_counter) { - __cpuid(cpu_info, parameter_containing_non_stop_time_stamp_counter); - has_non_stop_time_stamp_counter_ = (cpu_info[3] & (1 << 8)) != 0; - } -#elif defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX)) - cpu_brand_.assign(g_lazy_cpuinfo.Get().brand()); - has_broken_neon_ = g_lazy_cpuinfo.Get().has_broken_neon(); -#endif -} - -CPU::IntelMicroArchitecture CPU::GetIntelMicroArchitecture() const { - if (has_avx2()) return AVX2; - if (has_avx()) return AVX; - if (has_sse42()) return SSE42; - if (has_sse41()) return SSE41; - if (has_ssse3()) return SSSE3; - if (has_sse3()) return SSE3; - if (has_sse2()) return SSE2; - if (has_sse()) return SSE; - return PENTIUM; -} - -} // namespace base diff --git a/security/sandbox/chromium/base/cpu.h b/security/sandbox/chromium/base/cpu.h deleted file mode 100644 index 8c3c06c04..000000000 --- a/security/sandbox/chromium/base/cpu.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_CPU_H_ -#define BASE_CPU_H_ - -#include <string> - -#include "base/base_export.h" - -namespace base { - -// Query information about the processor. -class BASE_EXPORT CPU { - public: - // Constructor - CPU(); - - enum IntelMicroArchitecture { - PENTIUM, - SSE, - SSE2, - SSE3, - SSSE3, - SSE41, - SSE42, - AVX, - AVX2, - MAX_INTEL_MICRO_ARCHITECTURE - }; - - // Accessors for CPU information. - const std::string& vendor_name() const { return cpu_vendor_; } - int signature() const { return signature_; } - int stepping() const { return stepping_; } - int model() const { return model_; } - int family() const { return family_; } - int type() const { return type_; } - int extended_model() const { return ext_model_; } - int extended_family() const { return ext_family_; } - bool has_mmx() const { return has_mmx_; } - bool has_sse() const { return has_sse_; } - bool has_sse2() const { return has_sse2_; } - bool has_sse3() const { return has_sse3_; } - bool has_ssse3() const { return has_ssse3_; } - bool has_sse41() const { return has_sse41_; } - bool has_sse42() const { return has_sse42_; } - bool has_avx() const { return has_avx_; } - bool has_avx2() const { return has_avx2_; } - bool has_aesni() const { return has_aesni_; } - bool has_non_stop_time_stamp_counter() const { - return has_non_stop_time_stamp_counter_; - } - // has_broken_neon is only valid on ARM chips. If true, it indicates that we - // believe that the NEON unit on the current CPU is flawed and cannot execute - // some code. See https://code.google.com/p/chromium/issues/detail?id=341598 - bool has_broken_neon() const { return has_broken_neon_; } - - IntelMicroArchitecture GetIntelMicroArchitecture() const; - const std::string& cpu_brand() const { return cpu_brand_; } - - private: - // Query the processor for CPUID information. - void Initialize(); - - int signature_; // raw form of type, family, model, and stepping - int type_; // process type - int family_; // family of the processor - int model_; // model of processor - int stepping_; // processor revision number - int ext_model_; - int ext_family_; - bool has_mmx_; - bool has_sse_; - bool has_sse2_; - bool has_sse3_; - bool has_ssse3_; - bool has_sse41_; - bool has_sse42_; - bool has_avx_; - bool has_avx2_; - bool has_aesni_; - bool has_non_stop_time_stamp_counter_; - bool has_broken_neon_; - std::string cpu_vendor_; - std::string cpu_brand_; -}; - -} // namespace base - -#endif // BASE_CPU_H_ diff --git a/security/sandbox/chromium/base/debug/alias.cc b/security/sandbox/chromium/base/debug/alias.cc deleted file mode 100644 index 6b0caaa6d..000000000 --- a/security/sandbox/chromium/base/debug/alias.cc +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/debug/alias.h" -#include "build/build_config.h" - -namespace base { -namespace debug { - -#if defined(COMPILER_MSVC) -#pragma optimize("", off) -#endif - -void Alias(const void* var) { -} - -#if defined(COMPILER_MSVC) -#pragma optimize("", on) -#endif - -} // namespace debug -} // namespace base diff --git a/security/sandbox/chromium/base/debug/alias.h b/security/sandbox/chromium/base/debug/alias.h deleted file mode 100644 index 3b2ab64f3..000000000 --- a/security/sandbox/chromium/base/debug/alias.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_DEBUG_ALIAS_H_ -#define BASE_DEBUG_ALIAS_H_ - -#include "base/base_export.h" - -namespace base { -namespace debug { - -// Make the optimizer think that var is aliased. This is to prevent it from -// optimizing out variables that that would not otherwise be live at the point -// of a potential crash. -void BASE_EXPORT Alias(const void* var); - -} // namespace debug -} // namespace base - -#endif // BASE_DEBUG_ALIAS_H_ diff --git a/security/sandbox/chromium/base/debug/debugger.h b/security/sandbox/chromium/base/debug/debugger.h deleted file mode 100644 index 8680e281e..000000000 --- a/security/sandbox/chromium/base/debug/debugger.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This is a cross platform interface for helper functions related to -// debuggers. You should use this to test if you're running under a debugger, -// and if you would like to yield (breakpoint) into the debugger. - -#ifndef BASE_DEBUG_DEBUGGER_H_ -#define BASE_DEBUG_DEBUGGER_H_ - -#include "base/base_export.h" - -namespace base { -namespace debug { - -// Waits wait_seconds seconds for a debugger to attach to the current process. -// When silent is false, an exception is thrown when a debugger is detected. -BASE_EXPORT bool WaitForDebugger(int wait_seconds, bool silent); - -// Returns true if the given process is being run under a debugger. -// -// On OS X, the underlying mechanism doesn't work when the sandbox is enabled. -// To get around this, this function caches its value. -// -// WARNING: Because of this, on OS X, a call MUST be made to this function -// BEFORE the sandbox is enabled. -BASE_EXPORT bool BeingDebugged(); - -// Break into the debugger, assumes a debugger is present. -BASE_EXPORT void BreakDebugger(); - -// Used in test code, this controls whether showing dialogs and breaking into -// the debugger is suppressed for debug errors, even in debug mode (normally -// release mode doesn't do this stuff -- this is controlled separately). -// Normally UI is not suppressed. This is normally used when running automated -// tests where we want a crash rather than a dialog or a debugger. -BASE_EXPORT void SetSuppressDebugUI(bool suppress); -BASE_EXPORT bool IsDebugUISuppressed(); - -} // namespace debug -} // namespace base - -#endif // BASE_DEBUG_DEBUGGER_H_ diff --git a/security/sandbox/chromium/base/debug/leak_annotations.h b/security/sandbox/chromium/base/debug/leak_annotations.h deleted file mode 100644 index dc502461d..000000000 --- a/security/sandbox/chromium/base/debug/leak_annotations.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_DEBUG_LEAK_ANNOTATIONS_H_ -#define BASE_DEBUG_LEAK_ANNOTATIONS_H_ - -#include "base/macros.h" -#include "build/build_config.h" - -// This file defines macros which can be used to annotate intentional memory -// leaks. Support for annotations is implemented in LeakSanitizer. Annotated -// objects will be treated as a source of live pointers, i.e. any heap objects -// reachable by following pointers from an annotated object will not be -// reported as leaks. -// -// ANNOTATE_SCOPED_MEMORY_LEAK: all allocations made in the current scope -// will be annotated as leaks. -// ANNOTATE_LEAKING_OBJECT_PTR(X): the heap object referenced by pointer X will -// be annotated as a leak. - -#if defined(LEAK_SANITIZER) && !defined(OS_NACL) - -#include <sanitizer/lsan_interface.h> - -class ScopedLeakSanitizerDisabler { - public: - ScopedLeakSanitizerDisabler() { __lsan_disable(); } - ~ScopedLeakSanitizerDisabler() { __lsan_enable(); } - private: - DISALLOW_COPY_AND_ASSIGN(ScopedLeakSanitizerDisabler); -}; - -#define ANNOTATE_SCOPED_MEMORY_LEAK \ - ScopedLeakSanitizerDisabler leak_sanitizer_disabler; static_cast<void>(0) - -#define ANNOTATE_LEAKING_OBJECT_PTR(X) __lsan_ignore_object(X); - -#else - -#define ANNOTATE_SCOPED_MEMORY_LEAK ((void)0) -#define ANNOTATE_LEAKING_OBJECT_PTR(X) ((void)0) - -#endif - -#endif // BASE_DEBUG_LEAK_ANNOTATIONS_H_ diff --git a/security/sandbox/chromium/base/debug/profiler.cc b/security/sandbox/chromium/base/debug/profiler.cc deleted file mode 100644 index 75e9aac0c..000000000 --- a/security/sandbox/chromium/base/debug/profiler.cc +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/debug/profiler.h" - -#include <string> - -#include "base/debug/debugging_flags.h" -#include "base/process/process_handle.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "build/build_config.h" - -#if defined(OS_WIN) -#include "base/win/pe_image.h" -#endif // defined(OS_WIN) - -// TODO(peria): Enable profiling on Windows. -#if BUILDFLAG(ENABLE_PROFILING) && !defined(NO_TCMALLOC) && !defined(OS_WIN) -#include "third_party/tcmalloc/chromium/src/gperftools/profiler.h" -#endif - -namespace base { -namespace debug { - -// TODO(peria): Enable profiling on Windows. -#if BUILDFLAG(ENABLE_PROFILING) && !defined(NO_TCMALLOC) && !defined(OS_WIN) - -static int profile_count = 0; - -void StartProfiling(const std::string& name) { - ++profile_count; - std::string full_name(name); - std::string pid = IntToString(GetCurrentProcId()); - std::string count = IntToString(profile_count); - ReplaceSubstringsAfterOffset(&full_name, 0, "{pid}", pid); - ReplaceSubstringsAfterOffset(&full_name, 0, "{count}", count); - ProfilerStart(full_name.c_str()); -} - -void StopProfiling() { - ProfilerFlush(); - ProfilerStop(); -} - -void FlushProfiling() { - ProfilerFlush(); -} - -bool BeingProfiled() { - return ProfilingIsEnabledForAllThreads(); -} - -void RestartProfilingAfterFork() { - ProfilerRegisterThread(); -} - -#else - -void StartProfiling(const std::string& name) { -} - -void StopProfiling() { -} - -void FlushProfiling() { -} - -bool BeingProfiled() { - return false; -} - -void RestartProfilingAfterFork() { -} - -#endif - -#if !defined(OS_WIN) - -bool IsBinaryInstrumented() { - return false; -} - -ReturnAddressLocationResolver GetProfilerReturnAddrResolutionFunc() { - return NULL; -} - -DynamicFunctionEntryHook GetProfilerDynamicFunctionEntryHookFunc() { - return NULL; -} - -AddDynamicSymbol GetProfilerAddDynamicSymbolFunc() { - return NULL; -} - -MoveDynamicSymbol GetProfilerMoveDynamicSymbolFunc() { - return NULL; -} - -#else // defined(OS_WIN) - -// http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx -extern "C" IMAGE_DOS_HEADER __ImageBase; - -bool IsBinaryInstrumented() { - enum InstrumentationCheckState { - UNINITIALIZED, - INSTRUMENTED_IMAGE, - NON_INSTRUMENTED_IMAGE, - }; - - static InstrumentationCheckState state = UNINITIALIZED; - - if (state == UNINITIALIZED) { - HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase); - base::win::PEImage image(this_module); - - // Check to be sure our image is structured as we'd expect. - DCHECK(image.VerifyMagic()); - - // Syzygy-instrumented binaries contain a PE image section named ".thunks", - // and all Syzygy-modified binaries contain the ".syzygy" image section. - // This is a very fast check, as it only looks at the image header. - if ((image.GetImageSectionHeaderByName(".thunks") != NULL) && - (image.GetImageSectionHeaderByName(".syzygy") != NULL)) { - state = INSTRUMENTED_IMAGE; - } else { - state = NON_INSTRUMENTED_IMAGE; - } - } - DCHECK(state != UNINITIALIZED); - - return state == INSTRUMENTED_IMAGE; -} - -namespace { - -struct FunctionSearchContext { - const char* name; - FARPROC function; -}; - -// Callback function to PEImage::EnumImportChunks. -bool FindResolutionFunctionInImports( - const base::win::PEImage &image, const char* module_name, - PIMAGE_THUNK_DATA unused_name_table, PIMAGE_THUNK_DATA import_address_table, - PVOID cookie) { - FunctionSearchContext* context = - reinterpret_cast<FunctionSearchContext*>(cookie); - - DCHECK_NE(static_cast<FunctionSearchContext*>(NULL), context); - DCHECK_EQ(static_cast<FARPROC>(NULL), context->function); - - // Our import address table contains pointers to the functions we import - // at this point. Let's retrieve the first such function and use it to - // find the module this import was resolved to by the loader. - const wchar_t* function_in_module = - reinterpret_cast<const wchar_t*>(import_address_table->u1.Function); - - // Retrieve the module by a function in the module. - const DWORD kFlags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | - GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT; - HMODULE module = NULL; - if (!::GetModuleHandleEx(kFlags, function_in_module, &module)) { - // This can happen if someone IAT patches us to a thunk. - return true; - } - - // See whether this module exports the function we're looking for. - FARPROC exported_func = ::GetProcAddress(module, context->name); - if (exported_func != NULL) { - // We found it, return the function and terminate the enumeration. - context->function = exported_func; - return false; - } - - // Keep going. - return true; -} - -template <typename FunctionType> -FunctionType FindFunctionInImports(const char* function_name) { - if (!IsBinaryInstrumented()) - return NULL; - - HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase); - base::win::PEImage image(this_module); - - FunctionSearchContext ctx = { function_name, NULL }; - image.EnumImportChunks(FindResolutionFunctionInImports, &ctx); - - return reinterpret_cast<FunctionType>(ctx.function); -} - -} // namespace - -ReturnAddressLocationResolver GetProfilerReturnAddrResolutionFunc() { - return FindFunctionInImports<ReturnAddressLocationResolver>( - "ResolveReturnAddressLocation"); -} - -DynamicFunctionEntryHook GetProfilerDynamicFunctionEntryHookFunc() { - return FindFunctionInImports<DynamicFunctionEntryHook>( - "OnDynamicFunctionEntry"); -} - -AddDynamicSymbol GetProfilerAddDynamicSymbolFunc() { - return FindFunctionInImports<AddDynamicSymbol>( - "AddDynamicSymbol"); -} - -MoveDynamicSymbol GetProfilerMoveDynamicSymbolFunc() { - return FindFunctionInImports<MoveDynamicSymbol>( - "MoveDynamicSymbol"); -} - -#endif // defined(OS_WIN) - -} // namespace debug -} // namespace base diff --git a/security/sandbox/chromium/base/debug/profiler.h b/security/sandbox/chromium/base/debug/profiler.h deleted file mode 100644 index 7cce7b08f..000000000 --- a/security/sandbox/chromium/base/debug/profiler.h +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_DEBUG_PROFILER_H_ -#define BASE_DEBUG_PROFILER_H_ - -#include <stddef.h> - -#include <string> - -#include "base/base_export.h" - -// The Profiler functions allow usage of the underlying sampling based -// profiler. If the application has not been built with the necessary -// flags (-DENABLE_PROFILING and not -DNO_TCMALLOC) then these functions -// are noops. -namespace base { -namespace debug { - -// Start profiling with the supplied name. -// {pid} will be replaced by the process' pid and {count} will be replaced -// by the count of the profile run (starts at 1 with each process). -BASE_EXPORT void StartProfiling(const std::string& name); - -// Stop profiling and write out data. -BASE_EXPORT void StopProfiling(); - -// Force data to be written to file. -BASE_EXPORT void FlushProfiling(); - -// Returns true if process is being profiled. -BASE_EXPORT bool BeingProfiled(); - -// Reset profiling after a fork, which disables timers. -BASE_EXPORT void RestartProfilingAfterFork(); - -// Returns true iff this executable is instrumented with the Syzygy profiler. -BASE_EXPORT bool IsBinaryInstrumented(); - -// There's a class of profilers that use "return address swizzling" to get a -// hook on function exits. This class of profilers uses some form of entry hook, -// like e.g. binary instrumentation, or a compiler flag, that calls a hook each -// time a function is invoked. The hook then switches the return address on the -// stack for the address of an exit hook function, and pushes the original -// return address to a shadow stack of some type. When in due course the CPU -// executes a return to the exit hook, the exit hook will do whatever work it -// does on function exit, then arrange to return to the original return address. -// This class of profiler does not play well with programs that look at the -// return address, as does e.g. V8. V8 uses the return address to certain -// runtime functions to find the JIT code that called it, and from there finds -// the V8 data structures associated to the JS function involved. -// A return address resolution function is used to fix this. It allows such -// programs to resolve a location on stack where a return address originally -// resided, to the shadow stack location where the profiler stashed it. -typedef uintptr_t (*ReturnAddressLocationResolver)( - uintptr_t return_addr_location); - -// This type declaration must match V8's FunctionEntryHook. -typedef void (*DynamicFunctionEntryHook)(uintptr_t function, - uintptr_t return_addr_location); - -// The functions below here are to support profiling V8-generated code. -// V8 has provisions for generating a call to an entry hook for newly generated -// JIT code, and it can push symbol information on code generation and advise -// when the garbage collector moves code. The functions declarations below here -// make glue between V8's facilities and a profiler. - -// This type declaration must match V8's FunctionEntryHook. -typedef void (*DynamicFunctionEntryHook)(uintptr_t function, - uintptr_t return_addr_location); - -typedef void (*AddDynamicSymbol)(const void* address, - size_t length, - const char* name, - size_t name_len); -typedef void (*MoveDynamicSymbol)(const void* address, const void* new_address); - - -// If this binary is instrumented and the instrumentation supplies a function -// for each of those purposes, find and return the function in question. -// Otherwise returns NULL. -BASE_EXPORT ReturnAddressLocationResolver GetProfilerReturnAddrResolutionFunc(); -BASE_EXPORT DynamicFunctionEntryHook GetProfilerDynamicFunctionEntryHookFunc(); -BASE_EXPORT AddDynamicSymbol GetProfilerAddDynamicSymbolFunc(); -BASE_EXPORT MoveDynamicSymbol GetProfilerMoveDynamicSymbolFunc(); - -} // namespace debug -} // namespace base - -#endif // BASE_DEBUG_PROFILER_H_ diff --git a/security/sandbox/chromium/base/file_descriptor_posix.h b/security/sandbox/chromium/base/file_descriptor_posix.h deleted file mode 100644 index 2a366116a..000000000 --- a/security/sandbox/chromium/base/file_descriptor_posix.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_FILE_DESCRIPTOR_POSIX_H_ -#define BASE_FILE_DESCRIPTOR_POSIX_H_ - -#include "base/files/file.h" -#include "base/files/scoped_file.h" - -namespace base { - -// ----------------------------------------------------------------------------- -// We introduct a special structure for file descriptors in order that we are -// able to use template specialisation to special-case their handling. -// -// IMPORTANT: This is primarily intended for use when sending file descriptors -// over IPC. Even if |auto_close| is true, base::FileDescriptor does NOT close() -// |fd| when going out of scope. Instead, a consumer of a base::FileDescriptor -// must invoke close() on |fd| if |auto_close| is true. -// -// In the case of IPC, the the IPC subsystem knows to close() |fd| after sending -// a message that contains a base::FileDescriptor if auto_close == true. On the -// other end, the receiver must make sure to close() |fd| after it has finished -// processing the IPC message. See the IPC::ParamTraits<> specialization in -// ipc/ipc_message_utils.h for all the details. -// ----------------------------------------------------------------------------- -struct FileDescriptor { - FileDescriptor() : fd(-1), auto_close(false) {} - - FileDescriptor(int ifd, bool iauto_close) : fd(ifd), auto_close(iauto_close) { - } - - FileDescriptor(File file) : fd(file.TakePlatformFile()), auto_close(true) {} - explicit FileDescriptor(ScopedFD fd) : fd(fd.release()), auto_close(true) {} - - bool operator==(const FileDescriptor& other) const { - return (fd == other.fd && auto_close == other.auto_close); - } - - bool operator!=(const FileDescriptor& other) const { - return !operator==(other); - } - - // A comparison operator so that we can use these as keys in a std::map. - bool operator<(const FileDescriptor& other) const { - return other.fd < fd; - } - - int fd; - // If true, this file descriptor should be closed after it has been used. For - // example an IPC system might interpret this flag as indicating that the - // file descriptor it has been given should be closed after use. - bool auto_close; -}; - -} // namespace base - -#endif // BASE_FILE_DESCRIPTOR_POSIX_H_ diff --git a/security/sandbox/chromium/base/files/file_path.h b/security/sandbox/chromium/base/files/file_path.h deleted file mode 100644 index 89e9cbfb1..000000000 --- a/security/sandbox/chromium/base/files/file_path.h +++ /dev/null @@ -1,477 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// FilePath is a container for pathnames stored in a platform's native string -// type, providing containers for manipulation in according with the -// platform's conventions for pathnames. It supports the following path -// types: -// -// POSIX Windows -// --------------- ---------------------------------- -// Fundamental type char[] wchar_t[] -// Encoding unspecified* UTF-16 -// Separator / \, tolerant of / -// Drive letters no case-insensitive A-Z followed by : -// Alternate root // (surprise!) \\, for UNC paths -// -// * The encoding need not be specified on POSIX systems, although some -// POSIX-compliant systems do specify an encoding. Mac OS X uses UTF-8. -// Chrome OS also uses UTF-8. -// Linux does not specify an encoding, but in practice, the locale's -// character set may be used. -// -// For more arcane bits of path trivia, see below. -// -// FilePath objects are intended to be used anywhere paths are. An -// application may pass FilePath objects around internally, masking the -// underlying differences between systems, only differing in implementation -// where interfacing directly with the system. For example, a single -// OpenFile(const FilePath &) function may be made available, allowing all -// callers to operate without regard to the underlying implementation. On -// POSIX-like platforms, OpenFile might wrap fopen, and on Windows, it might -// wrap _wfopen_s, perhaps both by calling file_path.value().c_str(). This -// allows each platform to pass pathnames around without requiring conversions -// between encodings, which has an impact on performance, but more imporantly, -// has an impact on correctness on platforms that do not have well-defined -// encodings for pathnames. -// -// Several methods are available to perform common operations on a FilePath -// object, such as determining the parent directory (DirName), isolating the -// final path component (BaseName), and appending a relative pathname string -// to an existing FilePath object (Append). These methods are highly -// recommended over attempting to split and concatenate strings directly. -// These methods are based purely on string manipulation and knowledge of -// platform-specific pathname conventions, and do not consult the filesystem -// at all, making them safe to use without fear of blocking on I/O operations. -// These methods do not function as mutators but instead return distinct -// instances of FilePath objects, and are therefore safe to use on const -// objects. The objects themselves are safe to share between threads. -// -// To aid in initialization of FilePath objects from string literals, a -// FILE_PATH_LITERAL macro is provided, which accounts for the difference -// between char[]-based pathnames on POSIX systems and wchar_t[]-based -// pathnames on Windows. -// -// As a precaution against premature truncation, paths can't contain NULs. -// -// Because a FilePath object should not be instantiated at the global scope, -// instead, use a FilePath::CharType[] and initialize it with -// FILE_PATH_LITERAL. At runtime, a FilePath object can be created from the -// character array. Example: -// -// | const FilePath::CharType kLogFileName[] = FILE_PATH_LITERAL("log.txt"); -// | -// | void Function() { -// | FilePath log_file_path(kLogFileName); -// | [...] -// | } -// -// WARNING: FilePaths should ALWAYS be displayed with LTR directionality, even -// when the UI language is RTL. This means you always need to pass filepaths -// through base::i18n::WrapPathWithLTRFormatting() before displaying it in the -// RTL UI. -// -// This is a very common source of bugs, please try to keep this in mind. -// -// ARCANE BITS OF PATH TRIVIA -// -// - A double leading slash is actually part of the POSIX standard. Systems -// are allowed to treat // as an alternate root, as Windows does for UNC -// (network share) paths. Most POSIX systems don't do anything special -// with two leading slashes, but FilePath handles this case properly -// in case it ever comes across such a system. FilePath needs this support -// for Windows UNC paths, anyway. -// References: -// The Open Group Base Specifications Issue 7, sections 3.267 ("Pathname") -// and 4.12 ("Pathname Resolution"), available at: -// http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_267 -// http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_12 -// -// - Windows treats c:\\ the same way it treats \\. This was intended to -// allow older applications that require drive letters to support UNC paths -// like \\server\share\path, by permitting c:\\server\share\path as an -// equivalent. Since the OS treats these paths specially, FilePath needs -// to do the same. Since Windows can use either / or \ as the separator, -// FilePath treats c://, c:\\, //, and \\ all equivalently. -// Reference: -// The Old New Thing, "Why is a drive letter permitted in front of UNC -// paths (sometimes)?", available at: -// http://blogs.msdn.com/oldnewthing/archive/2005/11/22/495740.aspx - -#ifndef BASE_FILES_FILE_PATH_H_ -#define BASE_FILES_FILE_PATH_H_ - -#include <stddef.h> - -#include <iosfwd> -#include <string> -#include <vector> - -#include "base/base_export.h" -#include "base/compiler_specific.h" -#include "base/containers/hash_tables.h" -#include "base/macros.h" -#include "base/strings/string16.h" -#include "base/strings/string_piece.h" -#include "build/build_config.h" - -// Windows-style drive letter support and pathname separator characters can be -// enabled and disabled independently, to aid testing. These #defines are -// here so that the same setting can be used in both the implementation and -// in the unit test. -#if defined(OS_WIN) -#define FILE_PATH_USES_DRIVE_LETTERS -#define FILE_PATH_USES_WIN_SEPARATORS -#endif // OS_WIN - -// To print path names portably use PRIsFP (based on PRIuS and friends from -// C99 and format_macros.h) like this: -// base::StringPrintf("Path is %" PRIsFP ".\n", path.value().c_str()); -#if defined(OS_POSIX) -#define PRIsFP "s" -#elif defined(OS_WIN) -#define PRIsFP "ls" -#endif // OS_WIN - -namespace base { - -class Pickle; -class PickleIterator; - -// An abstraction to isolate users from the differences between native -// pathnames on different platforms. -class BASE_EXPORT FilePath { - public: -#if defined(OS_POSIX) - // On most platforms, native pathnames are char arrays, and the encoding - // may or may not be specified. On Mac OS X, native pathnames are encoded - // in UTF-8. - typedef std::string StringType; -#elif defined(OS_WIN) - // On Windows, for Unicode-aware applications, native pathnames are wchar_t - // arrays encoded in UTF-16. - typedef std::wstring StringType; -#endif // OS_WIN - - typedef BasicStringPiece<StringType> StringPieceType; - typedef StringType::value_type CharType; - - // Null-terminated array of separators used to separate components in - // hierarchical paths. Each character in this array is a valid separator, - // but kSeparators[0] is treated as the canonical separator and will be used - // when composing pathnames. - static const CharType kSeparators[]; - - // arraysize(kSeparators). - static const size_t kSeparatorsLength; - - // A special path component meaning "this directory." - static const CharType kCurrentDirectory[]; - - // A special path component meaning "the parent directory." - static const CharType kParentDirectory[]; - - // The character used to identify a file extension. - static const CharType kExtensionSeparator; - - FilePath(); - FilePath(const FilePath& that); - explicit FilePath(StringPieceType path); - ~FilePath(); - FilePath& operator=(const FilePath& that); - - bool operator==(const FilePath& that) const; - - bool operator!=(const FilePath& that) const; - - // Required for some STL containers and operations - bool operator<(const FilePath& that) const { - return path_ < that.path_; - } - - const StringType& value() const { return path_; } - - bool empty() const { return path_.empty(); } - - void clear() { path_.clear(); } - - // Returns true if |character| is in kSeparators. - static bool IsSeparator(CharType character); - - // Returns a vector of all of the components of the provided path. It is - // equivalent to calling DirName().value() on the path's root component, - // and BaseName().value() on each child component. - // - // To make sure this is lossless so we can differentiate absolute and - // relative paths, the root slash will be included even though no other - // slashes will be. The precise behavior is: - // - // Posix: "/foo/bar" -> [ "/", "foo", "bar" ] - // Windows: "C:\foo\bar" -> [ "C:", "\\", "foo", "bar" ] - void GetComponents(std::vector<FilePath::StringType>* components) const; - - // Returns true if this FilePath is a strict parent of the |child|. Absolute - // and relative paths are accepted i.e. is /foo parent to /foo/bar and - // is foo parent to foo/bar. Does not convert paths to absolute, follow - // symlinks or directory navigation (e.g. ".."). A path is *NOT* its own - // parent. - bool IsParent(const FilePath& child) const; - - // If IsParent(child) holds, appends to path (if non-NULL) the - // relative path to child and returns true. For example, if parent - // holds "/Users/johndoe/Library/Application Support", child holds - // "/Users/johndoe/Library/Application Support/Google/Chrome/Default", and - // *path holds "/Users/johndoe/Library/Caches", then after - // parent.AppendRelativePath(child, path) is called *path will hold - // "/Users/johndoe/Library/Caches/Google/Chrome/Default". Otherwise, - // returns false. - bool AppendRelativePath(const FilePath& child, FilePath* path) const; - - // Returns a FilePath corresponding to the directory containing the path - // named by this object, stripping away the file component. If this object - // only contains one component, returns a FilePath identifying - // kCurrentDirectory. If this object already refers to the root directory, - // returns a FilePath identifying the root directory. - FilePath DirName() const WARN_UNUSED_RESULT; - - // Returns a FilePath corresponding to the last path component of this - // object, either a file or a directory. If this object already refers to - // the root directory, returns a FilePath identifying the root directory; - // this is the only situation in which BaseName will return an absolute path. - FilePath BaseName() const WARN_UNUSED_RESULT; - - // Returns ".jpg" for path "C:\pics\jojo.jpg", or an empty string if - // the file has no extension. If non-empty, Extension() will always start - // with precisely one ".". The following code should always work regardless - // of the value of path. For common double-extensions like .tar.gz and - // .user.js, this method returns the combined extension. For a single - // component, use FinalExtension(). - // new_path = path.RemoveExtension().value().append(path.Extension()); - // ASSERT(new_path == path.value()); - // NOTE: this is different from the original file_util implementation which - // returned the extension without a leading "." ("jpg" instead of ".jpg") - StringType Extension() const WARN_UNUSED_RESULT; - - // Returns the path's file extension, as in Extension(), but will - // never return a double extension. - // - // TODO(davidben): Check all our extension-sensitive code to see if - // we can rename this to Extension() and the other to something like - // LongExtension(), defaulting to short extensions and leaving the - // long "extensions" to logic like base::GetUniquePathNumber(). - StringType FinalExtension() const WARN_UNUSED_RESULT; - - // Returns "C:\pics\jojo" for path "C:\pics\jojo.jpg" - // NOTE: this is slightly different from the similar file_util implementation - // which returned simply 'jojo'. - FilePath RemoveExtension() const WARN_UNUSED_RESULT; - - // Removes the path's file extension, as in RemoveExtension(), but - // ignores double extensions. - FilePath RemoveFinalExtension() const WARN_UNUSED_RESULT; - - // Inserts |suffix| after the file name portion of |path| but before the - // extension. Returns "" if BaseName() == "." or "..". - // Examples: - // path == "C:\pics\jojo.jpg" suffix == " (1)", returns "C:\pics\jojo (1).jpg" - // path == "jojo.jpg" suffix == " (1)", returns "jojo (1).jpg" - // path == "C:\pics\jojo" suffix == " (1)", returns "C:\pics\jojo (1)" - // path == "C:\pics.old\jojo" suffix == " (1)", returns "C:\pics.old\jojo (1)" - FilePath InsertBeforeExtension( - StringPieceType suffix) const WARN_UNUSED_RESULT; - FilePath InsertBeforeExtensionASCII( - StringPiece suffix) const WARN_UNUSED_RESULT; - - // Adds |extension| to |file_name|. Returns the current FilePath if - // |extension| is empty. Returns "" if BaseName() == "." or "..". - FilePath AddExtension(StringPieceType extension) const WARN_UNUSED_RESULT; - - // Replaces the extension of |file_name| with |extension|. If |file_name| - // does not have an extension, then |extension| is added. If |extension| is - // empty, then the extension is removed from |file_name|. - // Returns "" if BaseName() == "." or "..". - FilePath ReplaceExtension(StringPieceType extension) const WARN_UNUSED_RESULT; - - // Returns true if the file path matches the specified extension. The test is - // case insensitive. Don't forget the leading period if appropriate. - bool MatchesExtension(StringPieceType extension) const; - - // Returns a FilePath by appending a separator and the supplied path - // component to this object's path. Append takes care to avoid adding - // excessive separators if this object's path already ends with a separator. - // If this object's path is kCurrentDirectory, a new FilePath corresponding - // only to |component| is returned. |component| must be a relative path; - // it is an error to pass an absolute path. - FilePath Append(StringPieceType component) const WARN_UNUSED_RESULT; - FilePath Append(const FilePath& component) const WARN_UNUSED_RESULT; - - // Although Windows StringType is std::wstring, since the encoding it uses for - // paths is well defined, it can handle ASCII path components as well. - // Mac uses UTF8, and since ASCII is a subset of that, it works there as well. - // On Linux, although it can use any 8-bit encoding for paths, we assume that - // ASCII is a valid subset, regardless of the encoding, since many operating - // system paths will always be ASCII. - FilePath AppendASCII(StringPiece component) const WARN_UNUSED_RESULT; - - // Returns true if this FilePath contains an absolute path. On Windows, an - // absolute path begins with either a drive letter specification followed by - // a separator character, or with two separator characters. On POSIX - // platforms, an absolute path begins with a separator character. - bool IsAbsolute() const; - - // Returns true if the patch ends with a path separator character. - bool EndsWithSeparator() const WARN_UNUSED_RESULT; - - // Returns a copy of this FilePath that ends with a trailing separator. If - // the input path is empty, an empty FilePath will be returned. - FilePath AsEndingWithSeparator() const WARN_UNUSED_RESULT; - - // Returns a copy of this FilePath that does not end with a trailing - // separator. - FilePath StripTrailingSeparators() const WARN_UNUSED_RESULT; - - // Returns true if this FilePath contains an attempt to reference a parent - // directory (e.g. has a path component that is ".."). - bool ReferencesParent() const; - - // Return a Unicode human-readable version of this path. - // Warning: you can *not*, in general, go from a display name back to a real - // path. Only use this when displaying paths to users, not just when you - // want to stuff a string16 into some other API. - string16 LossyDisplayName() const; - - // Return the path as ASCII, or the empty string if the path is not ASCII. - // This should only be used for cases where the FilePath is representing a - // known-ASCII filename. - std::string MaybeAsASCII() const; - - // Return the path as UTF-8. - // - // This function is *unsafe* as there is no way to tell what encoding is - // used in file names on POSIX systems other than Mac and Chrome OS, - // although UTF-8 is practically used everywhere these days. To mitigate - // the encoding issue, this function internally calls - // SysNativeMBToWide() on POSIX systems other than Mac and Chrome OS, - // per assumption that the current locale's encoding is used in file - // names, but this isn't a perfect solution. - // - // Once it becomes safe to to stop caring about non-UTF-8 file names, - // the SysNativeMBToWide() hack will be removed from the code, along - // with "Unsafe" in the function name. - std::string AsUTF8Unsafe() const; - - // Similar to AsUTF8Unsafe, but returns UTF-16 instead. - string16 AsUTF16Unsafe() const; - - // Returns a FilePath object from a path name in UTF-8. This function - // should only be used for cases where you are sure that the input - // string is UTF-8. - // - // Like AsUTF8Unsafe(), this function is unsafe. This function - // internally calls SysWideToNativeMB() on POSIX systems other than Mac - // and Chrome OS, to mitigate the encoding issue. See the comment at - // AsUTF8Unsafe() for details. - static FilePath FromUTF8Unsafe(const std::string& utf8); - - // Similar to FromUTF8Unsafe, but accepts UTF-16 instead. - static FilePath FromUTF16Unsafe(const string16& utf16); - - void WriteToPickle(Pickle* pickle) const; - bool ReadFromPickle(PickleIterator* iter); - - // Normalize all path separators to backslash on Windows - // (if FILE_PATH_USES_WIN_SEPARATORS is true), or do nothing on POSIX systems. - FilePath NormalizePathSeparators() const; - - // Normalize all path separattors to given type on Windows - // (if FILE_PATH_USES_WIN_SEPARATORS is true), or do nothing on POSIX systems. - FilePath NormalizePathSeparatorsTo(CharType separator) const; - - // Compare two strings in the same way the file system does. - // Note that these always ignore case, even on file systems that are case- - // sensitive. If case-sensitive comparison is ever needed, add corresponding - // methods here. - // The methods are written as a static method so that they can also be used - // on parts of a file path, e.g., just the extension. - // CompareIgnoreCase() returns -1, 0 or 1 for less-than, equal-to and - // greater-than respectively. - static int CompareIgnoreCase(StringPieceType string1, - StringPieceType string2); - static bool CompareEqualIgnoreCase(StringPieceType string1, - StringPieceType string2) { - return CompareIgnoreCase(string1, string2) == 0; - } - static bool CompareLessIgnoreCase(StringPieceType string1, - StringPieceType string2) { - return CompareIgnoreCase(string1, string2) < 0; - } - -#if defined(OS_MACOSX) - // Returns the string in the special canonical decomposed form as defined for - // HFS, which is close to, but not quite, decomposition form D. See - // http://developer.apple.com/mac/library/technotes/tn/tn1150.html#UnicodeSubtleties - // for further comments. - // Returns the epmty string if the conversion failed. - static StringType GetHFSDecomposedForm(StringPieceType string); - - // Special UTF-8 version of FastUnicodeCompare. Cf: - // http://developer.apple.com/mac/library/technotes/tn/tn1150.html#StringComparisonAlgorithm - // IMPORTANT: The input strings must be in the special HFS decomposed form! - // (cf. above GetHFSDecomposedForm method) - static int HFSFastUnicodeCompare(StringPieceType string1, - StringPieceType string2); -#endif - -#if defined(OS_ANDROID) - // On android, file selection dialog can return a file with content uri - // scheme(starting with content://). Content uri needs to be opened with - // ContentResolver to guarantee that the app has appropriate permissions - // to access it. - // Returns true if the path is a content uri, or false otherwise. - bool IsContentUri() const; -#endif - - private: - // Remove trailing separators from this object. If the path is absolute, it - // will never be stripped any more than to refer to the absolute root - // directory, so "////" will become "/", not "". A leading pair of - // separators is never stripped, to support alternate roots. This is used to - // support UNC paths on Windows. - void StripTrailingSeparatorsInternal(); - - StringType path_; -}; - -// This is required by googletest to print a readable output on test failures. -// This is declared here for use in gtest-based unit tests but is defined in -// the test_support_base target. Depend on that to use this in your unit test. -// This should not be used in production code - call ToString() instead. -void PrintTo(const FilePath& path, std::ostream* out); - -} // namespace base - -// Macros for string literal initialization of FilePath::CharType[], and for -// using a FilePath::CharType[] in a printf-style format string. -#if defined(OS_POSIX) -#define FILE_PATH_LITERAL(x) x -#define PRFilePath "s" -#elif defined(OS_WIN) -#define FILE_PATH_LITERAL(x) L ## x -#define PRFilePath "ls" -#endif // OS_WIN - -// Provide a hash function so that hash_sets and maps can contain FilePath -// objects. -namespace BASE_HASH_NAMESPACE { - -template<> -struct hash<base::FilePath> { - size_t operator()(const base::FilePath& f) const { - return hash<base::FilePath::StringType>()(f.value()); - } -}; - -} // namespace BASE_HASH_NAMESPACE - -#endif // BASE_FILES_FILE_PATH_H_ diff --git a/security/sandbox/chromium/base/guid.h b/security/sandbox/chromium/base/guid.h deleted file mode 100644 index c0a06f885..000000000 --- a/security/sandbox/chromium/base/guid.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_GUID_H_ -#define BASE_GUID_H_ - -#include <stdint.h> - -#include <string> - -#include "base/base_export.h" -#include "build/build_config.h" - -namespace base { - -// Generate a 128-bit random GUID of the form: "%08X-%04X-%04X-%04X-%012llX". -// If GUID generation fails an empty string is returned. -// The POSIX implementation uses pseudo random number generation to create -// the GUID. The Windows implementation uses system services. -BASE_EXPORT std::string GenerateGUID(); - -// Returns true if the input string conforms to the GUID format. -BASE_EXPORT bool IsValidGUID(const std::string& guid); - -#if defined(OS_POSIX) -// For unit testing purposes only. Do not use outside of tests. -BASE_EXPORT std::string RandomDataToGUIDString(const uint64_t bytes[2]); -#endif - -} // namespace base - -#endif // BASE_GUID_H_ diff --git a/security/sandbox/chromium/base/hash.cc b/security/sandbox/chromium/base/hash.cc deleted file mode 100644 index d3206f6a6..000000000 --- a/security/sandbox/chromium/base/hash.cc +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/hash.h" - -// Definition in base/third_party/superfasthash/superfasthash.c. (Third-party -// code did not come with its own header file, so declaring the function here.) -// Note: This algorithm is also in Blink under Source/wtf/StringHasher.h. -extern "C" uint32_t SuperFastHash(const char* data, int len); - -namespace base { - -uint32_t SuperFastHash(const char* data, int len) { - return ::SuperFastHash(data, len); -} - -} // namespace base diff --git a/security/sandbox/chromium/base/hash.h b/security/sandbox/chromium/base/hash.h deleted file mode 100644 index ed8d9fd4c..000000000 --- a/security/sandbox/chromium/base/hash.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_HASH_H_ -#define BASE_HASH_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <limits> -#include <string> - -#include "base/base_export.h" -#include "base/logging.h" - -namespace base { - -// WARNING: This hash function should not be used for any cryptographic purpose. -BASE_EXPORT uint32_t SuperFastHash(const char* data, int len); - -// Computes a hash of a memory buffer |data| of a given |length|. -// WARNING: This hash function should not be used for any cryptographic purpose. -inline uint32_t Hash(const char* data, size_t length) { - if (length > static_cast<size_t>(std::numeric_limits<int>::max())) { - NOTREACHED(); - return 0; - } - return SuperFastHash(data, static_cast<int>(length)); -} - -// Computes a hash of a string |str|. -// WARNING: This hash function should not be used for any cryptographic purpose. -inline uint32_t Hash(const std::string& str) { - return Hash(str.data(), str.size()); -} - -} // namespace base - -#endif // BASE_HASH_H_ diff --git a/security/sandbox/chromium/base/lazy_instance.cc b/security/sandbox/chromium/base/lazy_instance.cc deleted file mode 100644 index 54680655a..000000000 --- a/security/sandbox/chromium/base/lazy_instance.cc +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/lazy_instance.h" - -#include "base/at_exit.h" -#include "base/atomicops.h" -#include "base/threading/platform_thread.h" - -namespace base { -namespace internal { - -// TODO(joth): This function could be shared with Singleton, in place of its -// WaitForInstance() call. -bool NeedsLazyInstance(subtle::AtomicWord* state) { - // Try to create the instance, if we're the first, will go from 0 to - // kLazyInstanceStateCreating, otherwise we've already been beaten here. - // The memory access has no memory ordering as state 0 and - // kLazyInstanceStateCreating have no associated data (memory barriers are - // all about ordering of memory accesses to *associated* data). - if (subtle::NoBarrier_CompareAndSwap(state, 0, - kLazyInstanceStateCreating) == 0) - // Caller must create instance - return true; - - // It's either in the process of being created, or already created. Spin. - // The load has acquire memory ordering as a thread which sees - // state_ == STATE_CREATED needs to acquire visibility over - // the associated data (buf_). Pairing Release_Store is in - // CompleteLazyInstance(). - while (subtle::Acquire_Load(state) == kLazyInstanceStateCreating) { - PlatformThread::YieldCurrentThread(); - } - // Someone else created the instance. - return false; -} - -void CompleteLazyInstance(subtle::AtomicWord* state, - subtle::AtomicWord new_instance, - void* lazy_instance, - void (*dtor)(void*)) { - // Instance is created, go from CREATING to CREATED. - // Releases visibility over private_buf_ to readers. Pairing Acquire_Load's - // are in NeedsInstance() and Pointer(). - subtle::Release_Store(state, new_instance); - - // Make sure that the lazily instantiated object will get destroyed at exit. - if (dtor) - AtExitManager::RegisterCallback(dtor, lazy_instance); -} - -} // namespace internal -} // namespace base diff --git a/security/sandbox/chromium/base/lazy_instance.h b/security/sandbox/chromium/base/lazy_instance.h deleted file mode 100644 index fd0321017..000000000 --- a/security/sandbox/chromium/base/lazy_instance.h +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// The LazyInstance<Type, Traits> class manages a single instance of Type, -// which will be lazily created on the first time it's accessed. This class is -// useful for places you would normally use a function-level static, but you -// need to have guaranteed thread-safety. The Type constructor will only ever -// be called once, even if two threads are racing to create the object. Get() -// and Pointer() will always return the same, completely initialized instance. -// When the instance is constructed it is registered with AtExitManager. The -// destructor will be called on program exit. -// -// LazyInstance is completely thread safe, assuming that you create it safely. -// The class was designed to be POD initialized, so it shouldn't require a -// static constructor. It really only makes sense to declare a LazyInstance as -// a global variable using the LAZY_INSTANCE_INITIALIZER initializer. -// -// LazyInstance is similar to Singleton, except it does not have the singleton -// property. You can have multiple LazyInstance's of the same type, and each -// will manage a unique instance. It also preallocates the space for Type, as -// to avoid allocating the Type instance on the heap. This may help with the -// performance of creating the instance, and reducing heap fragmentation. This -// requires that Type be a complete type so we can determine the size. -// -// Example usage: -// static LazyInstance<MyClass> my_instance = LAZY_INSTANCE_INITIALIZER; -// void SomeMethod() { -// my_instance.Get().SomeMethod(); // MyClass::SomeMethod() -// -// MyClass* ptr = my_instance.Pointer(); -// ptr->DoDoDo(); // MyClass::DoDoDo -// } - -#ifndef BASE_LAZY_INSTANCE_H_ -#define BASE_LAZY_INSTANCE_H_ - -#include <new> // For placement new. - -#include "base/atomicops.h" -#include "base/base_export.h" -#include "base/debug/leak_annotations.h" -#include "base/logging.h" -#include "base/memory/aligned_memory.h" -#include "base/threading/thread_restrictions.h" - -// LazyInstance uses its own struct initializer-list style static -// initialization, as base's LINKER_INITIALIZED requires a constructor and on -// some compilers (notably gcc 4.4) this still ends up needing runtime -// initialization. -#define LAZY_INSTANCE_INITIALIZER {0} - -namespace base { - -template <typename Type> -struct DefaultLazyInstanceTraits { - static const bool kRegisterOnExit = true; -#ifndef NDEBUG - static const bool kAllowedToAccessOnNonjoinableThread = false; -#endif - - static Type* New(void* instance) { - DCHECK_EQ(reinterpret_cast<uintptr_t>(instance) & (ALIGNOF(Type) - 1), 0u) - << ": Bad boy, the buffer passed to placement new is not aligned!\n" - "This may break some stuff like SSE-based optimizations assuming the " - "<Type> objects are word aligned."; - // Use placement new to initialize our instance in our preallocated space. - // The parenthesis is very important here to force POD type initialization. - return new (instance) Type(); - } - static void Delete(Type* instance) { - // Explicitly call the destructor. - instance->~Type(); - } -}; - -// We pull out some of the functionality into non-templated functions, so we -// can implement the more complicated pieces out of line in the .cc file. -namespace internal { - -// Use LazyInstance<T>::Leaky for a less-verbose call-site typedef; e.g.: -// base::LazyInstance<T>::Leaky my_leaky_lazy_instance; -// instead of: -// base::LazyInstance<T, base::internal::LeakyLazyInstanceTraits<T> > -// my_leaky_lazy_instance; -// (especially when T is MyLongTypeNameImplClientHolderFactory). -// Only use this internal::-qualified verbose form to extend this traits class -// (depending on its implementation details). -template <typename Type> -struct LeakyLazyInstanceTraits { - static const bool kRegisterOnExit = false; -#ifndef NDEBUG - static const bool kAllowedToAccessOnNonjoinableThread = true; -#endif - - static Type* New(void* instance) { - ANNOTATE_SCOPED_MEMORY_LEAK; - return DefaultLazyInstanceTraits<Type>::New(instance); - } - static void Delete(Type* instance) { - } -}; - -// Our AtomicWord doubles as a spinlock, where a value of -// kBeingCreatedMarker means the spinlock is being held for creation. -static const subtle::AtomicWord kLazyInstanceStateCreating = 1; - -// Check if instance needs to be created. If so return true otherwise -// if another thread has beat us, wait for instance to be created and -// return false. -BASE_EXPORT bool NeedsLazyInstance(subtle::AtomicWord* state); - -// After creating an instance, call this to register the dtor to be called -// at program exit and to update the atomic state to hold the |new_instance| -BASE_EXPORT void CompleteLazyInstance(subtle::AtomicWord* state, - subtle::AtomicWord new_instance, - void* lazy_instance, - void (*dtor)(void*)); - -} // namespace internal - -template <typename Type, typename Traits = DefaultLazyInstanceTraits<Type> > -class LazyInstance { - public: - // Do not define a destructor, as doing so makes LazyInstance a - // non-POD-struct. We don't want that because then a static initializer will - // be created to register the (empty) destructor with atexit() under MSVC, for - // example. We handle destruction of the contained Type class explicitly via - // the OnExit member function, where needed. - // ~LazyInstance() {} - - // Convenience typedef to avoid having to repeat Type for leaky lazy - // instances. - typedef LazyInstance<Type, internal::LeakyLazyInstanceTraits<Type> > Leaky; - - Type& Get() { - return *Pointer(); - } - - Type* Pointer() { -#ifndef NDEBUG - // Avoid making TLS lookup on release builds. - if (!Traits::kAllowedToAccessOnNonjoinableThread) - ThreadRestrictions::AssertSingletonAllowed(); -#endif - // If any bit in the created mask is true, the instance has already been - // fully constructed. - static const subtle::AtomicWord kLazyInstanceCreatedMask = - ~internal::kLazyInstanceStateCreating; - - // We will hopefully have fast access when the instance is already created. - // Since a thread sees private_instance_ == 0 or kLazyInstanceStateCreating - // at most once, the load is taken out of NeedsInstance() as a fast-path. - // The load has acquire memory ordering as a thread which sees - // private_instance_ > creating needs to acquire visibility over - // the associated data (private_buf_). Pairing Release_Store is in - // CompleteLazyInstance(). - subtle::AtomicWord value = subtle::Acquire_Load(&private_instance_); - if (!(value & kLazyInstanceCreatedMask) && - internal::NeedsLazyInstance(&private_instance_)) { - // Create the instance in the space provided by |private_buf_|. - value = reinterpret_cast<subtle::AtomicWord>( - Traits::New(private_buf_.void_data())); - internal::CompleteLazyInstance(&private_instance_, value, this, - Traits::kRegisterOnExit ? OnExit : NULL); - } - return instance(); - } - - bool operator==(Type* p) { - switch (subtle::NoBarrier_Load(&private_instance_)) { - case 0: - return p == NULL; - case internal::kLazyInstanceStateCreating: - return static_cast<void*>(p) == private_buf_.void_data(); - default: - return p == instance(); - } - } - - // Effectively private: member data is only public to allow the linker to - // statically initialize it and to maintain a POD class. DO NOT USE FROM - // OUTSIDE THIS CLASS. - - subtle::AtomicWord private_instance_; - // Preallocated space for the Type instance. - base::AlignedMemory<sizeof(Type), ALIGNOF(Type)> private_buf_; - - private: - Type* instance() { - return reinterpret_cast<Type*>(subtle::NoBarrier_Load(&private_instance_)); - } - - // Adapter function for use with AtExit. This should be called single - // threaded, so don't synchronize across threads. - // Calling OnExit while the instance is in use by other threads is a mistake. - static void OnExit(void* lazy_instance) { - LazyInstance<Type, Traits>* me = - reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); - Traits::Delete(me->instance()); - subtle::NoBarrier_Store(&me->private_instance_, 0); - } -}; - -} // namespace base - -#endif // BASE_LAZY_INSTANCE_H_ diff --git a/security/sandbox/chromium/base/location.cc b/security/sandbox/chromium/base/location.cc deleted file mode 100644 index 1333e6ec4..000000000 --- a/security/sandbox/chromium/base/location.cc +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "build/build_config.h" - -#if defined(COMPILER_MSVC) -#include <intrin.h> -#endif - -#include "base/location.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/stringprintf.h" - -namespace tracked_objects { - -Location::Location(const char* function_name, - const char* file_name, - int line_number, - const void* program_counter) - : function_name_(function_name), - file_name_(file_name), - line_number_(line_number), - program_counter_(program_counter) { -} - -Location::Location() - : function_name_("Unknown"), - file_name_("Unknown"), - line_number_(-1), - program_counter_(NULL) { -} - -Location::Location(const Location& other) - : function_name_(other.function_name_), - file_name_(other.file_name_), - line_number_(other.line_number_), - program_counter_(other.program_counter_) { -} - -std::string Location::ToString() const { - return std::string(function_name_) + "@" + file_name_ + ":" + - base::IntToString(line_number_); -} - -void Location::Write(bool display_filename, bool display_function_name, - std::string* output) const { - base::StringAppendF(output, "%s[%d] ", - display_filename ? file_name_ : "line", - line_number_); - - if (display_function_name) { - WriteFunctionName(output); - output->push_back(' '); - } -} - -void Location::WriteFunctionName(std::string* output) const { - // Translate "<" to "<" for HTML safety. - // TODO(jar): Support ASCII or html for logging in ASCII. - for (const char *p = function_name_; *p; p++) { - switch (*p) { - case '<': - output->append("<"); - break; - - case '>': - output->append(">"); - break; - - default: - output->push_back(*p); - break; - } - } -} - -//------------------------------------------------------------------------------ -LocationSnapshot::LocationSnapshot() : line_number(-1) { -} - -LocationSnapshot::LocationSnapshot( - const tracked_objects::Location& location) - : file_name(location.file_name()), - function_name(location.function_name()), - line_number(location.line_number()) { -} - -LocationSnapshot::~LocationSnapshot() { -} - -//------------------------------------------------------------------------------ -#if defined(COMPILER_MSVC) -__declspec(noinline) -#endif -BASE_EXPORT const void* GetProgramCounter() { -#if defined(COMPILER_MSVC) - return _ReturnAddress(); -#elif defined(COMPILER_GCC) && !defined(OS_NACL) - return __builtin_extract_return_addr(__builtin_return_address(0)); -#else - return NULL; -#endif -} - -} // namespace tracked_objects diff --git a/security/sandbox/chromium/base/location.h b/security/sandbox/chromium/base/location.h deleted file mode 100644 index d3bb23c63..000000000 --- a/security/sandbox/chromium/base/location.h +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_LOCATION_H_ -#define BASE_LOCATION_H_ - -#include <stddef.h> - -#include <cassert> -#include <string> - -#include "base/base_export.h" -#include "base/containers/hash_tables.h" - -namespace tracked_objects { - -// Location provides basic info where of an object was constructed, or was -// significantly brought to life. -class BASE_EXPORT Location { - public: - // Constructor should be called with a long-lived char*, such as __FILE__. - // It assumes the provided value will persist as a global constant, and it - // will not make a copy of it. - Location(const char* function_name, - const char* file_name, - int line_number, - const void* program_counter); - - // Provide a default constructor for easy of debugging. - Location(); - - // Copy constructor. - Location(const Location& other); - - // Comparator for hash map insertion. - // No need to use |function_name_| since the other two fields uniquely - // identify this location. - bool operator==(const Location& other) const { - return line_number_ == other.line_number_ && - file_name_ == other.file_name_; - } - - const char* function_name() const { return function_name_; } - const char* file_name() const { return file_name_; } - int line_number() const { return line_number_; } - const void* program_counter() const { return program_counter_; } - - std::string ToString() const; - - // Hash operator for hash maps. - struct Hash { - size_t operator()(const Location& location) const { - // Compute the hash value using file name pointer and line number. - // No need to use |function_name_| since the other two fields uniquely - // identify this location. - - // The file name will always be uniquely identified by its pointer since - // it comes from __FILE__, so no need to check the contents of the string. - // See the definition of FROM_HERE in location.h, and how it is used - // elsewhere. - return base::HashPair(reinterpret_cast<uintptr_t>(location.file_name()), - location.line_number()); - } - }; - - // Translate the some of the state in this instance into a human readable - // string with HTML characters in the function names escaped, and append that - // string to |output|. Inclusion of the file_name_ and function_name_ are - // optional, and controlled by the boolean arguments. - void Write(bool display_filename, bool display_function_name, - std::string* output) const; - - // Write function_name_ in HTML with '<' and '>' properly encoded. - void WriteFunctionName(std::string* output) const; - - private: - const char* function_name_; - const char* file_name_; - int line_number_; - const void* program_counter_; -}; - -// A "snapshotted" representation of the Location class that can safely be -// passed across process boundaries. -struct BASE_EXPORT LocationSnapshot { - // The default constructor is exposed to support the IPC serialization macros. - LocationSnapshot(); - explicit LocationSnapshot(const tracked_objects::Location& location); - ~LocationSnapshot(); - - std::string file_name; - std::string function_name; - int line_number; -}; - -BASE_EXPORT const void* GetProgramCounter(); - -// Define a macro to record the current source location. -#define FROM_HERE FROM_HERE_WITH_EXPLICIT_FUNCTION(__FUNCTION__) - -#define FROM_HERE_WITH_EXPLICIT_FUNCTION(function_name) \ - ::tracked_objects::Location(function_name, \ - __FILE__, \ - __LINE__, \ - ::tracked_objects::GetProgramCounter()) - -} // namespace tracked_objects - -#endif // BASE_LOCATION_H_ diff --git a/security/sandbox/chromium/base/logging.h b/security/sandbox/chromium/base/logging.h deleted file mode 100644 index 300c9b526..000000000 --- a/security/sandbox/chromium/base/logging.h +++ /dev/null @@ -1,976 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_LOGGING_H_ -#define BASE_LOGGING_H_ - -#include <stddef.h> - -#include <cassert> -#include <cstring> -#include <sstream> -#include <string> - -#include "base/base_export.h" -#include "base/debug/debugger.h" -#include "base/macros.h" -#include "build/build_config.h" - -// -// Optional message capabilities -// ----------------------------- -// Assertion failed messages and fatal errors are displayed in a dialog box -// before the application exits. However, running this UI creates a message -// loop, which causes application messages to be processed and potentially -// dispatched to existing application windows. Since the application is in a -// bad state when this assertion dialog is displayed, these messages may not -// get processed and hang the dialog, or the application might go crazy. -// -// Therefore, it can be beneficial to display the error dialog in a separate -// process from the main application. When the logging system needs to display -// a fatal error dialog box, it will look for a program called -// "DebugMessage.exe" in the same directory as the application executable. It -// will run this application with the message as the command line, and will -// not include the name of the application as is traditional for easier -// parsing. -// -// The code for DebugMessage.exe is only one line. In WinMain, do: -// MessageBox(NULL, GetCommandLineW(), L"Fatal Error", 0); -// -// If DebugMessage.exe is not found, the logging code will use a normal -// MessageBox, potentially causing the problems discussed above. - - -// Instructions -// ------------ -// -// Make a bunch of macros for logging. The way to log things is to stream -// things to LOG(<a particular severity level>). E.g., -// -// LOG(INFO) << "Found " << num_cookies << " cookies"; -// -// You can also do conditional logging: -// -// LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; -// -// The CHECK(condition) macro is active in both debug and release builds and -// effectively performs a LOG(FATAL) which terminates the process and -// generates a crashdump unless a debugger is attached. -// -// There are also "debug mode" logging macros like the ones above: -// -// DLOG(INFO) << "Found cookies"; -// -// DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; -// -// All "debug mode" logging is compiled away to nothing for non-debug mode -// compiles. LOG_IF and development flags also work well together -// because the code can be compiled away sometimes. -// -// We also have -// -// LOG_ASSERT(assertion); -// DLOG_ASSERT(assertion); -// -// which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion; -// -// There are "verbose level" logging macros. They look like -// -// VLOG(1) << "I'm printed when you run the program with --v=1 or more"; -// VLOG(2) << "I'm printed when you run the program with --v=2 or more"; -// -// These always log at the INFO log level (when they log at all). -// The verbose logging can also be turned on module-by-module. For instance, -// --vmodule=profile=2,icon_loader=1,browser_*=3,*/chromeos/*=4 --v=0 -// will cause: -// a. VLOG(2) and lower messages to be printed from profile.{h,cc} -// b. VLOG(1) and lower messages to be printed from icon_loader.{h,cc} -// c. VLOG(3) and lower messages to be printed from files prefixed with -// "browser" -// d. VLOG(4) and lower messages to be printed from files under a -// "chromeos" directory. -// e. VLOG(0) and lower messages to be printed from elsewhere -// -// The wildcarding functionality shown by (c) supports both '*' (match -// 0 or more characters) and '?' (match any single character) -// wildcards. Any pattern containing a forward or backward slash will -// be tested against the whole pathname and not just the module. -// E.g., "*/foo/bar/*=2" would change the logging level for all code -// in source files under a "foo/bar" directory. -// -// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as -// -// if (VLOG_IS_ON(2)) { -// // do some logging preparation and logging -// // that can't be accomplished with just VLOG(2) << ...; -// } -// -// There is also a VLOG_IF "verbose level" condition macro for sample -// cases, when some extra computation and preparation for logs is not -// needed. -// -// VLOG_IF(1, (size > 1024)) -// << "I'm printed when size is more than 1024 and when you run the " -// "program with --v=1 or more"; -// -// We also override the standard 'assert' to use 'DLOG_ASSERT'. -// -// Lastly, there is: -// -// PLOG(ERROR) << "Couldn't do foo"; -// DPLOG(ERROR) << "Couldn't do foo"; -// PLOG_IF(ERROR, cond) << "Couldn't do foo"; -// DPLOG_IF(ERROR, cond) << "Couldn't do foo"; -// PCHECK(condition) << "Couldn't do foo"; -// DPCHECK(condition) << "Couldn't do foo"; -// -// which append the last system error to the message in string form (taken from -// GetLastError() on Windows and errno on POSIX). -// -// The supported severity levels for macros that allow you to specify one -// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL. -// -// Very important: logging a message at the FATAL severity level causes -// the program to terminate (after the message is logged). -// -// There is the special severity of DFATAL, which logs FATAL in debug mode, -// ERROR in normal mode. - -namespace logging { - -// TODO(avi): do we want to do a unification of character types here? -#if defined(OS_WIN) -typedef wchar_t PathChar; -#else -typedef char PathChar; -#endif - -// Where to record logging output? A flat file and/or system debug log -// via OutputDebugString. -enum LoggingDestination { - LOG_NONE = 0, - LOG_TO_FILE = 1 << 0, - LOG_TO_SYSTEM_DEBUG_LOG = 1 << 1, - - LOG_TO_ALL = LOG_TO_FILE | LOG_TO_SYSTEM_DEBUG_LOG, - - // On Windows, use a file next to the exe; on POSIX platforms, where - // it may not even be possible to locate the executable on disk, use - // stderr. -#if defined(OS_WIN) - LOG_DEFAULT = LOG_TO_FILE, -#elif defined(OS_POSIX) - LOG_DEFAULT = LOG_TO_SYSTEM_DEBUG_LOG, -#endif -}; - -// Indicates that the log file should be locked when being written to. -// Unless there is only one single-threaded process that is logging to -// the log file, the file should be locked during writes to make each -// log output atomic. Other writers will block. -// -// All processes writing to the log file must have their locking set for it to -// work properly. Defaults to LOCK_LOG_FILE. -enum LogLockingState { LOCK_LOG_FILE, DONT_LOCK_LOG_FILE }; - -// On startup, should we delete or append to an existing log file (if any)? -// Defaults to APPEND_TO_OLD_LOG_FILE. -enum OldFileDeletionState { DELETE_OLD_LOG_FILE, APPEND_TO_OLD_LOG_FILE }; - -struct BASE_EXPORT LoggingSettings { - // The defaults values are: - // - // logging_dest: LOG_DEFAULT - // log_file: NULL - // lock_log: LOCK_LOG_FILE - // delete_old: APPEND_TO_OLD_LOG_FILE - LoggingSettings(); - - LoggingDestination logging_dest; - - // The three settings below have an effect only when LOG_TO_FILE is - // set in |logging_dest|. - const PathChar* log_file; - LogLockingState lock_log; - OldFileDeletionState delete_old; -}; - -// Define different names for the BaseInitLoggingImpl() function depending on -// whether NDEBUG is defined or not so that we'll fail to link if someone tries -// to compile logging.cc with NDEBUG but includes logging.h without defining it, -// or vice versa. -#if NDEBUG -#define BaseInitLoggingImpl BaseInitLoggingImpl_built_with_NDEBUG -#else -#define BaseInitLoggingImpl BaseInitLoggingImpl_built_without_NDEBUG -#endif - -// Implementation of the InitLogging() method declared below. We use a -// more-specific name so we can #define it above without affecting other code -// that has named stuff "InitLogging". -BASE_EXPORT bool BaseInitLoggingImpl(const LoggingSettings& settings); - -// Sets the log file name and other global logging state. Calling this function -// is recommended, and is normally done at the beginning of application init. -// If you don't call it, all the flags will be initialized to their default -// values, and there is a race condition that may leak a critical section -// object if two threads try to do the first log at the same time. -// See the definition of the enums above for descriptions and default values. -// -// The default log file is initialized to "debug.log" in the application -// directory. You probably don't want this, especially since the program -// directory may not be writable on an enduser's system. -// -// This function may be called a second time to re-direct logging (e.g after -// loging in to a user partition), however it should never be called more than -// twice. -inline bool InitLogging(const LoggingSettings& settings) { - return BaseInitLoggingImpl(settings); -} - -// Sets the log level. Anything at or above this level will be written to the -// log file/displayed to the user (if applicable). Anything below this level -// will be silently ignored. The log level defaults to 0 (everything is logged -// up to level INFO) if this function is not called. -// Note that log messages for VLOG(x) are logged at level -x, so setting -// the min log level to negative values enables verbose logging. -BASE_EXPORT void SetMinLogLevel(int level); - -// Gets the current log level. -BASE_EXPORT int GetMinLogLevel(); - -// Used by LOG_IS_ON to lazy-evaluate stream arguments. -BASE_EXPORT bool ShouldCreateLogMessage(int severity); - -// Gets the VLOG default verbosity level. -BASE_EXPORT int GetVlogVerbosity(); - -// Gets the current vlog level for the given file (usually taken from -// __FILE__). - -// Note that |N| is the size *with* the null terminator. -BASE_EXPORT int GetVlogLevelHelper(const char* file_start, size_t N); - -template <size_t N> -int GetVlogLevel(const char (&file)[N]) { - return GetVlogLevelHelper(file, N); -} - -// Sets the common items you want to be prepended to each log message. -// process and thread IDs default to off, the timestamp defaults to on. -// If this function is not called, logging defaults to writing the timestamp -// only. -BASE_EXPORT void SetLogItems(bool enable_process_id, bool enable_thread_id, - bool enable_timestamp, bool enable_tickcount); - -// Sets whether or not you'd like to see fatal debug messages popped up in -// a dialog box or not. -// Dialogs are not shown by default. -BASE_EXPORT void SetShowErrorDialogs(bool enable_dialogs); - -// Sets the Log Assert Handler that will be used to notify of check failures. -// The default handler shows a dialog box and then terminate the process, -// however clients can use this function to override with their own handling -// (e.g. a silent one for Unit Tests) -typedef void (*LogAssertHandlerFunction)(const std::string& str); -BASE_EXPORT void SetLogAssertHandler(LogAssertHandlerFunction handler); - -// Sets the Log Message Handler that gets passed every log message before -// it's sent to other log destinations (if any). -// Returns true to signal that it handled the message and the message -// should not be sent to other log destinations. -typedef bool (*LogMessageHandlerFunction)(int severity, - const char* file, int line, size_t message_start, const std::string& str); -BASE_EXPORT void SetLogMessageHandler(LogMessageHandlerFunction handler); -BASE_EXPORT LogMessageHandlerFunction GetLogMessageHandler(); - -typedef int LogSeverity; -const LogSeverity LOG_VERBOSE = -1; // This is level 1 verbosity -// Note: the log severities are used to index into the array of names, -// see log_severity_names. -const LogSeverity LOG_INFO = 0; -const LogSeverity LOG_WARNING = 1; -const LogSeverity LOG_ERROR = 2; -const LogSeverity LOG_FATAL = 3; -const LogSeverity LOG_NUM_SEVERITIES = 4; - -// LOG_DFATAL is LOG_FATAL in debug mode, ERROR in normal mode -#ifdef NDEBUG -const LogSeverity LOG_DFATAL = LOG_ERROR; -#else -const LogSeverity LOG_DFATAL = LOG_FATAL; -#endif - -// A few definitions of macros that don't generate much code. These are used -// by LOG() and LOG_IF, etc. Since these are used all over our code, it's -// better to have compact code for these operations. -#define COMPACT_GOOGLE_LOG_EX_INFO(ClassName, ...) \ - logging::ClassName(__FILE__, __LINE__, logging::LOG_INFO , ##__VA_ARGS__) -#define COMPACT_GOOGLE_LOG_EX_WARNING(ClassName, ...) \ - logging::ClassName(__FILE__, __LINE__, logging::LOG_WARNING , ##__VA_ARGS__) -#define COMPACT_GOOGLE_LOG_EX_ERROR(ClassName, ...) \ - logging::ClassName(__FILE__, __LINE__, logging::LOG_ERROR , ##__VA_ARGS__) -#define COMPACT_GOOGLE_LOG_EX_FATAL(ClassName, ...) \ - logging::ClassName(__FILE__, __LINE__, logging::LOG_FATAL , ##__VA_ARGS__) -#define COMPACT_GOOGLE_LOG_EX_DFATAL(ClassName, ...) \ - logging::ClassName(__FILE__, __LINE__, logging::LOG_DFATAL , ##__VA_ARGS__) - -#define COMPACT_GOOGLE_LOG_INFO \ - COMPACT_GOOGLE_LOG_EX_INFO(LogMessage) -#define COMPACT_GOOGLE_LOG_WARNING \ - COMPACT_GOOGLE_LOG_EX_WARNING(LogMessage) -#define COMPACT_GOOGLE_LOG_ERROR \ - COMPACT_GOOGLE_LOG_EX_ERROR(LogMessage) -#define COMPACT_GOOGLE_LOG_FATAL \ - COMPACT_GOOGLE_LOG_EX_FATAL(LogMessage) -#define COMPACT_GOOGLE_LOG_DFATAL \ - COMPACT_GOOGLE_LOG_EX_DFATAL(LogMessage) - -#if defined(OS_WIN) -// wingdi.h defines ERROR to be 0. When we call LOG(ERROR), it gets -// substituted with 0, and it expands to COMPACT_GOOGLE_LOG_0. To allow us -// to keep using this syntax, we define this macro to do the same thing -// as COMPACT_GOOGLE_LOG_ERROR, and also define ERROR the same way that -// the Windows SDK does for consistency. -#define ERROR 0 -#define COMPACT_GOOGLE_LOG_EX_0(ClassName, ...) \ - COMPACT_GOOGLE_LOG_EX_ERROR(ClassName , ##__VA_ARGS__) -#define COMPACT_GOOGLE_LOG_0 COMPACT_GOOGLE_LOG_ERROR -// Needed for LOG_IS_ON(ERROR). -const LogSeverity LOG_0 = LOG_ERROR; -#endif - -// As special cases, we can assume that LOG_IS_ON(FATAL) always holds. Also, -// LOG_IS_ON(DFATAL) always holds in debug mode. In particular, CHECK()s will -// always fire if they fail. -#define LOG_IS_ON(severity) \ - (::logging::ShouldCreateLogMessage(::logging::LOG_##severity)) - -// We can't do any caching tricks with VLOG_IS_ON() like the -// google-glog version since it requires GCC extensions. This means -// that using the v-logging functions in conjunction with --vmodule -// may be slow. -#define VLOG_IS_ON(verboselevel) \ - ((verboselevel) <= ::logging::GetVlogLevel(__FILE__)) - -// Helper macro which avoids evaluating the arguments to a stream if -// the condition doesn't hold. Condition is evaluated once and only once. -#define LAZY_STREAM(stream, condition) \ - !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream) - -// We use the preprocessor's merging operator, "##", so that, e.g., -// LOG(INFO) becomes the token COMPACT_GOOGLE_LOG_INFO. There's some funny -// subtle difference between ostream member streaming functions (e.g., -// ostream::operator<<(int) and ostream non-member streaming functions -// (e.g., ::operator<<(ostream&, string&): it turns out that it's -// impossible to stream something like a string directly to an unnamed -// ostream. We employ a neat hack by calling the stream() member -// function of LogMessage which seems to avoid the problem. -#define LOG_STREAM(severity) COMPACT_GOOGLE_LOG_ ## severity.stream() - -#define LOG(severity) LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity)) -#define LOG_IF(severity, condition) \ - LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity) && (condition)) - -#define SYSLOG(severity) LOG(severity) -#define SYSLOG_IF(severity, condition) LOG_IF(severity, condition) - -// The VLOG macros log with negative verbosities. -#define VLOG_STREAM(verbose_level) \ - logging::LogMessage(__FILE__, __LINE__, -verbose_level).stream() - -#define VLOG(verbose_level) \ - LAZY_STREAM(VLOG_STREAM(verbose_level), VLOG_IS_ON(verbose_level)) - -#define VLOG_IF(verbose_level, condition) \ - LAZY_STREAM(VLOG_STREAM(verbose_level), \ - VLOG_IS_ON(verbose_level) && (condition)) - -#if defined (OS_WIN) -#define VPLOG_STREAM(verbose_level) \ - logging::Win32ErrorLogMessage(__FILE__, __LINE__, -verbose_level, \ - ::logging::GetLastSystemErrorCode()).stream() -#elif defined(OS_POSIX) -#define VPLOG_STREAM(verbose_level) \ - logging::ErrnoLogMessage(__FILE__, __LINE__, -verbose_level, \ - ::logging::GetLastSystemErrorCode()).stream() -#endif - -#define VPLOG(verbose_level) \ - LAZY_STREAM(VPLOG_STREAM(verbose_level), VLOG_IS_ON(verbose_level)) - -#define VPLOG_IF(verbose_level, condition) \ - LAZY_STREAM(VPLOG_STREAM(verbose_level), \ - VLOG_IS_ON(verbose_level) && (condition)) - -// TODO(akalin): Add more VLOG variants, e.g. VPLOG. - -#define LOG_ASSERT(condition) \ - LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". " -#define SYSLOG_ASSERT(condition) \ - SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". " - -#if defined(OS_WIN) -#define PLOG_STREAM(severity) \ - COMPACT_GOOGLE_LOG_EX_ ## severity(Win32ErrorLogMessage, \ - ::logging::GetLastSystemErrorCode()).stream() -#elif defined(OS_POSIX) -#define PLOG_STREAM(severity) \ - COMPACT_GOOGLE_LOG_EX_ ## severity(ErrnoLogMessage, \ - ::logging::GetLastSystemErrorCode()).stream() -#endif - -#define PLOG(severity) \ - LAZY_STREAM(PLOG_STREAM(severity), LOG_IS_ON(severity)) - -#define PLOG_IF(severity, condition) \ - LAZY_STREAM(PLOG_STREAM(severity), LOG_IS_ON(severity) && (condition)) - -// The actual stream used isn't important. -#define EAT_STREAM_PARAMETERS \ - true ? (void) 0 : ::logging::LogMessageVoidify() & LOG_STREAM(FATAL) - -// Captures the result of a CHECK_EQ (for example) and facilitates testing as a -// boolean. -class CheckOpResult { - public: - // |message| must be null if and only if the check failed. - CheckOpResult(std::string* message) : message_(message) {} - // Returns true if the check succeeded. - operator bool() const { return !message_; } - // Returns the message. - std::string* message() { return message_; } - - private: - std::string* message_; -}; - -// CHECK dies with a fatal error if condition is not true. It is *not* -// controlled by NDEBUG, so the check will be executed regardless of -// compilation mode. -// -// We make sure CHECK et al. always evaluates their arguments, as -// doing CHECK(FunctionWithSideEffect()) is a common idiom. - -#if defined(OFFICIAL_BUILD) && defined(NDEBUG) && !defined(OS_ANDROID) - -// Make all CHECK functions discard their log strings to reduce code -// bloat for official release builds (except Android). - -// TODO(akalin): This would be more valuable if there were some way to -// remove BreakDebugger() from the backtrace, perhaps by turning it -// into a macro (like __debugbreak() on Windows). -#define CHECK(condition) \ - !(condition) ? ::base::debug::BreakDebugger() : EAT_STREAM_PARAMETERS - -#define PCHECK(condition) CHECK(condition) - -#define CHECK_OP(name, op, val1, val2) CHECK((val1) op (val2)) - -#else - -#if defined(_PREFAST_) && defined(OS_WIN) -// Use __analysis_assume to tell the VC++ static analysis engine that -// assert conditions are true, to suppress warnings. The LAZY_STREAM -// parameter doesn't reference 'condition' in /analyze builds because -// this evaluation confuses /analyze. The !! before condition is because -// __analysis_assume gets confused on some conditions: -// http://randomascii.wordpress.com/2011/09/13/analyze-for-visual-studio-the-ugly-part-5/ - -#define CHECK(condition) \ - __analysis_assume(!!(condition)), \ - LAZY_STREAM(LOG_STREAM(FATAL), false) \ - << "Check failed: " #condition ". " - -#define PCHECK(condition) \ - __analysis_assume(!!(condition)), \ - LAZY_STREAM(PLOG_STREAM(FATAL), false) \ - << "Check failed: " #condition ". " - -#else // _PREFAST_ - -// Do as much work as possible out of line to reduce inline code size. -#define CHECK(condition) \ - LAZY_STREAM(logging::LogMessage(__FILE__, __LINE__, #condition).stream(), \ - !(condition)) - -#define PCHECK(condition) \ - LAZY_STREAM(PLOG_STREAM(FATAL), !(condition)) \ - << "Check failed: " #condition ". " - -#endif // _PREFAST_ - -// Helper macro for binary operators. -// Don't use this macro directly in your code, use CHECK_EQ et al below. -// The 'switch' is used to prevent the 'else' from being ambiguous when the -// macro is used in an 'if' clause such as: -// if (a == 1) -// CHECK_EQ(2, a); -#define CHECK_OP(name, op, val1, val2) \ - switch (0) case 0: default: \ - if (logging::CheckOpResult true_if_passed = \ - logging::Check##name##Impl((val1), (val2), \ - #val1 " " #op " " #val2)) \ - ; \ - else \ - logging::LogMessage(__FILE__, __LINE__, true_if_passed.message()).stream() - -#endif - -// Build the error message string. This is separate from the "Impl" -// function template because it is not performance critical and so can -// be out of line, while the "Impl" code should be inline. Caller -// takes ownership of the returned string. -template<class t1, class t2> -std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { - std::ostringstream ss; - ss << names << " (" << v1 << " vs. " << v2 << ")"; - std::string* msg = new std::string(ss.str()); - return msg; -} - -// Commonly used instantiations of MakeCheckOpString<>. Explicitly instantiated -// in logging.cc. -extern template BASE_EXPORT std::string* MakeCheckOpString<int, int>( - const int&, const int&, const char* names); -extern template BASE_EXPORT -std::string* MakeCheckOpString<unsigned long, unsigned long>( - const unsigned long&, const unsigned long&, const char* names); -extern template BASE_EXPORT -std::string* MakeCheckOpString<unsigned long, unsigned int>( - const unsigned long&, const unsigned int&, const char* names); -extern template BASE_EXPORT -std::string* MakeCheckOpString<unsigned int, unsigned long>( - const unsigned int&, const unsigned long&, const char* names); -extern template BASE_EXPORT -std::string* MakeCheckOpString<std::string, std::string>( - const std::string&, const std::string&, const char* name); - -// Helper functions for CHECK_OP macro. -// The (int, int) specialization works around the issue that the compiler -// will not instantiate the template version of the function on values of -// unnamed enum type - see comment below. -#define DEFINE_CHECK_OP_IMPL(name, op) \ - template <class t1, class t2> \ - inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \ - const char* names) { \ - if (v1 op v2) return NULL; \ - else return MakeCheckOpString(v1, v2, names); \ - } \ - inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \ - if (v1 op v2) return NULL; \ - else return MakeCheckOpString(v1, v2, names); \ - } -DEFINE_CHECK_OP_IMPL(EQ, ==) -DEFINE_CHECK_OP_IMPL(NE, !=) -DEFINE_CHECK_OP_IMPL(LE, <=) -DEFINE_CHECK_OP_IMPL(LT, < ) -DEFINE_CHECK_OP_IMPL(GE, >=) -DEFINE_CHECK_OP_IMPL(GT, > ) -#undef DEFINE_CHECK_OP_IMPL - -#define CHECK_EQ(val1, val2) CHECK_OP(EQ, ==, val1, val2) -#define CHECK_NE(val1, val2) CHECK_OP(NE, !=, val1, val2) -#define CHECK_LE(val1, val2) CHECK_OP(LE, <=, val1, val2) -#define CHECK_LT(val1, val2) CHECK_OP(LT, < , val1, val2) -#define CHECK_GE(val1, val2) CHECK_OP(GE, >=, val1, val2) -#define CHECK_GT(val1, val2) CHECK_OP(GT, > , val1, val2) - -#if defined(NDEBUG) -#define ENABLE_DLOG 0 -#else -#define ENABLE_DLOG 1 -#endif - -#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) -#define DCHECK_IS_ON() 0 -#else -#define DCHECK_IS_ON() 1 -#endif - -// Definitions for DLOG et al. - -#if ENABLE_DLOG - -#define DLOG_IS_ON(severity) LOG_IS_ON(severity) -#define DLOG_IF(severity, condition) LOG_IF(severity, condition) -#define DLOG_ASSERT(condition) LOG_ASSERT(condition) -#define DPLOG_IF(severity, condition) PLOG_IF(severity, condition) -#define DVLOG_IF(verboselevel, condition) VLOG_IF(verboselevel, condition) -#define DVPLOG_IF(verboselevel, condition) VPLOG_IF(verboselevel, condition) - -#else // ENABLE_DLOG - -// If ENABLE_DLOG is off, we want to avoid emitting any references to -// |condition| (which may reference a variable defined only if NDEBUG -// is not defined). Contrast this with DCHECK et al., which has -// different behavior. - -#define DLOG_IS_ON(severity) false -#define DLOG_IF(severity, condition) EAT_STREAM_PARAMETERS -#define DLOG_ASSERT(condition) EAT_STREAM_PARAMETERS -#define DPLOG_IF(severity, condition) EAT_STREAM_PARAMETERS -#define DVLOG_IF(verboselevel, condition) EAT_STREAM_PARAMETERS -#define DVPLOG_IF(verboselevel, condition) EAT_STREAM_PARAMETERS - -#endif // ENABLE_DLOG - -// DEBUG_MODE is for uses like -// if (DEBUG_MODE) foo.CheckThatFoo(); -// instead of -// #ifndef NDEBUG -// foo.CheckThatFoo(); -// #endif -// -// We tie its state to ENABLE_DLOG. -enum { DEBUG_MODE = ENABLE_DLOG }; - -#undef ENABLE_DLOG - -#define DLOG(severity) \ - LAZY_STREAM(LOG_STREAM(severity), DLOG_IS_ON(severity)) - -#define DPLOG(severity) \ - LAZY_STREAM(PLOG_STREAM(severity), DLOG_IS_ON(severity)) - -#define DVLOG(verboselevel) DVLOG_IF(verboselevel, VLOG_IS_ON(verboselevel)) - -#define DVPLOG(verboselevel) DVPLOG_IF(verboselevel, VLOG_IS_ON(verboselevel)) - -// Definitions for DCHECK et al. - -#if DCHECK_IS_ON() - -#define COMPACT_GOOGLE_LOG_EX_DCHECK(ClassName, ...) \ - COMPACT_GOOGLE_LOG_EX_FATAL(ClassName , ##__VA_ARGS__) -#define COMPACT_GOOGLE_LOG_DCHECK COMPACT_GOOGLE_LOG_FATAL -const LogSeverity LOG_DCHECK = LOG_FATAL; - -#else // DCHECK_IS_ON() - -// These are just dummy values. -#define COMPACT_GOOGLE_LOG_EX_DCHECK(ClassName, ...) \ - COMPACT_GOOGLE_LOG_EX_INFO(ClassName , ##__VA_ARGS__) -#define COMPACT_GOOGLE_LOG_DCHECK COMPACT_GOOGLE_LOG_INFO -const LogSeverity LOG_DCHECK = LOG_INFO; - -#endif // DCHECK_IS_ON() - -// DCHECK et al. make sure to reference |condition| regardless of -// whether DCHECKs are enabled; this is so that we don't get unused -// variable warnings if the only use of a variable is in a DCHECK. -// This behavior is different from DLOG_IF et al. - -#if defined(_PREFAST_) && defined(OS_WIN) -// See comments on the previous use of __analysis_assume. - -#define DCHECK(condition) \ - __analysis_assume(!!(condition)), \ - LAZY_STREAM(LOG_STREAM(DCHECK), false) \ - << "Check failed: " #condition ". " - -#define DPCHECK(condition) \ - __analysis_assume(!!(condition)), \ - LAZY_STREAM(PLOG_STREAM(DCHECK), false) \ - << "Check failed: " #condition ". " - -#else // _PREFAST_ - -#define DCHECK(condition) \ - LAZY_STREAM(LOG_STREAM(DCHECK), DCHECK_IS_ON() ? !(condition) : false) \ - << "Check failed: " #condition ". " - -#define DPCHECK(condition) \ - LAZY_STREAM(PLOG_STREAM(DCHECK), DCHECK_IS_ON() ? !(condition) : false) \ - << "Check failed: " #condition ". " - -#endif // _PREFAST_ - -// Helper macro for binary operators. -// Don't use this macro directly in your code, use DCHECK_EQ et al below. -// The 'switch' is used to prevent the 'else' from being ambiguous when the -// macro is used in an 'if' clause such as: -// if (a == 1) -// DCHECK_EQ(2, a); -#define DCHECK_OP(name, op, val1, val2) \ - switch (0) case 0: default: \ - if (logging::CheckOpResult true_if_passed = \ - DCHECK_IS_ON() ? \ - logging::Check##name##Impl((val1), (val2), \ - #val1 " " #op " " #val2) : nullptr) \ - ; \ - else \ - logging::LogMessage(__FILE__, __LINE__, ::logging::LOG_DCHECK, \ - true_if_passed.message()).stream() - -// Equality/Inequality checks - compare two values, and log a -// LOG_DCHECK message including the two values when the result is not -// as expected. The values must have operator<<(ostream, ...) -// defined. -// -// You may append to the error message like so: -// DCHECK_NE(1, 2) << ": The world must be ending!"; -// -// We are very careful to ensure that each argument is evaluated exactly -// once, and that anything which is legal to pass as a function argument is -// legal here. In particular, the arguments may be temporary expressions -// which will end up being destroyed at the end of the apparent statement, -// for example: -// DCHECK_EQ(string("abc")[1], 'b'); -// -// WARNING: These may not compile correctly if one of the arguments is a pointer -// and the other is NULL. To work around this, simply static_cast NULL to the -// type of the desired pointer. - -#define DCHECK_EQ(val1, val2) DCHECK_OP(EQ, ==, val1, val2) -#define DCHECK_NE(val1, val2) DCHECK_OP(NE, !=, val1, val2) -#define DCHECK_LE(val1, val2) DCHECK_OP(LE, <=, val1, val2) -#define DCHECK_LT(val1, val2) DCHECK_OP(LT, < , val1, val2) -#define DCHECK_GE(val1, val2) DCHECK_OP(GE, >=, val1, val2) -#define DCHECK_GT(val1, val2) DCHECK_OP(GT, > , val1, val2) - -#if !DCHECK_IS_ON() && defined(OS_CHROMEOS) -// Implement logging of NOTREACHED() as a dedicated function to get function -// call overhead down to a minimum. -void LogErrorNotReached(const char* file, int line); -#define NOTREACHED() \ - true ? ::logging::LogErrorNotReached(__FILE__, __LINE__) \ - : EAT_STREAM_PARAMETERS -#else -#define NOTREACHED() DCHECK(false) -#endif - -// Redefine the standard assert to use our nice log files -#undef assert -#define assert(x) DLOG_ASSERT(x) - -// This class more or less represents a particular log message. You -// create an instance of LogMessage and then stream stuff to it. -// When you finish streaming to it, ~LogMessage is called and the -// full message gets streamed to the appropriate destination. -// -// You shouldn't actually use LogMessage's constructor to log things, -// though. You should use the LOG() macro (and variants thereof) -// above. -class BASE_EXPORT LogMessage { - public: - // Used for LOG(severity). - LogMessage(const char* file, int line, LogSeverity severity); - - // Used for CHECK(). Implied severity = LOG_FATAL. - LogMessage(const char* file, int line, const char* condition); - - // Used for CHECK_EQ(), etc. Takes ownership of the given string. - // Implied severity = LOG_FATAL. - LogMessage(const char* file, int line, std::string* result); - - // Used for DCHECK_EQ(), etc. Takes ownership of the given string. - LogMessage(const char* file, int line, LogSeverity severity, - std::string* result); - - ~LogMessage(); - - std::ostream& stream() { return stream_; } - - private: - void Init(const char* file, int line); - - LogSeverity severity_; - std::ostringstream stream_; - size_t message_start_; // Offset of the start of the message (past prefix - // info). - // The file and line information passed in to the constructor. - const char* file_; - const int line_; - -#if defined(OS_WIN) - // Stores the current value of GetLastError in the constructor and restores - // it in the destructor by calling SetLastError. - // This is useful since the LogMessage class uses a lot of Win32 calls - // that will lose the value of GLE and the code that called the log function - // will have lost the thread error value when the log call returns. - class SaveLastError { - public: - SaveLastError(); - ~SaveLastError(); - - unsigned long get_error() const { return last_error_; } - - protected: - unsigned long last_error_; - }; - - SaveLastError last_error_; -#endif - - DISALLOW_COPY_AND_ASSIGN(LogMessage); -}; - -// A non-macro interface to the log facility; (useful -// when the logging level is not a compile-time constant). -inline void LogAtLevel(int log_level, const std::string& msg) { - LogMessage(__FILE__, __LINE__, log_level).stream() << msg; -} - -// This class is used to explicitly ignore values in the conditional -// logging macros. This avoids compiler warnings like "value computed -// is not used" and "statement has no effect". -class LogMessageVoidify { - public: - LogMessageVoidify() { } - // This has to be an operator with a precedence lower than << but - // higher than ?: - void operator&(std::ostream&) { } -}; - -#if defined(OS_WIN) -typedef unsigned long SystemErrorCode; -#elif defined(OS_POSIX) -typedef int SystemErrorCode; -#endif - -// Alias for ::GetLastError() on Windows and errno on POSIX. Avoids having to -// pull in windows.h just for GetLastError() and DWORD. -BASE_EXPORT SystemErrorCode GetLastSystemErrorCode(); -BASE_EXPORT std::string SystemErrorCodeToString(SystemErrorCode error_code); - -#if defined(OS_WIN) -// Appends a formatted system message of the GetLastError() type. -class BASE_EXPORT Win32ErrorLogMessage { - public: - Win32ErrorLogMessage(const char* file, - int line, - LogSeverity severity, - SystemErrorCode err); - - // Appends the error message before destructing the encapsulated class. - ~Win32ErrorLogMessage(); - - std::ostream& stream() { return log_message_.stream(); } - - private: - SystemErrorCode err_; - LogMessage log_message_; - - DISALLOW_COPY_AND_ASSIGN(Win32ErrorLogMessage); -}; -#elif defined(OS_POSIX) -// Appends a formatted system message of the errno type -class BASE_EXPORT ErrnoLogMessage { - public: - ErrnoLogMessage(const char* file, - int line, - LogSeverity severity, - SystemErrorCode err); - - // Appends the error message before destructing the encapsulated class. - ~ErrnoLogMessage(); - - std::ostream& stream() { return log_message_.stream(); } - - private: - SystemErrorCode err_; - LogMessage log_message_; - - DISALLOW_COPY_AND_ASSIGN(ErrnoLogMessage); -}; -#endif // OS_WIN - -// Closes the log file explicitly if open. -// NOTE: Since the log file is opened as necessary by the action of logging -// statements, there's no guarantee that it will stay closed -// after this call. -BASE_EXPORT void CloseLogFile(); - -// Async signal safe logging mechanism. -BASE_EXPORT void RawLog(int level, const char* message); - -#define RAW_LOG(level, message) logging::RawLog(logging::LOG_ ## level, message) - -#define RAW_CHECK(condition) \ - do { \ - if (!(condition)) \ - logging::RawLog(logging::LOG_FATAL, "Check failed: " #condition "\n"); \ - } while (0) - -#if defined(OS_WIN) -// Returns true if logging to file is enabled. -BASE_EXPORT bool IsLoggingToFileEnabled(); - -// Returns the default log file path. -BASE_EXPORT std::wstring GetLogFileFullPath(); -#endif - -} // namespace logging - -// Note that "The behavior of a C++ program is undefined if it adds declarations -// or definitions to namespace std or to a namespace within namespace std unless -// otherwise specified." --C++11[namespace.std] -// -// We've checked that this particular definition has the intended behavior on -// our implementations, but it's prone to breaking in the future, and please -// don't imitate this in your own definitions without checking with some -// standard library experts. -namespace std { -// These functions are provided as a convenience for logging, which is where we -// use streams (it is against Google style to use streams in other places). It -// is designed to allow you to emit non-ASCII Unicode strings to the log file, -// which is normally ASCII. It is relatively slow, so try not to use it for -// common cases. Non-ASCII characters will be converted to UTF-8 by these -// operators. -BASE_EXPORT std::ostream& operator<<(std::ostream& out, const wchar_t* wstr); -inline std::ostream& operator<<(std::ostream& out, const std::wstring& wstr) { - return out << wstr.c_str(); -} -} // namespace std - -// The NOTIMPLEMENTED() macro annotates codepaths which have -// not been implemented yet. -// -// The implementation of this macro is controlled by NOTIMPLEMENTED_POLICY: -// 0 -- Do nothing (stripped by compiler) -// 1 -- Warn at compile time -// 2 -- Fail at compile time -// 3 -- Fail at runtime (DCHECK) -// 4 -- [default] LOG(ERROR) at runtime -// 5 -- LOG(ERROR) at runtime, only once per call-site - -#ifndef NOTIMPLEMENTED_POLICY -#if defined(OS_ANDROID) && defined(OFFICIAL_BUILD) -#define NOTIMPLEMENTED_POLICY 0 -#else -// Select default policy: LOG(ERROR) -#define NOTIMPLEMENTED_POLICY 4 -#endif -#endif - -#if defined(COMPILER_GCC) -// On Linux, with GCC, we can use __PRETTY_FUNCTION__ to get the demangled name -// of the current function in the NOTIMPLEMENTED message. -#define NOTIMPLEMENTED_MSG "Not implemented reached in " << __PRETTY_FUNCTION__ -#else -#define NOTIMPLEMENTED_MSG "NOT IMPLEMENTED" -#endif - -#if NOTIMPLEMENTED_POLICY == 0 -#define NOTIMPLEMENTED() EAT_STREAM_PARAMETERS -#elif NOTIMPLEMENTED_POLICY == 1 -// TODO, figure out how to generate a warning -#define NOTIMPLEMENTED() static_assert(false, "NOT_IMPLEMENTED") -#elif NOTIMPLEMENTED_POLICY == 2 -#define NOTIMPLEMENTED() static_assert(false, "NOT_IMPLEMENTED") -#elif NOTIMPLEMENTED_POLICY == 3 -#define NOTIMPLEMENTED() NOTREACHED() -#elif NOTIMPLEMENTED_POLICY == 4 -#define NOTIMPLEMENTED() LOG(ERROR) << NOTIMPLEMENTED_MSG -#elif NOTIMPLEMENTED_POLICY == 5 -#define NOTIMPLEMENTED() do {\ - static bool logged_once = false;\ - LOG_IF(ERROR, !logged_once) << NOTIMPLEMENTED_MSG;\ - logged_once = true;\ -} while(0);\ -EAT_STREAM_PARAMETERS -#endif - -#endif // BASE_LOGGING_H_ diff --git a/security/sandbox/chromium/base/macros.h b/security/sandbox/chromium/base/macros.h deleted file mode 100644 index 46ee1dadb..000000000 --- a/security/sandbox/chromium/base/macros.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file contains macros and macro-like constructs (e.g., templates) that -// are commonly used throughout Chromium source. (It may also contain things -// that are closely related to things that are commonly used that belong in this -// file.) - -#ifndef BASE_MACROS_H_ -#define BASE_MACROS_H_ - -#include <stddef.h> // For size_t. - -// Put this in the declarations for a class to be uncopyable. -#define DISALLOW_COPY(TypeName) \ - TypeName(const TypeName&) = delete - -// Put this in the declarations for a class to be unassignable. -#define DISALLOW_ASSIGN(TypeName) \ - void operator=(const TypeName&) = delete - -// A macro to disallow the copy constructor and operator= functions -// This should be used in the private: declarations for a class -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) - -// A macro to disallow all the implicit constructors, namely the -// default constructor, copy constructor and operator= functions. -// -// This should be used in the private: declarations for a class -// that wants to prevent anyone from instantiating it. This is -// especially useful for classes containing only static methods. -#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ - TypeName() = delete; \ - DISALLOW_COPY_AND_ASSIGN(TypeName) - -// The arraysize(arr) macro returns the # of elements in an array arr. The -// expression is a compile-time constant, and therefore can be used in defining -// new arrays, for example. If you use arraysize on a pointer by mistake, you -// will get a compile-time error. For the technical details, refer to -// http://blogs.msdn.com/b/the1/archive/2004/05/07/128242.aspx. - -// This template function declaration is used in defining arraysize. -// Note that the function doesn't need an implementation, as we only -// use its type. -template <typename T, size_t N> char (&ArraySizeHelper(T (&array)[N]))[N]; -#define arraysize(array) (sizeof(ArraySizeHelper(array))) - -// Used to explicitly mark the return value of a function as unused. If you are -// really sure you don't want to do anything with the return value of a function -// that has been marked WARN_UNUSED_RESULT, wrap it with this. Example: -// -// scoped_ptr<MyType> my_var = ...; -// if (TakeOwnership(my_var.get()) == SUCCESS) -// ignore_result(my_var.release()); -// -template<typename T> -inline void ignore_result(const T&) { -} - -// The following enum should be used only as a constructor argument to indicate -// that the variable has static storage class, and that the constructor should -// do nothing to its state. It indicates to the reader that it is legal to -// declare a static instance of the class, provided the constructor is given -// the base::LINKER_INITIALIZED argument. Normally, it is unsafe to declare a -// static variable that has a constructor or a destructor because invocation -// order is undefined. However, IF the type can be initialized by filling with -// zeroes (which the loader does for static variables), AND the destructor also -// does nothing to the storage, AND there are no virtual methods, then a -// constructor declared as -// explicit MyClass(base::LinkerInitialized x) {} -// and invoked as -// static MyClass my_variable_name(base::LINKER_INITIALIZED); -namespace base { -enum LinkerInitialized { LINKER_INITIALIZED }; - -// Use these to declare and define a static local variable (static T;) so that -// it is leaked so that its destructors are not called at exit. If you need -// thread-safe initialization, use base/lazy_instance.h instead. -#define CR_DEFINE_STATIC_LOCAL(type, name, arguments) \ - static type& name = *new type arguments - -} // base - -#endif // BASE_MACROS_H_ diff --git a/security/sandbox/chromium/base/memory/aligned_memory.h b/security/sandbox/chromium/base/memory/aligned_memory.h deleted file mode 100644 index bb7bd872c..000000000 --- a/security/sandbox/chromium/base/memory/aligned_memory.h +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// AlignedMemory is a POD type that gives you a portable way to specify static -// or local stack data of a given alignment and size. For example, if you need -// static storage for a class, but you want manual control over when the object -// is constructed and destructed (you don't want static initialization and -// destruction), use AlignedMemory: -// -// static AlignedMemory<sizeof(MyClass), ALIGNOF(MyClass)> my_class; -// -// // ... at runtime: -// new(my_class.void_data()) MyClass(); -// -// // ... use it: -// MyClass* mc = my_class.data_as<MyClass>(); -// -// // ... later, to destruct my_class: -// my_class.data_as<MyClass>()->MyClass::~MyClass(); -// -// Alternatively, a runtime sized aligned allocation can be created: -// -// float* my_array = static_cast<float*>(AlignedAlloc(size, alignment)); -// -// // ... later, to release the memory: -// AlignedFree(my_array); -// -// Or using scoped_ptr: -// -// scoped_ptr<float, AlignedFreeDeleter> my_array( -// static_cast<float*>(AlignedAlloc(size, alignment))); - -#ifndef BASE_MEMORY_ALIGNED_MEMORY_H_ -#define BASE_MEMORY_ALIGNED_MEMORY_H_ - -#include <stddef.h> -#include <stdint.h> - -#include "base/base_export.h" -#include "base/compiler_specific.h" - -#if defined(COMPILER_MSVC) -#include <malloc.h> -#else -#include <stdlib.h> -#endif - -namespace base { - -// AlignedMemory is specialized for all supported alignments. -// Make sure we get a compiler error if someone uses an unsupported alignment. -template <size_t Size, size_t ByteAlignment> -struct AlignedMemory {}; - -#define BASE_DECL_ALIGNED_MEMORY(byte_alignment) \ - template <size_t Size> \ - class AlignedMemory<Size, byte_alignment> { \ - public: \ - ALIGNAS(byte_alignment) uint8_t data_[Size]; \ - void* void_data() { return static_cast<void*>(data_); } \ - const void* void_data() const { return static_cast<const void*>(data_); } \ - template <typename Type> \ - Type* data_as() { \ - return static_cast<Type*>(void_data()); \ - } \ - template <typename Type> \ - const Type* data_as() const { \ - return static_cast<const Type*>(void_data()); \ - } \ - \ - private: \ - void* operator new(size_t); \ - void operator delete(void*); \ - } - -// Specialization for all alignments is required because MSVC (as of VS 2008) -// does not understand ALIGNAS(ALIGNOF(Type)) or ALIGNAS(template_param). -// Greater than 4096 alignment is not supported by some compilers, so 4096 is -// the maximum specified here. -BASE_DECL_ALIGNED_MEMORY(1); -BASE_DECL_ALIGNED_MEMORY(2); -BASE_DECL_ALIGNED_MEMORY(4); -BASE_DECL_ALIGNED_MEMORY(8); -BASE_DECL_ALIGNED_MEMORY(16); -BASE_DECL_ALIGNED_MEMORY(32); -BASE_DECL_ALIGNED_MEMORY(64); -BASE_DECL_ALIGNED_MEMORY(128); -BASE_DECL_ALIGNED_MEMORY(256); -BASE_DECL_ALIGNED_MEMORY(512); -BASE_DECL_ALIGNED_MEMORY(1024); -BASE_DECL_ALIGNED_MEMORY(2048); -BASE_DECL_ALIGNED_MEMORY(4096); - -#undef BASE_DECL_ALIGNED_MEMORY - -BASE_EXPORT void* AlignedAlloc(size_t size, size_t alignment); - -inline void AlignedFree(void* ptr) { -#if defined(COMPILER_MSVC) - _aligned_free(ptr); -#else - free(ptr); -#endif -} - -// Deleter for use with scoped_ptr. E.g., use as -// scoped_ptr<Foo, base::AlignedFreeDeleter> foo; -struct AlignedFreeDeleter { - inline void operator()(void* ptr) const { - AlignedFree(ptr); - } -}; - -} // namespace base - -#endif // BASE_MEMORY_ALIGNED_MEMORY_H_ diff --git a/security/sandbox/chromium/base/memory/raw_scoped_refptr_mismatch_checker.h b/security/sandbox/chromium/base/memory/raw_scoped_refptr_mismatch_checker.h deleted file mode 100644 index 09f982b12..000000000 --- a/security/sandbox/chromium/base/memory/raw_scoped_refptr_mismatch_checker.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_ -#define BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_ - -#include "base/memory/ref_counted.h" -#include "base/template_util.h" -#include "base/tuple.h" -#include "build/build_config.h" - -// It is dangerous to post a task with a T* argument where T is a subtype of -// RefCounted(Base|ThreadSafeBase), since by the time the parameter is used, the -// object may already have been deleted since it was not held with a -// scoped_refptr. Example: http://crbug.com/27191 -// The following set of traits are designed to generate a compile error -// whenever this antipattern is attempted. - -namespace base { - -// This is a base internal implementation file used by task.h and callback.h. -// Not for public consumption, so we wrap it in namespace internal. -namespace internal { - -template <typename T> -struct NeedsScopedRefptrButGetsRawPtr { -#if defined(OS_WIN) - enum { - value = base::false_type::value - }; -#else - enum { - // Human readable translation: you needed to be a scoped_refptr if you are a - // raw pointer type and are convertible to a RefCounted(Base|ThreadSafeBase) - // type. - value = (is_pointer<T>::value && - (is_convertible<T, subtle::RefCountedBase*>::value || - is_convertible<T, subtle::RefCountedThreadSafeBase*>::value)) - }; -#endif -}; - -template <typename Params> -struct ParamsUseScopedRefptrCorrectly { - enum { value = 0 }; -}; - -template <> -struct ParamsUseScopedRefptrCorrectly<Tuple<>> { - enum { value = 1 }; -}; - -template <typename Head, typename... Tail> -struct ParamsUseScopedRefptrCorrectly<Tuple<Head, Tail...>> { - enum { value = !NeedsScopedRefptrButGetsRawPtr<Head>::value && - ParamsUseScopedRefptrCorrectly<Tuple<Tail...>>::value }; -}; - -} // namespace internal - -} // namespace base - -#endif // BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_ diff --git a/security/sandbox/chromium/base/memory/ref_counted.cc b/security/sandbox/chromium/base/memory/ref_counted.cc deleted file mode 100644 index f5924d0fe..000000000 --- a/security/sandbox/chromium/base/memory/ref_counted.cc +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/memory/ref_counted.h" -#include "base/threading/thread_collision_warner.h" - -namespace base { - -namespace subtle { - -bool RefCountedThreadSafeBase::HasOneRef() const { - return AtomicRefCountIsOne( - &const_cast<RefCountedThreadSafeBase*>(this)->ref_count_); -} - -RefCountedThreadSafeBase::RefCountedThreadSafeBase() : ref_count_(0) { -#ifndef NDEBUG - in_dtor_ = false; -#endif -} - -RefCountedThreadSafeBase::~RefCountedThreadSafeBase() { -#ifndef NDEBUG - DCHECK(in_dtor_) << "RefCountedThreadSafe object deleted without " - "calling Release()"; -#endif -} - -void RefCountedThreadSafeBase::AddRef() const { -#ifndef NDEBUG - DCHECK(!in_dtor_); -#endif - AtomicRefCountInc(&ref_count_); -} - -bool RefCountedThreadSafeBase::Release() const { -#ifndef NDEBUG - DCHECK(!in_dtor_); - DCHECK(!AtomicRefCountIsZero(&ref_count_)); -#endif - if (!AtomicRefCountDec(&ref_count_)) { -#ifndef NDEBUG - in_dtor_ = true; -#endif - return true; - } - return false; -} - -} // namespace subtle - -} // namespace base diff --git a/security/sandbox/chromium/base/memory/ref_counted.h b/security/sandbox/chromium/base/memory/ref_counted.h deleted file mode 100644 index a1c126969..000000000 --- a/security/sandbox/chromium/base/memory/ref_counted.h +++ /dev/null @@ -1,446 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_MEMORY_REF_COUNTED_H_ -#define BASE_MEMORY_REF_COUNTED_H_ - -#include <cassert> -#include <iosfwd> - -#include "base/atomic_ref_count.h" -#include "base/base_export.h" -#include "base/compiler_specific.h" -#include "base/macros.h" -#ifndef NDEBUG -#include "base/logging.h" -#endif -#include "base/threading/thread_collision_warner.h" -#include "build/build_config.h" - -namespace base { - -namespace subtle { - -class BASE_EXPORT RefCountedBase { - public: - bool HasOneRef() const { return ref_count_ == 1; } - - protected: - RefCountedBase() - : ref_count_(0) - #ifndef NDEBUG - , in_dtor_(false) - #endif - { - } - - ~RefCountedBase() { - #ifndef NDEBUG - DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()"; - #endif - } - - - void AddRef() const { - // TODO(maruel): Add back once it doesn't assert 500 times/sec. - // Current thread books the critical section "AddRelease" - // without release it. - // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_); - #ifndef NDEBUG - DCHECK(!in_dtor_); - #endif - ++ref_count_; - } - - // Returns true if the object should self-delete. - bool Release() const { - // TODO(maruel): Add back once it doesn't assert 500 times/sec. - // Current thread books the critical section "AddRelease" - // without release it. - // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_); - #ifndef NDEBUG - DCHECK(!in_dtor_); - #endif - if (--ref_count_ == 0) { - #ifndef NDEBUG - in_dtor_ = true; - #endif - return true; - } - return false; - } - - private: - mutable int ref_count_; -#ifndef NDEBUG - mutable bool in_dtor_; -#endif - - DFAKE_MUTEX(add_release_); - - DISALLOW_COPY_AND_ASSIGN(RefCountedBase); -}; - -class BASE_EXPORT RefCountedThreadSafeBase { - public: - bool HasOneRef() const; - - protected: - RefCountedThreadSafeBase(); - ~RefCountedThreadSafeBase(); - - void AddRef() const; - - // Returns true if the object should self-delete. - bool Release() const; - - private: - mutable AtomicRefCount ref_count_; -#ifndef NDEBUG - mutable bool in_dtor_; -#endif - - DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase); -}; - -} // namespace subtle - -// -// A base class for reference counted classes. Otherwise, known as a cheap -// knock-off of WebKit's RefCounted<T> class. To use this guy just extend your -// class from it like so: -// -// class MyFoo : public base::RefCounted<MyFoo> { -// ... -// private: -// friend class base::RefCounted<MyFoo>; -// ~MyFoo(); -// }; -// -// You should always make your destructor non-public, to avoid any code deleting -// the object accidently while there are references to it. -template <class T> -class RefCounted : public subtle::RefCountedBase { - public: - RefCounted() {} - - void AddRef() const { - subtle::RefCountedBase::AddRef(); - } - - void Release() const { - if (subtle::RefCountedBase::Release()) { - delete static_cast<const T*>(this); - } - } - - protected: - ~RefCounted() {} - - private: - DISALLOW_COPY_AND_ASSIGN(RefCounted<T>); -}; - -// Forward declaration. -template <class T, typename Traits> class RefCountedThreadSafe; - -// Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref -// count reaches 0. Overload to delete it on a different thread etc. -template<typename T> -struct DefaultRefCountedThreadSafeTraits { - static void Destruct(const T* x) { - // Delete through RefCountedThreadSafe to make child classes only need to be - // friend with RefCountedThreadSafe instead of this struct, which is an - // implementation detail. - RefCountedThreadSafe<T, - DefaultRefCountedThreadSafeTraits>::DeleteInternal(x); - } -}; - -// -// A thread-safe variant of RefCounted<T> -// -// class MyFoo : public base::RefCountedThreadSafe<MyFoo> { -// ... -// }; -// -// If you're using the default trait, then you should add compile time -// asserts that no one else is deleting your object. i.e. -// private: -// friend class base::RefCountedThreadSafe<MyFoo>; -// ~MyFoo(); -template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> > -class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase { - public: - RefCountedThreadSafe() {} - - void AddRef() const { - subtle::RefCountedThreadSafeBase::AddRef(); - } - - void Release() const { - if (subtle::RefCountedThreadSafeBase::Release()) { - Traits::Destruct(static_cast<const T*>(this)); - } - } - - protected: - ~RefCountedThreadSafe() {} - - private: - friend struct DefaultRefCountedThreadSafeTraits<T>; - static void DeleteInternal(const T* x) { delete x; } - - DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe); -}; - -// -// A thread-safe wrapper for some piece of data so we can place other -// things in scoped_refptrs<>. -// -template<typename T> -class RefCountedData - : public base::RefCountedThreadSafe< base::RefCountedData<T> > { - public: - RefCountedData() : data() {} - RefCountedData(const T& in_value) : data(in_value) {} - - T data; - - private: - friend class base::RefCountedThreadSafe<base::RefCountedData<T> >; - ~RefCountedData() {} -}; - -} // namespace base - -// -// A smart pointer class for reference counted objects. Use this class instead -// of calling AddRef and Release manually on a reference counted object to -// avoid common memory leaks caused by forgetting to Release an object -// reference. Sample usage: -// -// class MyFoo : public RefCounted<MyFoo> { -// ... -// }; -// -// void some_function() { -// scoped_refptr<MyFoo> foo = new MyFoo(); -// foo->Method(param); -// // |foo| is released when this function returns -// } -// -// void some_other_function() { -// scoped_refptr<MyFoo> foo = new MyFoo(); -// ... -// foo = NULL; // explicitly releases |foo| -// ... -// if (foo) -// foo->Method(param); -// } -// -// The above examples show how scoped_refptr<T> acts like a pointer to T. -// Given two scoped_refptr<T> classes, it is also possible to exchange -// references between the two objects, like so: -// -// { -// scoped_refptr<MyFoo> a = new MyFoo(); -// scoped_refptr<MyFoo> b; -// -// b.swap(a); -// // now, |b| references the MyFoo object, and |a| references NULL. -// } -// -// To make both |a| and |b| in the above example reference the same MyFoo -// object, simply use the assignment operator: -// -// { -// scoped_refptr<MyFoo> a = new MyFoo(); -// scoped_refptr<MyFoo> b; -// -// b = a; -// // now, |a| and |b| each own a reference to the same MyFoo object. -// } -// -template <class T> -class scoped_refptr { - public: - typedef T element_type; - - scoped_refptr() : ptr_(NULL) { - } - - scoped_refptr(T* p) : ptr_(p) { - if (ptr_) - AddRef(ptr_); - } - - // Copy constructor. - scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) { - if (ptr_) - AddRef(ptr_); - } - - // Copy conversion constructor. - template <typename U> - scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) { - if (ptr_) - AddRef(ptr_); - } - - // Move constructor. This is required in addition to the conversion - // constructor below in order for clang to warn about pessimizing moves. - scoped_refptr(scoped_refptr&& r) : ptr_(r.get()) { r.ptr_ = nullptr; } - - // Move conversion constructor. - template <typename U> - scoped_refptr(scoped_refptr<U>&& r) : ptr_(r.get()) { - r.ptr_ = nullptr; - } - - ~scoped_refptr() { - if (ptr_) - Release(ptr_); - } - - T* get() const { return ptr_; } - - T& operator*() const { - assert(ptr_ != NULL); - return *ptr_; - } - - T* operator->() const { - assert(ptr_ != NULL); - return ptr_; - } - - scoped_refptr<T>& operator=(T* p) { - // AddRef first so that self assignment should work - if (p) - AddRef(p); - T* old_ptr = ptr_; - ptr_ = p; - if (old_ptr) - Release(old_ptr); - return *this; - } - - scoped_refptr<T>& operator=(const scoped_refptr<T>& r) { - return *this = r.ptr_; - } - - template <typename U> - scoped_refptr<T>& operator=(const scoped_refptr<U>& r) { - return *this = r.get(); - } - - scoped_refptr<T>& operator=(scoped_refptr<T>&& r) { - scoped_refptr<T>(std::move(r)).swap(*this); - return *this; - } - - template <typename U> - scoped_refptr<T>& operator=(scoped_refptr<U>&& r) { - scoped_refptr<T>(std::move(r)).swap(*this); - return *this; - } - - void swap(T** pp) { - T* p = ptr_; - ptr_ = *pp; - *pp = p; - } - - void swap(scoped_refptr<T>& r) { - swap(&r.ptr_); - } - - private: - template <typename U> friend class scoped_refptr; - - // Allow scoped_refptr<T> to be used in boolean expressions, but not - // implicitly convertible to a real bool (which is dangerous). - // - // Note that this trick is only safe when the == and != operators - // are declared explicitly, as otherwise "refptr1 == refptr2" - // will compile but do the wrong thing (i.e., convert to Testable - // and then do the comparison). - typedef T* scoped_refptr::*Testable; - - public: - operator Testable() const { return ptr_ ? &scoped_refptr::ptr_ : nullptr; } - - template <typename U> - bool operator==(const scoped_refptr<U>& rhs) const { - return ptr_ == rhs.get(); - } - - template <typename U> - bool operator!=(const scoped_refptr<U>& rhs) const { - return !operator==(rhs); - } - - template <typename U> - bool operator<(const scoped_refptr<U>& rhs) const { - return ptr_ < rhs.get(); - } - - protected: - T* ptr_; - - private: - // Non-inline helpers to allow: - // class Opaque; - // extern template class scoped_refptr<Opaque>; - // Otherwise the compiler will complain that Opaque is an incomplete type. - static void AddRef(T* ptr); - static void Release(T* ptr); -}; - -template <typename T> -void scoped_refptr<T>::AddRef(T* ptr) { - ptr->AddRef(); -} - -template <typename T> -void scoped_refptr<T>::Release(T* ptr) { - ptr->Release(); -} - -// Handy utility for creating a scoped_refptr<T> out of a T* explicitly without -// having to retype all the template arguments -template <typename T> -scoped_refptr<T> make_scoped_refptr(T* t) { - return scoped_refptr<T>(t); -} - -// Temporary operator overloads to facilitate the transition. See -// https://crbug.com/110610. -template <typename T, typename U> -bool operator==(const scoped_refptr<T>& lhs, const U* rhs) { - return lhs.get() == rhs; -} - -template <typename T, typename U> -bool operator==(const T* lhs, const scoped_refptr<U>& rhs) { - return lhs == rhs.get(); -} - -template <typename T, typename U> -bool operator!=(const scoped_refptr<T>& lhs, const U* rhs) { - return !operator==(lhs, rhs); -} - -template <typename T, typename U> -bool operator!=(const T* lhs, const scoped_refptr<U>& rhs) { - return !operator==(lhs, rhs); -} - -template <typename T> -std::ostream& operator<<(std::ostream& out, const scoped_refptr<T>& p) { - return out << p.get(); -} - -#endif // BASE_MEMORY_REF_COUNTED_H_ diff --git a/security/sandbox/chromium/base/memory/scoped_ptr.h b/security/sandbox/chromium/base/memory/scoped_ptr.h deleted file mode 100644 index 282a01486..000000000 --- a/security/sandbox/chromium/base/memory/scoped_ptr.h +++ /dev/null @@ -1,607 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Scopers help you manage ownership of a pointer, helping you easily manage a -// pointer within a scope, and automatically destroying the pointer at the end -// of a scope. There are two main classes you will use, which correspond to the -// operators new/delete and new[]/delete[]. -// -// Example usage (scoped_ptr<T>): -// { -// scoped_ptr<Foo> foo(new Foo("wee")); -// } // foo goes out of scope, releasing the pointer with it. -// -// { -// scoped_ptr<Foo> foo; // No pointer managed. -// foo.reset(new Foo("wee")); // Now a pointer is managed. -// foo.reset(new Foo("wee2")); // Foo("wee") was destroyed. -// foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed. -// foo->Method(); // Foo::Method() called. -// foo.get()->Method(); // Foo::Method() called. -// SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer -// // manages a pointer. -// foo.reset(new Foo("wee4")); // foo manages a pointer again. -// foo.reset(); // Foo("wee4") destroyed, foo no longer -// // manages a pointer. -// } // foo wasn't managing a pointer, so nothing was destroyed. -// -// Example usage (scoped_ptr<T[]>): -// { -// scoped_ptr<Foo[]> foo(new Foo[100]); -// foo.get()->Method(); // Foo::Method on the 0th element. -// foo[10].Method(); // Foo::Method on the 10th element. -// } -// -// These scopers also implement part of the functionality of C++11 unique_ptr -// in that they are "movable but not copyable." You can use the scopers in -// the parameter and return types of functions to signify ownership transfer -// in to and out of a function. When calling a function that has a scoper -// as the argument type, it must be called with an rvalue of a scoper, which -// can be created by using std::move(), or the result of another function that -// generates a temporary; passing by copy will NOT work. Here is an example -// using scoped_ptr: -// -// void TakesOwnership(scoped_ptr<Foo> arg) { -// // Do something with arg. -// } -// scoped_ptr<Foo> CreateFoo() { -// // No need for calling std::move() for returning a move-only value, or -// // when you already have an rvalue as we do here. -// return scoped_ptr<Foo>(new Foo("new")); -// } -// scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) { -// return arg; -// } -// -// { -// scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay"). -// TakesOwnership(std::move(ptr)); // ptr no longer owns Foo("yay"). -// scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo. -// scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2. -// PassThru(std::move(ptr2)); // ptr2 is correspondingly nullptr. -// } -// -// Notice that if you do not call std::move() when returning from PassThru(), or -// when invoking TakesOwnership(), the code will not compile because scopers -// are not copyable; they only implement move semantics which require calling -// the std::move() function to signify a destructive transfer of state. -// CreateFoo() is different though because we are constructing a temporary on -// the return line and thus can avoid needing to call std::move(). -// -// The conversion move-constructor properly handles upcast in initialization, -// i.e. you can use a scoped_ptr<Child> to initialize a scoped_ptr<Parent>: -// -// scoped_ptr<Foo> foo(new Foo()); -// scoped_ptr<FooParent> parent(std::move(foo)); - -#ifndef BASE_MEMORY_SCOPED_PTR_H_ -#define BASE_MEMORY_SCOPED_PTR_H_ - -// This is an implementation designed to match the anticipated future TR2 -// implementation of the scoped_ptr class. - -#include <assert.h> -#include <stddef.h> -#include <stdlib.h> - -#include <iosfwd> -#include <memory> -#include <type_traits> -#include <utility> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/move.h" -#include "base/template_util.h" - -namespace base { - -namespace subtle { -class RefCountedBase; -class RefCountedThreadSafeBase; -} // namespace subtle - -// Function object which invokes 'free' on its parameter, which must be -// a pointer. Can be used to store malloc-allocated pointers in scoped_ptr: -// -// scoped_ptr<int, base::FreeDeleter> foo_ptr( -// static_cast<int*>(malloc(sizeof(int)))); -struct FreeDeleter { - inline void operator()(void* ptr) const { - free(ptr); - } -}; - -namespace internal { - -template <typename T> struct IsNotRefCounted { - enum { - value = !base::is_convertible<T*, base::subtle::RefCountedBase*>::value && - !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>:: - value - }; -}; - -// Minimal implementation of the core logic of scoped_ptr, suitable for -// reuse in both scoped_ptr and its specializations. -template <class T, class D> -class scoped_ptr_impl { - public: - explicit scoped_ptr_impl(T* p) : data_(p) {} - - // Initializer for deleters that have data parameters. - scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} - - // Templated constructor that destructively takes the value from another - // scoped_ptr_impl. - template <typename U, typename V> - scoped_ptr_impl(scoped_ptr_impl<U, V>* other) - : data_(other->release(), other->get_deleter()) { - // We do not support move-only deleters. We could modify our move - // emulation to have base::subtle::move() and base::subtle::forward() - // functions that are imperfect emulations of their C++11 equivalents, - // but until there's a requirement, just assume deleters are copyable. - } - - template <typename U, typename V> - void TakeState(scoped_ptr_impl<U, V>* other) { - // See comment in templated constructor above regarding lack of support - // for move-only deleters. - reset(other->release()); - get_deleter() = other->get_deleter(); - } - - ~scoped_ptr_impl() { - // Match libc++, which calls reset() in its destructor. - // Use nullptr as the new value for three reasons: - // 1. libc++ does it. - // 2. Avoids infinitely recursing into destructors if two classes are owned - // in a reference cycle (see ScopedPtrTest.ReferenceCycle). - // 3. If |this| is accessed in the future, in a use-after-free bug, attempts - // to dereference |this|'s pointer should cause either a failure or a - // segfault closer to the problem. If |this| wasn't reset to nullptr, - // the access would cause the deleted memory to be read or written - // leading to other more subtle issues. - reset(nullptr); - } - - void reset(T* p) { - // Match C++11's definition of unique_ptr::reset(), which requires changing - // the pointer before invoking the deleter on the old pointer. This prevents - // |this| from being accessed after the deleter is run, which may destroy - // |this|. - T* old = data_.ptr; - data_.ptr = p; - if (old != nullptr) - static_cast<D&>(data_)(old); - } - - T* get() const { return data_.ptr; } - - D& get_deleter() { return data_; } - const D& get_deleter() const { return data_; } - - void swap(scoped_ptr_impl& p2) { - // Standard swap idiom: 'using std::swap' ensures that std::swap is - // present in the overload set, but we call swap unqualified so that - // any more-specific overloads can be used, if available. - using std::swap; - swap(static_cast<D&>(data_), static_cast<D&>(p2.data_)); - swap(data_.ptr, p2.data_.ptr); - } - - T* release() { - T* old_ptr = data_.ptr; - data_.ptr = nullptr; - return old_ptr; - } - - private: - // Needed to allow type-converting constructor. - template <typename U, typename V> friend class scoped_ptr_impl; - - // Use the empty base class optimization to allow us to have a D - // member, while avoiding any space overhead for it when D is an - // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good - // discussion of this technique. - struct Data : public D { - explicit Data(T* ptr_in) : ptr(ptr_in) {} - Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {} - T* ptr; - }; - - Data data_; - - DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl); -}; - -} // namespace internal - -} // namespace base - -// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> -// automatically deletes the pointer it holds (if any). -// That is, scoped_ptr<T> owns the T object that it points to. -// Like a T*, a scoped_ptr<T> may hold either nullptr or a pointer to a T -// object. Also like T*, scoped_ptr<T> is thread-compatible, and once you -// dereference it, you get the thread safety guarantees of T. -// -// The size of scoped_ptr is small. On most compilers, when using the -// std::default_delete, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters -// will increase the size proportional to whatever state they need to have. See -// comments inside scoped_ptr_impl<> for details. -// -// Current implementation targets having a strict subset of C++11's -// unique_ptr<> features. Known deficiencies include not supporting move-only -// deleteres, function pointers as deleters, and deleters with reference -// types. -template <class T, class D = std::default_delete<T>> -class scoped_ptr { - DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND(scoped_ptr) - - static_assert(!std::is_array<T>::value, - "scoped_ptr doesn't support array with size"); - static_assert(base::internal::IsNotRefCounted<T>::value, - "T is a refcounted type and needs a scoped_refptr"); - - public: - // The element and deleter types. - using element_type = T; - using deleter_type = D; - - // Constructor. Defaults to initializing with nullptr. - scoped_ptr() : impl_(nullptr) {} - - // Constructor. Takes ownership of p. - explicit scoped_ptr(element_type* p) : impl_(p) {} - - // Constructor. Allows initialization of a stateful deleter. - scoped_ptr(element_type* p, const D& d) : impl_(p, d) {} - - // Constructor. Allows construction from a nullptr. - scoped_ptr(std::nullptr_t) : impl_(nullptr) {} - - // Move constructor. - // - // IMPLEMENTATION NOTE: Clang requires a move constructor to be defined (and - // not just the conversion constructor) in order to warn on pessimizing moves. - // The requirements for the move constructor are specified in C++11 - // 20.7.1.2.1.15-17, which has some subtleties around reference deleters. As - // we don't support reference (or move-only) deleters, the post conditions are - // trivially true: we always copy construct the deleter from other's deleter. - scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {} - - // Conversion constructor. Allows construction from a scoped_ptr rvalue for a - // convertible type and deleter. - // - // IMPLEMENTATION NOTE: C++ 20.7.1.2.1.19 requires this constructor to only - // participate in overload resolution if all the following are true: - // - U is implicitly convertible to T: this is important for 2 reasons: - // 1. So type traits don't incorrectly return true, e.g. - // std::is_convertible<scoped_ptr<Base>, scoped_ptr<Derived>>::value - // should be false. - // 2. To make sure code like this compiles: - // void F(scoped_ptr<int>); - // void F(scoped_ptr<Base>); - // // Ambiguous since both conversion constructors match. - // F(scoped_ptr<Derived>()); - // - U is not an array type: to prevent conversions from scoped_ptr<T[]> to - // scoped_ptr<T>. - // - D is a reference type and E is the same type, or D is not a reference - // type and E is implicitly convertible to D: again, we don't support - // reference deleters, so we only worry about the latter requirement. - template <typename U, - typename E, - typename std::enable_if<!std::is_array<U>::value && - std::is_convertible<U*, T*>::value && - std::is_convertible<E, D>::value>::type* = - nullptr> - scoped_ptr(scoped_ptr<U, E>&& other) - : impl_(&other.impl_) {} - - // operator=. - // - // IMPLEMENTATION NOTE: Unlike the move constructor, Clang does not appear to - // require a move assignment operator to trigger the pessimizing move warning: - // in this case, the warning triggers when moving a temporary. For consistency - // with the move constructor, we define it anyway. C++11 20.7.1.2.3.1-3 - // defines several requirements around this: like the move constructor, the - // requirements are simplified by the fact that we don't support move-only or - // reference deleters. - scoped_ptr& operator=(scoped_ptr&& rhs) { - impl_.TakeState(&rhs.impl_); - return *this; - } - - // operator=. Allows assignment from a scoped_ptr rvalue for a convertible - // type and deleter. - // - // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from - // the normal move assignment operator. C++11 20.7.1.2.3.4-7 contains the - // requirement for this operator, but like the conversion constructor, the - // requirements are greatly simplified by not supporting move-only or - // reference deleters. - template <typename U, - typename E, - typename std::enable_if<!std::is_array<U>::value && - std::is_convertible<U*, T*>::value && - // Note that this really should be - // std::is_assignable, but <type_traits> - // appears to be missing this on some - // platforms. This is close enough (though - // it's not the same). - std::is_convertible<D, E>::value>::type* = - nullptr> - scoped_ptr& operator=(scoped_ptr<U, E>&& rhs) { - impl_.TakeState(&rhs.impl_); - return *this; - } - - // operator=. Allows assignment from a nullptr. Deletes the currently owned - // object, if any. - scoped_ptr& operator=(std::nullptr_t) { - reset(); - return *this; - } - - // Reset. Deletes the currently owned object, if any. - // Then takes ownership of a new object, if given. - void reset(element_type* p = nullptr) { impl_.reset(p); } - - // Accessors to get the owned object. - // operator* and operator-> will assert() if there is no current object. - element_type& operator*() const { - assert(impl_.get() != nullptr); - return *impl_.get(); - } - element_type* operator->() const { - assert(impl_.get() != nullptr); - return impl_.get(); - } - element_type* get() const { return impl_.get(); } - - // Access to the deleter. - deleter_type& get_deleter() { return impl_.get_deleter(); } - const deleter_type& get_deleter() const { return impl_.get_deleter(); } - - // Allow scoped_ptr<element_type> to be used in boolean expressions, but not - // implicitly convertible to a real bool (which is dangerous). - // - // Note that this trick is only safe when the == and != operators - // are declared explicitly, as otherwise "scoped_ptr1 == - // scoped_ptr2" will compile but do the wrong thing (i.e., convert - // to Testable and then do the comparison). - private: - typedef base::internal::scoped_ptr_impl<element_type, deleter_type> - scoped_ptr::*Testable; - - public: - operator Testable() const { - return impl_.get() ? &scoped_ptr::impl_ : nullptr; - } - - // Swap two scoped pointers. - void swap(scoped_ptr& p2) { - impl_.swap(p2.impl_); - } - - // Release a pointer. - // The return value is the current pointer held by this object. If this object - // holds a nullptr, the return value is nullptr. After this operation, this - // object will hold a nullptr, and will not own the object any more. - element_type* release() WARN_UNUSED_RESULT { - return impl_.release(); - } - - private: - // Needed to reach into |impl_| in the constructor. - template <typename U, typename V> friend class scoped_ptr; - base::internal::scoped_ptr_impl<element_type, deleter_type> impl_; - - // Forbidden for API compatibility with std::unique_ptr. - explicit scoped_ptr(int disallow_construction_from_null); -}; - -template <class T, class D> -class scoped_ptr<T[], D> { - DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND(scoped_ptr) - - public: - // The element and deleter types. - using element_type = T; - using deleter_type = D; - - // Constructor. Defaults to initializing with nullptr. - scoped_ptr() : impl_(nullptr) {} - - // Constructor. Stores the given array. Note that the argument's type - // must exactly match T*. In particular: - // - it cannot be a pointer to a type derived from T, because it is - // inherently unsafe in the general case to access an array through a - // pointer whose dynamic type does not match its static type (eg., if - // T and the derived types had different sizes access would be - // incorrectly calculated). Deletion is also always undefined - // (C++98 [expr.delete]p3). If you're doing this, fix your code. - // - it cannot be const-qualified differently from T per unique_ptr spec - // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting - // to work around this may use const_cast<const T*>(). - explicit scoped_ptr(element_type* array) : impl_(array) {} - - // Constructor. Allows construction from a nullptr. - scoped_ptr(std::nullptr_t) : impl_(nullptr) {} - - // Constructor. Allows construction from a scoped_ptr rvalue. - scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {} - - // operator=. Allows assignment from a scoped_ptr rvalue. - scoped_ptr& operator=(scoped_ptr&& rhs) { - impl_.TakeState(&rhs.impl_); - return *this; - } - - // operator=. Allows assignment from a nullptr. Deletes the currently owned - // array, if any. - scoped_ptr& operator=(std::nullptr_t) { - reset(); - return *this; - } - - // Reset. Deletes the currently owned array, if any. - // Then takes ownership of a new object, if given. - void reset(element_type* array = nullptr) { impl_.reset(array); } - - // Accessors to get the owned array. - element_type& operator[](size_t i) const { - assert(impl_.get() != nullptr); - return impl_.get()[i]; - } - element_type* get() const { return impl_.get(); } - - // Access to the deleter. - deleter_type& get_deleter() { return impl_.get_deleter(); } - const deleter_type& get_deleter() const { return impl_.get_deleter(); } - - // Allow scoped_ptr<element_type> to be used in boolean expressions, but not - // implicitly convertible to a real bool (which is dangerous). - private: - typedef base::internal::scoped_ptr_impl<element_type, deleter_type> - scoped_ptr::*Testable; - - public: - operator Testable() const { - return impl_.get() ? &scoped_ptr::impl_ : nullptr; - } - - // Swap two scoped pointers. - void swap(scoped_ptr& p2) { - impl_.swap(p2.impl_); - } - - // Release a pointer. - // The return value is the current pointer held by this object. If this object - // holds a nullptr, the return value is nullptr. After this operation, this - // object will hold a nullptr, and will not own the object any more. - element_type* release() WARN_UNUSED_RESULT { - return impl_.release(); - } - - private: - // Force element_type to be a complete type. - enum { type_must_be_complete = sizeof(element_type) }; - - // Actually hold the data. - base::internal::scoped_ptr_impl<element_type, deleter_type> impl_; - - // Disable initialization from any type other than element_type*, by - // providing a constructor that matches such an initialization, but is - // private and has no definition. This is disabled because it is not safe to - // call delete[] on an array whose static type does not match its dynamic - // type. - template <typename U> explicit scoped_ptr(U* array); - explicit scoped_ptr(int disallow_construction_from_null); - - // Disable reset() from any type other than element_type*, for the same - // reasons as the constructor above. - template <typename U> void reset(U* array); - void reset(int disallow_reset_from_null); -}; - -// Free functions -template <class T, class D> -void swap(scoped_ptr<T, D>& p1, scoped_ptr<T, D>& p2) { - p1.swap(p2); -} - -template <class T1, class D1, class T2, class D2> -bool operator==(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) { - return p1.get() == p2.get(); -} -template <class T, class D> -bool operator==(const scoped_ptr<T, D>& p, std::nullptr_t) { - return p.get() == nullptr; -} -template <class T, class D> -bool operator==(std::nullptr_t, const scoped_ptr<T, D>& p) { - return p.get() == nullptr; -} - -template <class T1, class D1, class T2, class D2> -bool operator!=(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) { - return !(p1 == p2); -} -template <class T, class D> -bool operator!=(const scoped_ptr<T, D>& p, std::nullptr_t) { - return !(p == nullptr); -} -template <class T, class D> -bool operator!=(std::nullptr_t, const scoped_ptr<T, D>& p) { - return !(p == nullptr); -} - -template <class T1, class D1, class T2, class D2> -bool operator<(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) { - return p1.get() < p2.get(); -} -template <class T, class D> -bool operator<(const scoped_ptr<T, D>& p, std::nullptr_t) { - return p.get() < nullptr; -} -template <class T, class D> -bool operator<(std::nullptr_t, const scoped_ptr<T, D>& p) { - return nullptr < p.get(); -} - -template <class T1, class D1, class T2, class D2> -bool operator>(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) { - return p2 < p1; -} -template <class T, class D> -bool operator>(const scoped_ptr<T, D>& p, std::nullptr_t) { - return nullptr < p; -} -template <class T, class D> -bool operator>(std::nullptr_t, const scoped_ptr<T, D>& p) { - return p < nullptr; -} - -template <class T1, class D1, class T2, class D2> -bool operator<=(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) { - return !(p1 > p2); -} -template <class T, class D> -bool operator<=(const scoped_ptr<T, D>& p, std::nullptr_t) { - return !(p > nullptr); -} -template <class T, class D> -bool operator<=(std::nullptr_t, const scoped_ptr<T, D>& p) { - return !(nullptr > p); -} - -template <class T1, class D1, class T2, class D2> -bool operator>=(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) { - return !(p1 < p2); -} -template <class T, class D> -bool operator>=(const scoped_ptr<T, D>& p, std::nullptr_t) { - return !(p < nullptr); -} -template <class T, class D> -bool operator>=(std::nullptr_t, const scoped_ptr<T, D>& p) { - return !(nullptr < p); -} - -// A function to convert T* into scoped_ptr<T> -// Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation -// for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) -template <typename T> -scoped_ptr<T> make_scoped_ptr(T* ptr) { - return scoped_ptr<T>(ptr); -} - -template <typename T> -std::ostream& operator<<(std::ostream& out, const scoped_ptr<T>& p) { - return out << p.get(); -} - -#endif // BASE_MEMORY_SCOPED_PTR_H_ diff --git a/security/sandbox/chromium/base/memory/singleton.cc b/security/sandbox/chromium/base/memory/singleton.cc deleted file mode 100644 index f68ecaa8d..000000000 --- a/security/sandbox/chromium/base/memory/singleton.cc +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/memory/singleton.h" -#include "base/threading/platform_thread.h" - -namespace base { -namespace internal { - -subtle::AtomicWord WaitForInstance(subtle::AtomicWord* instance) { - // Handle the race. Another thread beat us and either: - // - Has the object in BeingCreated state - // - Already has the object created... - // We know value != NULL. It could be kBeingCreatedMarker, or a valid ptr. - // Unless your constructor can be very time consuming, it is very unlikely - // to hit this race. When it does, we just spin and yield the thread until - // the object has been created. - subtle::AtomicWord value; - while (true) { - // The load has acquire memory ordering as the thread which reads the - // instance pointer must acquire visibility over the associated data. - // The pairing Release_Store operation is in Singleton::get(). - value = subtle::Acquire_Load(instance); - if (value != kBeingCreatedMarker) - break; - PlatformThread::YieldCurrentThread(); - } - return value; -} - -} // namespace internal -} // namespace base - diff --git a/security/sandbox/chromium/base/memory/singleton.h b/security/sandbox/chromium/base/memory/singleton.h deleted file mode 100644 index 79e4441a8..000000000 --- a/security/sandbox/chromium/base/memory/singleton.h +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// PLEASE READ: Do you really need a singleton? -// -// Singletons make it hard to determine the lifetime of an object, which can -// lead to buggy code and spurious crashes. -// -// Instead of adding another singleton into the mix, try to identify either: -// a) An existing singleton that can manage your object's lifetime -// b) Locations where you can deterministically create the object and pass -// into other objects -// -// If you absolutely need a singleton, please keep them as trivial as possible -// and ideally a leaf dependency. Singletons get problematic when they attempt -// to do too much in their destructor or have circular dependencies. - -#ifndef BASE_MEMORY_SINGLETON_H_ -#define BASE_MEMORY_SINGLETON_H_ - -#include "base/at_exit.h" -#include "base/atomicops.h" -#include "base/base_export.h" -#include "base/macros.h" -#include "base/memory/aligned_memory.h" -#include "base/threading/thread_restrictions.h" - -namespace base { -namespace internal { - -// Our AtomicWord doubles as a spinlock, where a value of -// kBeingCreatedMarker means the spinlock is being held for creation. -static const subtle::AtomicWord kBeingCreatedMarker = 1; - -// We pull out some of the functionality into a non-templated function, so that -// we can implement the more complicated pieces out of line in the .cc file. -BASE_EXPORT subtle::AtomicWord WaitForInstance(subtle::AtomicWord* instance); - -class DeleteTraceLogForTesting; - -} // namespace internal - - -// Default traits for Singleton<Type>. Calls operator new and operator delete on -// the object. Registers automatic deletion at process exit. -// Overload if you need arguments or another memory allocation function. -template<typename Type> -struct DefaultSingletonTraits { - // Allocates the object. - static Type* New() { - // The parenthesis is very important here; it forces POD type - // initialization. - return new Type(); - } - - // Destroys the object. - static void Delete(Type* x) { - delete x; - } - - // Set to true to automatically register deletion of the object on process - // exit. See below for the required call that makes this happen. - static const bool kRegisterAtExit = true; - -#ifndef NDEBUG - // Set to false to disallow access on a non-joinable thread. This is - // different from kRegisterAtExit because StaticMemorySingletonTraits allows - // access on non-joinable threads, and gracefully handles this. - static const bool kAllowedToAccessOnNonjoinableThread = false; -#endif -}; - - -// Alternate traits for use with the Singleton<Type>. Identical to -// DefaultSingletonTraits except that the Singleton will not be cleaned up -// at exit. -template<typename Type> -struct LeakySingletonTraits : public DefaultSingletonTraits<Type> { - static const bool kRegisterAtExit = false; -#ifndef NDEBUG - static const bool kAllowedToAccessOnNonjoinableThread = true; -#endif -}; - - -// Alternate traits for use with the Singleton<Type>. Allocates memory -// for the singleton instance from a static buffer. The singleton will -// be cleaned up at exit, but can't be revived after destruction unless -// the Resurrect() method is called. -// -// This is useful for a certain category of things, notably logging and -// tracing, where the singleton instance is of a type carefully constructed to -// be safe to access post-destruction. -// In logging and tracing you'll typically get stray calls at odd times, like -// during static destruction, thread teardown and the like, and there's a -// termination race on the heap-based singleton - e.g. if one thread calls -// get(), but then another thread initiates AtExit processing, the first thread -// may call into an object residing in unallocated memory. If the instance is -// allocated from the data segment, then this is survivable. -// -// The destructor is to deallocate system resources, in this case to unregister -// a callback the system will invoke when logging levels change. Note that -// this is also used in e.g. Chrome Frame, where you have to allow for the -// possibility of loading briefly into someone else's process space, and -// so leaking is not an option, as that would sabotage the state of your host -// process once you've unloaded. -template <typename Type> -struct StaticMemorySingletonTraits { - // WARNING: User has to deal with get() in the singleton class - // this is traits for returning NULL. - static Type* New() { - // Only constructs once and returns pointer; otherwise returns NULL. - if (subtle::NoBarrier_AtomicExchange(&dead_, 1)) - return NULL; - - return new(buffer_.void_data()) Type(); - } - - static void Delete(Type* p) { - if (p != NULL) - p->Type::~Type(); - } - - static const bool kRegisterAtExit = true; - static const bool kAllowedToAccessOnNonjoinableThread = true; - - // Exposed for unittesting. - static void Resurrect() { subtle::NoBarrier_Store(&dead_, 0); } - - private: - static AlignedMemory<sizeof(Type), ALIGNOF(Type)> buffer_; - // Signal the object was already deleted, so it is not revived. - static subtle::Atomic32 dead_; -}; - -template <typename Type> -AlignedMemory<sizeof(Type), ALIGNOF(Type)> - StaticMemorySingletonTraits<Type>::buffer_; -template <typename Type> -subtle::Atomic32 StaticMemorySingletonTraits<Type>::dead_ = 0; - -// The Singleton<Type, Traits, DifferentiatingType> class manages a single -// instance of Type which will be created on first use and will be destroyed at -// normal process exit). The Trait::Delete function will not be called on -// abnormal process exit. -// -// DifferentiatingType is used as a key to differentiate two different -// singletons having the same memory allocation functions but serving a -// different purpose. This is mainly used for Locks serving different purposes. -// -// Example usage: -// -// In your header: -// template <typename T> struct DefaultSingletonTraits; -// class FooClass { -// public: -// static FooClass* GetInstance(); <-- See comment below on this. -// void Bar() { ... } -// private: -// FooClass() { ... } -// friend struct DefaultSingletonTraits<FooClass>; -// -// DISALLOW_COPY_AND_ASSIGN(FooClass); -// }; -// -// In your source file: -// #include "base/memory/singleton.h" -// FooClass* FooClass::GetInstance() { -// return Singleton<FooClass>::get(); -// } -// -// And to call methods on FooClass: -// FooClass::GetInstance()->Bar(); -// -// NOTE: The method accessing Singleton<T>::get() has to be named as GetInstance -// and it is important that FooClass::GetInstance() is not inlined in the -// header. This makes sure that when source files from multiple targets include -// this header they don't end up with different copies of the inlined code -// creating multiple copies of the singleton. -// -// Singleton<> has no non-static members and doesn't need to actually be -// instantiated. -// -// This class is itself thread-safe. The underlying Type must of course be -// thread-safe if you want to use it concurrently. Two parameters may be tuned -// depending on the user's requirements. -// -// Glossary: -// RAE = kRegisterAtExit -// -// On every platform, if Traits::RAE is true, the singleton will be destroyed at -// process exit. More precisely it uses AtExitManager which requires an -// object of this type to be instantiated. AtExitManager mimics the semantics -// of atexit() such as LIFO order but under Windows is safer to call. For more -// information see at_exit.h. -// -// If Traits::RAE is false, the singleton will not be freed at process exit, -// thus the singleton will be leaked if it is ever accessed. Traits::RAE -// shouldn't be false unless absolutely necessary. Remember that the heap where -// the object is allocated may be destroyed by the CRT anyway. -// -// Caveats: -// (a) Every call to get(), operator->() and operator*() incurs some overhead -// (16ns on my P4/2.8GHz) to check whether the object has already been -// initialized. You may wish to cache the result of get(); it will not -// change. -// -// (b) Your factory function must never throw an exception. This class is not -// exception-safe. -// - -template <typename Type, - typename Traits = DefaultSingletonTraits<Type>, - typename DifferentiatingType = Type> -class Singleton { - private: - // Classes using the Singleton<T> pattern should declare a GetInstance() - // method and call Singleton::get() from within that. - friend Type* Type::GetInstance(); - - // Allow TraceLog tests to test tracing after OnExit. - friend class internal::DeleteTraceLogForTesting; - - // This class is safe to be constructed and copy-constructed since it has no - // member. - - // Return a pointer to the one true instance of the class. - static Type* get() { -#ifndef NDEBUG - // Avoid making TLS lookup on release builds. - if (!Traits::kAllowedToAccessOnNonjoinableThread) - ThreadRestrictions::AssertSingletonAllowed(); -#endif - - // The load has acquire memory ordering as the thread which reads the - // instance_ pointer must acquire visibility over the singleton data. - subtle::AtomicWord value = subtle::Acquire_Load(&instance_); - if (value != 0 && value != internal::kBeingCreatedMarker) { - return reinterpret_cast<Type*>(value); - } - - // Object isn't created yet, maybe we will get to create it, let's try... - if (subtle::Acquire_CompareAndSwap(&instance_, 0, - internal::kBeingCreatedMarker) == 0) { - // instance_ was NULL and is now kBeingCreatedMarker. Only one thread - // will ever get here. Threads might be spinning on us, and they will - // stop right after we do this store. - Type* newval = Traits::New(); - - // Releases the visibility over instance_ to the readers. - subtle::Release_Store(&instance_, - reinterpret_cast<subtle::AtomicWord>(newval)); - - if (newval != NULL && Traits::kRegisterAtExit) - AtExitManager::RegisterCallback(OnExit, NULL); - - return newval; - } - - // We hit a race. Wait for the other thread to complete it. - value = internal::WaitForInstance(&instance_); - - return reinterpret_cast<Type*>(value); - } - - // Adapter function for use with AtExit(). This should be called single - // threaded, so don't use atomic operations. - // Calling OnExit while singleton is in use by other threads is a mistake. - static void OnExit(void* /*unused*/) { - // AtExit should only ever be register after the singleton instance was - // created. We should only ever get here with a valid instance_ pointer. - Traits::Delete(reinterpret_cast<Type*>(subtle::NoBarrier_Load(&instance_))); - instance_ = 0; - } - static subtle::AtomicWord instance_; -}; - -template <typename Type, typename Traits, typename DifferentiatingType> -subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>::instance_ = 0; - -} // namespace base - -#endif // BASE_MEMORY_SINGLETON_H_ diff --git a/security/sandbox/chromium/base/memory/weak_ptr.h b/security/sandbox/chromium/base/memory/weak_ptr.h deleted file mode 100644 index 33d1e4736..000000000 --- a/security/sandbox/chromium/base/memory/weak_ptr.h +++ /dev/null @@ -1,345 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Weak pointers are pointers to an object that do not affect its lifetime, -// and which may be invalidated (i.e. reset to NULL) by the object, or its -// owner, at any time, most commonly when the object is about to be deleted. - -// Weak pointers are useful when an object needs to be accessed safely by one -// or more objects other than its owner, and those callers can cope with the -// object vanishing and e.g. tasks posted to it being silently dropped. -// Reference-counting such an object would complicate the ownership graph and -// make it harder to reason about the object's lifetime. - -// EXAMPLE: -// -// class Controller { -// public: -// Controller() : weak_factory_(this) {} -// void SpawnWorker() { Worker::StartNew(weak_factory_.GetWeakPtr()); } -// void WorkComplete(const Result& result) { ... } -// private: -// // Member variables should appear before the WeakPtrFactory, to ensure -// // that any WeakPtrs to Controller are invalidated before its members -// // variable's destructors are executed, rendering them invalid. -// WeakPtrFactory<Controller> weak_factory_; -// }; -// -// class Worker { -// public: -// static void StartNew(const WeakPtr<Controller>& controller) { -// Worker* worker = new Worker(controller); -// // Kick off asynchronous processing... -// } -// private: -// Worker(const WeakPtr<Controller>& controller) -// : controller_(controller) {} -// void DidCompleteAsynchronousProcessing(const Result& result) { -// if (controller_) -// controller_->WorkComplete(result); -// } -// WeakPtr<Controller> controller_; -// }; -// -// With this implementation a caller may use SpawnWorker() to dispatch multiple -// Workers and subsequently delete the Controller, without waiting for all -// Workers to have completed. - -// ------------------------- IMPORTANT: Thread-safety ------------------------- - -// Weak pointers may be passed safely between threads, but must always be -// dereferenced and invalidated on the same SequencedTaskRunner otherwise -// checking the pointer would be racey. -// -// To ensure correct use, the first time a WeakPtr issued by a WeakPtrFactory -// is dereferenced, the factory and its WeakPtrs become bound to the calling -// thread or current SequencedWorkerPool token, and cannot be dereferenced or -// invalidated on any other task runner. Bound WeakPtrs can still be handed -// off to other task runners, e.g. to use to post tasks back to object on the -// bound sequence. -// -// If all WeakPtr objects are destroyed or invalidated then the factory is -// unbound from the SequencedTaskRunner/Thread. The WeakPtrFactory may then be -// destroyed, or new WeakPtr objects may be used, from a different sequence. -// -// Thus, at least one WeakPtr object must exist and have been dereferenced on -// the correct thread to enforce that other WeakPtr objects will enforce they -// are used on the desired thread. - -#ifndef BASE_MEMORY_WEAK_PTR_H_ -#define BASE_MEMORY_WEAK_PTR_H_ - -#include "base/base_export.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/sequence_checker.h" -#include "base/template_util.h" - -namespace base { - -template <typename T> class SupportsWeakPtr; -template <typename T> class WeakPtr; - -namespace internal { -// These classes are part of the WeakPtr implementation. -// DO NOT USE THESE CLASSES DIRECTLY YOURSELF. - -class BASE_EXPORT WeakReference { - public: - // Although Flag is bound to a specific SequencedTaskRunner, it may be - // deleted from another via base::WeakPtr::~WeakPtr(). - class BASE_EXPORT Flag : public RefCountedThreadSafe<Flag> { - public: - Flag(); - - void Invalidate(); - bool IsValid() const; - - private: - friend class base::RefCountedThreadSafe<Flag>; - - ~Flag(); - - SequenceChecker sequence_checker_; - bool is_valid_; - }; - - WeakReference(); - explicit WeakReference(const Flag* flag); - ~WeakReference(); - - bool is_valid() const; - - private: - scoped_refptr<const Flag> flag_; -}; - -class BASE_EXPORT WeakReferenceOwner { - public: - WeakReferenceOwner(); - ~WeakReferenceOwner(); - - WeakReference GetRef() const; - - bool HasRefs() const { - return flag_.get() && !flag_->HasOneRef(); - } - - void Invalidate(); - - private: - mutable scoped_refptr<WeakReference::Flag> flag_; -}; - -// This class simplifies the implementation of WeakPtr's type conversion -// constructor by avoiding the need for a public accessor for ref_. A -// WeakPtr<T> cannot access the private members of WeakPtr<U>, so this -// base class gives us a way to access ref_ in a protected fashion. -class BASE_EXPORT WeakPtrBase { - public: - WeakPtrBase(); - ~WeakPtrBase(); - - protected: - explicit WeakPtrBase(const WeakReference& ref); - - WeakReference ref_; -}; - -// This class provides a common implementation of common functions that would -// otherwise get instantiated separately for each distinct instantiation of -// SupportsWeakPtr<>. -class SupportsWeakPtrBase { - public: - // A safe static downcast of a WeakPtr<Base> to WeakPtr<Derived>. This - // conversion will only compile if there is exists a Base which inherits - // from SupportsWeakPtr<Base>. See base::AsWeakPtr() below for a helper - // function that makes calling this easier. - template<typename Derived> - static WeakPtr<Derived> StaticAsWeakPtr(Derived* t) { - typedef - is_convertible<Derived, internal::SupportsWeakPtrBase&> convertible; - static_assert(convertible::value, - "AsWeakPtr argument must inherit from SupportsWeakPtr"); - return AsWeakPtrImpl<Derived>(t, *t); - } - - private: - // This template function uses type inference to find a Base of Derived - // which is an instance of SupportsWeakPtr<Base>. We can then safely - // static_cast the Base* to a Derived*. - template <typename Derived, typename Base> - static WeakPtr<Derived> AsWeakPtrImpl( - Derived* t, const SupportsWeakPtr<Base>&) { - WeakPtr<Base> ptr = t->Base::AsWeakPtr(); - return WeakPtr<Derived>(ptr.ref_, static_cast<Derived*>(ptr.ptr_)); - } -}; - -} // namespace internal - -template <typename T> class WeakPtrFactory; - -// The WeakPtr class holds a weak reference to |T*|. -// -// This class is designed to be used like a normal pointer. You should always -// null-test an object of this class before using it or invoking a method that -// may result in the underlying object being destroyed. -// -// EXAMPLE: -// -// class Foo { ... }; -// WeakPtr<Foo> foo; -// if (foo) -// foo->method(); -// -template <typename T> -class WeakPtr : public internal::WeakPtrBase { - public: - WeakPtr() : ptr_(NULL) { - } - - // Allow conversion from U to T provided U "is a" T. Note that this - // is separate from the (implicit) copy constructor. - template <typename U> - WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.ptr_) { - } - - T* get() const { return ref_.is_valid() ? ptr_ : NULL; } - - T& operator*() const { - DCHECK(get() != NULL); - return *get(); - } - T* operator->() const { - DCHECK(get() != NULL); - return get(); - } - - // Allow WeakPtr<element_type> to be used in boolean expressions, but not - // implicitly convertible to a real bool (which is dangerous). - // - // Note that this trick is only safe when the == and != operators - // are declared explicitly, as otherwise "weak_ptr1 == weak_ptr2" - // will compile but do the wrong thing (i.e., convert to Testable - // and then do the comparison). - private: - typedef T* WeakPtr::*Testable; - - public: - operator Testable() const { return get() ? &WeakPtr::ptr_ : NULL; } - - void reset() { - ref_ = internal::WeakReference(); - ptr_ = NULL; - } - - private: - // Explicitly declare comparison operators as required by the bool - // trick, but keep them private. - template <class U> bool operator==(WeakPtr<U> const&) const; - template <class U> bool operator!=(WeakPtr<U> const&) const; - - friend class internal::SupportsWeakPtrBase; - template <typename U> friend class WeakPtr; - friend class SupportsWeakPtr<T>; - friend class WeakPtrFactory<T>; - - WeakPtr(const internal::WeakReference& ref, T* ptr) - : WeakPtrBase(ref), - ptr_(ptr) { - } - - // This pointer is only valid when ref_.is_valid() is true. Otherwise, its - // value is undefined (as opposed to NULL). - T* ptr_; -}; - -// A class may be composed of a WeakPtrFactory and thereby -// control how it exposes weak pointers to itself. This is helpful if you only -// need weak pointers within the implementation of a class. This class is also -// useful when working with primitive types. For example, you could have a -// WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. -template <class T> -class WeakPtrFactory { - public: - explicit WeakPtrFactory(T* ptr) : ptr_(ptr) { - } - - ~WeakPtrFactory() { - ptr_ = NULL; - } - - WeakPtr<T> GetWeakPtr() { - DCHECK(ptr_); - return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_); - } - - // Call this method to invalidate all existing weak pointers. - void InvalidateWeakPtrs() { - DCHECK(ptr_); - weak_reference_owner_.Invalidate(); - } - - // Call this method to determine if any weak pointers exist. - bool HasWeakPtrs() const { - DCHECK(ptr_); - return weak_reference_owner_.HasRefs(); - } - - private: - internal::WeakReferenceOwner weak_reference_owner_; - T* ptr_; - DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); -}; - -// A class may extend from SupportsWeakPtr to let others take weak pointers to -// it. This avoids the class itself implementing boilerplate to dispense weak -// pointers. However, since SupportsWeakPtr's destructor won't invalidate -// weak pointers to the class until after the derived class' members have been -// destroyed, its use can lead to subtle use-after-destroy issues. -template <class T> -class SupportsWeakPtr : public internal::SupportsWeakPtrBase { - public: - SupportsWeakPtr() {} - - WeakPtr<T> AsWeakPtr() { - return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this)); - } - - protected: - ~SupportsWeakPtr() {} - - private: - internal::WeakReferenceOwner weak_reference_owner_; - DISALLOW_COPY_AND_ASSIGN(SupportsWeakPtr); -}; - -// Helper function that uses type deduction to safely return a WeakPtr<Derived> -// when Derived doesn't directly extend SupportsWeakPtr<Derived>, instead it -// extends a Base that extends SupportsWeakPtr<Base>. -// -// EXAMPLE: -// class Base : public base::SupportsWeakPtr<Producer> {}; -// class Derived : public Base {}; -// -// Derived derived; -// base::WeakPtr<Derived> ptr = base::AsWeakPtr(&derived); -// -// Note that the following doesn't work (invalid type conversion) since -// Derived::AsWeakPtr() is WeakPtr<Base> SupportsWeakPtr<Base>::AsWeakPtr(), -// and there's no way to safely cast WeakPtr<Base> to WeakPtr<Derived> at -// the caller. -// -// base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. - -template <typename Derived> -WeakPtr<Derived> AsWeakPtr(Derived* t) { - return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); -} - -} // namespace base - -#endif // BASE_MEMORY_WEAK_PTR_H_ diff --git a/security/sandbox/chromium/base/move.h b/security/sandbox/chromium/base/move.h deleted file mode 100644 index 0af416e00..000000000 --- a/security/sandbox/chromium/base/move.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_MOVE_H_ -#define BASE_MOVE_H_ - -#include <utility> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "build/build_config.h" - -// TODO(crbug.com/566182): DEPRECATED! -// Use DISALLOW_COPY_AND_ASSIGN instead, or if your type will be used in -// Callbacks, use DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND instead. -#define MOVE_ONLY_TYPE_FOR_CPP_03(type) \ - DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND(type) - -// A macro to disallow the copy constructor and copy assignment functions. -// This should be used in the private: declarations for a class. -// -// Use this macro instead of DISALLOW_COPY_AND_ASSIGN if you want to pass -// ownership of the type through a base::Callback without heap-allocating it -// into a scoped_ptr. The class must define a move constructor and move -// assignment operator to make this work. -// -// This version of the macro adds a Pass() function and a cryptic -// MoveOnlyTypeForCPP03 typedef for the base::Callback implementation to use. -// See IsMoveOnlyType template and its usage in base/callback_internal.h -// for more details. -// TODO(crbug.com/566182): Remove this macro and use DISALLOW_COPY_AND_ASSIGN -// everywhere instead. -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_MACOSX) -#define DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND(type) \ - private: \ - type(const type&) = delete; \ - void operator=(const type&) = delete; \ - \ - public: \ - typedef void MoveOnlyTypeForCPP03; \ - \ - private: -#else -#define DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND(type) \ - private: \ - type(const type&) = delete; \ - void operator=(const type&) = delete; \ - \ - public: \ - type&& Pass() WARN_UNUSED_RESULT { return std::move(*this); } \ - typedef void MoveOnlyTypeForCPP03; \ - \ - private: -#endif - -#endif // BASE_MOVE_H_ diff --git a/security/sandbox/chromium/base/numerics/safe_conversions.h b/security/sandbox/chromium/base/numerics/safe_conversions.h deleted file mode 100644 index baac188fd..000000000 --- a/security/sandbox/chromium/base/numerics/safe_conversions.h +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_NUMERICS_SAFE_CONVERSIONS_H_ -#define BASE_NUMERICS_SAFE_CONVERSIONS_H_ - -#include <stddef.h> - -#include <limits> -#include <type_traits> - -#include "base/logging.h" -#include "base/numerics/safe_conversions_impl.h" - -namespace base { - -// Convenience function that returns true if the supplied value is in range -// for the destination type. -template <typename Dst, typename Src> -inline bool IsValueInRangeForNumericType(Src value) { - return internal::DstRangeRelationToSrcRange<Dst>(value) == - internal::RANGE_VALID; -} - -// Convenience function for determining if a numeric value is negative without -// throwing compiler warnings on: unsigned(value) < 0. -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type -IsValueNegative(T value) { - static_assert(std::numeric_limits<T>::is_specialized, - "Argument must be numeric."); - return value < 0; -} - -template <typename T> -typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type - IsValueNegative(T) { - static_assert(std::numeric_limits<T>::is_specialized, - "Argument must be numeric."); - return false; -} - -// checked_cast<> is analogous to static_cast<> for numeric types, -// except that it CHECKs that the specified numeric conversion will not -// overflow or underflow. NaN source will always trigger a CHECK. -template <typename Dst, typename Src> -inline Dst checked_cast(Src value) { - CHECK(IsValueInRangeForNumericType<Dst>(value)); - return static_cast<Dst>(value); -} - -// HandleNaN will cause this class to CHECK(false). -struct SaturatedCastNaNBehaviorCheck { - template <typename T> - static T HandleNaN() { - CHECK(false); - return T(); - } -}; - -// HandleNaN will return 0 in this case. -struct SaturatedCastNaNBehaviorReturnZero { - template <typename T> - static T HandleNaN() { - return T(); - } -}; - -// saturated_cast<> is analogous to static_cast<> for numeric types, except -// that the specified numeric conversion will saturate rather than overflow or -// underflow. NaN assignment to an integral will defer the behavior to a -// specified class. By default, it will return 0. -template <typename Dst, - class NaNHandler = SaturatedCastNaNBehaviorReturnZero, - typename Src> -inline Dst saturated_cast(Src value) { - // Optimization for floating point values, which already saturate. - if (std::numeric_limits<Dst>::is_iec559) - return static_cast<Dst>(value); - - switch (internal::DstRangeRelationToSrcRange<Dst>(value)) { - case internal::RANGE_VALID: - return static_cast<Dst>(value); - - case internal::RANGE_UNDERFLOW: - return std::numeric_limits<Dst>::min(); - - case internal::RANGE_OVERFLOW: - return std::numeric_limits<Dst>::max(); - - // Should fail only on attempting to assign NaN to a saturated integer. - case internal::RANGE_INVALID: - return NaNHandler::template HandleNaN<Dst>(); - } - - NOTREACHED(); - return static_cast<Dst>(value); -} - -// strict_cast<> is analogous to static_cast<> for numeric types, except that -// it will cause a compile failure if the destination type is not large enough -// to contain any value in the source type. It performs no runtime checking. -template <typename Dst, typename Src> -inline Dst strict_cast(Src value) { - static_assert(std::numeric_limits<Src>::is_specialized, - "Argument must be numeric."); - static_assert(std::numeric_limits<Dst>::is_specialized, - "Result must be numeric."); - static_assert((internal::StaticDstRangeRelationToSrcRange<Dst, Src>::value == - internal::NUMERIC_RANGE_CONTAINED), - "The numeric conversion is out of range for this type. You " - "should probably use one of the following conversion " - "mechanisms on the value you want to pass:\n" - "- base::checked_cast\n" - "- base::saturated_cast\n" - "- base::CheckedNumeric"); - - return static_cast<Dst>(value); -} - -// StrictNumeric implements compile time range checking between numeric types by -// wrapping assignment operations in a strict_cast. This class is intended to be -// used for function arguments and return types, to ensure the destination type -// can always contain the source type. This is essentially the same as enforcing -// -Wconversion in gcc and C4302 warnings on MSVC, but it can be applied -// incrementally at API boundaries, making it easier to convert code so that it -// compiles cleanly with truncation warnings enabled. -// This template should introduce no runtime overhead, but it also provides no -// runtime checking of any of the associated mathematical operations. Use -// CheckedNumeric for runtime range checks of tha actual value being assigned. -template <typename T> -class StrictNumeric { - public: - typedef T type; - - StrictNumeric() : value_(0) {} - - // Copy constructor. - template <typename Src> - StrictNumeric(const StrictNumeric<Src>& rhs) - : value_(strict_cast<T>(rhs.value_)) {} - - // This is not an explicit constructor because we implicitly upgrade regular - // numerics to StrictNumerics to make them easier to use. - template <typename Src> - StrictNumeric(Src value) - : value_(strict_cast<T>(value)) {} - - // The numeric cast operator basically handles all the magic. - template <typename Dst> - operator Dst() const { - return strict_cast<Dst>(value_); - } - - private: - T value_; -}; - -// Explicitly make a shorter size_t typedef for convenience. -typedef StrictNumeric<size_t> SizeT; - -} // namespace base - -#endif // BASE_NUMERICS_SAFE_CONVERSIONS_H_ diff --git a/security/sandbox/chromium/base/numerics/safe_conversions_impl.h b/security/sandbox/chromium/base/numerics/safe_conversions_impl.h deleted file mode 100644 index 02e68e25d..000000000 --- a/security/sandbox/chromium/base/numerics/safe_conversions_impl.h +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ -#define BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ - -#include <limits.h> -#include <stdint.h> - -#include <limits> - -#include "base/template_util.h" - -namespace base { -namespace internal { - -// The std library doesn't provide a binary max_exponent for integers, however -// we can compute one by adding one to the number of non-sign bits. This allows -// for accurate range comparisons between floating point and integer types. -template <typename NumericType> -struct MaxExponent { - static const int value = std::numeric_limits<NumericType>::is_iec559 - ? std::numeric_limits<NumericType>::max_exponent - : (sizeof(NumericType) * 8 + 1 - - std::numeric_limits<NumericType>::is_signed); -}; - -enum IntegerRepresentation { - INTEGER_REPRESENTATION_UNSIGNED, - INTEGER_REPRESENTATION_SIGNED -}; - -// A range for a given nunmeric Src type is contained for a given numeric Dst -// type if both numeric_limits<Src>::max() <= numeric_limits<Dst>::max() and -// numeric_limits<Src>::min() >= numeric_limits<Dst>::min() are true. -// We implement this as template specializations rather than simple static -// comparisons to ensure type correctness in our comparisons. -enum NumericRangeRepresentation { - NUMERIC_RANGE_NOT_CONTAINED, - NUMERIC_RANGE_CONTAINED -}; - -// Helper templates to statically determine if our destination type can contain -// maximum and minimum values represented by the source type. - -template < - typename Dst, - typename Src, - IntegerRepresentation DstSign = std::numeric_limits<Dst>::is_signed - ? INTEGER_REPRESENTATION_SIGNED - : INTEGER_REPRESENTATION_UNSIGNED, - IntegerRepresentation SrcSign = - std::numeric_limits<Src>::is_signed - ? INTEGER_REPRESENTATION_SIGNED - : INTEGER_REPRESENTATION_UNSIGNED > -struct StaticDstRangeRelationToSrcRange; - -// Same sign: Dst is guaranteed to contain Src only if its range is equal or -// larger. -template <typename Dst, typename Src, IntegerRepresentation Sign> -struct StaticDstRangeRelationToSrcRange<Dst, Src, Sign, Sign> { - static const NumericRangeRepresentation value = - MaxExponent<Dst>::value >= MaxExponent<Src>::value - ? NUMERIC_RANGE_CONTAINED - : NUMERIC_RANGE_NOT_CONTAINED; -}; - -// Unsigned to signed: Dst is guaranteed to contain source only if its range is -// larger. -template <typename Dst, typename Src> -struct StaticDstRangeRelationToSrcRange<Dst, - Src, - INTEGER_REPRESENTATION_SIGNED, - INTEGER_REPRESENTATION_UNSIGNED> { - static const NumericRangeRepresentation value = - MaxExponent<Dst>::value > MaxExponent<Src>::value - ? NUMERIC_RANGE_CONTAINED - : NUMERIC_RANGE_NOT_CONTAINED; -}; - -// Signed to unsigned: Dst cannot be statically determined to contain Src. -template <typename Dst, typename Src> -struct StaticDstRangeRelationToSrcRange<Dst, - Src, - INTEGER_REPRESENTATION_UNSIGNED, - INTEGER_REPRESENTATION_SIGNED> { - static const NumericRangeRepresentation value = NUMERIC_RANGE_NOT_CONTAINED; -}; - -enum RangeConstraint { - RANGE_VALID = 0x0, // Value can be represented by the destination type. - RANGE_UNDERFLOW = 0x1, // Value would overflow. - RANGE_OVERFLOW = 0x2, // Value would underflow. - RANGE_INVALID = RANGE_UNDERFLOW | RANGE_OVERFLOW // Invalid (i.e. NaN). -}; - -// Helper function for coercing an int back to a RangeContraint. -inline RangeConstraint GetRangeConstraint(int integer_range_constraint) { - DCHECK(integer_range_constraint >= RANGE_VALID && - integer_range_constraint <= RANGE_INVALID); - return static_cast<RangeConstraint>(integer_range_constraint); -} - -// This function creates a RangeConstraint from an upper and lower bound -// check by taking advantage of the fact that only NaN can be out of range in -// both directions at once. -inline RangeConstraint GetRangeConstraint(bool is_in_upper_bound, - bool is_in_lower_bound) { - return GetRangeConstraint((is_in_upper_bound ? 0 : RANGE_OVERFLOW) | - (is_in_lower_bound ? 0 : RANGE_UNDERFLOW)); -} - -// The following helper template addresses a corner case in range checks for -// conversion from a floating-point type to an integral type of smaller range -// but larger precision (e.g. float -> unsigned). The problem is as follows: -// 1. Integral maximum is always one less than a power of two, so it must be -// truncated to fit the mantissa of the floating point. The direction of -// rounding is implementation defined, but by default it's always IEEE -// floats, which round to nearest and thus result in a value of larger -// magnitude than the integral value. -// Example: float f = UINT_MAX; // f is 4294967296f but UINT_MAX -// // is 4294967295u. -// 2. If the floating point value is equal to the promoted integral maximum -// value, a range check will erroneously pass. -// Example: (4294967296f <= 4294967295u) // This is true due to a precision -// // loss in rounding up to float. -// 3. When the floating point value is then converted to an integral, the -// resulting value is out of range for the target integral type and -// thus is implementation defined. -// Example: unsigned u = (float)INT_MAX; // u will typically overflow to 0. -// To fix this bug we manually truncate the maximum value when the destination -// type is an integral of larger precision than the source floating-point type, -// such that the resulting maximum is represented exactly as a floating point. -template <typename Dst, typename Src> -struct NarrowingRange { - typedef typename std::numeric_limits<Src> SrcLimits; - typedef typename std::numeric_limits<Dst> DstLimits; - - static Dst max() { - // The following logic avoids warnings where the max function is - // instantiated with invalid values for a bit shift (even though - // such a function can never be called). - static const int shift = - (MaxExponent<Src>::value > MaxExponent<Dst>::value && - SrcLimits::digits < DstLimits::digits && SrcLimits::is_iec559 && - DstLimits::is_integer) - ? (DstLimits::digits - SrcLimits::digits) - : 0; - - // We use UINTMAX_C below to avoid compiler warnings about shifting floating - // points. Since it's a compile time calculation, it shouldn't have any - // performance impact. - return DstLimits::max() - static_cast<Dst>((UINTMAX_C(1) << shift) - 1); - } - - static Dst min() { - return std::numeric_limits<Dst>::is_iec559 ? -DstLimits::max() - : DstLimits::min(); - } -}; - -template < - typename Dst, - typename Src, - IntegerRepresentation DstSign = std::numeric_limits<Dst>::is_signed - ? INTEGER_REPRESENTATION_SIGNED - : INTEGER_REPRESENTATION_UNSIGNED, - IntegerRepresentation SrcSign = std::numeric_limits<Src>::is_signed - ? INTEGER_REPRESENTATION_SIGNED - : INTEGER_REPRESENTATION_UNSIGNED, - NumericRangeRepresentation DstRange = - StaticDstRangeRelationToSrcRange<Dst, Src>::value > -struct DstRangeRelationToSrcRangeImpl; - -// The following templates are for ranges that must be verified at runtime. We -// split it into checks based on signedness to avoid confusing casts and -// compiler warnings on signed an unsigned comparisons. - -// Dst range is statically determined to contain Src: Nothing to check. -template <typename Dst, - typename Src, - IntegerRepresentation DstSign, - IntegerRepresentation SrcSign> -struct DstRangeRelationToSrcRangeImpl<Dst, - Src, - DstSign, - SrcSign, - NUMERIC_RANGE_CONTAINED> { - static RangeConstraint Check(Src value) { return RANGE_VALID; } -}; - -// Signed to signed narrowing: Both the upper and lower boundaries may be -// exceeded. -template <typename Dst, typename Src> -struct DstRangeRelationToSrcRangeImpl<Dst, - Src, - INTEGER_REPRESENTATION_SIGNED, - INTEGER_REPRESENTATION_SIGNED, - NUMERIC_RANGE_NOT_CONTAINED> { - static RangeConstraint Check(Src value) { - return GetRangeConstraint((value <= NarrowingRange<Dst, Src>::max()), - (value >= NarrowingRange<Dst, Src>::min())); - } -}; - -// Unsigned to unsigned narrowing: Only the upper boundary can be exceeded. -template <typename Dst, typename Src> -struct DstRangeRelationToSrcRangeImpl<Dst, - Src, - INTEGER_REPRESENTATION_UNSIGNED, - INTEGER_REPRESENTATION_UNSIGNED, - NUMERIC_RANGE_NOT_CONTAINED> { - static RangeConstraint Check(Src value) { - return GetRangeConstraint(value <= NarrowingRange<Dst, Src>::max(), true); - } -}; - -// Unsigned to signed: The upper boundary may be exceeded. -template <typename Dst, typename Src> -struct DstRangeRelationToSrcRangeImpl<Dst, - Src, - INTEGER_REPRESENTATION_SIGNED, - INTEGER_REPRESENTATION_UNSIGNED, - NUMERIC_RANGE_NOT_CONTAINED> { - static RangeConstraint Check(Src value) { - return sizeof(Dst) > sizeof(Src) - ? RANGE_VALID - : GetRangeConstraint( - value <= static_cast<Src>(NarrowingRange<Dst, Src>::max()), - true); - } -}; - -// Signed to unsigned: The upper boundary may be exceeded for a narrower Dst, -// and any negative value exceeds the lower boundary. -template <typename Dst, typename Src> -struct DstRangeRelationToSrcRangeImpl<Dst, - Src, - INTEGER_REPRESENTATION_UNSIGNED, - INTEGER_REPRESENTATION_SIGNED, - NUMERIC_RANGE_NOT_CONTAINED> { - static RangeConstraint Check(Src value) { - return (MaxExponent<Dst>::value >= MaxExponent<Src>::value) - ? GetRangeConstraint(true, value >= static_cast<Src>(0)) - : GetRangeConstraint( - value <= static_cast<Src>(NarrowingRange<Dst, Src>::max()), - value >= static_cast<Src>(0)); - } -}; - -template <typename Dst, typename Src> -inline RangeConstraint DstRangeRelationToSrcRange(Src value) { - static_assert(std::numeric_limits<Src>::is_specialized, - "Argument must be numeric."); - static_assert(std::numeric_limits<Dst>::is_specialized, - "Result must be numeric."); - return DstRangeRelationToSrcRangeImpl<Dst, Src>::Check(value); -} - -} // namespace internal -} // namespace base - -#endif // BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ diff --git a/security/sandbox/chromium/base/numerics/safe_math.h b/security/sandbox/chromium/base/numerics/safe_math.h deleted file mode 100644 index d169690a8..000000000 --- a/security/sandbox/chromium/base/numerics/safe_math.h +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_NUMERICS_SAFE_MATH_H_ -#define BASE_NUMERICS_SAFE_MATH_H_ - -#include <stddef.h> - -#include "base/numerics/safe_math_impl.h" - -namespace base { - -namespace internal { - -// CheckedNumeric implements all the logic and operators for detecting integer -// boundary conditions such as overflow, underflow, and invalid conversions. -// The CheckedNumeric type implicitly converts from floating point and integer -// data types, and contains overloads for basic arithmetic operations (i.e.: +, -// -, *, /, %). -// -// The following methods convert from CheckedNumeric to standard numeric values: -// IsValid() - Returns true if the underlying numeric value is valid (i.e. has -// has not wrapped and is not the result of an invalid conversion). -// ValueOrDie() - Returns the underlying value. If the state is not valid this -// call will crash on a CHECK. -// ValueOrDefault() - Returns the current value, or the supplied default if the -// state is not valid. -// ValueFloating() - Returns the underlying floating point value (valid only -// only for floating point CheckedNumeric types). -// -// Bitwise operations are explicitly not supported, because correct -// handling of some cases (e.g. sign manipulation) is ambiguous. Comparison -// operations are explicitly not supported because they could result in a crash -// on a CHECK condition. You should use patterns like the following for these -// operations: -// Bitwise operation: -// CheckedNumeric<int> checked_int = untrusted_input_value; -// int x = checked_int.ValueOrDefault(0) | kFlagValues; -// Comparison: -// CheckedNumeric<size_t> checked_size = untrusted_input_value; -// checked_size += HEADER LENGTH; -// if (checked_size.IsValid() && checked_size.ValueOrDie() < buffer_size) -// Do stuff... -template <typename T> -class CheckedNumeric { - public: - typedef T type; - - CheckedNumeric() {} - - // Copy constructor. - template <typename Src> - CheckedNumeric(const CheckedNumeric<Src>& rhs) - : state_(rhs.ValueUnsafe(), rhs.validity()) {} - - template <typename Src> - CheckedNumeric(Src value, RangeConstraint validity) - : state_(value, validity) {} - - // This is not an explicit constructor because we implicitly upgrade regular - // numerics to CheckedNumerics to make them easier to use. - template <typename Src> - CheckedNumeric(Src value) - : state_(value) { - static_assert(std::numeric_limits<Src>::is_specialized, - "Argument must be numeric."); - } - - // This is not an explicit constructor because we want a seamless conversion - // from StrictNumeric types. - template <typename Src> - CheckedNumeric(StrictNumeric<Src> value) - : state_(static_cast<Src>(value)) { - } - - // IsValid() is the public API to test if a CheckedNumeric is currently valid. - bool IsValid() const { return validity() == RANGE_VALID; } - - // ValueOrDie() The primary accessor for the underlying value. If the current - // state is not valid it will CHECK and crash. - T ValueOrDie() const { - CHECK(IsValid()); - return state_.value(); - } - - // ValueOrDefault(T default_value) A convenience method that returns the - // current value if the state is valid, and the supplied default_value for - // any other state. - T ValueOrDefault(T default_value) const { - return IsValid() ? state_.value() : default_value; - } - - // ValueFloating() - Since floating point values include their validity state, - // we provide an easy method for extracting them directly, without a risk of - // crashing on a CHECK. - T ValueFloating() const { - static_assert(std::numeric_limits<T>::is_iec559, "Argument must be float."); - return CheckedNumeric<T>::cast(*this).ValueUnsafe(); - } - - // validity() - DO NOT USE THIS IN EXTERNAL CODE - It is public right now for - // tests and to avoid a big matrix of friend operator overloads. But the - // values it returns are likely to change in the future. - // Returns: current validity state (i.e. valid, overflow, underflow, nan). - // TODO(jschuh): crbug.com/332611 Figure out and implement semantics for - // saturation/wrapping so we can expose this state consistently and implement - // saturated arithmetic. - RangeConstraint validity() const { return state_.validity(); } - - // ValueUnsafe() - DO NOT USE THIS IN EXTERNAL CODE - It is public right now - // for tests and to avoid a big matrix of friend operator overloads. But the - // values it returns are likely to change in the future. - // Returns: the raw numeric value, regardless of the current state. - // TODO(jschuh): crbug.com/332611 Figure out and implement semantics for - // saturation/wrapping so we can expose this state consistently and implement - // saturated arithmetic. - T ValueUnsafe() const { return state_.value(); } - - // Prototypes for the supported arithmetic operator overloads. - template <typename Src> CheckedNumeric& operator+=(Src rhs); - template <typename Src> CheckedNumeric& operator-=(Src rhs); - template <typename Src> CheckedNumeric& operator*=(Src rhs); - template <typename Src> CheckedNumeric& operator/=(Src rhs); - template <typename Src> CheckedNumeric& operator%=(Src rhs); - - CheckedNumeric operator-() const { - RangeConstraint validity; - T value = CheckedNeg(state_.value(), &validity); - // Negation is always valid for floating point. - if (std::numeric_limits<T>::is_iec559) - return CheckedNumeric<T>(value); - - validity = GetRangeConstraint(state_.validity() | validity); - return CheckedNumeric<T>(value, validity); - } - - CheckedNumeric Abs() const { - RangeConstraint validity; - T value = CheckedAbs(state_.value(), &validity); - // Absolute value is always valid for floating point. - if (std::numeric_limits<T>::is_iec559) - return CheckedNumeric<T>(value); - - validity = GetRangeConstraint(state_.validity() | validity); - return CheckedNumeric<T>(value, validity); - } - - // This function is available only for integral types. It returns an unsigned - // integer of the same width as the source type, containing the absolute value - // of the source, and properly handling signed min. - CheckedNumeric<typename UnsignedOrFloatForSize<T>::type> UnsignedAbs() const { - return CheckedNumeric<typename UnsignedOrFloatForSize<T>::type>( - CheckedUnsignedAbs(state_.value()), state_.validity()); - } - - CheckedNumeric& operator++() { - *this += 1; - return *this; - } - - CheckedNumeric operator++(int) { - CheckedNumeric value = *this; - *this += 1; - return value; - } - - CheckedNumeric& operator--() { - *this -= 1; - return *this; - } - - CheckedNumeric operator--(int) { - CheckedNumeric value = *this; - *this -= 1; - return value; - } - - // These static methods behave like a convenience cast operator targeting - // the desired CheckedNumeric type. As an optimization, a reference is - // returned when Src is the same type as T. - template <typename Src> - static CheckedNumeric<T> cast( - Src u, - typename std::enable_if<std::numeric_limits<Src>::is_specialized, - int>::type = 0) { - return u; - } - - template <typename Src> - static CheckedNumeric<T> cast( - const CheckedNumeric<Src>& u, - typename std::enable_if<!is_same<Src, T>::value, int>::type = 0) { - return u; - } - - static const CheckedNumeric<T>& cast(const CheckedNumeric<T>& u) { return u; } - - private: - template <typename NumericType> - struct UnderlyingType { - using type = NumericType; - }; - - template <typename NumericType> - struct UnderlyingType<CheckedNumeric<NumericType>> { - using type = NumericType; - }; - - CheckedNumericState<T> state_; -}; - -// This is the boilerplate for the standard arithmetic operator overloads. A -// macro isn't the prettiest solution, but it beats rewriting these five times. -// Some details worth noting are: -// * We apply the standard arithmetic promotions. -// * We skip range checks for floating points. -// * We skip range checks for destination integers with sufficient range. -// TODO(jschuh): extract these out into templates. -#define BASE_NUMERIC_ARITHMETIC_OPERATORS(NAME, OP, COMPOUND_OP) \ - /* Binary arithmetic operator for CheckedNumerics of the same type. */ \ - template <typename T> \ - CheckedNumeric<typename ArithmeticPromotion<T>::type> operator OP( \ - const CheckedNumeric<T>& lhs, const CheckedNumeric<T>& rhs) { \ - typedef typename ArithmeticPromotion<T>::type Promotion; \ - /* Floating point always takes the fast path */ \ - if (std::numeric_limits<T>::is_iec559) \ - return CheckedNumeric<T>(lhs.ValueUnsafe() OP rhs.ValueUnsafe()); \ - if (IsIntegerArithmeticSafe<Promotion, T, T>::value) \ - return CheckedNumeric<Promotion>( \ - lhs.ValueUnsafe() OP rhs.ValueUnsafe(), \ - GetRangeConstraint(rhs.validity() | lhs.validity())); \ - RangeConstraint validity = RANGE_VALID; \ - T result = static_cast<T>(Checked##NAME( \ - static_cast<Promotion>(lhs.ValueUnsafe()), \ - static_cast<Promotion>(rhs.ValueUnsafe()), \ - &validity)); \ - return CheckedNumeric<Promotion>( \ - result, \ - GetRangeConstraint(validity | lhs.validity() | rhs.validity())); \ - } \ - /* Assignment arithmetic operator implementation from CheckedNumeric. */ \ - template <typename T> \ - template <typename Src> \ - CheckedNumeric<T>& CheckedNumeric<T>::operator COMPOUND_OP(Src rhs) { \ - *this = CheckedNumeric<T>::cast(*this) \ - OP CheckedNumeric<typename UnderlyingType<Src>::type>::cast(rhs); \ - return *this; \ - } \ - /* Binary arithmetic operator for CheckedNumeric of different type. */ \ - template <typename T, typename Src> \ - CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP( \ - const CheckedNumeric<Src>& lhs, const CheckedNumeric<T>& rhs) { \ - typedef typename ArithmeticPromotion<T, Src>::type Promotion; \ - if (IsIntegerArithmeticSafe<Promotion, T, Src>::value) \ - return CheckedNumeric<Promotion>( \ - lhs.ValueUnsafe() OP rhs.ValueUnsafe(), \ - GetRangeConstraint(rhs.validity() | lhs.validity())); \ - return CheckedNumeric<Promotion>::cast(lhs) \ - OP CheckedNumeric<Promotion>::cast(rhs); \ - } \ - /* Binary arithmetic operator for left CheckedNumeric and right numeric. */ \ - template <typename T, typename Src> \ - CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP( \ - const CheckedNumeric<T>& lhs, Src rhs) { \ - typedef typename ArithmeticPromotion<T, Src>::type Promotion; \ - if (IsIntegerArithmeticSafe<Promotion, T, Src>::value) \ - return CheckedNumeric<Promotion>(lhs.ValueUnsafe() OP rhs, \ - lhs.validity()); \ - return CheckedNumeric<Promotion>::cast(lhs) \ - OP CheckedNumeric<Promotion>::cast(rhs); \ - } \ - /* Binary arithmetic operator for right numeric and left CheckedNumeric. */ \ - template <typename T, typename Src> \ - CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP( \ - Src lhs, const CheckedNumeric<T>& rhs) { \ - typedef typename ArithmeticPromotion<T, Src>::type Promotion; \ - if (IsIntegerArithmeticSafe<Promotion, T, Src>::value) \ - return CheckedNumeric<Promotion>(lhs OP rhs.ValueUnsafe(), \ - rhs.validity()); \ - return CheckedNumeric<Promotion>::cast(lhs) \ - OP CheckedNumeric<Promotion>::cast(rhs); \ - } - -BASE_NUMERIC_ARITHMETIC_OPERATORS(Add, +, += ) -BASE_NUMERIC_ARITHMETIC_OPERATORS(Sub, -, -= ) -BASE_NUMERIC_ARITHMETIC_OPERATORS(Mul, *, *= ) -BASE_NUMERIC_ARITHMETIC_OPERATORS(Div, /, /= ) -BASE_NUMERIC_ARITHMETIC_OPERATORS(Mod, %, %= ) - -#undef BASE_NUMERIC_ARITHMETIC_OPERATORS - -} // namespace internal - -using internal::CheckedNumeric; - -} // namespace base - -#endif // BASE_NUMERICS_SAFE_MATH_H_ diff --git a/security/sandbox/chromium/base/numerics/safe_math_impl.h b/security/sandbox/chromium/base/numerics/safe_math_impl.h deleted file mode 100644 index 4fbcc045b..000000000 --- a/security/sandbox/chromium/base/numerics/safe_math_impl.h +++ /dev/null @@ -1,545 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_NUMERICS_SAFE_MATH_IMPL_H_ -#define BASE_NUMERICS_SAFE_MATH_IMPL_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <cmath> -#include <cstdlib> -#include <limits> -#include <type_traits> - -#include "base/numerics/safe_conversions.h" -#include "base/template_util.h" - -namespace base { -namespace internal { - -// Everything from here up to the floating point operations is portable C++, -// but it may not be fast. This code could be split based on -// platform/architecture and replaced with potentially faster implementations. - -// Integer promotion templates used by the portable checked integer arithmetic. -template <size_t Size, bool IsSigned> -struct IntegerForSizeAndSign; -template <> -struct IntegerForSizeAndSign<1, true> { - typedef int8_t type; -}; -template <> -struct IntegerForSizeAndSign<1, false> { - typedef uint8_t type; -}; -template <> -struct IntegerForSizeAndSign<2, true> { - typedef int16_t type; -}; -template <> -struct IntegerForSizeAndSign<2, false> { - typedef uint16_t type; -}; -template <> -struct IntegerForSizeAndSign<4, true> { - typedef int32_t type; -}; -template <> -struct IntegerForSizeAndSign<4, false> { - typedef uint32_t type; -}; -template <> -struct IntegerForSizeAndSign<8, true> { - typedef int64_t type; -}; -template <> -struct IntegerForSizeAndSign<8, false> { - typedef uint64_t type; -}; - -// WARNING: We have no IntegerForSizeAndSign<16, *>. If we ever add one to -// support 128-bit math, then the ArithmeticPromotion template below will need -// to be updated (or more likely replaced with a decltype expression). - -template <typename Integer> -struct UnsignedIntegerForSize { - typedef typename std::enable_if< - std::numeric_limits<Integer>::is_integer, - typename IntegerForSizeAndSign<sizeof(Integer), false>::type>::type type; -}; - -template <typename Integer> -struct SignedIntegerForSize { - typedef typename std::enable_if< - std::numeric_limits<Integer>::is_integer, - typename IntegerForSizeAndSign<sizeof(Integer), true>::type>::type type; -}; - -template <typename Integer> -struct TwiceWiderInteger { - typedef typename std::enable_if< - std::numeric_limits<Integer>::is_integer, - typename IntegerForSizeAndSign< - sizeof(Integer) * 2, - std::numeric_limits<Integer>::is_signed>::type>::type type; -}; - -template <typename Integer> -struct PositionOfSignBit { - static const typename std::enable_if<std::numeric_limits<Integer>::is_integer, - size_t>::type value = - 8 * sizeof(Integer) - 1; -}; - -// This is used for UnsignedAbs, where we need to support floating-point -// template instantiations even though we don't actually support the operations. -// However, there is no corresponding implementation of e.g. CheckedUnsignedAbs, -// so the float versions will not compile. -template <typename Numeric, - bool IsInteger = std::numeric_limits<Numeric>::is_integer, - bool IsFloat = std::numeric_limits<Numeric>::is_iec559> -struct UnsignedOrFloatForSize; - -template <typename Numeric> -struct UnsignedOrFloatForSize<Numeric, true, false> { - typedef typename UnsignedIntegerForSize<Numeric>::type type; -}; - -template <typename Numeric> -struct UnsignedOrFloatForSize<Numeric, false, true> { - typedef Numeric type; -}; - -// Helper templates for integer manipulations. - -template <typename T> -bool HasSignBit(T x) { - // Cast to unsigned since right shift on signed is undefined. - return !!(static_cast<typename UnsignedIntegerForSize<T>::type>(x) >> - PositionOfSignBit<T>::value); -} - -// This wrapper undoes the standard integer promotions. -template <typename T> -T BinaryComplement(T x) { - return ~x; -} - -// Here are the actual portable checked integer math implementations. -// TODO(jschuh): Break this code out from the enable_if pattern and find a clean -// way to coalesce things into the CheckedNumericState specializations below. - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer, T>::type -CheckedAdd(T x, T y, RangeConstraint* validity) { - // Since the value of x+y is undefined if we have a signed type, we compute - // it using the unsigned type of the same size. - typedef typename UnsignedIntegerForSize<T>::type UnsignedDst; - UnsignedDst ux = static_cast<UnsignedDst>(x); - UnsignedDst uy = static_cast<UnsignedDst>(y); - UnsignedDst uresult = ux + uy; - // Addition is valid if the sign of (x + y) is equal to either that of x or - // that of y. - if (std::numeric_limits<T>::is_signed) { - if (HasSignBit(BinaryComplement((uresult ^ ux) & (uresult ^ uy)))) - *validity = RANGE_VALID; - else // Direction of wrap is inverse of result sign. - *validity = HasSignBit(uresult) ? RANGE_OVERFLOW : RANGE_UNDERFLOW; - - } else { // Unsigned is either valid or overflow. - *validity = BinaryComplement(x) >= y ? RANGE_VALID : RANGE_OVERFLOW; - } - return static_cast<T>(uresult); -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer, T>::type -CheckedSub(T x, T y, RangeConstraint* validity) { - // Since the value of x+y is undefined if we have a signed type, we compute - // it using the unsigned type of the same size. - typedef typename UnsignedIntegerForSize<T>::type UnsignedDst; - UnsignedDst ux = static_cast<UnsignedDst>(x); - UnsignedDst uy = static_cast<UnsignedDst>(y); - UnsignedDst uresult = ux - uy; - // Subtraction is valid if either x and y have same sign, or (x-y) and x have - // the same sign. - if (std::numeric_limits<T>::is_signed) { - if (HasSignBit(BinaryComplement((uresult ^ ux) & (ux ^ uy)))) - *validity = RANGE_VALID; - else // Direction of wrap is inverse of result sign. - *validity = HasSignBit(uresult) ? RANGE_OVERFLOW : RANGE_UNDERFLOW; - - } else { // Unsigned is either valid or underflow. - *validity = x >= y ? RANGE_VALID : RANGE_UNDERFLOW; - } - return static_cast<T>(uresult); -} - -// Integer multiplication is a bit complicated. In the fast case we just -// we just promote to a twice wider type, and range check the result. In the -// slow case we need to manually check that the result won't be truncated by -// checking with division against the appropriate bound. -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - sizeof(T) * 2 <= sizeof(uintmax_t), - T>::type -CheckedMul(T x, T y, RangeConstraint* validity) { - typedef typename TwiceWiderInteger<T>::type IntermediateType; - IntermediateType tmp = - static_cast<IntermediateType>(x) * static_cast<IntermediateType>(y); - *validity = DstRangeRelationToSrcRange<T>(tmp); - return static_cast<T>(tmp); -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed && - (sizeof(T) * 2 > sizeof(uintmax_t)), - T>::type -CheckedMul(T x, T y, RangeConstraint* validity) { - // If either side is zero then the result will be zero. - if (!x || !y) { - return RANGE_VALID; - - } else if (x > 0) { - if (y > 0) - *validity = - x <= std::numeric_limits<T>::max() / y ? RANGE_VALID : RANGE_OVERFLOW; - else - *validity = y >= std::numeric_limits<T>::min() / x ? RANGE_VALID - : RANGE_UNDERFLOW; - - } else { - if (y > 0) - *validity = x >= std::numeric_limits<T>::min() / y ? RANGE_VALID - : RANGE_UNDERFLOW; - else - *validity = - y >= std::numeric_limits<T>::max() / x ? RANGE_VALID : RANGE_OVERFLOW; - } - - return x * y; -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed && - (sizeof(T) * 2 > sizeof(uintmax_t)), - T>::type -CheckedMul(T x, T y, RangeConstraint* validity) { - *validity = (y == 0 || x <= std::numeric_limits<T>::max() / y) - ? RANGE_VALID - : RANGE_OVERFLOW; - return x * y; -} - -// Division just requires a check for an invalid negation on signed min/-1. -template <typename T> -T CheckedDiv(T x, - T y, - RangeConstraint* validity, - typename std::enable_if<std::numeric_limits<T>::is_integer, - int>::type = 0) { - if (std::numeric_limits<T>::is_signed && x == std::numeric_limits<T>::min() && - y == static_cast<T>(-1)) { - *validity = RANGE_OVERFLOW; - return std::numeric_limits<T>::min(); - } - - *validity = RANGE_VALID; - return x / y; -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, - T>::type -CheckedMod(T x, T y, RangeConstraint* validity) { - *validity = y > 0 ? RANGE_VALID : RANGE_INVALID; - return x % y; -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, - T>::type -CheckedMod(T x, T y, RangeConstraint* validity) { - *validity = RANGE_VALID; - return x % y; -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, - T>::type -CheckedNeg(T value, RangeConstraint* validity) { - *validity = - value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW; - // The negation of signed min is min, so catch that one. - return -value; -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, - T>::type -CheckedNeg(T value, RangeConstraint* validity) { - // The only legal unsigned negation is zero. - *validity = value ? RANGE_UNDERFLOW : RANGE_VALID; - return static_cast<T>( - -static_cast<typename SignedIntegerForSize<T>::type>(value)); -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, - T>::type -CheckedAbs(T value, RangeConstraint* validity) { - *validity = - value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW; - return static_cast<T>(std::abs(value)); -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, - T>::type -CheckedAbs(T value, RangeConstraint* validity) { - // T is unsigned, so |value| must already be positive. - *validity = RANGE_VALID; - return value; -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, - typename UnsignedIntegerForSize<T>::type>::type -CheckedUnsignedAbs(T value) { - typedef typename UnsignedIntegerForSize<T>::type UnsignedT; - return value == std::numeric_limits<T>::min() - ? static_cast<UnsignedT>(std::numeric_limits<T>::max()) + 1 - : static_cast<UnsignedT>(std::abs(value)); -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, - T>::type -CheckedUnsignedAbs(T value) { - // T is unsigned, so |value| must already be positive. - return value; -} - -// These are the floating point stubs that the compiler needs to see. Only the -// negation operation is ever called. -#define BASE_FLOAT_ARITHMETIC_STUBS(NAME) \ - template <typename T> \ - typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type \ - Checked##NAME(T, T, RangeConstraint*) { \ - NOTREACHED(); \ - return 0; \ - } - -BASE_FLOAT_ARITHMETIC_STUBS(Add) -BASE_FLOAT_ARITHMETIC_STUBS(Sub) -BASE_FLOAT_ARITHMETIC_STUBS(Mul) -BASE_FLOAT_ARITHMETIC_STUBS(Div) -BASE_FLOAT_ARITHMETIC_STUBS(Mod) - -#undef BASE_FLOAT_ARITHMETIC_STUBS - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type CheckedNeg( - T value, - RangeConstraint*) { - return -value; -} - -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type CheckedAbs( - T value, - RangeConstraint*) { - return std::abs(value); -} - -// Floats carry around their validity state with them, but integers do not. So, -// we wrap the underlying value in a specialization in order to hide that detail -// and expose an interface via accessors. -enum NumericRepresentation { - NUMERIC_INTEGER, - NUMERIC_FLOATING, - NUMERIC_UNKNOWN -}; - -template <typename NumericType> -struct GetNumericRepresentation { - static const NumericRepresentation value = - std::numeric_limits<NumericType>::is_integer - ? NUMERIC_INTEGER - : (std::numeric_limits<NumericType>::is_iec559 ? NUMERIC_FLOATING - : NUMERIC_UNKNOWN); -}; - -template <typename T, NumericRepresentation type = - GetNumericRepresentation<T>::value> -class CheckedNumericState {}; - -// Integrals require quite a bit of additional housekeeping to manage state. -template <typename T> -class CheckedNumericState<T, NUMERIC_INTEGER> { - private: - T value_; - RangeConstraint validity_; - - public: - template <typename Src, NumericRepresentation type> - friend class CheckedNumericState; - - CheckedNumericState() : value_(0), validity_(RANGE_VALID) {} - - template <typename Src> - CheckedNumericState(Src value, RangeConstraint validity) - : value_(static_cast<T>(value)), - validity_(GetRangeConstraint(validity | - DstRangeRelationToSrcRange<T>(value))) { - static_assert(std::numeric_limits<Src>::is_specialized, - "Argument must be numeric."); - } - - // Copy constructor. - template <typename Src> - CheckedNumericState(const CheckedNumericState<Src>& rhs) - : value_(static_cast<T>(rhs.value())), - validity_(GetRangeConstraint( - rhs.validity() | DstRangeRelationToSrcRange<T>(rhs.value()))) {} - - template <typename Src> - explicit CheckedNumericState( - Src value, - typename std::enable_if<std::numeric_limits<Src>::is_specialized, - int>::type = 0) - : value_(static_cast<T>(value)), - validity_(DstRangeRelationToSrcRange<T>(value)) {} - - RangeConstraint validity() const { return validity_; } - T value() const { return value_; } -}; - -// Floating points maintain their own validity, but need translation wrappers. -template <typename T> -class CheckedNumericState<T, NUMERIC_FLOATING> { - private: - T value_; - - public: - template <typename Src, NumericRepresentation type> - friend class CheckedNumericState; - - CheckedNumericState() : value_(0.0) {} - - template <typename Src> - CheckedNumericState( - Src value, - RangeConstraint validity, - typename std::enable_if<std::numeric_limits<Src>::is_integer, int>::type = - 0) { - switch (DstRangeRelationToSrcRange<T>(value)) { - case RANGE_VALID: - value_ = static_cast<T>(value); - break; - - case RANGE_UNDERFLOW: - value_ = -std::numeric_limits<T>::infinity(); - break; - - case RANGE_OVERFLOW: - value_ = std::numeric_limits<T>::infinity(); - break; - - case RANGE_INVALID: - value_ = std::numeric_limits<T>::quiet_NaN(); - break; - - default: - NOTREACHED(); - } - } - - template <typename Src> - explicit CheckedNumericState( - Src value, - typename std::enable_if<std::numeric_limits<Src>::is_specialized, - int>::type = 0) - : value_(static_cast<T>(value)) {} - - // Copy constructor. - template <typename Src> - CheckedNumericState(const CheckedNumericState<Src>& rhs) - : value_(static_cast<T>(rhs.value())) {} - - RangeConstraint validity() const { - return GetRangeConstraint(value_ <= std::numeric_limits<T>::max(), - value_ >= -std::numeric_limits<T>::max()); - } - T value() const { return value_; } -}; - -// For integers less than 128-bit and floats 32-bit or larger, we can distil -// C/C++ arithmetic promotions down to two simple rules: -// 1. The type with the larger maximum exponent always takes precedence. -// 2. The resulting type must be promoted to at least an int. -// The following template specializations implement that promotion logic. -enum ArithmeticPromotionCategory { - LEFT_PROMOTION, - RIGHT_PROMOTION, - DEFAULT_PROMOTION -}; - -template <typename Lhs, - typename Rhs = Lhs, - ArithmeticPromotionCategory Promotion = - (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value) - ? (MaxExponent<Lhs>::value > MaxExponent<int>::value - ? LEFT_PROMOTION - : DEFAULT_PROMOTION) - : (MaxExponent<Rhs>::value > MaxExponent<int>::value - ? RIGHT_PROMOTION - : DEFAULT_PROMOTION) > -struct ArithmeticPromotion; - -template <typename Lhs, typename Rhs> -struct ArithmeticPromotion<Lhs, Rhs, LEFT_PROMOTION> { - typedef Lhs type; -}; - -template <typename Lhs, typename Rhs> -struct ArithmeticPromotion<Lhs, Rhs, RIGHT_PROMOTION> { - typedef Rhs type; -}; - -template <typename Lhs, typename Rhs> -struct ArithmeticPromotion<Lhs, Rhs, DEFAULT_PROMOTION> { - typedef int type; -}; - -// We can statically check if operations on the provided types can wrap, so we -// can skip the checked operations if they're not needed. So, for an integer we -// care if the destination type preserves the sign and is twice the width of -// the source. -template <typename T, typename Lhs, typename Rhs> -struct IsIntegerArithmeticSafe { - static const bool value = !std::numeric_limits<T>::is_iec559 && - StaticDstRangeRelationToSrcRange<T, Lhs>::value == - NUMERIC_RANGE_CONTAINED && - sizeof(T) >= (2 * sizeof(Lhs)) && - StaticDstRangeRelationToSrcRange<T, Rhs>::value != - NUMERIC_RANGE_CONTAINED && - sizeof(T) >= (2 * sizeof(Rhs)); -}; - -} // namespace internal -} // namespace base - -#endif // BASE_NUMERICS_SAFE_MATH_IMPL_H_ diff --git a/security/sandbox/chromium/base/os_compat_android.h b/security/sandbox/chromium/base/os_compat_android.h deleted file mode 100644 index 0f2544496..000000000 --- a/security/sandbox/chromium/base/os_compat_android.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_OS_COMPAT_ANDROID_H_ -#define BASE_OS_COMPAT_ANDROID_H_ - -#include <fcntl.h> -#include <sys/types.h> -#include <utime.h> - -// Not implemented in Bionic. -extern "C" int futimes(int fd, const struct timeval tv[2]); - -// Not exposed or implemented in Bionic. -extern "C" char* mkdtemp(char* path); - -// Android has no timegm(). -extern "C" time_t timegm(struct tm* const t); - -// The lockf() function is not available on Android; we translate to flock(). -#define F_LOCK LOCK_EX -#define F_ULOCK LOCK_UN -inline int lockf(int fd, int cmd, off_t ignored_len) { - return flock(fd, cmd); -} - -#endif // BASE_OS_COMPAT_ANDROID_H_ diff --git a/security/sandbox/chromium/base/path_service.h b/security/sandbox/chromium/base/path_service.h deleted file mode 100644 index c7f1abe71..000000000 --- a/security/sandbox/chromium/base/path_service.h +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_PATH_SERVICE_H_ -#define BASE_PATH_SERVICE_H_ - -#include <string> - -#include "base/base_export.h" -#include "base/base_paths.h" -#include "base/gtest_prod_util.h" -#include "build/build_config.h" - -namespace base { - -class FilePath; -class ScopedPathOverride; - -// The path service is a global table mapping keys to file system paths. It is -// OK to use this service from multiple threads. -// -class BASE_EXPORT PathService { - public: - // Retrieves a path to a special directory or file and places it into the - // string pointed to by 'path'. If you ask for a directory it is guaranteed - // to NOT have a path separator at the end. For example, "c:\windows\temp" - // Directories are also guaranteed to exist when this function succeeds. - // - // Returns true if the directory or file was successfully retrieved. On - // failure, 'path' will not be changed. - static bool Get(int key, FilePath* path); - - // Overrides the path to a special directory or file. This cannot be used to - // change the value of DIR_CURRENT, but that should be obvious. Also, if the - // path specifies a directory that does not exist, the directory will be - // created by this method. This method returns true if successful. - // - // If the given path is relative, then it will be resolved against - // DIR_CURRENT. - // - // WARNING: Consumers of PathService::Get may expect paths to be constant - // over the lifetime of the app, so this method should be used with caution. - // - // Unit tests generally should use ScopedPathOverride instead. Overrides from - // one test should not carry over to another. - static bool Override(int key, const FilePath& path); - - // This function does the same as PathService::Override but it takes extra - // parameters: - // - |is_absolute| indicates that |path| has already been expanded into an - // absolute path, otherwise MakeAbsoluteFilePath() will be used. This is - // useful to override paths that may not exist yet, since MakeAbsoluteFilePath - // fails for those. Note that MakeAbsoluteFilePath also expands symbolic - // links, even if path.IsAbsolute() is already true. - // - |create| guides whether the directory to be overriden must - // be created in case it doesn't exist already. - static bool OverrideAndCreateIfNeeded(int key, - const FilePath& path, - bool is_absolute, - bool create); - - // To extend the set of supported keys, you can register a path provider, - // which is just a function mirroring PathService::Get. The ProviderFunc - // returns false if it cannot provide a non-empty path for the given key. - // Otherwise, true is returned. - // - // WARNING: This function could be called on any thread from which the - // PathService is used, so a the ProviderFunc MUST BE THREADSAFE. - // - typedef bool (*ProviderFunc)(int, FilePath*); - - // Call to register a path provider. You must specify the range "[key_start, - // key_end)" of supported path keys. - static void RegisterProvider(ProviderFunc provider, - int key_start, - int key_end); - - // Disable internal cache. - static void DisableCache(); - - private: - friend class ScopedPathOverride; - FRIEND_TEST_ALL_PREFIXES(PathServiceTest, RemoveOverride); - - // Removes an override for a special directory or file. Returns true if there - // was an override to remove or false if none was present. - // NOTE: This function is intended to be used by tests only! - static bool RemoveOverride(int key); -}; - -} // namespace base - -// TODO(brettw) Convert all callers to using the base namespace and remove this. -using base::PathService; - -#endif // BASE_PATH_SERVICE_H_ diff --git a/security/sandbox/chromium/base/posix/eintr_wrapper.h b/security/sandbox/chromium/base/posix/eintr_wrapper.h deleted file mode 100644 index 5a5dc758a..000000000 --- a/security/sandbox/chromium/base/posix/eintr_wrapper.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This provides a wrapper around system calls which may be interrupted by a -// signal and return EINTR. See man 7 signal. -// To prevent long-lasting loops (which would likely be a bug, such as a signal -// that should be masked) to go unnoticed, there is a limit after which the -// caller will nonetheless see an EINTR in Debug builds. -// -// On Windows, this wrapper macro does nothing. -// -// Don't wrap close calls in HANDLE_EINTR. Use IGNORE_EINTR if the return -// value of close is significant. See http://crbug.com/269623. - -#ifndef BASE_POSIX_EINTR_WRAPPER_H_ -#define BASE_POSIX_EINTR_WRAPPER_H_ - -#include "build/build_config.h" - -#if defined(OS_POSIX) - -#include <errno.h> - -#if defined(NDEBUG) - -#define HANDLE_EINTR(x) ({ \ - decltype(x) eintr_wrapper_result; \ - do { \ - eintr_wrapper_result = (x); \ - } while (eintr_wrapper_result == -1 && errno == EINTR); \ - eintr_wrapper_result; \ -}) - -#else - -#define HANDLE_EINTR(x) ({ \ - int eintr_wrapper_counter = 0; \ - decltype(x) eintr_wrapper_result; \ - do { \ - eintr_wrapper_result = (x); \ - } while (eintr_wrapper_result == -1 && errno == EINTR && \ - eintr_wrapper_counter++ < 100); \ - eintr_wrapper_result; \ -}) - -#endif // NDEBUG - -#define IGNORE_EINTR(x) ({ \ - decltype(x) eintr_wrapper_result; \ - do { \ - eintr_wrapper_result = (x); \ - if (eintr_wrapper_result == -1 && errno == EINTR) { \ - eintr_wrapper_result = 0; \ - } \ - } while (0); \ - eintr_wrapper_result; \ -}) - -#else - -#define HANDLE_EINTR(x) (x) -#define IGNORE_EINTR(x) (x) - -#endif // OS_POSIX - -#endif // BASE_POSIX_EINTR_WRAPPER_H_ diff --git a/security/sandbox/chromium/base/process/process_handle.h b/security/sandbox/chromium/base/process/process_handle.h deleted file mode 100644 index ef7a60255..000000000 --- a/security/sandbox/chromium/base/process/process_handle.h +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_PROCESS_PROCESS_HANDLE_H_ -#define BASE_PROCESS_PROCESS_HANDLE_H_ - -#include <stdint.h> -#include <sys/types.h> - -#include "base/base_export.h" -#include "base/files/file_path.h" -#include "build/build_config.h" - -#if defined(OS_WIN) -#include <windows.h> -#endif - -namespace base { - -// ProcessHandle is a platform specific type which represents the underlying OS -// handle to a process. -// ProcessId is a number which identifies the process in the OS. -#if defined(OS_WIN) -typedef HANDLE ProcessHandle; -typedef DWORD ProcessId; -typedef HANDLE UserTokenHandle; -const ProcessHandle kNullProcessHandle = NULL; -const ProcessId kNullProcessId = 0; -#elif defined(OS_POSIX) -// On POSIX, our ProcessHandle will just be the PID. -typedef pid_t ProcessHandle; -typedef pid_t ProcessId; -const ProcessHandle kNullProcessHandle = 0; -const ProcessId kNullProcessId = 0; -#endif // defined(OS_WIN) - -// Returns the id of the current process. -// Note that on some platforms, this is not guaranteed to be unique across -// processes (use GetUniqueIdForProcess if uniqueness is required). -BASE_EXPORT ProcessId GetCurrentProcId(); - -// Returns a unique ID for the current process. The ID will be unique across all -// currently running processes within the chrome session, but IDs of terminated -// processes may be reused. This returns an opaque value that is different from -// a process's PID. -BASE_EXPORT uint32_t GetUniqueIdForProcess(); - -#if defined(OS_LINUX) -// When a process is started in a different PID namespace from the browser -// process, this function must be called with the process's PID in the browser's -// PID namespace in order to initialize its unique ID. Not thread safe. -// WARNING: To avoid inconsistent results from GetUniqueIdForProcess, this -// should only be called very early after process startup - ideally as soon -// after process creation as possible. -BASE_EXPORT void InitUniqueIdForProcessInPidNamespace( - ProcessId pid_outside_of_namespace); -#endif - -// Returns the ProcessHandle of the current process. -BASE_EXPORT ProcessHandle GetCurrentProcessHandle(); - -// Returns the process ID for the specified process. This is functionally the -// same as Windows' GetProcessId(), but works on versions of Windows before Win -// XP SP1 as well. -// DEPRECATED. New code should be using Process::Pid() instead. -// Note that on some platforms, this is not guaranteed to be unique across -// processes. -BASE_EXPORT ProcessId GetProcId(ProcessHandle process); - -// Returns the ID for the parent of the given process. -BASE_EXPORT ProcessId GetParentProcessId(ProcessHandle process); - -#if defined(OS_POSIX) -// Returns the path to the executable of the given process. -BASE_EXPORT FilePath GetProcessExecutablePath(ProcessHandle process); -#endif - -} // namespace base - -#endif // BASE_PROCESS_PROCESS_HANDLE_H_ diff --git a/security/sandbox/chromium/base/rand_util.h b/security/sandbox/chromium/base/rand_util.h deleted file mode 100644 index 881dbd50b..000000000 --- a/security/sandbox/chromium/base/rand_util.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_RAND_UTIL_H_ -#define BASE_RAND_UTIL_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <string> - -#include "base/base_export.h" -#include "build/build_config.h" - -namespace base { - -// Returns a random number in range [0, UINT64_MAX]. Thread-safe. -BASE_EXPORT uint64_t RandUint64(); - -// Returns a random number between min and max (inclusive). Thread-safe. -BASE_EXPORT int RandInt(int min, int max); - -// Returns a random number in range [0, range). Thread-safe. -// -// Note that this can be used as an adapter for std::random_shuffle(): -// Given a pre-populated |std::vector<int> myvector|, shuffle it as -// std::random_shuffle(myvector.begin(), myvector.end(), base::RandGenerator); -BASE_EXPORT uint64_t RandGenerator(uint64_t range); - -// Returns a random double in range [0, 1). Thread-safe. -BASE_EXPORT double RandDouble(); - -// Given input |bits|, convert with maximum precision to a double in -// the range [0, 1). Thread-safe. -BASE_EXPORT double BitsToOpenEndedUnitInterval(uint64_t bits); - -// Fills |output_length| bytes of |output| with random data. -// -// WARNING: -// Do not use for security-sensitive purposes. -// See crypto/ for cryptographically secure random number generation APIs. -BASE_EXPORT void RandBytes(void* output, size_t output_length); - -// Fills a string of length |length| with random data and returns it. -// |length| should be nonzero. -// -// Note that this is a variation of |RandBytes| with a different return type. -// The returned string is likely not ASCII/UTF-8. Use with care. -// -// WARNING: -// Do not use for security-sensitive purposes. -// See crypto/ for cryptographically secure random number generation APIs. -BASE_EXPORT std::string RandBytesAsString(size_t length); - -#if defined(OS_POSIX) -BASE_EXPORT int GetUrandomFD(); -#endif - -} // namespace base - -#endif // BASE_RAND_UTIL_H_ diff --git a/security/sandbox/chromium/base/scoped_clear_errno.h b/security/sandbox/chromium/base/scoped_clear_errno.h deleted file mode 100644 index 585f6f768..000000000 --- a/security/sandbox/chromium/base/scoped_clear_errno.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_SCOPED_CLEAR_ERRNO_H_ -#define BASE_SCOPED_CLEAR_ERRNO_H_ - -#include <errno.h> - -#include "base/macros.h" - -namespace base { - -// Simple scoper that saves the current value of errno, resets it to 0, and on -// destruction puts the old value back. -class ScopedClearErrno { - public: - ScopedClearErrno() : old_errno_(errno) { - errno = 0; - } - ~ScopedClearErrno() { - if (errno == 0) - errno = old_errno_; - } - - private: - const int old_errno_; - - DISALLOW_COPY_AND_ASSIGN(ScopedClearErrno); -}; - -} // namespace base - -#endif // BASE_SCOPED_CLEAR_ERRNO_H_ diff --git a/security/sandbox/chromium/base/sequence_checker.h b/security/sandbox/chromium/base/sequence_checker.h deleted file mode 100644 index ad0182825..000000000 --- a/security/sandbox/chromium/base/sequence_checker.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_SEQUENCE_CHECKER_H_ -#define BASE_SEQUENCE_CHECKER_H_ - -// See comments for the similar block in thread_checker.h. -#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) -#define ENABLE_SEQUENCE_CHECKER 1 -#else -#define ENABLE_SEQUENCE_CHECKER 0 -#endif - -#include "base/sequence_checker_impl.h" - -namespace base { - -// Do nothing implementation, for use in release mode. -// -// Note: You should almost always use the SequenceChecker class to get -// the right version for your build configuration. -class SequenceCheckerDoNothing { - public: - bool CalledOnValidSequencedThread() const { - return true; - } - - void DetachFromSequence() {} -}; - -// SequenceChecker is a helper class used to help verify that some -// methods of a class are called in sequence -- that is, called from -// the same SequencedTaskRunner. It is a generalization of -// ThreadChecker; see comments in sequence_checker_impl.h for details. -// -// Example: -// class MyClass { -// public: -// void Foo() { -// DCHECK(sequence_checker_.CalledOnValidSequencedThread()); -// ... (do stuff) ... -// } -// -// private: -// SequenceChecker sequence_checker_; -// } -// -// In Release mode, CalledOnValidSequencedThread() will always return true. -#if ENABLE_SEQUENCE_CHECKER -class SequenceChecker : public SequenceCheckerImpl { -}; -#else -class SequenceChecker : public SequenceCheckerDoNothing { -}; -#endif // ENABLE_SEQUENCE_CHECKER - -#undef ENABLE_SEQUENCE_CHECKER - -} // namespace base - -#endif // BASE_SEQUENCE_CHECKER_H_ diff --git a/security/sandbox/chromium/base/sequence_checker_impl.h b/security/sandbox/chromium/base/sequence_checker_impl.h deleted file mode 100644 index e3c5fed50..000000000 --- a/security/sandbox/chromium/base/sequence_checker_impl.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_SEQUENCE_CHECKER_IMPL_H_ -#define BASE_SEQUENCE_CHECKER_IMPL_H_ - -#include "base/base_export.h" -#include "base/macros.h" -#include "base/synchronization/lock.h" -#include "base/threading/sequenced_worker_pool.h" -#include "base/threading/thread_checker_impl.h" - -namespace base { - -// SequenceCheckerImpl is used to help verify that some methods of a -// class are called in sequence -- that is, called from the same -// SequencedTaskRunner. It is a generalization of ThreadChecker; in -// particular, it behaves exactly like ThreadChecker if constructed -// on a thread that is not part of a SequencedWorkerPool. -class BASE_EXPORT SequenceCheckerImpl { - public: - SequenceCheckerImpl(); - ~SequenceCheckerImpl(); - - // Returns whether the we are being called on the same sequence token - // as previous calls. If there is no associated sequence, then returns - // whether we are being called on the underlying ThreadChecker's thread. - bool CalledOnValidSequencedThread() const; - - // Unbinds the checker from the currently associated sequence. The - // checker will be re-bound on the next call to CalledOnValidSequence(). - void DetachFromSequence(); - - private: - void EnsureSequenceTokenAssigned() const; - - // Guards all variables below. - mutable Lock lock_; - - // Used if |sequence_token_| is not valid. - ThreadCheckerImpl thread_checker_; - mutable bool sequence_token_assigned_; - - mutable SequencedWorkerPool::SequenceToken sequence_token_; - - DISALLOW_COPY_AND_ASSIGN(SequenceCheckerImpl); -}; - -} // namespace base - -#endif // BASE_SEQUENCE_CHECKER_IMPL_H_ diff --git a/security/sandbox/chromium/base/sequenced_task_runner.h b/security/sandbox/chromium/base/sequenced_task_runner.h deleted file mode 100644 index 6bb3f2b87..000000000 --- a/security/sandbox/chromium/base/sequenced_task_runner.h +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_SEQUENCED_TASK_RUNNER_H_ -#define BASE_SEQUENCED_TASK_RUNNER_H_ - -#include "base/base_export.h" -#include "base/sequenced_task_runner_helpers.h" -#include "base/task_runner.h" - -namespace base { - -// A SequencedTaskRunner is a subclass of TaskRunner that provides -// additional guarantees on the order that tasks are started, as well -// as guarantees on when tasks are in sequence, i.e. one task finishes -// before the other one starts. -// -// Summary -// ------- -// Non-nested tasks with the same delay will run one by one in FIFO -// order. -// -// Detailed guarantees -// ------------------- -// -// SequencedTaskRunner also adds additional methods for posting -// non-nestable tasks. In general, an implementation of TaskRunner -// may expose task-running methods which are themselves callable from -// within tasks. A non-nestable task is one that is guaranteed to not -// be run from within an already-running task. Conversely, a nestable -// task (the default) is a task that can be run from within an -// already-running task. -// -// The guarantees of SequencedTaskRunner are as follows: -// -// - Given two tasks T2 and T1, T2 will start after T1 starts if: -// -// * T2 is posted after T1; and -// * T2 has equal or higher delay than T1; and -// * T2 is non-nestable or T1 is nestable. -// -// - If T2 will start after T1 starts by the above guarantee, then -// T2 will start after T1 finishes and is destroyed if: -// -// * T2 is non-nestable, or -// * T1 doesn't call any task-running methods. -// -// - If T2 will start after T1 finishes by the above guarantee, then -// all memory changes in T1 and T1's destruction will be visible -// to T2. -// -// - If T2 runs nested within T1 via a call to the task-running -// method M, then all memory changes in T1 up to the call to M -// will be visible to T2, and all memory changes in T2 will be -// visible to T1 from the return from M. -// -// Note that SequencedTaskRunner does not guarantee that tasks are run -// on a single dedicated thread, although the above guarantees provide -// most (but not all) of the same guarantees. If you do need to -// guarantee that tasks are run on a single dedicated thread, see -// SingleThreadTaskRunner (in single_thread_task_runner.h). -// -// Some corollaries to the above guarantees, assuming the tasks in -// question don't call any task-running methods: -// -// - Tasks posted via PostTask are run in FIFO order. -// -// - Tasks posted via PostNonNestableTask are run in FIFO order. -// -// - Tasks posted with the same delay and the same nestable state -// are run in FIFO order. -// -// - A list of tasks with the same nestable state posted in order of -// non-decreasing delay is run in FIFO order. -// -// - A list of tasks posted in order of non-decreasing delay with at -// most a single change in nestable state from nestable to -// non-nestable is run in FIFO order. (This is equivalent to the -// statement of the first guarantee above.) -// -// Some theoretical implementations of SequencedTaskRunner: -// -// - A SequencedTaskRunner that wraps a regular TaskRunner but makes -// sure that only one task at a time is posted to the TaskRunner, -// with appropriate memory barriers in between tasks. -// -// - A SequencedTaskRunner that, for each task, spawns a joinable -// thread to run that task and immediately quit, and then -// immediately joins that thread. -// -// - A SequencedTaskRunner that stores the list of posted tasks and -// has a method Run() that runs each runnable task in FIFO order -// that can be called from any thread, but only if another -// (non-nested) Run() call isn't already happening. -class BASE_EXPORT SequencedTaskRunner : public TaskRunner { - public: - // The two PostNonNestable*Task methods below are like their - // nestable equivalents in TaskRunner, but they guarantee that the - // posted task will not run nested within an already-running task. - // - // A simple corollary is that posting a task as non-nestable can - // only delay when the task gets run. That is, posting a task as - // non-nestable may not affect when the task gets run, or it could - // make it run later than it normally would, but it won't make it - // run earlier than it normally would. - - // TODO(akalin): Get rid of the boolean return value for the methods - // below. - - bool PostNonNestableTask(const tracked_objects::Location& from_here, - const Closure& task); - - virtual bool PostNonNestableDelayedTask( - const tracked_objects::Location& from_here, - const Closure& task, - base::TimeDelta delay) = 0; - - // Submits a non-nestable task to delete the given object. Returns - // true if the object may be deleted at some point in the future, - // and false if the object definitely will not be deleted. - template <class T> - bool DeleteSoon(const tracked_objects::Location& from_here, - const T* object) { - return - subtle::DeleteHelperInternal<T, bool>::DeleteViaSequencedTaskRunner( - this, from_here, object); - } - - // Submits a non-nestable task to release the given object. Returns - // true if the object may be released at some point in the future, - // and false if the object definitely will not be released. - template <class T> - bool ReleaseSoon(const tracked_objects::Location& from_here, - T* object) { - return - subtle::ReleaseHelperInternal<T, bool>::ReleaseViaSequencedTaskRunner( - this, from_here, object); - } - - protected: - ~SequencedTaskRunner() override {} - - private: - template <class T, class R> friend class subtle::DeleteHelperInternal; - template <class T, class R> friend class subtle::ReleaseHelperInternal; - - bool DeleteSoonInternal(const tracked_objects::Location& from_here, - void(*deleter)(const void*), - const void* object); - - bool ReleaseSoonInternal(const tracked_objects::Location& from_here, - void(*releaser)(const void*), - const void* object); -}; - -} // namespace base - -#endif // BASE_SEQUENCED_TASK_RUNNER_H_ diff --git a/security/sandbox/chromium/base/sequenced_task_runner_helpers.h b/security/sandbox/chromium/base/sequenced_task_runner_helpers.h deleted file mode 100644 index 7980b46b6..000000000 --- a/security/sandbox/chromium/base/sequenced_task_runner_helpers.h +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_SEQUENCED_TASK_RUNNER_HELPERS_H_ -#define BASE_SEQUENCED_TASK_RUNNER_HELPERS_H_ - -#include "base/debug/alias.h" -#include "base/macros.h" - -// TODO(akalin): Investigate whether it's possible to just have -// SequencedTaskRunner use these helpers (instead of MessageLoop). -// Then we can just move these to sequenced_task_runner.h. - -namespace tracked_objects { -class Location; -} - -namespace base { - -namespace subtle { -template <class T, class R> class DeleteHelperInternal; -template <class T, class R> class ReleaseHelperInternal; -} - -// Template helpers which use function indirection to erase T from the -// function signature while still remembering it so we can call the -// correct destructor/release function. -// -// We use this trick so we don't need to include bind.h in a header -// file like sequenced_task_runner.h. We also wrap the helpers in a -// templated class to make it easier for users of DeleteSoon to -// declare the helper as a friend. -template <class T> -class DeleteHelper { - private: - template <class T2, class R> friend class subtle::DeleteHelperInternal; - - static void DoDelete(const void* object) { - delete reinterpret_cast<const T*>(object); - } - - DISALLOW_COPY_AND_ASSIGN(DeleteHelper); -}; - -template <class T> -class ReleaseHelper { - private: - template <class T2, class R> friend class subtle::ReleaseHelperInternal; - - static void DoRelease(const void* object) { - reinterpret_cast<const T*>(object)->Release(); - } - - DISALLOW_COPY_AND_ASSIGN(ReleaseHelper); -}; - -namespace subtle { - -// An internal SequencedTaskRunner-like class helper for DeleteHelper -// and ReleaseHelper. We don't want to expose the Do*() functions -// directly directly since the void* argument makes it possible to -// pass/ an object of the wrong type to delete. Instead, we force -// callers to go through these internal helpers for type -// safety. SequencedTaskRunner-like classes which expose DeleteSoon or -// ReleaseSoon methods should friend the appropriate helper and -// implement a corresponding *Internal method with the following -// signature: -// -// bool(const tracked_objects::Location&, -// void(*function)(const void*), -// void* object) -// -// An implementation of this function should simply create a -// base::Closure from (function, object) and return the result of -// posting the task. -template <class T, class ReturnType> -class DeleteHelperInternal { - public: - template <class SequencedTaskRunnerType> - static ReturnType DeleteViaSequencedTaskRunner( - SequencedTaskRunnerType* sequenced_task_runner, - const tracked_objects::Location& from_here, - const T* object) { - return sequenced_task_runner->DeleteSoonInternal( - from_here, &DeleteHelper<T>::DoDelete, object); - } - - private: - DISALLOW_COPY_AND_ASSIGN(DeleteHelperInternal); -}; - -template <class T, class ReturnType> -class ReleaseHelperInternal { - public: - template <class SequencedTaskRunnerType> - static ReturnType ReleaseViaSequencedTaskRunner( - SequencedTaskRunnerType* sequenced_task_runner, - const tracked_objects::Location& from_here, - const T* object) { - return sequenced_task_runner->ReleaseSoonInternal( - from_here, &ReleaseHelper<T>::DoRelease, object); - } - - private: - DISALLOW_COPY_AND_ASSIGN(ReleaseHelperInternal); -}; - -} // namespace subtle - -} // namespace base - -#endif // BASE_SEQUENCED_TASK_RUNNER_HELPERS_H_ diff --git a/security/sandbox/chromium/base/single_thread_task_runner.h b/security/sandbox/chromium/base/single_thread_task_runner.h deleted file mode 100644 index 6e9319314..000000000 --- a/security/sandbox/chromium/base/single_thread_task_runner.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_SINGLE_THREAD_TASK_RUNNER_H_ -#define BASE_SINGLE_THREAD_TASK_RUNNER_H_ - -#include "base/base_export.h" -#include "base/sequenced_task_runner.h" - -namespace base { - -// A SingleThreadTaskRunner is a SequencedTaskRunner with one more -// guarantee; namely, that all tasks are run on a single dedicated -// thread. Most use cases require only a SequencedTaskRunner, unless -// there is a specific need to run tasks on only a single thread. -// -// SingleThreadTaskRunner implementations might: -// - Post tasks to an existing thread's MessageLoop (see -// MessageLoop::task_runner()). -// - Create their own worker thread and MessageLoop to post tasks to. -// - Add tasks to a FIFO and signal to a non-MessageLoop thread for them to -// be processed. This allows TaskRunner-oriented code run on threads -// running other kinds of message loop, e.g. Jingle threads. -class BASE_EXPORT SingleThreadTaskRunner : public SequencedTaskRunner { - public: - // A more explicit alias to RunsTasksOnCurrentThread(). - bool BelongsToCurrentThread() const { - return RunsTasksOnCurrentThread(); - } - - protected: - ~SingleThreadTaskRunner() override {} -}; - -} // namespace base - -#endif // BASE_SINGLE_THREAD_TASK_RUNNER_H_ diff --git a/security/sandbox/chromium/base/stl_util.h b/security/sandbox/chromium/base/stl_util.h deleted file mode 100644 index 12e226a9d..000000000 --- a/security/sandbox/chromium/base/stl_util.h +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Derived from google3/util/gtl/stl_util.h - -#ifndef BASE_STL_UTIL_H_ -#define BASE_STL_UTIL_H_ - -#include <algorithm> -#include <functional> -#include <iterator> -#include <string> -#include <vector> - -#include "base/logging.h" - -// Clears internal memory of an STL object. -// STL clear()/reserve(0) does not always free internal memory allocated -// This function uses swap/destructor to ensure the internal memory is freed. -template<class T> -void STLClearObject(T* obj) { - T tmp; - tmp.swap(*obj); - // Sometimes "T tmp" allocates objects with memory (arena implementation?). - // Hence using additional reserve(0) even if it doesn't always work. - obj->reserve(0); -} - -// For a range within a container of pointers, calls delete (non-array version) -// on these pointers. -// NOTE: for these three functions, we could just implement a DeleteObject -// functor and then call for_each() on the range and functor, but this -// requires us to pull in all of algorithm.h, which seems expensive. -// For hash_[multi]set, it is important that this deletes behind the iterator -// because the hash_set may call the hash function on the iterator when it is -// advanced, which could result in the hash function trying to deference a -// stale pointer. -template <class ForwardIterator> -void STLDeleteContainerPointers(ForwardIterator begin, ForwardIterator end) { - while (begin != end) { - ForwardIterator temp = begin; - ++begin; - delete *temp; - } -} - -// For a range within a container of pairs, calls delete (non-array version) on -// BOTH items in the pairs. -// NOTE: Like STLDeleteContainerPointers, it is important that this deletes -// behind the iterator because if both the key and value are deleted, the -// container may call the hash function on the iterator when it is advanced, -// which could result in the hash function trying to dereference a stale -// pointer. -template <class ForwardIterator> -void STLDeleteContainerPairPointers(ForwardIterator begin, - ForwardIterator end) { - while (begin != end) { - ForwardIterator temp = begin; - ++begin; - delete temp->first; - delete temp->second; - } -} - -// For a range within a container of pairs, calls delete (non-array version) on -// the FIRST item in the pairs. -// NOTE: Like STLDeleteContainerPointers, deleting behind the iterator. -template <class ForwardIterator> -void STLDeleteContainerPairFirstPointers(ForwardIterator begin, - ForwardIterator end) { - while (begin != end) { - ForwardIterator temp = begin; - ++begin; - delete temp->first; - } -} - -// For a range within a container of pairs, calls delete. -// NOTE: Like STLDeleteContainerPointers, deleting behind the iterator. -// Deleting the value does not always invalidate the iterator, but it may -// do so if the key is a pointer into the value object. -template <class ForwardIterator> -void STLDeleteContainerPairSecondPointers(ForwardIterator begin, - ForwardIterator end) { - while (begin != end) { - ForwardIterator temp = begin; - ++begin; - delete temp->second; - } -} - -// Counts the number of instances of val in a container. -template <typename Container, typename T> -typename std::iterator_traits< - typename Container::const_iterator>::difference_type -STLCount(const Container& container, const T& val) { - return std::count(container.begin(), container.end(), val); -} - -// Return a mutable char* pointing to a string's internal buffer, -// which may not be null-terminated. Writing through this pointer will -// modify the string. -// -// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the -// next call to a string method that invalidates iterators. -// -// As of 2006-04, there is no standard-blessed way of getting a -// mutable reference to a string's internal buffer. However, issue 530 -// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530) -// proposes this as the method. According to Matt Austern, this should -// already work on all current implementations. -inline char* string_as_array(std::string* str) { - // DO NOT USE const_cast<char*>(str->data()) - return str->empty() ? NULL : &*str->begin(); -} - -// The following functions are useful for cleaning up STL containers whose -// elements point to allocated memory. - -// STLDeleteElements() deletes all the elements in an STL container and clears -// the container. This function is suitable for use with a vector, set, -// hash_set, or any other STL container which defines sensible begin(), end(), -// and clear() methods. -// -// If container is NULL, this function is a no-op. -// -// As an alternative to calling STLDeleteElements() directly, consider -// STLElementDeleter (defined below), which ensures that your container's -// elements are deleted when the STLElementDeleter goes out of scope. -template <class T> -void STLDeleteElements(T* container) { - if (!container) - return; - STLDeleteContainerPointers(container->begin(), container->end()); - container->clear(); -} - -// Given an STL container consisting of (key, value) pairs, STLDeleteValues -// deletes all the "value" components and clears the container. Does nothing -// in the case it's given a NULL pointer. -template <class T> -void STLDeleteValues(T* container) { - if (!container) - return; - STLDeleteContainerPairSecondPointers(container->begin(), container->end()); - container->clear(); -} - - -// The following classes provide a convenient way to delete all elements or -// values from STL containers when they goes out of scope. This greatly -// simplifies code that creates temporary objects and has multiple return -// statements. Example: -// -// vector<MyProto *> tmp_proto; -// STLElementDeleter<vector<MyProto *> > d(&tmp_proto); -// if (...) return false; -// ... -// return success; - -// Given a pointer to an STL container this class will delete all the element -// pointers when it goes out of scope. -template<class T> -class STLElementDeleter { - public: - STLElementDeleter<T>(T* container) : container_(container) {} - ~STLElementDeleter<T>() { STLDeleteElements(container_); } - - private: - T* container_; -}; - -// Given a pointer to an STL container this class will delete all the value -// pointers when it goes out of scope. -template<class T> -class STLValueDeleter { - public: - STLValueDeleter<T>(T* container) : container_(container) {} - ~STLValueDeleter<T>() { STLDeleteValues(container_); } - - private: - T* container_; -}; - -// Test to see if a set, map, hash_set or hash_map contains a particular key. -// Returns true if the key is in the collection. -template <typename Collection, typename Key> -bool ContainsKey(const Collection& collection, const Key& key) { - return collection.find(key) != collection.end(); -} - -// Test to see if a collection like a vector contains a particular value. -// Returns true if the value is in the collection. -template <typename Collection, typename Value> -bool ContainsValue(const Collection& collection, const Value& value) { - return std::find(collection.begin(), collection.end(), value) != - collection.end(); -} - -namespace base { - -// Returns true if the container is sorted. -template <typename Container> -bool STLIsSorted(const Container& cont) { - // Note: Use reverse iterator on container to ensure we only require - // value_type to implement operator<. - return std::adjacent_find(cont.rbegin(), cont.rend(), - std::less<typename Container::value_type>()) - == cont.rend(); -} - -// Returns a new ResultType containing the difference of two sorted containers. -template <typename ResultType, typename Arg1, typename Arg2> -ResultType STLSetDifference(const Arg1& a1, const Arg2& a2) { - DCHECK(STLIsSorted(a1)); - DCHECK(STLIsSorted(a2)); - ResultType difference; - std::set_difference(a1.begin(), a1.end(), - a2.begin(), a2.end(), - std::inserter(difference, difference.end())); - return difference; -} - -// Returns a new ResultType containing the union of two sorted containers. -template <typename ResultType, typename Arg1, typename Arg2> -ResultType STLSetUnion(const Arg1& a1, const Arg2& a2) { - DCHECK(STLIsSorted(a1)); - DCHECK(STLIsSorted(a2)); - ResultType result; - std::set_union(a1.begin(), a1.end(), - a2.begin(), a2.end(), - std::inserter(result, result.end())); - return result; -} - -// Returns a new ResultType containing the intersection of two sorted -// containers. -template <typename ResultType, typename Arg1, typename Arg2> -ResultType STLSetIntersection(const Arg1& a1, const Arg2& a2) { - DCHECK(STLIsSorted(a1)); - DCHECK(STLIsSorted(a2)); - ResultType result; - std::set_intersection(a1.begin(), a1.end(), - a2.begin(), a2.end(), - std::inserter(result, result.end())); - return result; -} - -// Returns true if the sorted container |a1| contains all elements of the sorted -// container |a2|. -template <typename Arg1, typename Arg2> -bool STLIncludes(const Arg1& a1, const Arg2& a2) { - DCHECK(STLIsSorted(a1)); - DCHECK(STLIsSorted(a2)); - return std::includes(a1.begin(), a1.end(), - a2.begin(), a2.end()); -} - -} // namespace base - -#endif // BASE_STL_UTIL_H_ diff --git a/security/sandbox/chromium/base/strings/nullable_string16.cc b/security/sandbox/chromium/base/strings/nullable_string16.cc deleted file mode 100644 index 07f81d433..000000000 --- a/security/sandbox/chromium/base/strings/nullable_string16.cc +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/nullable_string16.h" - -#include <ostream> - -#include "base/strings/utf_string_conversions.h" - -namespace base { - -std::ostream& operator<<(std::ostream& out, const NullableString16& value) { - return value.is_null() ? out << "(null)" : out << UTF16ToUTF8(value.string()); -} - -} // namespace base diff --git a/security/sandbox/chromium/base/strings/nullable_string16.h b/security/sandbox/chromium/base/strings/nullable_string16.h deleted file mode 100644 index 016c25c25..000000000 --- a/security/sandbox/chromium/base/strings/nullable_string16.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_STRINGS_NULLABLE_STRING16_H_ -#define BASE_STRINGS_NULLABLE_STRING16_H_ - -#include <iosfwd> - -#include "base/base_export.h" -#include "base/strings/string16.h" - -namespace base { - -// This class is a simple wrapper for string16 which also contains a null -// state. This should be used only where the difference between null and -// empty is meaningful. -class NullableString16 { - public: - NullableString16() : is_null_(true) { } - NullableString16(const string16& string, bool is_null) - : string_(string), is_null_(is_null) { - } - - const string16& string() const { return string_; } - bool is_null() const { return is_null_; } - - private: - string16 string_; - bool is_null_; -}; - -inline bool operator==(const NullableString16& a, const NullableString16& b) { - return a.is_null() == b.is_null() && a.string() == b.string(); -} - -inline bool operator!=(const NullableString16& a, const NullableString16& b) { - return !(a == b); -} - -BASE_EXPORT std::ostream& operator<<(std::ostream& out, - const NullableString16& value); - -} // namespace base - -#endif // BASE_STRINGS_NULLABLE_STRING16_H_ diff --git a/security/sandbox/chromium/base/strings/safe_sprintf.cc b/security/sandbox/chromium/base/strings/safe_sprintf.cc deleted file mode 100644 index a51c77827..000000000 --- a/security/sandbox/chromium/base/strings/safe_sprintf.cc +++ /dev/null @@ -1,686 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/safe_sprintf.h" - -#include <errno.h> -#include <string.h> - -#include <limits> - -#include "base/macros.h" -#include "build/build_config.h" - -#if !defined(NDEBUG) -// In debug builds, we use RAW_CHECK() to print useful error messages, if -// SafeSPrintf() is called with broken arguments. -// As our contract promises that SafeSPrintf() can be called from any -// restricted run-time context, it is not actually safe to call logging -// functions from it; and we only ever do so for debug builds and hope for the -// best. We should _never_ call any logging function other than RAW_CHECK(), -// and we should _never_ include any logging code that is active in production -// builds. Most notably, we should not include these logging functions in -// unofficial release builds, even though those builds would otherwise have -// DCHECKS() enabled. -// In other words; please do not remove the #ifdef around this #include. -// Instead, in production builds we opt for returning a degraded result, -// whenever an error is encountered. -// E.g. The broken function call -// SafeSPrintf("errno = %d (%x)", errno, strerror(errno)) -// will print something like -// errno = 13, (%x) -// instead of -// errno = 13 (Access denied) -// In most of the anticipated use cases, that's probably the preferred -// behavior. -#include "base/logging.h" -#define DEBUG_CHECK RAW_CHECK -#else -#define DEBUG_CHECK(x) do { if (x) { } } while (0) -#endif - -namespace base { -namespace strings { - -// The code in this file is extremely careful to be async-signal-safe. -// -// Most obviously, we avoid calling any code that could dynamically allocate -// memory. Doing so would almost certainly result in bugs and dead-locks. -// We also avoid calling any other STL functions that could have unintended -// side-effects involving memory allocation or access to other shared -// resources. -// -// But on top of that, we also avoid calling other library functions, as many -// of them have the side-effect of calling getenv() (in order to deal with -// localization) or accessing errno. The latter sounds benign, but there are -// several execution contexts where it isn't even possible to safely read let -// alone write errno. -// -// The stated design goal of the SafeSPrintf() function is that it can be -// called from any context that can safely call C or C++ code (i.e. anything -// that doesn't require assembly code). -// -// For a brief overview of some but not all of the issues with async-signal- -// safety, refer to: -// http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html - -namespace { -const size_t kSSizeMaxConst = ((size_t)(ssize_t)-1) >> 1; - -const char kUpCaseHexDigits[] = "0123456789ABCDEF"; -const char kDownCaseHexDigits[] = "0123456789abcdef"; -} - -#if defined(NDEBUG) -// We would like to define kSSizeMax as std::numeric_limits<ssize_t>::max(), -// but C++ doesn't allow us to do that for constants. Instead, we have to -// use careful casting and shifting. We later use a static_assert to -// verify that this worked correctly. -namespace { -const size_t kSSizeMax = kSSizeMaxConst; -} -#else // defined(NDEBUG) -// For efficiency, we really need kSSizeMax to be a constant. But for unit -// tests, it should be adjustable. This allows us to verify edge cases without -// having to fill the entire available address space. As a compromise, we make -// kSSizeMax adjustable in debug builds, and then only compile that particular -// part of the unit test in debug builds. -namespace { -static size_t kSSizeMax = kSSizeMaxConst; -} - -namespace internal { -void SetSafeSPrintfSSizeMaxForTest(size_t max) { - kSSizeMax = max; -} - -size_t GetSafeSPrintfSSizeMaxForTest() { - return kSSizeMax; -} -} -#endif // defined(NDEBUG) - -namespace { -class Buffer { - public: - // |buffer| is caller-allocated storage that SafeSPrintf() writes to. It - // has |size| bytes of writable storage. It is the caller's responsibility - // to ensure that the buffer is at least one byte in size, so that it fits - // the trailing NUL that will be added by the destructor. The buffer also - // must be smaller or equal to kSSizeMax in size. - Buffer(char* buffer, size_t size) - : buffer_(buffer), - size_(size - 1), // Account for trailing NUL byte - count_(0) { -// MSVS2013's standard library doesn't mark max() as constexpr yet. cl.exe -// supports static_cast but doesn't really implement constexpr yet so it doesn't -// complain, but clang does. -#if __cplusplus >= 201103 && !(defined(__clang__) && defined(OS_WIN)) - static_assert(kSSizeMaxConst == - static_cast<size_t>(std::numeric_limits<ssize_t>::max()), - "kSSizeMaxConst should be the max value of an ssize_t"); -#endif - DEBUG_CHECK(size > 0); - DEBUG_CHECK(size <= kSSizeMax); - } - - ~Buffer() { - // The code calling the constructor guaranteed that there was enough space - // to store a trailing NUL -- and in debug builds, we are actually - // verifying this with DEBUG_CHECK()s in the constructor. So, we can - // always unconditionally write the NUL byte in the destructor. We do not - // need to adjust the count_, as SafeSPrintf() copies snprintf() in not - // including the NUL byte in its return code. - *GetInsertionPoint() = '\000'; - } - - // Returns true, iff the buffer is filled all the way to |kSSizeMax-1|. The - // caller can now stop adding more data, as GetCount() has reached its - // maximum possible value. - inline bool OutOfAddressableSpace() const { - return count_ == static_cast<size_t>(kSSizeMax - 1); - } - - // Returns the number of bytes that would have been emitted to |buffer_| - // if it was sized sufficiently large. This number can be larger than - // |size_|, if the caller provided an insufficiently large output buffer. - // But it will never be bigger than |kSSizeMax-1|. - inline ssize_t GetCount() const { - DEBUG_CHECK(count_ < kSSizeMax); - return static_cast<ssize_t>(count_); - } - - // Emits one |ch| character into the |buffer_| and updates the |count_| of - // characters that are currently supposed to be in the buffer. - // Returns "false", iff the buffer was already full. - // N.B. |count_| increases even if no characters have been written. This is - // needed so that GetCount() can return the number of bytes that should - // have been allocated for the |buffer_|. - inline bool Out(char ch) { - if (size_ >= 1 && count_ < size_) { - buffer_[count_] = ch; - return IncrementCountByOne(); - } - // |count_| still needs to be updated, even if the buffer has been - // filled completely. This allows SafeSPrintf() to return the number of - // bytes that should have been emitted. - IncrementCountByOne(); - return false; - } - - // Inserts |padding|-|len| bytes worth of padding into the |buffer_|. - // |count_| will also be incremented by the number of bytes that were meant - // to be emitted. The |pad| character is typically either a ' ' space - // or a '0' zero, but other non-NUL values are legal. - // Returns "false", iff the the |buffer_| filled up (i.e. |count_| - // overflowed |size_|) at any time during padding. - inline bool Pad(char pad, size_t padding, size_t len) { - DEBUG_CHECK(pad); - DEBUG_CHECK(padding <= kSSizeMax); - for (; padding > len; --padding) { - if (!Out(pad)) { - if (--padding) { - IncrementCount(padding-len); - } - return false; - } - } - return true; - } - - // POSIX doesn't define any async-signal-safe function for converting - // an integer to ASCII. Define our own version. - // - // This also gives us the ability to make the function a little more - // powerful and have it deal with |padding|, with truncation, and with - // predicting the length of the untruncated output. - // - // IToASCII() converts an integer |i| to ASCII. - // - // Unlike similar functions in the standard C library, it never appends a - // NUL character. This is left for the caller to do. - // - // While the function signature takes a signed int64_t, the code decides at - // run-time whether to treat the argument as signed (int64_t) or as unsigned - // (uint64_t) based on the value of |sign|. - // - // It supports |base|s 2 through 16. Only a |base| of 10 is allowed to have - // a |sign|. Otherwise, |i| is treated as unsigned. - // - // For bases larger than 10, |upcase| decides whether lower-case or upper- - // case letters should be used to designate digits greater than 10. - // - // Padding can be done with either '0' zeros or ' ' spaces. Padding has to - // be positive and will always be applied to the left of the output. - // - // Prepends a |prefix| to the number (e.g. "0x"). This prefix goes to - // the left of |padding|, if |pad| is '0'; and to the right of |padding| - // if |pad| is ' '. - // - // Returns "false", if the |buffer_| overflowed at any time. - bool IToASCII(bool sign, bool upcase, int64_t i, int base, - char pad, size_t padding, const char* prefix); - - private: - // Increments |count_| by |inc| unless this would cause |count_| to - // overflow |kSSizeMax-1|. Returns "false", iff an overflow was detected; - // it then clamps |count_| to |kSSizeMax-1|. - inline bool IncrementCount(size_t inc) { - // "inc" is either 1 or a "padding" value. Padding is clamped at - // run-time to at most kSSizeMax-1. So, we know that "inc" is always in - // the range 1..kSSizeMax-1. - // This allows us to compute "kSSizeMax - 1 - inc" without incurring any - // integer overflows. - DEBUG_CHECK(inc <= kSSizeMax - 1); - if (count_ > kSSizeMax - 1 - inc) { - count_ = kSSizeMax - 1; - return false; - } else { - count_ += inc; - return true; - } - } - - // Convenience method for the common case of incrementing |count_| by one. - inline bool IncrementCountByOne() { - return IncrementCount(1); - } - - // Return the current insertion point into the buffer. This is typically - // at |buffer_| + |count_|, but could be before that if truncation - // happened. It always points to one byte past the last byte that was - // successfully placed into the |buffer_|. - inline char* GetInsertionPoint() const { - size_t idx = count_; - if (idx > size_) { - idx = size_; - } - return buffer_ + idx; - } - - // User-provided buffer that will receive the fully formatted output string. - char* buffer_; - - // Number of bytes that are available in the buffer excluding the trailing - // NUL byte that will be added by the destructor. - const size_t size_; - - // Number of bytes that would have been emitted to the buffer, if the buffer - // was sufficiently big. This number always excludes the trailing NUL byte - // and it is guaranteed to never grow bigger than kSSizeMax-1. - size_t count_; - - DISALLOW_COPY_AND_ASSIGN(Buffer); -}; - - -bool Buffer::IToASCII(bool sign, bool upcase, int64_t i, int base, - char pad, size_t padding, const char* prefix) { - // Sanity check for parameters. None of these should ever fail, but see - // above for the rationale why we can't call CHECK(). - DEBUG_CHECK(base >= 2); - DEBUG_CHECK(base <= 16); - DEBUG_CHECK(!sign || base == 10); - DEBUG_CHECK(pad == '0' || pad == ' '); - DEBUG_CHECK(padding <= kSSizeMax); - DEBUG_CHECK(!(sign && prefix && *prefix)); - - // Handle negative numbers, if the caller indicated that |i| should be - // treated as a signed number; otherwise treat |i| as unsigned (even if the - // MSB is set!) - // Details are tricky, because of limited data-types, but equivalent pseudo- - // code would look like: - // if (sign && i < 0) - // prefix = "-"; - // num = abs(i); - int minint = 0; - uint64_t num; - if (sign && i < 0) { - prefix = "-"; - - // Turn our number positive. - if (i == std::numeric_limits<int64_t>::min()) { - // The most negative integer needs special treatment. - minint = 1; - num = static_cast<uint64_t>(-(i + 1)); - } else { - // "Normal" negative numbers are easy. - num = static_cast<uint64_t>(-i); - } - } else { - num = static_cast<uint64_t>(i); - } - - // If padding with '0' zero, emit the prefix or '-' character now. Otherwise, - // make the prefix accessible in reverse order, so that we can later output - // it right between padding and the number. - // We cannot choose the easier approach of just reversing the number, as that - // fails in situations where we need to truncate numbers that have padding - // and/or prefixes. - const char* reverse_prefix = NULL; - if (prefix && *prefix) { - if (pad == '0') { - while (*prefix) { - if (padding) { - --padding; - } - Out(*prefix++); - } - prefix = NULL; - } else { - for (reverse_prefix = prefix; *reverse_prefix; ++reverse_prefix) { - } - } - } else - prefix = NULL; - const size_t prefix_length = reverse_prefix - prefix; - - // Loop until we have converted the entire number. Output at least one - // character (i.e. '0'). - size_t start = count_; - size_t discarded = 0; - bool started = false; - do { - // Make sure there is still enough space left in our output buffer. - if (count_ >= size_) { - if (start < size_) { - // It is rare that we need to output a partial number. But if asked - // to do so, we will still make sure we output the correct number of - // leading digits. - // Since we are generating the digits in reverse order, we actually - // have to discard digits in the order that we have already emitted - // them. This is essentially equivalent to: - // memmove(buffer_ + start, buffer_ + start + 1, size_ - start - 1) - for (char* move = buffer_ + start, *end = buffer_ + size_ - 1; - move < end; - ++move) { - *move = move[1]; - } - ++discarded; - --count_; - } else if (count_ - size_ > 1) { - // Need to increment either |count_| or |discarded| to make progress. - // The latter is more efficient, as it eventually triggers fast - // handling of padding. But we have to ensure we don't accidentally - // change the overall state (i.e. switch the state-machine from - // discarding to non-discarding). |count_| needs to always stay - // bigger than |size_|. - --count_; - ++discarded; - } - } - - // Output the next digit and (if necessary) compensate for the most - // negative integer needing special treatment. This works because, - // no matter the bit width of the integer, the lowest-most decimal - // integer always ends in 2, 4, 6, or 8. - if (!num && started) { - if (reverse_prefix > prefix) { - Out(*--reverse_prefix); - } else { - Out(pad); - } - } else { - started = true; - Out((upcase ? kUpCaseHexDigits : kDownCaseHexDigits)[num%base + minint]); - } - - minint = 0; - num /= base; - - // Add padding, if requested. - if (padding > 0) { - --padding; - - // Performance optimization for when we are asked to output excessive - // padding, but our output buffer is limited in size. Even if we output - // a 64bit number in binary, we would never write more than 64 plus - // prefix non-padding characters. So, once this limit has been passed, - // any further state change can be computed arithmetically; we know that - // by this time, our entire final output consists of padding characters - // that have all already been output. - if (discarded > 8*sizeof(num) + prefix_length) { - IncrementCount(padding); - padding = 0; - } - } - } while (num || padding || (reverse_prefix > prefix)); - - // Conversion to ASCII actually resulted in the digits being in reverse - // order. We can't easily generate them in forward order, as we can't tell - // the number of characters needed until we are done converting. - // So, now, we reverse the string (except for the possible '-' sign). - char* front = buffer_ + start; - char* back = GetInsertionPoint(); - while (--back > front) { - char ch = *back; - *back = *front; - *front++ = ch; - } - - IncrementCount(discarded); - return !discarded; -} - -} // anonymous namespace - -namespace internal { - -ssize_t SafeSNPrintf(char* buf, size_t sz, const char* fmt, const Arg* args, - const size_t max_args) { - // Make sure that at least one NUL byte can be written, and that the buffer - // never overflows kSSizeMax. Not only does that use up most or all of the - // address space, it also would result in a return code that cannot be - // represented. - if (static_cast<ssize_t>(sz) < 1) { - return -1; - } else if (sz > kSSizeMax) { - sz = kSSizeMax; - } - - // Iterate over format string and interpret '%' arguments as they are - // encountered. - Buffer buffer(buf, sz); - size_t padding; - char pad; - for (unsigned int cur_arg = 0; *fmt && !buffer.OutOfAddressableSpace(); ) { - if (*fmt++ == '%') { - padding = 0; - pad = ' '; - char ch = *fmt++; - format_character_found: - switch (ch) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - // Found a width parameter. Convert to an integer value and store in - // "padding". If the leading digit is a zero, change the padding - // character from a space ' ' to a zero '0'. - pad = ch == '0' ? '0' : ' '; - for (;;) { - // The maximum allowed padding fills all the available address - // space and leaves just enough space to insert the trailing NUL. - const size_t max_padding = kSSizeMax - 1; - if (padding > max_padding/10 || - 10*padding > max_padding - (ch - '0')) { - DEBUG_CHECK(padding <= max_padding/10 && - 10*padding <= max_padding - (ch - '0')); - // Integer overflow detected. Skip the rest of the width until - // we find the format character, then do the normal error handling. - padding_overflow: - padding = max_padding; - while ((ch = *fmt++) >= '0' && ch <= '9') { - } - if (cur_arg < max_args) { - ++cur_arg; - } - goto fail_to_expand; - } - padding = 10*padding + ch - '0'; - if (padding > max_padding) { - // This doesn't happen for "sane" values of kSSizeMax. But once - // kSSizeMax gets smaller than about 10, our earlier range checks - // are incomplete. Unittests do trigger this artificial corner - // case. - DEBUG_CHECK(padding <= max_padding); - goto padding_overflow; - } - ch = *fmt++; - if (ch < '0' || ch > '9') { - // Reached the end of the width parameter. This is where the format - // character is found. - goto format_character_found; - } - } - break; - case 'c': { // Output an ASCII character. - // Check that there are arguments left to be inserted. - if (cur_arg >= max_args) { - DEBUG_CHECK(cur_arg < max_args); - goto fail_to_expand; - } - - // Check that the argument has the expected type. - const Arg& arg = args[cur_arg++]; - if (arg.type != Arg::INT && arg.type != Arg::UINT) { - DEBUG_CHECK(arg.type == Arg::INT || arg.type == Arg::UINT); - goto fail_to_expand; - } - - // Apply padding, if needed. - buffer.Pad(' ', padding, 1); - - // Convert the argument to an ASCII character and output it. - char as_char = static_cast<char>(arg.integer.i); - if (!as_char) { - goto end_of_output_buffer; - } - buffer.Out(as_char); - break; } - case 'd': // Output a possibly signed decimal value. - case 'o': // Output an unsigned octal value. - case 'x': // Output an unsigned hexadecimal value. - case 'X': - case 'p': { // Output a pointer value. - // Check that there are arguments left to be inserted. - if (cur_arg >= max_args) { - DEBUG_CHECK(cur_arg < max_args); - goto fail_to_expand; - } - - const Arg& arg = args[cur_arg++]; - int64_t i; - const char* prefix = NULL; - if (ch != 'p') { - // Check that the argument has the expected type. - if (arg.type != Arg::INT && arg.type != Arg::UINT) { - DEBUG_CHECK(arg.type == Arg::INT || arg.type == Arg::UINT); - goto fail_to_expand; - } - i = arg.integer.i; - - if (ch != 'd') { - // The Arg() constructor automatically performed sign expansion on - // signed parameters. This is great when outputting a %d decimal - // number, but can result in unexpected leading 0xFF bytes when - // outputting a %x hexadecimal number. Mask bits, if necessary. - // We have to do this here, instead of in the Arg() constructor, as - // the Arg() constructor cannot tell whether we will output a %d - // or a %x. Only the latter should experience masking. - if (arg.integer.width < sizeof(int64_t)) { - i &= (1LL << (8*arg.integer.width)) - 1; - } - } - } else { - // Pointer values require an actual pointer or a string. - if (arg.type == Arg::POINTER) { - i = reinterpret_cast<uintptr_t>(arg.ptr); - } else if (arg.type == Arg::STRING) { - i = reinterpret_cast<uintptr_t>(arg.str); - } else if (arg.type == Arg::INT && - arg.integer.width == sizeof(NULL) && - arg.integer.i == 0) { // Allow C++'s version of NULL - i = 0; - } else { - DEBUG_CHECK(arg.type == Arg::POINTER || arg.type == Arg::STRING); - goto fail_to_expand; - } - - // Pointers always include the "0x" prefix. - prefix = "0x"; - } - - // Use IToASCII() to convert to ASCII representation. For decimal - // numbers, optionally print a sign. For hexadecimal numbers, - // distinguish between upper and lower case. %p addresses are always - // printed as upcase. Supports base 8, 10, and 16. Prints padding - // and/or prefixes, if so requested. - buffer.IToASCII(ch == 'd' && arg.type == Arg::INT, - ch != 'x', i, - ch == 'o' ? 8 : ch == 'd' ? 10 : 16, - pad, padding, prefix); - break; } - case 's': { - // Check that there are arguments left to be inserted. - if (cur_arg >= max_args) { - DEBUG_CHECK(cur_arg < max_args); - goto fail_to_expand; - } - - // Check that the argument has the expected type. - const Arg& arg = args[cur_arg++]; - const char *s; - if (arg.type == Arg::STRING) { - s = arg.str ? arg.str : "<NULL>"; - } else if (arg.type == Arg::INT && arg.integer.width == sizeof(NULL) && - arg.integer.i == 0) { // Allow C++'s version of NULL - s = "<NULL>"; - } else { - DEBUG_CHECK(arg.type == Arg::STRING); - goto fail_to_expand; - } - - // Apply padding, if needed. This requires us to first check the - // length of the string that we are outputting. - if (padding) { - size_t len = 0; - for (const char* src = s; *src++; ) { - ++len; - } - buffer.Pad(' ', padding, len); - } - - // Printing a string involves nothing more than copying it into the - // output buffer and making sure we don't output more bytes than - // available space; Out() takes care of doing that. - for (const char* src = s; *src; ) { - buffer.Out(*src++); - } - break; } - case '%': - // Quoted percent '%' character. - goto copy_verbatim; - fail_to_expand: - // C++ gives us tools to do type checking -- something that snprintf() - // could never really do. So, whenever we see arguments that don't - // match up with the format string, we refuse to output them. But - // since we have to be extremely conservative about being async- - // signal-safe, we are limited in the type of error handling that we - // can do in production builds (in debug builds we can use - // DEBUG_CHECK() and hope for the best). So, all we do is pass the - // format string unchanged. That should eventually get the user's - // attention; and in the meantime, it hopefully doesn't lose too much - // data. - default: - // Unknown or unsupported format character. Just copy verbatim to - // output. - buffer.Out('%'); - DEBUG_CHECK(ch); - if (!ch) { - goto end_of_format_string; - } - buffer.Out(ch); - break; - } - } else { - copy_verbatim: - buffer.Out(fmt[-1]); - } - } - end_of_format_string: - end_of_output_buffer: - return buffer.GetCount(); -} - -} // namespace internal - -ssize_t SafeSNPrintf(char* buf, size_t sz, const char* fmt) { - // Make sure that at least one NUL byte can be written, and that the buffer - // never overflows kSSizeMax. Not only does that use up most or all of the - // address space, it also would result in a return code that cannot be - // represented. - if (static_cast<ssize_t>(sz) < 1) { - return -1; - } else if (sz > kSSizeMax) { - sz = kSSizeMax; - } - - Buffer buffer(buf, sz); - - // In the slow-path, we deal with errors by copying the contents of - // "fmt" unexpanded. This means, if there are no arguments passed, the - // SafeSPrintf() function always degenerates to a version of strncpy() that - // de-duplicates '%' characters. - const char* src = fmt; - for (; *src; ++src) { - buffer.Out(*src); - DEBUG_CHECK(src[0] != '%' || src[1] == '%'); - if (src[0] == '%' && src[1] == '%') { - ++src; - } - } - return buffer.GetCount(); -} - -} // namespace strings -} // namespace base diff --git a/security/sandbox/chromium/base/strings/safe_sprintf.h b/security/sandbox/chromium/base/strings/safe_sprintf.h deleted file mode 100644 index 65524a50c..000000000 --- a/security/sandbox/chromium/base/strings/safe_sprintf.h +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_STRINGS_SAFE_SPRINTF_H_ -#define BASE_STRINGS_SAFE_SPRINTF_H_ - -#include "build/build_config.h" - -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> - -#if defined(OS_POSIX) -// For ssize_t -#include <unistd.h> -#endif - -#include "base/base_export.h" - -namespace base { -namespace strings { - -#if defined(_MSC_VER) -// Define ssize_t inside of our namespace. -#if defined(_WIN64) -typedef __int64 ssize_t; -#else -typedef long ssize_t; -#endif -#endif - -// SafeSPrintf() is a type-safe and completely self-contained version of -// snprintf(). -// -// SafeSNPrintf() is an alternative function signature that can be used when -// not dealing with fixed-sized buffers. When possible, SafeSPrintf() should -// always be used instead of SafeSNPrintf() -// -// These functions allow for formatting complicated messages from contexts that -// require strict async-signal-safety. In fact, it is safe to call them from -// any low-level execution context, as they are guaranteed to make no library -// or system calls. It deliberately never touches "errno", either. -// -// The only exception to this rule is that in debug builds the code calls -// RAW_CHECK() to help diagnose problems when the format string does not -// match the rest of the arguments. In release builds, no CHECK()s are used, -// and SafeSPrintf() instead returns an output string that expands only -// those arguments that match their format characters. Mismatched arguments -// are ignored. -// -// The code currently only supports a subset of format characters: -// %c, %o, %d, %x, %X, %p, and %s. -// -// SafeSPrintf() aims to be as liberal as reasonably possible. Integer-like -// values of arbitrary width can be passed to all of the format characters -// that expect integers. Thus, it is explicitly legal to pass an "int" to -// "%c", and output will automatically look at the LSB only. It is also -// explicitly legal to pass either signed or unsigned values, and the format -// characters will automatically interpret the arguments accordingly. -// -// It is still not legal to mix-and-match integer-like values with pointer -// values. For instance, you cannot pass a pointer to %x, nor can you pass an -// integer to %p. -// -// The one exception is "0" zero being accepted by "%p". This works-around -// the problem of C++ defining NULL as an integer-like value. -// -// All format characters take an optional width parameter. This must be a -// positive integer. For %d, %o, %x, %X and %p, if the width starts with -// a leading '0', padding is done with '0' instead of ' ' characters. -// -// There are a few features of snprintf()-style format strings, that -// SafeSPrintf() does not support at this time. -// -// If an actual user showed up, there is no particularly strong reason they -// couldn't be added. But that assumes that the trade-offs between complexity -// and utility are favorable. -// -// For example, adding support for negative padding widths, and for %n are all -// likely to be viewed positively. They are all clearly useful, low-risk, easy -// to test, don't jeopardize the async-signal-safety of the code, and overall -// have little impact on other parts of SafeSPrintf() function. -// -// On the other hands, adding support for alternate forms, positional -// arguments, grouping, wide characters, localization or floating point numbers -// are all unlikely to ever be added. -// -// SafeSPrintf() and SafeSNPrintf() mimic the behavior of snprintf() and they -// return the number of bytes needed to store the untruncated output. This -// does *not* include the terminating NUL byte. -// -// They return -1, iff a fatal error happened. This typically can only happen, -// if the buffer size is a) negative, or b) zero (i.e. not even the NUL byte -// can be written). The return value can never be larger than SSIZE_MAX-1. -// This ensures that the caller can always add one to the signed return code -// in order to determine the amount of storage that needs to be allocated. -// -// While the code supports type checking and while it is generally very careful -// to avoid printing incorrect values, it tends to be conservative in printing -// as much as possible, even when given incorrect parameters. Typically, in -// case of an error, the format string will not be expanded. (i.e. something -// like SafeSPrintf(buf, "%p %d", 1, 2) results in "%p 2"). See above for -// the use of RAW_CHECK() in debug builds, though. -// -// Basic example: -// char buf[20]; -// base::strings::SafeSPrintf(buf, "The answer: %2d", 42); -// -// Example with dynamically sized buffer (async-signal-safe). This code won't -// work on Visual studio, as it requires dynamically allocating arrays on the -// stack. Consider picking a smaller value for |kMaxSize| if stack size is -// limited and known. On the other hand, if the parameters to SafeSNPrintf() -// are trusted and not controllable by the user, you can consider eliminating -// the check for |kMaxSize| altogether. The current value of SSIZE_MAX is -// essentially a no-op that just illustrates how to implement an upper bound: -// const size_t kInitialSize = 128; -// const size_t kMaxSize = std::numeric_limits<ssize_t>::max(); -// size_t size = kInitialSize; -// for (;;) { -// char buf[size]; -// size = SafeSNPrintf(buf, size, "Error message \"%s\"\n", err) + 1; -// if (sizeof(buf) < kMaxSize && size > kMaxSize) { -// size = kMaxSize; -// continue; -// } else if (size > sizeof(buf)) -// continue; -// write(2, buf, size-1); -// break; -// } - -namespace internal { -// Helpers that use C++ overloading, templates, and specializations to deduce -// and record type information from function arguments. This allows us to -// later write a type-safe version of snprintf(). - -struct Arg { - enum Type { INT, UINT, STRING, POINTER }; - - // Any integer-like value. - Arg(signed char c) : type(INT) { - integer.i = c; - integer.width = sizeof(char); - } - Arg(unsigned char c) : type(UINT) { - integer.i = c; - integer.width = sizeof(char); - } - Arg(signed short j) : type(INT) { - integer.i = j; - integer.width = sizeof(short); - } - Arg(unsigned short j) : type(UINT) { - integer.i = j; - integer.width = sizeof(short); - } - Arg(signed int j) : type(INT) { - integer.i = j; - integer.width = sizeof(int); - } - Arg(unsigned int j) : type(UINT) { - integer.i = j; - integer.width = sizeof(int); - } - Arg(signed long j) : type(INT) { - integer.i = j; - integer.width = sizeof(long); - } - Arg(unsigned long j) : type(UINT) { - integer.i = j; - integer.width = sizeof(long); - } - Arg(signed long long j) : type(INT) { - integer.i = j; - integer.width = sizeof(long long); - } - Arg(unsigned long long j) : type(UINT) { - integer.i = j; - integer.width = sizeof(long long); - } - - // A C-style text string. - Arg(const char* s) : str(s), type(STRING) { } - Arg(char* s) : str(s), type(STRING) { } - - // Any pointer value that can be cast to a "void*". - template<class T> Arg(T* p) : ptr((void*)p), type(POINTER) { } - - union { - // An integer-like value. - struct { - int64_t i; - unsigned char width; - } integer; - - // A C-style text string. - const char* str; - - // A pointer to an arbitrary object. - const void* ptr; - }; - const enum Type type; -}; - -// This is the internal function that performs the actual formatting of -// an snprintf()-style format string. -BASE_EXPORT ssize_t SafeSNPrintf(char* buf, size_t sz, const char* fmt, - const Arg* args, size_t max_args); - -#if !defined(NDEBUG) -// In debug builds, allow unit tests to artificially lower the kSSizeMax -// constant that is used as a hard upper-bound for all buffers. In normal -// use, this constant should always be std::numeric_limits<ssize_t>::max(). -BASE_EXPORT void SetSafeSPrintfSSizeMaxForTest(size_t max); -BASE_EXPORT size_t GetSafeSPrintfSSizeMaxForTest(); -#endif - -} // namespace internal - -template<typename... Args> -ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, Args... args) { - // Use Arg() object to record type information and then copy arguments to an - // array to make it easier to iterate over them. - const internal::Arg arg_array[] = { args... }; - return internal::SafeSNPrintf(buf, N, fmt, arg_array, sizeof...(args)); -} - -template<size_t N, typename... Args> -ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, Args... args) { - // Use Arg() object to record type information and then copy arguments to an - // array to make it easier to iterate over them. - const internal::Arg arg_array[] = { args... }; - return internal::SafeSNPrintf(buf, N, fmt, arg_array, sizeof...(args)); -} - -// Fast-path when we don't actually need to substitute any arguments. -BASE_EXPORT ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt); -template<size_t N> -inline ssize_t SafeSPrintf(char (&buf)[N], const char* fmt) { - return SafeSNPrintf(buf, N, fmt); -} - -} // namespace strings -} // namespace base - -#endif // BASE_STRINGS_SAFE_SPRINTF_H_ diff --git a/security/sandbox/chromium/base/strings/safe_sprintf_unittest.cc b/security/sandbox/chromium/base/strings/safe_sprintf_unittest.cc deleted file mode 100644 index 931ace8b1..000000000 --- a/security/sandbox/chromium/base/strings/safe_sprintf_unittest.cc +++ /dev/null @@ -1,763 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/safe_sprintf.h" - -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> - -#include <limits> - -#include "base/logging.h" -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "build/build_config.h" -#include "testing/gtest/include/gtest/gtest.h" - -// Death tests on Android are currently very flaky. No need to add more flaky -// tests, as they just make it hard to spot real problems. -// TODO(markus): See if the restrictions on Android can eventually be lifted. -#if defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID) -#define ALLOW_DEATH_TEST -#endif - -namespace base { -namespace strings { - -TEST(SafeSPrintfTest, Empty) { - char buf[2] = { 'X', 'X' }; - - // Negative buffer size should always result in an error. - EXPECT_EQ(-1, SafeSNPrintf(buf, static_cast<size_t>(-1), "")); - EXPECT_EQ('X', buf[0]); - EXPECT_EQ('X', buf[1]); - - // Zero buffer size should always result in an error. - EXPECT_EQ(-1, SafeSNPrintf(buf, 0, "")); - EXPECT_EQ('X', buf[0]); - EXPECT_EQ('X', buf[1]); - - // A one-byte buffer should always print a single NUL byte. - EXPECT_EQ(0, SafeSNPrintf(buf, 1, "")); - EXPECT_EQ(0, buf[0]); - EXPECT_EQ('X', buf[1]); - buf[0] = 'X'; - - // A larger buffer should leave the trailing bytes unchanged. - EXPECT_EQ(0, SafeSNPrintf(buf, 2, "")); - EXPECT_EQ(0, buf[0]); - EXPECT_EQ('X', buf[1]); - buf[0] = 'X'; - - // The same test using SafeSPrintf() instead of SafeSNPrintf(). - EXPECT_EQ(0, SafeSPrintf(buf, "")); - EXPECT_EQ(0, buf[0]); - EXPECT_EQ('X', buf[1]); - buf[0] = 'X'; -} - -TEST(SafeSPrintfTest, NoArguments) { - // Output a text message that doesn't require any substitutions. This - // is roughly equivalent to calling strncpy() (but unlike strncpy(), it does - // always add a trailing NUL; it always deduplicates '%' characters). - static const char text[] = "hello world"; - char ref[20], buf[20]; - memset(ref, 'X', sizeof(ref)); - memcpy(buf, ref, sizeof(buf)); - - // A negative buffer size should always result in an error. - EXPECT_EQ(-1, SafeSNPrintf(buf, static_cast<size_t>(-1), text)); - EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf))); - - // Zero buffer size should always result in an error. - EXPECT_EQ(-1, SafeSNPrintf(buf, 0, text)); - EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf))); - - // A one-byte buffer should always print a single NUL byte. - EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, SafeSNPrintf(buf, 1, text)); - EXPECT_EQ(0, buf[0]); - EXPECT_TRUE(!memcmp(buf+1, ref+1, sizeof(buf)-1)); - memcpy(buf, ref, sizeof(buf)); - - // A larger (but limited) buffer should always leave the trailing bytes - // unchanged. - EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, SafeSNPrintf(buf, 2, text)); - EXPECT_EQ(text[0], buf[0]); - EXPECT_EQ(0, buf[1]); - EXPECT_TRUE(!memcmp(buf+2, ref+2, sizeof(buf)-2)); - memcpy(buf, ref, sizeof(buf)); - - // A unrestricted buffer length should always leave the trailing bytes - // unchanged. - EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, - SafeSNPrintf(buf, sizeof(buf), text)); - EXPECT_EQ(std::string(text), std::string(buf)); - EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text), - sizeof(buf) - sizeof(text))); - memcpy(buf, ref, sizeof(buf)); - - // The same test using SafeSPrintf() instead of SafeSNPrintf(). - EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, SafeSPrintf(buf, text)); - EXPECT_EQ(std::string(text), std::string(buf)); - EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text), - sizeof(buf) - sizeof(text))); - memcpy(buf, ref, sizeof(buf)); - - // Check for deduplication of '%' percent characters. - EXPECT_EQ(1, SafeSPrintf(buf, "%%")); - EXPECT_EQ(2, SafeSPrintf(buf, "%%%%")); - EXPECT_EQ(2, SafeSPrintf(buf, "%%X")); - EXPECT_EQ(3, SafeSPrintf(buf, "%%%%X")); -#if defined(NDEBUG) - EXPECT_EQ(1, SafeSPrintf(buf, "%")); - EXPECT_EQ(2, SafeSPrintf(buf, "%%%")); - EXPECT_EQ(2, SafeSPrintf(buf, "%X")); - EXPECT_EQ(3, SafeSPrintf(buf, "%%%X")); -#elif defined(ALLOW_DEATH_TEST) - EXPECT_DEATH(SafeSPrintf(buf, "%"), "src.1. == '%'"); - EXPECT_DEATH(SafeSPrintf(buf, "%%%"), "src.1. == '%'"); - EXPECT_DEATH(SafeSPrintf(buf, "%X"), "src.1. == '%'"); - EXPECT_DEATH(SafeSPrintf(buf, "%%%X"), "src.1. == '%'"); -#endif -} - -TEST(SafeSPrintfTest, OneArgument) { - // Test basic single-argument single-character substitution. - const char text[] = "hello world"; - const char fmt[] = "hello%cworld"; - char ref[20], buf[20]; - memset(ref, 'X', sizeof(buf)); - memcpy(buf, ref, sizeof(buf)); - - // A negative buffer size should always result in an error. - EXPECT_EQ(-1, SafeSNPrintf(buf, static_cast<size_t>(-1), fmt, ' ')); - EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf))); - - // Zero buffer size should always result in an error. - EXPECT_EQ(-1, SafeSNPrintf(buf, 0, fmt, ' ')); - EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf))); - - // A one-byte buffer should always print a single NUL byte. - EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, - SafeSNPrintf(buf, 1, fmt, ' ')); - EXPECT_EQ(0, buf[0]); - EXPECT_TRUE(!memcmp(buf+1, ref+1, sizeof(buf)-1)); - memcpy(buf, ref, sizeof(buf)); - - // A larger (but limited) buffer should always leave the trailing bytes - // unchanged. - EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, - SafeSNPrintf(buf, 2, fmt, ' ')); - EXPECT_EQ(text[0], buf[0]); - EXPECT_EQ(0, buf[1]); - EXPECT_TRUE(!memcmp(buf+2, ref+2, sizeof(buf)-2)); - memcpy(buf, ref, sizeof(buf)); - - // A unrestricted buffer length should always leave the trailing bytes - // unchanged. - EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, - SafeSNPrintf(buf, sizeof(buf), fmt, ' ')); - EXPECT_EQ(std::string(text), std::string(buf)); - EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text), - sizeof(buf) - sizeof(text))); - memcpy(buf, ref, sizeof(buf)); - - // The same test using SafeSPrintf() instead of SafeSNPrintf(). - EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, SafeSPrintf(buf, fmt, ' ')); - EXPECT_EQ(std::string(text), std::string(buf)); - EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text), - sizeof(buf) - sizeof(text))); - memcpy(buf, ref, sizeof(buf)); - - // Check for deduplication of '%' percent characters. - EXPECT_EQ(1, SafeSPrintf(buf, "%%", 0)); - EXPECT_EQ(2, SafeSPrintf(buf, "%%%%", 0)); - EXPECT_EQ(2, SafeSPrintf(buf, "%Y", 0)); - EXPECT_EQ(2, SafeSPrintf(buf, "%%Y", 0)); - EXPECT_EQ(3, SafeSPrintf(buf, "%%%Y", 0)); - EXPECT_EQ(3, SafeSPrintf(buf, "%%%%Y", 0)); -#if defined(NDEBUG) - EXPECT_EQ(1, SafeSPrintf(buf, "%", 0)); - EXPECT_EQ(2, SafeSPrintf(buf, "%%%", 0)); -#elif defined(ALLOW_DEATH_TEST) - EXPECT_DEATH(SafeSPrintf(buf, "%", 0), "ch"); - EXPECT_DEATH(SafeSPrintf(buf, "%%%", 0), "ch"); -#endif -} - -TEST(SafeSPrintfTest, MissingArg) { -#if defined(NDEBUG) - char buf[20]; - EXPECT_EQ(3, SafeSPrintf(buf, "%c%c", 'A')); - EXPECT_EQ("A%c", std::string(buf)); -#elif defined(ALLOW_DEATH_TEST) - char buf[20]; - EXPECT_DEATH(SafeSPrintf(buf, "%c%c", 'A'), "cur_arg < max_args"); -#endif -} - -TEST(SafeSPrintfTest, ASANFriendlyBufferTest) { - // Print into a buffer that is sized exactly to size. ASAN can verify that - // nobody attempts to write past the end of the buffer. - // There is a more complicated test in PrintLongString() that covers a lot - // more edge case, but it is also harder to debug in case of a failure. - const char kTestString[] = "This is a test"; - scoped_ptr<char[]> buf(new char[sizeof(kTestString)]); - EXPECT_EQ(static_cast<ssize_t>(sizeof(kTestString) - 1), - SafeSNPrintf(buf.get(), sizeof(kTestString), kTestString)); - EXPECT_EQ(std::string(kTestString), std::string(buf.get())); - EXPECT_EQ(static_cast<ssize_t>(sizeof(kTestString) - 1), - SafeSNPrintf(buf.get(), sizeof(kTestString), "%s", kTestString)); - EXPECT_EQ(std::string(kTestString), std::string(buf.get())); -} - -TEST(SafeSPrintfTest, NArgs) { - // Pre-C++11 compilers have a different code path, that can only print - // up to ten distinct arguments. - // We test both SafeSPrintf() and SafeSNPrintf(). This makes sure we don't - // have typos in the copy-n-pasted code that is needed to deal with various - // numbers of arguments. - char buf[12]; - EXPECT_EQ(1, SafeSPrintf(buf, "%c", 1)); - EXPECT_EQ("\1", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%c%c", 1, 2)); - EXPECT_EQ("\1\2", std::string(buf)); - EXPECT_EQ(3, SafeSPrintf(buf, "%c%c%c", 1, 2, 3)); - EXPECT_EQ("\1\2\3", std::string(buf)); - EXPECT_EQ(4, SafeSPrintf(buf, "%c%c%c%c", 1, 2, 3, 4)); - EXPECT_EQ("\1\2\3\4", std::string(buf)); - EXPECT_EQ(5, SafeSPrintf(buf, "%c%c%c%c%c", 1, 2, 3, 4, 5)); - EXPECT_EQ("\1\2\3\4\5", std::string(buf)); - EXPECT_EQ(6, SafeSPrintf(buf, "%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6)); - EXPECT_EQ("\1\2\3\4\5\6", std::string(buf)); - EXPECT_EQ(7, SafeSPrintf(buf, "%c%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6, 7)); - EXPECT_EQ("\1\2\3\4\5\6\7", std::string(buf)); - EXPECT_EQ(8, SafeSPrintf(buf, "%c%c%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6, 7, 8)); - EXPECT_EQ("\1\2\3\4\5\6\7\10", std::string(buf)); - EXPECT_EQ(9, SafeSPrintf(buf, "%c%c%c%c%c%c%c%c%c", - 1, 2, 3, 4, 5, 6, 7, 8, 9)); - EXPECT_EQ("\1\2\3\4\5\6\7\10\11", std::string(buf)); - EXPECT_EQ(10, SafeSPrintf(buf, "%c%c%c%c%c%c%c%c%c%c", - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); - - // Repeat all the tests with SafeSNPrintf() instead of SafeSPrintf(). - EXPECT_EQ("\1\2\3\4\5\6\7\10\11\12", std::string(buf)); - EXPECT_EQ(1, SafeSNPrintf(buf, 11, "%c", 1)); - EXPECT_EQ("\1", std::string(buf)); - EXPECT_EQ(2, SafeSNPrintf(buf, 11, "%c%c", 1, 2)); - EXPECT_EQ("\1\2", std::string(buf)); - EXPECT_EQ(3, SafeSNPrintf(buf, 11, "%c%c%c", 1, 2, 3)); - EXPECT_EQ("\1\2\3", std::string(buf)); - EXPECT_EQ(4, SafeSNPrintf(buf, 11, "%c%c%c%c", 1, 2, 3, 4)); - EXPECT_EQ("\1\2\3\4", std::string(buf)); - EXPECT_EQ(5, SafeSNPrintf(buf, 11, "%c%c%c%c%c", 1, 2, 3, 4, 5)); - EXPECT_EQ("\1\2\3\4\5", std::string(buf)); - EXPECT_EQ(6, SafeSNPrintf(buf, 11, "%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6)); - EXPECT_EQ("\1\2\3\4\5\6", std::string(buf)); - EXPECT_EQ(7, SafeSNPrintf(buf, 11, "%c%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6, 7)); - EXPECT_EQ("\1\2\3\4\5\6\7", std::string(buf)); - EXPECT_EQ(8, SafeSNPrintf(buf, 11, "%c%c%c%c%c%c%c%c", - 1, 2, 3, 4, 5, 6, 7, 8)); - EXPECT_EQ("\1\2\3\4\5\6\7\10", std::string(buf)); - EXPECT_EQ(9, SafeSNPrintf(buf, 11, "%c%c%c%c%c%c%c%c%c", - 1, 2, 3, 4, 5, 6, 7, 8, 9)); - EXPECT_EQ("\1\2\3\4\5\6\7\10\11", std::string(buf)); - EXPECT_EQ(10, SafeSNPrintf(buf, 11, "%c%c%c%c%c%c%c%c%c%c", - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); - EXPECT_EQ("\1\2\3\4\5\6\7\10\11\12", std::string(buf)); - - EXPECT_EQ(11, SafeSPrintf(buf, "%c%c%c%c%c%c%c%c%c%c%c", - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)); - EXPECT_EQ("\1\2\3\4\5\6\7\10\11\12\13", std::string(buf)); - EXPECT_EQ(11, SafeSNPrintf(buf, 12, "%c%c%c%c%c%c%c%c%c%c%c", - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)); - EXPECT_EQ("\1\2\3\4\5\6\7\10\11\12\13", std::string(buf)); -} - -TEST(SafeSPrintfTest, DataTypes) { - char buf[40]; - - // Bytes - EXPECT_EQ(1, SafeSPrintf(buf, "%d", (uint8_t)1)); - EXPECT_EQ("1", std::string(buf)); - EXPECT_EQ(3, SafeSPrintf(buf, "%d", (uint8_t)-1)); - EXPECT_EQ("255", std::string(buf)); - EXPECT_EQ(1, SafeSPrintf(buf, "%d", (int8_t)1)); - EXPECT_EQ("1", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%d", (int8_t)-1)); - EXPECT_EQ("-1", std::string(buf)); - EXPECT_EQ(4, SafeSPrintf(buf, "%d", (int8_t)-128)); - EXPECT_EQ("-128", std::string(buf)); - - // Half-words - EXPECT_EQ(1, SafeSPrintf(buf, "%d", (uint16_t)1)); - EXPECT_EQ("1", std::string(buf)); - EXPECT_EQ(5, SafeSPrintf(buf, "%d", (uint16_t)-1)); - EXPECT_EQ("65535", std::string(buf)); - EXPECT_EQ(1, SafeSPrintf(buf, "%d", (int16_t)1)); - EXPECT_EQ("1", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%d", (int16_t)-1)); - EXPECT_EQ("-1", std::string(buf)); - EXPECT_EQ(6, SafeSPrintf(buf, "%d", (int16_t)-32768)); - EXPECT_EQ("-32768", std::string(buf)); - - // Words - EXPECT_EQ(1, SafeSPrintf(buf, "%d", (uint32_t)1)); - EXPECT_EQ("1", std::string(buf)); - EXPECT_EQ(10, SafeSPrintf(buf, "%d", (uint32_t)-1)); - EXPECT_EQ("4294967295", std::string(buf)); - EXPECT_EQ(1, SafeSPrintf(buf, "%d", (int32_t)1)); - EXPECT_EQ("1", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%d", (int32_t)-1)); - EXPECT_EQ("-1", std::string(buf)); - // Work-around for an limitation of C90 - EXPECT_EQ(11, SafeSPrintf(buf, "%d", (int32_t)-2147483647-1)); - EXPECT_EQ("-2147483648", std::string(buf)); - - // Quads - EXPECT_EQ(1, SafeSPrintf(buf, "%d", (uint64_t)1)); - EXPECT_EQ("1", std::string(buf)); - EXPECT_EQ(20, SafeSPrintf(buf, "%d", (uint64_t)-1)); - EXPECT_EQ("18446744073709551615", std::string(buf)); - EXPECT_EQ(1, SafeSPrintf(buf, "%d", (int64_t)1)); - EXPECT_EQ("1", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%d", (int64_t)-1)); - EXPECT_EQ("-1", std::string(buf)); - // Work-around for an limitation of C90 - EXPECT_EQ(20, SafeSPrintf(buf, "%d", (int64_t)-9223372036854775807LL-1)); - EXPECT_EQ("-9223372036854775808", std::string(buf)); - - // Strings (both const and mutable). - EXPECT_EQ(4, SafeSPrintf(buf, "test")); - EXPECT_EQ("test", std::string(buf)); - EXPECT_EQ(4, SafeSPrintf(buf, buf)); - EXPECT_EQ("test", std::string(buf)); - - // Pointer - char addr[20]; - sprintf(addr, "0x%llX", (unsigned long long)(uintptr_t)buf); - SafeSPrintf(buf, "%p", buf); - EXPECT_EQ(std::string(addr), std::string(buf)); - SafeSPrintf(buf, "%p", (const char *)buf); - EXPECT_EQ(std::string(addr), std::string(buf)); - sprintf(addr, "0x%llX", (unsigned long long)(uintptr_t)sprintf); - SafeSPrintf(buf, "%p", sprintf); - EXPECT_EQ(std::string(addr), std::string(buf)); - - // Padding for pointers is a little more complicated because of the "0x" - // prefix. Padding with '0' zeros is relatively straight-forward, but - // padding with ' ' spaces requires more effort. - sprintf(addr, "0x%017llX", (unsigned long long)(uintptr_t)buf); - SafeSPrintf(buf, "%019p", buf); - EXPECT_EQ(std::string(addr), std::string(buf)); - sprintf(addr, "0x%llX", (unsigned long long)(uintptr_t)buf); - memset(addr, ' ', - (char*)memmove(addr + sizeof(addr) - strlen(addr) - 1, - addr, strlen(addr)+1) - addr); - SafeSPrintf(buf, "%19p", buf); - EXPECT_EQ(std::string(addr), std::string(buf)); -} - -namespace { -void PrintLongString(char* buf, size_t sz) { - // Output a reasonably complex expression into a limited-size buffer. - // At least one byte is available for writing the NUL character. - CHECK_GT(sz, static_cast<size_t>(0)); - - // Allocate slightly more space, so that we can verify that SafeSPrintf() - // never writes past the end of the buffer. - scoped_ptr<char[]> tmp(new char[sz+2]); - memset(tmp.get(), 'X', sz+2); - - // Use SafeSPrintf() to output a complex list of arguments: - // - test padding and truncating %c single characters. - // - test truncating %s simple strings. - // - test mismatching arguments and truncating (for %d != %s). - // - test zero-padding and truncating %x hexadecimal numbers. - // - test outputting and truncating %d MININT. - // - test outputting and truncating %p arbitrary pointer values. - // - test outputting, padding and truncating NULL-pointer %s strings. - char* out = tmp.get(); - size_t out_sz = sz; - size_t len; - for (scoped_ptr<char[]> perfect_buf;;) { - size_t needed = SafeSNPrintf(out, out_sz, -#if defined(NDEBUG) - "A%2cong %s: %d %010X %d %p%7s", 'l', "string", "", -#else - "A%2cong %s: %%d %010X %d %p%7s", 'l', "string", -#endif - 0xDEADBEEF, std::numeric_limits<intptr_t>::min(), - PrintLongString, static_cast<char*>(NULL)) + 1; - - // Various sanity checks: - // The numbered of characters needed to print the full string should always - // be bigger or equal to the bytes that have actually been output. - len = strlen(tmp.get()); - CHECK_GE(needed, len+1); - - // The number of characters output should always fit into the buffer that - // was passed into SafeSPrintf(). - CHECK_LT(len, out_sz); - - // The output is always terminated with a NUL byte (actually, this test is - // always going to pass, as strlen() already verified this) - EXPECT_FALSE(tmp[len]); - - // ASAN can check that we are not overwriting buffers, iff we make sure the - // buffer is exactly the size that we are expecting to be written. After - // running SafeSNPrintf() the first time, it is possible to compute the - // correct buffer size for this test. So, allocate a second buffer and run - // the exact same SafeSNPrintf() command again. - if (!perfect_buf.get()) { - out_sz = std::min(needed, sz); - out = new char[out_sz]; - perfect_buf.reset(out); - } else { - break; - } - } - - // All trailing bytes are unchanged. - for (size_t i = len+1; i < sz+2; ++i) - EXPECT_EQ('X', tmp[i]); - - // The text that was generated by SafeSPrintf() should always match the - // equivalent text generated by sprintf(). Please note that the format - // string for sprintf() is not complicated, as it does not have the - // benefit of getting type information from the C++ compiler. - // - // N.B.: It would be so much cleaner to use snprintf(). But unfortunately, - // Visual Studio doesn't support this function, and the work-arounds - // are all really awkward. - char ref[256]; - CHECK_LE(sz, sizeof(ref)); - sprintf(ref, "A long string: %%d 00DEADBEEF %lld 0x%llX <NULL>", - static_cast<long long>(std::numeric_limits<intptr_t>::min()), - static_cast<unsigned long long>( - reinterpret_cast<uintptr_t>(PrintLongString))); - ref[sz-1] = '\000'; - -#if defined(NDEBUG) - const size_t kSSizeMax = std::numeric_limits<ssize_t>::max(); -#else - const size_t kSSizeMax = internal::GetSafeSPrintfSSizeMaxForTest(); -#endif - - // Compare the output from SafeSPrintf() to the one from sprintf(). - EXPECT_EQ(std::string(ref).substr(0, kSSizeMax-1), std::string(tmp.get())); - - // We allocated a slightly larger buffer, so that we could perform some - // extra sanity checks. Now that the tests have all passed, we copy the - // data to the output buffer that the caller provided. - memcpy(buf, tmp.get(), len+1); -} - -#if !defined(NDEBUG) -class ScopedSafeSPrintfSSizeMaxSetter { - public: - ScopedSafeSPrintfSSizeMaxSetter(size_t sz) { - old_ssize_max_ = internal::GetSafeSPrintfSSizeMaxForTest(); - internal::SetSafeSPrintfSSizeMaxForTest(sz); - } - - ~ScopedSafeSPrintfSSizeMaxSetter() { - internal::SetSafeSPrintfSSizeMaxForTest(old_ssize_max_); - } - - private: - size_t old_ssize_max_; - - DISALLOW_COPY_AND_ASSIGN(ScopedSafeSPrintfSSizeMaxSetter); -}; -#endif - -} // anonymous namespace - -TEST(SafeSPrintfTest, Truncation) { - // We use PrintLongString() to print a complex long string and then - // truncate to all possible lengths. This ends up exercising a lot of - // different code paths in SafeSPrintf() and IToASCII(), as truncation can - // happen in a lot of different states. - char ref[256]; - PrintLongString(ref, sizeof(ref)); - for (size_t i = strlen(ref)+1; i; --i) { - char buf[sizeof(ref)]; - PrintLongString(buf, i); - EXPECT_EQ(std::string(ref, i - 1), std::string(buf)); - } - - // When compiling in debug mode, we have the ability to fake a small - // upper limit for the maximum value that can be stored in an ssize_t. - // SafeSPrintf() uses this upper limit to determine how many bytes it will - // write to the buffer, even if the caller claimed a bigger buffer size. - // Repeat the truncation test and verify that this other code path in - // SafeSPrintf() works correctly, too. -#if !defined(NDEBUG) - for (size_t i = strlen(ref)+1; i > 1; --i) { - ScopedSafeSPrintfSSizeMaxSetter ssize_max_setter(i); - char buf[sizeof(ref)]; - PrintLongString(buf, sizeof(buf)); - EXPECT_EQ(std::string(ref, i - 1), std::string(buf)); - } - - // kSSizeMax is also used to constrain the maximum amount of padding, before - // SafeSPrintf() detects an error in the format string. - ScopedSafeSPrintfSSizeMaxSetter ssize_max_setter(100); - char buf[256]; - EXPECT_EQ(99, SafeSPrintf(buf, "%99c", ' ')); - EXPECT_EQ(std::string(99, ' '), std::string(buf)); - *buf = '\000'; -#if defined(ALLOW_DEATH_TEST) - EXPECT_DEATH(SafeSPrintf(buf, "%100c", ' '), "padding <= max_padding"); -#endif - EXPECT_EQ(0, *buf); -#endif -} - -TEST(SafeSPrintfTest, Padding) { - char buf[40], fmt[40]; - - // Chars %c - EXPECT_EQ(1, SafeSPrintf(buf, "%c", 'A')); - EXPECT_EQ("A", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%2c", 'A')); - EXPECT_EQ(" A", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%02c", 'A')); - EXPECT_EQ(" A", std::string(buf)); - EXPECT_EQ(4, SafeSPrintf(buf, "%-2c", 'A')); - EXPECT_EQ("%-2c", std::string(buf)); - SafeSPrintf(fmt, "%%%dc", std::numeric_limits<ssize_t>::max() - 1); - EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, SafeSPrintf(buf, fmt, 'A')); - SafeSPrintf(fmt, "%%%dc", - static_cast<size_t>(std::numeric_limits<ssize_t>::max())); -#if defined(NDEBUG) - EXPECT_EQ(2, SafeSPrintf(buf, fmt, 'A')); - EXPECT_EQ("%c", std::string(buf)); -#elif defined(ALLOW_DEATH_TEST) - EXPECT_DEATH(SafeSPrintf(buf, fmt, 'A'), "padding <= max_padding"); -#endif - - // Octal %o - EXPECT_EQ(1, SafeSPrintf(buf, "%o", 1)); - EXPECT_EQ("1", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%2o", 1)); - EXPECT_EQ(" 1", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%02o", 1)); - EXPECT_EQ("01", std::string(buf)); - EXPECT_EQ(12, SafeSPrintf(buf, "%12o", -1)); - EXPECT_EQ(" 37777777777", std::string(buf)); - EXPECT_EQ(12, SafeSPrintf(buf, "%012o", -1)); - EXPECT_EQ("037777777777", std::string(buf)); - EXPECT_EQ(23, SafeSPrintf(buf, "%23o", -1LL)); - EXPECT_EQ(" 1777777777777777777777", std::string(buf)); - EXPECT_EQ(23, SafeSPrintf(buf, "%023o", -1LL)); - EXPECT_EQ("01777777777777777777777", std::string(buf)); - EXPECT_EQ(3, SafeSPrintf(buf, "%2o", 0111)); - EXPECT_EQ("111", std::string(buf)); - EXPECT_EQ(4, SafeSPrintf(buf, "%-2o", 1)); - EXPECT_EQ("%-2o", std::string(buf)); - SafeSPrintf(fmt, "%%%do", std::numeric_limits<ssize_t>::max()-1); - EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, - SafeSNPrintf(buf, 4, fmt, 1)); - EXPECT_EQ(" ", std::string(buf)); - SafeSPrintf(fmt, "%%0%do", std::numeric_limits<ssize_t>::max()-1); - EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, - SafeSNPrintf(buf, 4, fmt, 1)); - EXPECT_EQ("000", std::string(buf)); - SafeSPrintf(fmt, "%%%do", - static_cast<size_t>(std::numeric_limits<ssize_t>::max())); -#if defined(NDEBUG) - EXPECT_EQ(2, SafeSPrintf(buf, fmt, 1)); - EXPECT_EQ("%o", std::string(buf)); -#elif defined(ALLOW_DEATH_TEST) - EXPECT_DEATH(SafeSPrintf(buf, fmt, 1), "padding <= max_padding"); -#endif - - // Decimals %d - EXPECT_EQ(1, SafeSPrintf(buf, "%d", 1)); - EXPECT_EQ("1", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%2d", 1)); - EXPECT_EQ(" 1", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%02d", 1)); - EXPECT_EQ("01", std::string(buf)); - EXPECT_EQ(3, SafeSPrintf(buf, "%3d", -1)); - EXPECT_EQ(" -1", std::string(buf)); - EXPECT_EQ(3, SafeSPrintf(buf, "%03d", -1)); - EXPECT_EQ("-01", std::string(buf)); - EXPECT_EQ(3, SafeSPrintf(buf, "%2d", 111)); - EXPECT_EQ("111", std::string(buf)); - EXPECT_EQ(4, SafeSPrintf(buf, "%2d", -111)); - EXPECT_EQ("-111", std::string(buf)); - EXPECT_EQ(4, SafeSPrintf(buf, "%-2d", 1)); - EXPECT_EQ("%-2d", std::string(buf)); - SafeSPrintf(fmt, "%%%dd", std::numeric_limits<ssize_t>::max()-1); - EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, - SafeSNPrintf(buf, 4, fmt, 1)); - EXPECT_EQ(" ", std::string(buf)); - SafeSPrintf(fmt, "%%0%dd", std::numeric_limits<ssize_t>::max()-1); - EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, - SafeSNPrintf(buf, 4, fmt, 1)); - EXPECT_EQ("000", std::string(buf)); - SafeSPrintf(fmt, "%%%dd", - static_cast<size_t>(std::numeric_limits<ssize_t>::max())); -#if defined(NDEBUG) - EXPECT_EQ(2, SafeSPrintf(buf, fmt, 1)); - EXPECT_EQ("%d", std::string(buf)); -#elif defined(ALLOW_DEATH_TEST) - EXPECT_DEATH(SafeSPrintf(buf, fmt, 1), "padding <= max_padding"); -#endif - - // Hex %X - EXPECT_EQ(1, SafeSPrintf(buf, "%X", 1)); - EXPECT_EQ("1", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%2X", 1)); - EXPECT_EQ(" 1", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%02X", 1)); - EXPECT_EQ("01", std::string(buf)); - EXPECT_EQ(9, SafeSPrintf(buf, "%9X", -1)); - EXPECT_EQ(" FFFFFFFF", std::string(buf)); - EXPECT_EQ(9, SafeSPrintf(buf, "%09X", -1)); - EXPECT_EQ("0FFFFFFFF", std::string(buf)); - EXPECT_EQ(17, SafeSPrintf(buf, "%17X", -1LL)); - EXPECT_EQ(" FFFFFFFFFFFFFFFF", std::string(buf)); - EXPECT_EQ(17, SafeSPrintf(buf, "%017X", -1LL)); - EXPECT_EQ("0FFFFFFFFFFFFFFFF", std::string(buf)); - EXPECT_EQ(3, SafeSPrintf(buf, "%2X", 0x111)); - EXPECT_EQ("111", std::string(buf)); - EXPECT_EQ(4, SafeSPrintf(buf, "%-2X", 1)); - EXPECT_EQ("%-2X", std::string(buf)); - SafeSPrintf(fmt, "%%%dX", std::numeric_limits<ssize_t>::max()-1); - EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, - SafeSNPrintf(buf, 4, fmt, 1)); - EXPECT_EQ(" ", std::string(buf)); - SafeSPrintf(fmt, "%%0%dX", std::numeric_limits<ssize_t>::max()-1); - EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, - SafeSNPrintf(buf, 4, fmt, 1)); - EXPECT_EQ("000", std::string(buf)); - SafeSPrintf(fmt, "%%%dX", - static_cast<size_t>(std::numeric_limits<ssize_t>::max())); -#if defined(NDEBUG) - EXPECT_EQ(2, SafeSPrintf(buf, fmt, 1)); - EXPECT_EQ("%X", std::string(buf)); -#elif defined(ALLOW_DEATH_TEST) - EXPECT_DEATH(SafeSPrintf(buf, fmt, 1), "padding <= max_padding"); -#endif - - // Pointer %p - EXPECT_EQ(3, SafeSPrintf(buf, "%p", (void*)1)); - EXPECT_EQ("0x1", std::string(buf)); - EXPECT_EQ(4, SafeSPrintf(buf, "%4p", (void*)1)); - EXPECT_EQ(" 0x1", std::string(buf)); - EXPECT_EQ(4, SafeSPrintf(buf, "%04p", (void*)1)); - EXPECT_EQ("0x01", std::string(buf)); - EXPECT_EQ(5, SafeSPrintf(buf, "%4p", (void*)0x111)); - EXPECT_EQ("0x111", std::string(buf)); - EXPECT_EQ(4, SafeSPrintf(buf, "%-2p", (void*)1)); - EXPECT_EQ("%-2p", std::string(buf)); - SafeSPrintf(fmt, "%%%dp", std::numeric_limits<ssize_t>::max()-1); - EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, - SafeSNPrintf(buf, 4, fmt, (void*)1)); - EXPECT_EQ(" ", std::string(buf)); - SafeSPrintf(fmt, "%%0%dp", std::numeric_limits<ssize_t>::max()-1); - EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, - SafeSNPrintf(buf, 4, fmt, (void*)1)); - EXPECT_EQ("0x0", std::string(buf)); - SafeSPrintf(fmt, "%%%dp", - static_cast<size_t>(std::numeric_limits<ssize_t>::max())); -#if defined(NDEBUG) - EXPECT_EQ(2, SafeSPrintf(buf, fmt, 1)); - EXPECT_EQ("%p", std::string(buf)); -#elif defined(ALLOW_DEATH_TEST) - EXPECT_DEATH(SafeSPrintf(buf, fmt, 1), "padding <= max_padding"); -#endif - - // String - EXPECT_EQ(1, SafeSPrintf(buf, "%s", "A")); - EXPECT_EQ("A", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%2s", "A")); - EXPECT_EQ(" A", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%02s", "A")); - EXPECT_EQ(" A", std::string(buf)); - EXPECT_EQ(3, SafeSPrintf(buf, "%2s", "AAA")); - EXPECT_EQ("AAA", std::string(buf)); - EXPECT_EQ(4, SafeSPrintf(buf, "%-2s", "A")); - EXPECT_EQ("%-2s", std::string(buf)); - SafeSPrintf(fmt, "%%%ds", std::numeric_limits<ssize_t>::max()-1); - EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, - SafeSNPrintf(buf, 4, fmt, "A")); - EXPECT_EQ(" ", std::string(buf)); - SafeSPrintf(fmt, "%%0%ds", std::numeric_limits<ssize_t>::max()-1); - EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, - SafeSNPrintf(buf, 4, fmt, "A")); - EXPECT_EQ(" ", std::string(buf)); - SafeSPrintf(fmt, "%%%ds", - static_cast<size_t>(std::numeric_limits<ssize_t>::max())); -#if defined(NDEBUG) - EXPECT_EQ(2, SafeSPrintf(buf, fmt, "A")); - EXPECT_EQ("%s", std::string(buf)); -#elif defined(ALLOW_DEATH_TEST) - EXPECT_DEATH(SafeSPrintf(buf, fmt, "A"), "padding <= max_padding"); -#endif -} - -TEST(SafeSPrintfTest, EmbeddedNul) { - char buf[] = { 'X', 'X', 'X', 'X' }; - EXPECT_EQ(2, SafeSPrintf(buf, "%3c", 0)); - EXPECT_EQ(' ', buf[0]); - EXPECT_EQ(' ', buf[1]); - EXPECT_EQ(0, buf[2]); - EXPECT_EQ('X', buf[3]); - - // Check handling of a NUL format character. N.B. this takes two different - // code paths depending on whether we are actually passing arguments. If - // we don't have any arguments, we are running in the fast-path code, that - // looks (almost) like a strncpy(). -#if defined(NDEBUG) - EXPECT_EQ(2, SafeSPrintf(buf, "%%%")); - EXPECT_EQ("%%", std::string(buf)); - EXPECT_EQ(2, SafeSPrintf(buf, "%%%", 0)); - EXPECT_EQ("%%", std::string(buf)); -#elif defined(ALLOW_DEATH_TEST) - EXPECT_DEATH(SafeSPrintf(buf, "%%%"), "src.1. == '%'"); - EXPECT_DEATH(SafeSPrintf(buf, "%%%", 0), "ch"); -#endif -} - -TEST(SafeSPrintfTest, EmitNULL) { - char buf[40]; -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion-null" -#endif - EXPECT_EQ(1, SafeSPrintf(buf, "%d", NULL)); - EXPECT_EQ("0", std::string(buf)); - EXPECT_EQ(3, SafeSPrintf(buf, "%p", NULL)); - EXPECT_EQ("0x0", std::string(buf)); - EXPECT_EQ(6, SafeSPrintf(buf, "%s", NULL)); - EXPECT_EQ("<NULL>", std::string(buf)); -#if defined(__GCC__) -#pragma GCC diagnostic pop -#endif -} - -TEST(SafeSPrintfTest, PointerSize) { - // The internal data representation is a 64bit value, independent of the - // native word size. We want to perform sign-extension for signed integers, - // but we want to avoid doing so for pointer types. This could be a - // problem on systems, where pointers are only 32bit. This tests verifies - // that there is no such problem. - char *str = reinterpret_cast<char *>(0x80000000u); - void *ptr = str; - char buf[40]; - EXPECT_EQ(10, SafeSPrintf(buf, "%p", str)); - EXPECT_EQ("0x80000000", std::string(buf)); - EXPECT_EQ(10, SafeSPrintf(buf, "%p", ptr)); - EXPECT_EQ("0x80000000", std::string(buf)); -} - -} // namespace strings -} // namespace base diff --git a/security/sandbox/chromium/base/strings/string16.cc b/security/sandbox/chromium/base/strings/string16.cc deleted file mode 100644 index f4c8cf746..000000000 --- a/security/sandbox/chromium/base/strings/string16.cc +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/string16.h" - -#if defined(WCHAR_T_IS_UTF16) - -#error This file should not be used on 2-byte wchar_t systems -// If this winds up being needed on 2-byte wchar_t systems, either the -// definitions below can be used, or the host system's wide character -// functions like wmemcmp can be wrapped. - -#elif defined(WCHAR_T_IS_UTF32) - -#include <ostream> - -#include "base/strings/utf_string_conversions.h" - -namespace base { - -int c16memcmp(const char16* s1, const char16* s2, size_t n) { - // We cannot call memcmp because that changes the semantics. - while (n-- > 0) { - if (*s1 != *s2) { - // We cannot use (*s1 - *s2) because char16 is unsigned. - return ((*s1 < *s2) ? -1 : 1); - } - ++s1; - ++s2; - } - return 0; -} - -size_t c16len(const char16* s) { - const char16 *s_orig = s; - while (*s) { - ++s; - } - return s - s_orig; -} - -const char16* c16memchr(const char16* s, char16 c, size_t n) { - while (n-- > 0) { - if (*s == c) { - return s; - } - ++s; - } - return 0; -} - -char16* c16memmove(char16* s1, const char16* s2, size_t n) { - return static_cast<char16*>(memmove(s1, s2, n * sizeof(char16))); -} - -char16* c16memcpy(char16* s1, const char16* s2, size_t n) { - return static_cast<char16*>(memcpy(s1, s2, n * sizeof(char16))); -} - -char16* c16memset(char16* s, char16 c, size_t n) { - char16 *s_orig = s; - while (n-- > 0) { - *s = c; - ++s; - } - return s_orig; -} - -std::ostream& operator<<(std::ostream& out, const string16& str) { - return out << UTF16ToUTF8(str); -} - -void PrintTo(const string16& str, std::ostream* out) { - *out << str; -} - -} // namespace base - -template class std::basic_string<base::char16, base::string16_char_traits>; - -#endif // WCHAR_T_IS_UTF32 diff --git a/security/sandbox/chromium/base/strings/string16.h b/security/sandbox/chromium/base/strings/string16.h deleted file mode 100644 index e47669c1b..000000000 --- a/security/sandbox/chromium/base/strings/string16.h +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_STRINGS_STRING16_H_ -#define BASE_STRINGS_STRING16_H_ - -// WHAT: -// A version of std::basic_string that provides 2-byte characters even when -// wchar_t is not implemented as a 2-byte type. You can access this class as -// string16. We also define char16, which string16 is based upon. -// -// WHY: -// On Windows, wchar_t is 2 bytes, and it can conveniently handle UTF-16/UCS-2 -// data. Plenty of existing code operates on strings encoded as UTF-16. -// -// On many other platforms, sizeof(wchar_t) is 4 bytes by default. We can make -// it 2 bytes by using the GCC flag -fshort-wchar. But then std::wstring fails -// at run time, because it calls some functions (like wcslen) that come from -// the system's native C library -- which was built with a 4-byte wchar_t! -// It's wasteful to use 4-byte wchar_t strings to carry UTF-16 data, and it's -// entirely improper on those systems where the encoding of wchar_t is defined -// as UTF-32. -// -// Here, we define string16, which is similar to std::wstring but replaces all -// libc functions with custom, 2-byte-char compatible routines. It is capable -// of carrying UTF-16-encoded data. - -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> -#include <string> - -#include "base/base_export.h" -#include "build/build_config.h" - -#if defined(WCHAR_T_IS_UTF16) - -namespace base { - -typedef wchar_t char16; -typedef std::wstring string16; -typedef std::char_traits<wchar_t> string16_char_traits; - -} // namespace base - -#elif defined(WCHAR_T_IS_UTF32) - -namespace base { - -typedef uint16_t char16; - -// char16 versions of the functions required by string16_char_traits; these -// are based on the wide character functions of similar names ("w" or "wcs" -// instead of "c16"). -BASE_EXPORT int c16memcmp(const char16* s1, const char16* s2, size_t n); -BASE_EXPORT size_t c16len(const char16* s); -BASE_EXPORT const char16* c16memchr(const char16* s, char16 c, size_t n); -BASE_EXPORT char16* c16memmove(char16* s1, const char16* s2, size_t n); -BASE_EXPORT char16* c16memcpy(char16* s1, const char16* s2, size_t n); -BASE_EXPORT char16* c16memset(char16* s, char16 c, size_t n); - -struct string16_char_traits { - typedef char16 char_type; - typedef int int_type; - - // int_type needs to be able to hold each possible value of char_type, and in - // addition, the distinct value of eof(). - static_assert(sizeof(int_type) > sizeof(char_type), - "int must be larger than 16 bits wide"); - - typedef std::streamoff off_type; - typedef mbstate_t state_type; - typedef std::fpos<state_type> pos_type; - - static void assign(char_type& c1, const char_type& c2) { - c1 = c2; - } - - static bool eq(const char_type& c1, const char_type& c2) { - return c1 == c2; - } - static bool lt(const char_type& c1, const char_type& c2) { - return c1 < c2; - } - - static int compare(const char_type* s1, const char_type* s2, size_t n) { - return c16memcmp(s1, s2, n); - } - - static size_t length(const char_type* s) { - return c16len(s); - } - - static const char_type* find(const char_type* s, size_t n, - const char_type& a) { - return c16memchr(s, a, n); - } - - static char_type* move(char_type* s1, const char_type* s2, size_t n) { - return c16memmove(s1, s2, n); - } - - static char_type* copy(char_type* s1, const char_type* s2, size_t n) { - return c16memcpy(s1, s2, n); - } - - static char_type* assign(char_type* s, size_t n, char_type a) { - return c16memset(s, a, n); - } - - static int_type not_eof(const int_type& c) { - return eq_int_type(c, eof()) ? 0 : c; - } - - static char_type to_char_type(const int_type& c) { - return char_type(c); - } - - static int_type to_int_type(const char_type& c) { - return int_type(c); - } - - static bool eq_int_type(const int_type& c1, const int_type& c2) { - return c1 == c2; - } - - static int_type eof() { - return static_cast<int_type>(EOF); - } -}; - -typedef std::basic_string<char16, base::string16_char_traits> string16; - -BASE_EXPORT extern std::ostream& operator<<(std::ostream& out, - const string16& str); - -// This is required by googletest to print a readable output on test failures. -BASE_EXPORT extern void PrintTo(const string16& str, std::ostream* out); - -} // namespace base - -// The string class will be explicitly instantiated only once, in string16.cc. -// -// std::basic_string<> in GNU libstdc++ contains a static data member, -// _S_empty_rep_storage, to represent empty strings. When an operation such -// as assignment or destruction is performed on a string, causing its existing -// data member to be invalidated, it must not be freed if this static data -// member is being used. Otherwise, it counts as an attempt to free static -// (and not allocated) data, which is a memory error. -// -// Generally, due to C++ template magic, _S_empty_rep_storage will be marked -// as a coalesced symbol, meaning that the linker will combine multiple -// instances into a single one when generating output. -// -// If a string class is used by multiple shared libraries, a problem occurs. -// Each library will get its own copy of _S_empty_rep_storage. When strings -// are passed across a library boundary for alteration or destruction, memory -// errors will result. GNU libstdc++ contains a configuration option, -// --enable-fully-dynamic-string (_GLIBCXX_FULLY_DYNAMIC_STRING), which -// disables the static data member optimization, but it's a good optimization -// and non-STL code is generally at the mercy of the system's STL -// configuration. Fully-dynamic strings are not the default for GNU libstdc++ -// libstdc++ itself or for the libstdc++ installations on the systems we care -// about, such as Mac OS X and relevant flavors of Linux. -// -// See also http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24196 . -// -// To avoid problems, string classes need to be explicitly instantiated only -// once, in exactly one library. All other string users see it via an "extern" -// declaration. This is precisely how GNU libstdc++ handles -// std::basic_string<char> (string) and std::basic_string<wchar_t> (wstring). -// -// This also works around a Mac OS X linker bug in ld64-85.2.1 (Xcode 3.1.2), -// in which the linker does not fully coalesce symbols when dead code -// stripping is enabled. This bug causes the memory errors described above -// to occur even when a std::basic_string<> does not cross shared library -// boundaries, such as in statically-linked executables. -// -// TODO(mark): File this bug with Apple and update this note with a bug number. - -extern template -class BASE_EXPORT std::basic_string<base::char16, base::string16_char_traits>; - -#endif // WCHAR_T_IS_UTF32 - -#endif // BASE_STRINGS_STRING16_H_ diff --git a/security/sandbox/chromium/base/strings/string_number_conversions.cc b/security/sandbox/chromium/base/strings/string_number_conversions.cc deleted file mode 100644 index 07248501e..000000000 --- a/security/sandbox/chromium/base/strings/string_number_conversions.cc +++ /dev/null @@ -1,485 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/string_number_conversions.h" - -#include <ctype.h> -#include <errno.h> -#include <stdlib.h> -#include <wctype.h> - -#include <limits> - -#include "base/logging.h" -#include "base/numerics/safe_conversions.h" -#include "base/numerics/safe_math.h" -#include "base/scoped_clear_errno.h" -#include "base/strings/utf_string_conversions.h" -#include "base/third_party/dmg_fp/dmg_fp.h" - -namespace base { - -namespace { - -template <typename STR, typename INT> -struct IntToStringT { - static STR IntToString(INT value) { - // log10(2) ~= 0.3 bytes needed per bit or per byte log10(2**8) ~= 2.4. - // So round up to allocate 3 output characters per byte, plus 1 for '-'. - const size_t kOutputBufSize = - 3 * sizeof(INT) + std::numeric_limits<INT>::is_signed; - - // Create the string in a temporary buffer, write it back to front, and - // then return the substr of what we ended up using. - using CHR = typename STR::value_type; - CHR outbuf[kOutputBufSize]; - - // The ValueOrDie call below can never fail, because UnsignedAbs is valid - // for all valid inputs. - auto res = CheckedNumeric<INT>(value).UnsignedAbs().ValueOrDie(); - - CHR* end = outbuf + kOutputBufSize; - CHR* i = end; - do { - --i; - DCHECK(i != outbuf); - *i = static_cast<CHR>((res % 10) + '0'); - res /= 10; - } while (res != 0); - if (IsValueNegative(value)) { - --i; - DCHECK(i != outbuf); - *i = static_cast<CHR>('-'); - } - return STR(i, end); - } -}; - -// Utility to convert a character to a digit in a given base -template<typename CHAR, int BASE, bool BASE_LTE_10> class BaseCharToDigit { -}; - -// Faster specialization for bases <= 10 -template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, true> { - public: - static bool Convert(CHAR c, uint8_t* digit) { - if (c >= '0' && c < '0' + BASE) { - *digit = static_cast<uint8_t>(c - '0'); - return true; - } - return false; - } -}; - -// Specialization for bases where 10 < base <= 36 -template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, false> { - public: - static bool Convert(CHAR c, uint8_t* digit) { - if (c >= '0' && c <= '9') { - *digit = c - '0'; - } else if (c >= 'a' && c < 'a' + BASE - 10) { - *digit = c - 'a' + 10; - } else if (c >= 'A' && c < 'A' + BASE - 10) { - *digit = c - 'A' + 10; - } else { - return false; - } - return true; - } -}; - -template <int BASE, typename CHAR> -bool CharToDigit(CHAR c, uint8_t* digit) { - return BaseCharToDigit<CHAR, BASE, BASE <= 10>::Convert(c, digit); -} - -// There is an IsUnicodeWhitespace for wchars defined in string_util.h, but it -// is locale independent, whereas the functions we are replacing were -// locale-dependent. TBD what is desired, but for the moment let's not -// introduce a change in behaviour. -template<typename CHAR> class WhitespaceHelper { -}; - -template<> class WhitespaceHelper<char> { - public: - static bool Invoke(char c) { - return 0 != isspace(static_cast<unsigned char>(c)); - } -}; - -template<> class WhitespaceHelper<char16> { - public: - static bool Invoke(char16 c) { - return 0 != iswspace(c); - } -}; - -template<typename CHAR> bool LocalIsWhitespace(CHAR c) { - return WhitespaceHelper<CHAR>::Invoke(c); -} - -// IteratorRangeToNumberTraits should provide: -// - a typedef for iterator_type, the iterator type used as input. -// - a typedef for value_type, the target numeric type. -// - static functions min, max (returning the minimum and maximum permitted -// values) -// - constant kBase, the base in which to interpret the input -template<typename IteratorRangeToNumberTraits> -class IteratorRangeToNumber { - public: - typedef IteratorRangeToNumberTraits traits; - typedef typename traits::iterator_type const_iterator; - typedef typename traits::value_type value_type; - - // Generalized iterator-range-to-number conversion. - // - static bool Invoke(const_iterator begin, - const_iterator end, - value_type* output) { - bool valid = true; - - while (begin != end && LocalIsWhitespace(*begin)) { - valid = false; - ++begin; - } - - if (begin != end && *begin == '-') { - if (!std::numeric_limits<value_type>::is_signed) { - valid = false; - } else if (!Negative::Invoke(begin + 1, end, output)) { - valid = false; - } - } else { - if (begin != end && *begin == '+') { - ++begin; - } - if (!Positive::Invoke(begin, end, output)) { - valid = false; - } - } - - return valid; - } - - private: - // Sign provides: - // - a static function, CheckBounds, that determines whether the next digit - // causes an overflow/underflow - // - a static function, Increment, that appends the next digit appropriately - // according to the sign of the number being parsed. - template<typename Sign> - class Base { - public: - static bool Invoke(const_iterator begin, const_iterator end, - typename traits::value_type* output) { - *output = 0; - - if (begin == end) { - return false; - } - - // Note: no performance difference was found when using template - // specialization to remove this check in bases other than 16 - if (traits::kBase == 16 && end - begin > 2 && *begin == '0' && - (*(begin + 1) == 'x' || *(begin + 1) == 'X')) { - begin += 2; - } - - for (const_iterator current = begin; current != end; ++current) { - uint8_t new_digit = 0; - - if (!CharToDigit<traits::kBase>(*current, &new_digit)) { - return false; - } - - if (current != begin) { - if (!Sign::CheckBounds(output, new_digit)) { - return false; - } - *output *= traits::kBase; - } - - Sign::Increment(new_digit, output); - } - return true; - } - }; - - class Positive : public Base<Positive> { - public: - static bool CheckBounds(value_type* output, uint8_t new_digit) { - if (*output > static_cast<value_type>(traits::max() / traits::kBase) || - (*output == static_cast<value_type>(traits::max() / traits::kBase) && - new_digit > traits::max() % traits::kBase)) { - *output = traits::max(); - return false; - } - return true; - } - static void Increment(uint8_t increment, value_type* output) { - *output += increment; - } - }; - - class Negative : public Base<Negative> { - public: - static bool CheckBounds(value_type* output, uint8_t new_digit) { - if (*output < traits::min() / traits::kBase || - (*output == traits::min() / traits::kBase && - new_digit > 0 - traits::min() % traits::kBase)) { - *output = traits::min(); - return false; - } - return true; - } - static void Increment(uint8_t increment, value_type* output) { - *output -= increment; - } - }; -}; - -template<typename ITERATOR, typename VALUE, int BASE> -class BaseIteratorRangeToNumberTraits { - public: - typedef ITERATOR iterator_type; - typedef VALUE value_type; - static value_type min() { - return std::numeric_limits<value_type>::min(); - } - static value_type max() { - return std::numeric_limits<value_type>::max(); - } - static const int kBase = BASE; -}; - -template<typename ITERATOR> -class BaseHexIteratorRangeToIntTraits - : public BaseIteratorRangeToNumberTraits<ITERATOR, int, 16> { -}; - -template <typename ITERATOR> -class BaseHexIteratorRangeToUIntTraits - : public BaseIteratorRangeToNumberTraits<ITERATOR, uint32_t, 16> {}; - -template <typename ITERATOR> -class BaseHexIteratorRangeToInt64Traits - : public BaseIteratorRangeToNumberTraits<ITERATOR, int64_t, 16> {}; - -template <typename ITERATOR> -class BaseHexIteratorRangeToUInt64Traits - : public BaseIteratorRangeToNumberTraits<ITERATOR, uint64_t, 16> {}; - -typedef BaseHexIteratorRangeToIntTraits<StringPiece::const_iterator> - HexIteratorRangeToIntTraits; - -typedef BaseHexIteratorRangeToUIntTraits<StringPiece::const_iterator> - HexIteratorRangeToUIntTraits; - -typedef BaseHexIteratorRangeToInt64Traits<StringPiece::const_iterator> - HexIteratorRangeToInt64Traits; - -typedef BaseHexIteratorRangeToUInt64Traits<StringPiece::const_iterator> - HexIteratorRangeToUInt64Traits; - -template <typename STR> -bool HexStringToBytesT(const STR& input, std::vector<uint8_t>* output) { - DCHECK_EQ(output->size(), 0u); - size_t count = input.size(); - if (count == 0 || (count % 2) != 0) - return false; - for (uintptr_t i = 0; i < count / 2; ++i) { - uint8_t msb = 0; // most significant 4 bits - uint8_t lsb = 0; // least significant 4 bits - if (!CharToDigit<16>(input[i * 2], &msb) || - !CharToDigit<16>(input[i * 2 + 1], &lsb)) - return false; - output->push_back((msb << 4) | lsb); - } - return true; -} - -template <typename VALUE, int BASE> -class StringPieceToNumberTraits - : public BaseIteratorRangeToNumberTraits<StringPiece::const_iterator, - VALUE, - BASE> { -}; - -template <typename VALUE> -bool StringToIntImpl(const StringPiece& input, VALUE* output) { - return IteratorRangeToNumber<StringPieceToNumberTraits<VALUE, 10> >::Invoke( - input.begin(), input.end(), output); -} - -template <typename VALUE, int BASE> -class StringPiece16ToNumberTraits - : public BaseIteratorRangeToNumberTraits<StringPiece16::const_iterator, - VALUE, - BASE> { -}; - -template <typename VALUE> -bool String16ToIntImpl(const StringPiece16& input, VALUE* output) { - return IteratorRangeToNumber<StringPiece16ToNumberTraits<VALUE, 10> >::Invoke( - input.begin(), input.end(), output); -} - -} // namespace - -std::string IntToString(int value) { - return IntToStringT<std::string, int>::IntToString(value); -} - -string16 IntToString16(int value) { - return IntToStringT<string16, int>::IntToString(value); -} - -std::string UintToString(unsigned int value) { - return IntToStringT<std::string, unsigned int>::IntToString(value); -} - -string16 UintToString16(unsigned int value) { - return IntToStringT<string16, unsigned int>::IntToString(value); -} - -std::string Int64ToString(int64_t value) { - return IntToStringT<std::string, int64_t>::IntToString(value); -} - -string16 Int64ToString16(int64_t value) { - return IntToStringT<string16, int64_t>::IntToString(value); -} - -std::string Uint64ToString(uint64_t value) { - return IntToStringT<std::string, uint64_t>::IntToString(value); -} - -string16 Uint64ToString16(uint64_t value) { - return IntToStringT<string16, uint64_t>::IntToString(value); -} - -std::string SizeTToString(size_t value) { - return IntToStringT<std::string, size_t>::IntToString(value); -} - -string16 SizeTToString16(size_t value) { - return IntToStringT<string16, size_t>::IntToString(value); -} - -std::string DoubleToString(double value) { - // According to g_fmt.cc, it is sufficient to declare a buffer of size 32. - char buffer[32]; - dmg_fp::g_fmt(buffer, value); - return std::string(buffer); -} - -bool StringToInt(const StringPiece& input, int* output) { - return StringToIntImpl(input, output); -} - -bool StringToInt(const StringPiece16& input, int* output) { - return String16ToIntImpl(input, output); -} - -bool StringToUint(const StringPiece& input, unsigned* output) { - return StringToIntImpl(input, output); -} - -bool StringToUint(const StringPiece16& input, unsigned* output) { - return String16ToIntImpl(input, output); -} - -bool StringToInt64(const StringPiece& input, int64_t* output) { - return StringToIntImpl(input, output); -} - -bool StringToInt64(const StringPiece16& input, int64_t* output) { - return String16ToIntImpl(input, output); -} - -bool StringToUint64(const StringPiece& input, uint64_t* output) { - return StringToIntImpl(input, output); -} - -bool StringToUint64(const StringPiece16& input, uint64_t* output) { - return String16ToIntImpl(input, output); -} - -bool StringToSizeT(const StringPiece& input, size_t* output) { - return StringToIntImpl(input, output); -} - -bool StringToSizeT(const StringPiece16& input, size_t* output) { - return String16ToIntImpl(input, output); -} - -bool StringToDouble(const std::string& input, double* output) { - // Thread-safe? It is on at least Mac, Linux, and Windows. - ScopedClearErrno clear_errno; - - char* endptr = NULL; - *output = dmg_fp::strtod(input.c_str(), &endptr); - - // Cases to return false: - // - If errno is ERANGE, there was an overflow or underflow. - // - If the input string is empty, there was nothing to parse. - // - If endptr does not point to the end of the string, there are either - // characters remaining in the string after a parsed number, or the string - // does not begin with a parseable number. endptr is compared to the - // expected end given the string's stated length to correctly catch cases - // where the string contains embedded NUL characters. - // - If the first character is a space, there was leading whitespace - return errno == 0 && - !input.empty() && - input.c_str() + input.length() == endptr && - !isspace(input[0]); -} - -// Note: if you need to add String16ToDouble, first ask yourself if it's -// really necessary. If it is, probably the best implementation here is to -// convert to 8-bit and then use the 8-bit version. - -// Note: if you need to add an iterator range version of StringToDouble, first -// ask yourself if it's really necessary. If it is, probably the best -// implementation here is to instantiate a string and use the string version. - -std::string HexEncode(const void* bytes, size_t size) { - static const char kHexChars[] = "0123456789ABCDEF"; - - // Each input byte creates two output hex characters. - std::string ret(size * 2, '\0'); - - for (size_t i = 0; i < size; ++i) { - char b = reinterpret_cast<const char*>(bytes)[i]; - ret[(i * 2)] = kHexChars[(b >> 4) & 0xf]; - ret[(i * 2) + 1] = kHexChars[b & 0xf]; - } - return ret; -} - -bool HexStringToInt(const StringPiece& input, int* output) { - return IteratorRangeToNumber<HexIteratorRangeToIntTraits>::Invoke( - input.begin(), input.end(), output); -} - -bool HexStringToUInt(const StringPiece& input, uint32_t* output) { - return IteratorRangeToNumber<HexIteratorRangeToUIntTraits>::Invoke( - input.begin(), input.end(), output); -} - -bool HexStringToInt64(const StringPiece& input, int64_t* output) { - return IteratorRangeToNumber<HexIteratorRangeToInt64Traits>::Invoke( - input.begin(), input.end(), output); -} - -bool HexStringToUInt64(const StringPiece& input, uint64_t* output) { - return IteratorRangeToNumber<HexIteratorRangeToUInt64Traits>::Invoke( - input.begin(), input.end(), output); -} - -bool HexStringToBytes(const std::string& input, std::vector<uint8_t>* output) { - return HexStringToBytesT(input, output); -} - -} // namespace base diff --git a/security/sandbox/chromium/base/strings/string_number_conversions.h b/security/sandbox/chromium/base/strings/string_number_conversions.h deleted file mode 100644 index 1265f0dcb..000000000 --- a/security/sandbox/chromium/base/strings/string_number_conversions.h +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_STRINGS_STRING_NUMBER_CONVERSIONS_H_ -#define BASE_STRINGS_STRING_NUMBER_CONVERSIONS_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <string> -#include <vector> - -#include "base/base_export.h" -#include "base/strings/string16.h" -#include "base/strings/string_piece.h" - -// ---------------------------------------------------------------------------- -// IMPORTANT MESSAGE FROM YOUR SPONSOR -// -// This file contains no "wstring" variants. New code should use string16. If -// you need to make old code work, use the UTF8 version and convert. Please do -// not add wstring variants. -// -// Please do not add "convenience" functions for converting strings to integers -// that return the value and ignore success/failure. That encourages people to -// write code that doesn't properly handle the error conditions. -// ---------------------------------------------------------------------------- - -namespace base { - -// Number -> string conversions ------------------------------------------------ - -BASE_EXPORT std::string IntToString(int value); -BASE_EXPORT string16 IntToString16(int value); - -BASE_EXPORT std::string UintToString(unsigned value); -BASE_EXPORT string16 UintToString16(unsigned value); - -BASE_EXPORT std::string Int64ToString(int64_t value); -BASE_EXPORT string16 Int64ToString16(int64_t value); - -BASE_EXPORT std::string Uint64ToString(uint64_t value); -BASE_EXPORT string16 Uint64ToString16(uint64_t value); - -BASE_EXPORT std::string SizeTToString(size_t value); -BASE_EXPORT string16 SizeTToString16(size_t value); - -// DoubleToString converts the double to a string format that ignores the -// locale. If you want to use locale specific formatting, use ICU. -BASE_EXPORT std::string DoubleToString(double value); - -// String -> number conversions ------------------------------------------------ - -// Perform a best-effort conversion of the input string to a numeric type, -// setting |*output| to the result of the conversion. Returns true for -// "perfect" conversions; returns false in the following cases: -// - Overflow. |*output| will be set to the maximum value supported -// by the data type. -// - Underflow. |*output| will be set to the minimum value supported -// by the data type. -// - Trailing characters in the string after parsing the number. |*output| -// will be set to the value of the number that was parsed. -// - Leading whitespace in the string before parsing the number. |*output| will -// be set to the value of the number that was parsed. -// - No characters parseable as a number at the beginning of the string. -// |*output| will be set to 0. -// - Empty string. |*output| will be set to 0. -// WARNING: Will write to |output| even when returning false. -// Read the comments above carefully. -BASE_EXPORT bool StringToInt(const StringPiece& input, int* output); -BASE_EXPORT bool StringToInt(const StringPiece16& input, int* output); - -BASE_EXPORT bool StringToUint(const StringPiece& input, unsigned* output); -BASE_EXPORT bool StringToUint(const StringPiece16& input, unsigned* output); - -BASE_EXPORT bool StringToInt64(const StringPiece& input, int64_t* output); -BASE_EXPORT bool StringToInt64(const StringPiece16& input, int64_t* output); - -BASE_EXPORT bool StringToUint64(const StringPiece& input, uint64_t* output); -BASE_EXPORT bool StringToUint64(const StringPiece16& input, uint64_t* output); - -BASE_EXPORT bool StringToSizeT(const StringPiece& input, size_t* output); -BASE_EXPORT bool StringToSizeT(const StringPiece16& input, size_t* output); - -// For floating-point conversions, only conversions of input strings in decimal -// form are defined to work. Behavior with strings representing floating-point -// numbers in hexadecimal, and strings representing non-finite values (such as -// NaN and inf) is undefined. Otherwise, these behave the same as the integral -// variants. This expects the input string to NOT be specific to the locale. -// If your input is locale specific, use ICU to read the number. -// WARNING: Will write to |output| even when returning false. -// Read the comments here and above StringToInt() carefully. -BASE_EXPORT bool StringToDouble(const std::string& input, double* output); - -// Hex encoding ---------------------------------------------------------------- - -// Returns a hex string representation of a binary buffer. The returned hex -// string will be in upper case. This function does not check if |size| is -// within reasonable limits since it's written with trusted data in mind. If -// you suspect that the data you want to format might be large, the absolute -// max size for |size| should be is -// std::numeric_limits<size_t>::max() / 2 -BASE_EXPORT std::string HexEncode(const void* bytes, size_t size); - -// Best effort conversion, see StringToInt above for restrictions. -// Will only successful parse hex values that will fit into |output|, i.e. -// -0x80000000 < |input| < 0x7FFFFFFF. -BASE_EXPORT bool HexStringToInt(const StringPiece& input, int* output); - -// Best effort conversion, see StringToInt above for restrictions. -// Will only successful parse hex values that will fit into |output|, i.e. -// 0x00000000 < |input| < 0xFFFFFFFF. -// The string is not required to start with 0x. -BASE_EXPORT bool HexStringToUInt(const StringPiece& input, uint32_t* output); - -// Best effort conversion, see StringToInt above for restrictions. -// Will only successful parse hex values that will fit into |output|, i.e. -// -0x8000000000000000 < |input| < 0x7FFFFFFFFFFFFFFF. -BASE_EXPORT bool HexStringToInt64(const StringPiece& input, int64_t* output); - -// Best effort conversion, see StringToInt above for restrictions. -// Will only successful parse hex values that will fit into |output|, i.e. -// 0x0000000000000000 < |input| < 0xFFFFFFFFFFFFFFFF. -// The string is not required to start with 0x. -BASE_EXPORT bool HexStringToUInt64(const StringPiece& input, uint64_t* output); - -// Similar to the previous functions, except that output is a vector of bytes. -// |*output| will contain as many bytes as were successfully parsed prior to the -// error. There is no overflow, but input.size() must be evenly divisible by 2. -// Leading 0x or +/- are not allowed. -BASE_EXPORT bool HexStringToBytes(const std::string& input, - std::vector<uint8_t>* output); - -} // namespace base - -#endif // BASE_STRINGS_STRING_NUMBER_CONVERSIONS_H_ diff --git a/security/sandbox/chromium/base/strings/string_piece.cc b/security/sandbox/chromium/base/strings/string_piece.cc deleted file mode 100644 index c26bb3652..000000000 --- a/security/sandbox/chromium/base/strings/string_piece.cc +++ /dev/null @@ -1,452 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// Copied from strings/stringpiece.cc with modifications - -#include "base/strings/string_piece.h" - -#include <limits.h> - -#include <algorithm> -#include <ostream> - -#include "base/logging.h" - -namespace base { -namespace { - -// For each character in characters_wanted, sets the index corresponding -// to the ASCII code of that character to 1 in table. This is used by -// the find_.*_of methods below to tell whether or not a character is in -// the lookup table in constant time. -// The argument `table' must be an array that is large enough to hold all -// the possible values of an unsigned char. Thus it should be be declared -// as follows: -// bool table[UCHAR_MAX + 1] -inline void BuildLookupTable(const StringPiece& characters_wanted, - bool* table) { - const size_t length = characters_wanted.length(); - const char* const data = characters_wanted.data(); - for (size_t i = 0; i < length; ++i) { - table[static_cast<unsigned char>(data[i])] = true; - } -} - -} // namespace - -// MSVC doesn't like complex extern templates and DLLs. -#if !defined(COMPILER_MSVC) -template class BasicStringPiece<std::string>; -template class BasicStringPiece<string16>; -#endif - -bool operator==(const StringPiece& x, const StringPiece& y) { - if (x.size() != y.size()) - return false; - - return StringPiece::wordmemcmp(x.data(), y.data(), x.size()) == 0; -} - -std::ostream& operator<<(std::ostream& o, const StringPiece& piece) { - o.write(piece.data(), static_cast<std::streamsize>(piece.size())); - return o; -} - -namespace internal { - -template<typename STR> -void CopyToStringT(const BasicStringPiece<STR>& self, STR* target) { - if (self.empty()) - target->clear(); - else - target->assign(self.data(), self.size()); -} - -void CopyToString(const StringPiece& self, std::string* target) { - CopyToStringT(self, target); -} - -void CopyToString(const StringPiece16& self, string16* target) { - CopyToStringT(self, target); -} - -template<typename STR> -void AppendToStringT(const BasicStringPiece<STR>& self, STR* target) { - if (!self.empty()) - target->append(self.data(), self.size()); -} - -void AppendToString(const StringPiece& self, std::string* target) { - AppendToStringT(self, target); -} - -void AppendToString(const StringPiece16& self, string16* target) { - AppendToStringT(self, target); -} - -template<typename STR> -size_t copyT(const BasicStringPiece<STR>& self, - typename STR::value_type* buf, - size_t n, - size_t pos) { - size_t ret = std::min(self.size() - pos, n); - memcpy(buf, self.data() + pos, ret * sizeof(typename STR::value_type)); - return ret; -} - -size_t copy(const StringPiece& self, char* buf, size_t n, size_t pos) { - return copyT(self, buf, n, pos); -} - -size_t copy(const StringPiece16& self, char16* buf, size_t n, size_t pos) { - return copyT(self, buf, n, pos); -} - -template<typename STR> -size_t findT(const BasicStringPiece<STR>& self, - const BasicStringPiece<STR>& s, - size_t pos) { - if (pos > self.size()) - return BasicStringPiece<STR>::npos; - - typename BasicStringPiece<STR>::const_iterator result = - std::search(self.begin() + pos, self.end(), s.begin(), s.end()); - const size_t xpos = - static_cast<size_t>(result - self.begin()); - return xpos + s.size() <= self.size() ? xpos : BasicStringPiece<STR>::npos; -} - -size_t find(const StringPiece& self, const StringPiece& s, size_t pos) { - return findT(self, s, pos); -} - -size_t find(const StringPiece16& self, const StringPiece16& s, size_t pos) { - return findT(self, s, pos); -} - -template<typename STR> -size_t findT(const BasicStringPiece<STR>& self, - typename STR::value_type c, - size_t pos) { - if (pos >= self.size()) - return BasicStringPiece<STR>::npos; - - typename BasicStringPiece<STR>::const_iterator result = - std::find(self.begin() + pos, self.end(), c); - return result != self.end() ? - static_cast<size_t>(result - self.begin()) : BasicStringPiece<STR>::npos; -} - -size_t find(const StringPiece& self, char c, size_t pos) { - return findT(self, c, pos); -} - -size_t find(const StringPiece16& self, char16 c, size_t pos) { - return findT(self, c, pos); -} - -template<typename STR> -size_t rfindT(const BasicStringPiece<STR>& self, - const BasicStringPiece<STR>& s, - size_t pos) { - if (self.size() < s.size()) - return BasicStringPiece<STR>::npos; - - if (s.empty()) - return std::min(self.size(), pos); - - typename BasicStringPiece<STR>::const_iterator last = - self.begin() + std::min(self.size() - s.size(), pos) + s.size(); - typename BasicStringPiece<STR>::const_iterator result = - std::find_end(self.begin(), last, s.begin(), s.end()); - return result != last ? - static_cast<size_t>(result - self.begin()) : BasicStringPiece<STR>::npos; -} - -size_t rfind(const StringPiece& self, const StringPiece& s, size_t pos) { - return rfindT(self, s, pos); -} - -size_t rfind(const StringPiece16& self, const StringPiece16& s, size_t pos) { - return rfindT(self, s, pos); -} - -template<typename STR> -size_t rfindT(const BasicStringPiece<STR>& self, - typename STR::value_type c, - size_t pos) { - if (self.size() == 0) - return BasicStringPiece<STR>::npos; - - for (size_t i = std::min(pos, self.size() - 1); ; - --i) { - if (self.data()[i] == c) - return i; - if (i == 0) - break; - } - return BasicStringPiece<STR>::npos; -} - -size_t rfind(const StringPiece& self, char c, size_t pos) { - return rfindT(self, c, pos); -} - -size_t rfind(const StringPiece16& self, char16 c, size_t pos) { - return rfindT(self, c, pos); -} - -// 8-bit version using lookup table. -size_t find_first_of(const StringPiece& self, - const StringPiece& s, - size_t pos) { - if (self.size() == 0 || s.size() == 0) - return StringPiece::npos; - - // Avoid the cost of BuildLookupTable() for a single-character search. - if (s.size() == 1) - return find(self, s.data()[0], pos); - - bool lookup[UCHAR_MAX + 1] = { false }; - BuildLookupTable(s, lookup); - for (size_t i = pos; i < self.size(); ++i) { - if (lookup[static_cast<unsigned char>(self.data()[i])]) { - return i; - } - } - return StringPiece::npos; -} - -// 16-bit brute force version. -size_t find_first_of(const StringPiece16& self, - const StringPiece16& s, - size_t pos) { - StringPiece16::const_iterator found = - std::find_first_of(self.begin() + pos, self.end(), s.begin(), s.end()); - if (found == self.end()) - return StringPiece16::npos; - return found - self.begin(); -} - -// 8-bit version using lookup table. -size_t find_first_not_of(const StringPiece& self, - const StringPiece& s, - size_t pos) { - if (self.size() == 0) - return StringPiece::npos; - - if (s.size() == 0) - return 0; - - // Avoid the cost of BuildLookupTable() for a single-character search. - if (s.size() == 1) - return find_first_not_of(self, s.data()[0], pos); - - bool lookup[UCHAR_MAX + 1] = { false }; - BuildLookupTable(s, lookup); - for (size_t i = pos; i < self.size(); ++i) { - if (!lookup[static_cast<unsigned char>(self.data()[i])]) { - return i; - } - } - return StringPiece::npos; -} - -// 16-bit brute-force version. -BASE_EXPORT size_t find_first_not_of(const StringPiece16& self, - const StringPiece16& s, - size_t pos) { - if (self.size() == 0) - return StringPiece16::npos; - - for (size_t self_i = pos; self_i < self.size(); ++self_i) { - bool found = false; - for (size_t s_i = 0; s_i < s.size(); ++s_i) { - if (self[self_i] == s[s_i]) { - found = true; - break; - } - } - if (!found) - return self_i; - } - return StringPiece16::npos; -} - -template<typename STR> -size_t find_first_not_ofT(const BasicStringPiece<STR>& self, - typename STR::value_type c, - size_t pos) { - if (self.size() == 0) - return BasicStringPiece<STR>::npos; - - for (; pos < self.size(); ++pos) { - if (self.data()[pos] != c) { - return pos; - } - } - return BasicStringPiece<STR>::npos; -} - -size_t find_first_not_of(const StringPiece& self, - char c, - size_t pos) { - return find_first_not_ofT(self, c, pos); -} - -size_t find_first_not_of(const StringPiece16& self, - char16 c, - size_t pos) { - return find_first_not_ofT(self, c, pos); -} - -// 8-bit version using lookup table. -size_t find_last_of(const StringPiece& self, const StringPiece& s, size_t pos) { - if (self.size() == 0 || s.size() == 0) - return StringPiece::npos; - - // Avoid the cost of BuildLookupTable() for a single-character search. - if (s.size() == 1) - return rfind(self, s.data()[0], pos); - - bool lookup[UCHAR_MAX + 1] = { false }; - BuildLookupTable(s, lookup); - for (size_t i = std::min(pos, self.size() - 1); ; --i) { - if (lookup[static_cast<unsigned char>(self.data()[i])]) - return i; - if (i == 0) - break; - } - return StringPiece::npos; -} - -// 16-bit brute-force version. -size_t find_last_of(const StringPiece16& self, - const StringPiece16& s, - size_t pos) { - if (self.size() == 0) - return StringPiece16::npos; - - for (size_t self_i = std::min(pos, self.size() - 1); ; - --self_i) { - for (size_t s_i = 0; s_i < s.size(); s_i++) { - if (self.data()[self_i] == s[s_i]) - return self_i; - } - if (self_i == 0) - break; - } - return StringPiece16::npos; -} - -// 8-bit version using lookup table. -size_t find_last_not_of(const StringPiece& self, - const StringPiece& s, - size_t pos) { - if (self.size() == 0) - return StringPiece::npos; - - size_t i = std::min(pos, self.size() - 1); - if (s.size() == 0) - return i; - - // Avoid the cost of BuildLookupTable() for a single-character search. - if (s.size() == 1) - return find_last_not_of(self, s.data()[0], pos); - - bool lookup[UCHAR_MAX + 1] = { false }; - BuildLookupTable(s, lookup); - for (; ; --i) { - if (!lookup[static_cast<unsigned char>(self.data()[i])]) - return i; - if (i == 0) - break; - } - return StringPiece::npos; -} - -// 16-bit brute-force version. -size_t find_last_not_of(const StringPiece16& self, - const StringPiece16& s, - size_t pos) { - if (self.size() == 0) - return StringPiece::npos; - - for (size_t self_i = std::min(pos, self.size() - 1); ; --self_i) { - bool found = false; - for (size_t s_i = 0; s_i < s.size(); s_i++) { - if (self.data()[self_i] == s[s_i]) { - found = true; - break; - } - } - if (!found) - return self_i; - if (self_i == 0) - break; - } - return StringPiece16::npos; -} - -template<typename STR> -size_t find_last_not_ofT(const BasicStringPiece<STR>& self, - typename STR::value_type c, - size_t pos) { - if (self.size() == 0) - return BasicStringPiece<STR>::npos; - - for (size_t i = std::min(pos, self.size() - 1); ; --i) { - if (self.data()[i] != c) - return i; - if (i == 0) - break; - } - return BasicStringPiece<STR>::npos; -} - -size_t find_last_not_of(const StringPiece& self, - char c, - size_t pos) { - return find_last_not_ofT(self, c, pos); -} - -size_t find_last_not_of(const StringPiece16& self, - char16 c, - size_t pos) { - return find_last_not_ofT(self, c, pos); -} - -template<typename STR> -BasicStringPiece<STR> substrT(const BasicStringPiece<STR>& self, - size_t pos, - size_t n) { - if (pos > self.size()) pos = self.size(); - if (n > self.size() - pos) n = self.size() - pos; - return BasicStringPiece<STR>(self.data() + pos, n); -} - -StringPiece substr(const StringPiece& self, - size_t pos, - size_t n) { - return substrT(self, pos, n); -} - -StringPiece16 substr(const StringPiece16& self, - size_t pos, - size_t n) { - return substrT(self, pos, n); -} - -#if DCHECK_IS_ON() -void AssertIteratorsInOrder(std::string::const_iterator begin, - std::string::const_iterator end) { - DCHECK(begin <= end) << "StringPiece iterators swapped or invalid."; -} -void AssertIteratorsInOrder(string16::const_iterator begin, - string16::const_iterator end) { - DCHECK(begin <= end) << "StringPiece iterators swapped or invalid."; -} -#endif - -} // namespace internal -} // namespace base diff --git a/security/sandbox/chromium/base/strings/string_piece.h b/security/sandbox/chromium/base/strings/string_piece.h deleted file mode 100644 index 31e7596d1..000000000 --- a/security/sandbox/chromium/base/strings/string_piece.h +++ /dev/null @@ -1,469 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// Copied from strings/stringpiece.h with modifications -// -// A string-like object that points to a sized piece of memory. -// -// You can use StringPiece as a function or method parameter. A StringPiece -// parameter can receive a double-quoted string literal argument, a "const -// char*" argument, a string argument, or a StringPiece argument with no data -// copying. Systematic use of StringPiece for arguments reduces data -// copies and strlen() calls. -// -// Prefer passing StringPieces by value: -// void MyFunction(StringPiece arg); -// If circumstances require, you may also pass by const reference: -// void MyFunction(const StringPiece& arg); // not preferred -// Both of these have the same lifetime semantics. Passing by value -// generates slightly smaller code. For more discussion, Googlers can see -// the thread go/stringpiecebyvalue on c-users. - -#ifndef BASE_STRINGS_STRING_PIECE_H_ -#define BASE_STRINGS_STRING_PIECE_H_ - -#include <stddef.h> - -#include <iosfwd> -#include <string> - -#include "base/base_export.h" -#include "base/containers/hash_tables.h" -#include "base/logging.h" -#include "base/strings/string16.h" - -namespace base { - -template <typename STRING_TYPE> class BasicStringPiece; -typedef BasicStringPiece<std::string> StringPiece; -typedef BasicStringPiece<string16> StringPiece16; - -// internal -------------------------------------------------------------------- - -// Many of the StringPiece functions use different implementations for the -// 8-bit and 16-bit versions, and we don't want lots of template expansions in -// this (very common) header that will slow down compilation. -// -// So here we define overloaded functions called by the StringPiece template. -// For those that share an implementation, the two versions will expand to a -// template internal to the .cc file. -namespace internal { - -BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target); -BASE_EXPORT void CopyToString(const StringPiece16& self, string16* target); - -BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target); -BASE_EXPORT void AppendToString(const StringPiece16& self, string16* target); - -BASE_EXPORT size_t copy(const StringPiece& self, - char* buf, - size_t n, - size_t pos); -BASE_EXPORT size_t copy(const StringPiece16& self, - char16* buf, - size_t n, - size_t pos); - -BASE_EXPORT size_t find(const StringPiece& self, - const StringPiece& s, - size_t pos); -BASE_EXPORT size_t find(const StringPiece16& self, - const StringPiece16& s, - size_t pos); -BASE_EXPORT size_t find(const StringPiece& self, - char c, - size_t pos); -BASE_EXPORT size_t find(const StringPiece16& self, - char16 c, - size_t pos); - -BASE_EXPORT size_t rfind(const StringPiece& self, - const StringPiece& s, - size_t pos); -BASE_EXPORT size_t rfind(const StringPiece16& self, - const StringPiece16& s, - size_t pos); -BASE_EXPORT size_t rfind(const StringPiece& self, - char c, - size_t pos); -BASE_EXPORT size_t rfind(const StringPiece16& self, - char16 c, - size_t pos); - -BASE_EXPORT size_t find_first_of(const StringPiece& self, - const StringPiece& s, - size_t pos); -BASE_EXPORT size_t find_first_of(const StringPiece16& self, - const StringPiece16& s, - size_t pos); - -BASE_EXPORT size_t find_first_not_of(const StringPiece& self, - const StringPiece& s, - size_t pos); -BASE_EXPORT size_t find_first_not_of(const StringPiece16& self, - const StringPiece16& s, - size_t pos); -BASE_EXPORT size_t find_first_not_of(const StringPiece& self, - char c, - size_t pos); -BASE_EXPORT size_t find_first_not_of(const StringPiece16& self, - char16 c, - size_t pos); - -BASE_EXPORT size_t find_last_of(const StringPiece& self, - const StringPiece& s, - size_t pos); -BASE_EXPORT size_t find_last_of(const StringPiece16& self, - const StringPiece16& s, - size_t pos); -BASE_EXPORT size_t find_last_of(const StringPiece& self, - char c, - size_t pos); -BASE_EXPORT size_t find_last_of(const StringPiece16& self, - char16 c, - size_t pos); - -BASE_EXPORT size_t find_last_not_of(const StringPiece& self, - const StringPiece& s, - size_t pos); -BASE_EXPORT size_t find_last_not_of(const StringPiece16& self, - const StringPiece16& s, - size_t pos); -BASE_EXPORT size_t find_last_not_of(const StringPiece16& self, - char16 c, - size_t pos); -BASE_EXPORT size_t find_last_not_of(const StringPiece& self, - char c, - size_t pos); - -BASE_EXPORT StringPiece substr(const StringPiece& self, - size_t pos, - size_t n); -BASE_EXPORT StringPiece16 substr(const StringPiece16& self, - size_t pos, - size_t n); - -#if DCHECK_IS_ON() -// Asserts that begin <= end to catch some errors with iterator usage. -BASE_EXPORT void AssertIteratorsInOrder(std::string::const_iterator begin, - std::string::const_iterator end); -BASE_EXPORT void AssertIteratorsInOrder(string16::const_iterator begin, - string16::const_iterator end); -#endif - -} // namespace internal - -// BasicStringPiece ------------------------------------------------------------ - -// Defines the types, methods, operators, and data members common to both -// StringPiece and StringPiece16. Do not refer to this class directly, but -// rather to BasicStringPiece, StringPiece, or StringPiece16. -// -// This is templatized by string class type rather than character type, so -// BasicStringPiece<std::string> or BasicStringPiece<base::string16>. -template <typename STRING_TYPE> class BasicStringPiece { - public: - // Standard STL container boilerplate. - typedef size_t size_type; - typedef typename STRING_TYPE::value_type value_type; - typedef const value_type* pointer; - typedef const value_type& reference; - typedef const value_type& const_reference; - typedef ptrdiff_t difference_type; - typedef const value_type* const_iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - - static const size_type npos; - - public: - // We provide non-explicit singleton constructors so users can pass - // in a "const char*" or a "string" wherever a "StringPiece" is - // expected (likewise for char16, string16, StringPiece16). - BasicStringPiece() : ptr_(NULL), length_(0) {} - BasicStringPiece(const value_type* str) - : ptr_(str), - length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {} - BasicStringPiece(const STRING_TYPE& str) - : ptr_(str.data()), length_(str.size()) {} - BasicStringPiece(const value_type* offset, size_type len) - : ptr_(offset), length_(len) {} - BasicStringPiece(const typename STRING_TYPE::const_iterator& begin, - const typename STRING_TYPE::const_iterator& end) { -#if DCHECK_IS_ON() - // This assertion is done out-of-line to avoid bringing in logging.h and - // instantiating logging macros for every instantiation. - internal::AssertIteratorsInOrder(begin, end); -#endif - length_ = static_cast<size_t>(std::distance(begin, end)); - - // The length test before assignment is to avoid dereferencing an iterator - // that may point to the end() of a string. - ptr_ = length_ > 0 ? &*begin : nullptr; - } - - // data() may return a pointer to a buffer with embedded NULs, and the - // returned buffer may or may not be null terminated. Therefore it is - // typically a mistake to pass data() to a routine that expects a NUL - // terminated string. - const value_type* data() const { return ptr_; } - size_type size() const { return length_; } - size_type length() const { return length_; } - bool empty() const { return length_ == 0; } - - void clear() { - ptr_ = NULL; - length_ = 0; - } - void set(const value_type* data, size_type len) { - ptr_ = data; - length_ = len; - } - void set(const value_type* str) { - ptr_ = str; - length_ = str ? STRING_TYPE::traits_type::length(str) : 0; - } - - value_type operator[](size_type i) const { return ptr_[i]; } - - void remove_prefix(size_type n) { - ptr_ += n; - length_ -= n; - } - - void remove_suffix(size_type n) { - length_ -= n; - } - - int compare(const BasicStringPiece<STRING_TYPE>& x) const { - int r = wordmemcmp( - ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_)); - if (r == 0) { - if (length_ < x.length_) r = -1; - else if (length_ > x.length_) r = +1; - } - return r; - } - - STRING_TYPE as_string() const { - // std::string doesn't like to take a NULL pointer even with a 0 size. - return empty() ? STRING_TYPE() : STRING_TYPE(data(), size()); - } - - const_iterator begin() const { return ptr_; } - const_iterator end() const { return ptr_ + length_; } - const_reverse_iterator rbegin() const { - return const_reverse_iterator(ptr_ + length_); - } - const_reverse_iterator rend() const { - return const_reverse_iterator(ptr_); - } - - size_type max_size() const { return length_; } - size_type capacity() const { return length_; } - - static int wordmemcmp(const value_type* p, - const value_type* p2, - size_type N) { - return STRING_TYPE::traits_type::compare(p, p2, N); - } - - // Sets the value of the given string target type to be the current string. - // This saves a temporary over doing |a = b.as_string()| - void CopyToString(STRING_TYPE* target) const { - internal::CopyToString(*this, target); - } - - void AppendToString(STRING_TYPE* target) const { - internal::AppendToString(*this, target); - } - - size_type copy(value_type* buf, size_type n, size_type pos = 0) const { - return internal::copy(*this, buf, n, pos); - } - - // Does "this" start with "x" - bool starts_with(const BasicStringPiece& x) const { - return ((this->length_ >= x.length_) && - (wordmemcmp(this->ptr_, x.ptr_, x.length_) == 0)); - } - - // Does "this" end with "x" - bool ends_with(const BasicStringPiece& x) const { - return ((this->length_ >= x.length_) && - (wordmemcmp(this->ptr_ + (this->length_-x.length_), - x.ptr_, x.length_) == 0)); - } - - // find: Search for a character or substring at a given offset. - size_type find(const BasicStringPiece<STRING_TYPE>& s, - size_type pos = 0) const { - return internal::find(*this, s, pos); - } - size_type find(value_type c, size_type pos = 0) const { - return internal::find(*this, c, pos); - } - - // rfind: Reverse find. - size_type rfind(const BasicStringPiece& s, - size_type pos = BasicStringPiece::npos) const { - return internal::rfind(*this, s, pos); - } - size_type rfind(value_type c, size_type pos = BasicStringPiece::npos) const { - return internal::rfind(*this, c, pos); - } - - // find_first_of: Find the first occurence of one of a set of characters. - size_type find_first_of(const BasicStringPiece& s, - size_type pos = 0) const { - return internal::find_first_of(*this, s, pos); - } - size_type find_first_of(value_type c, size_type pos = 0) const { - return find(c, pos); - } - - // find_first_not_of: Find the first occurence not of a set of characters. - size_type find_first_not_of(const BasicStringPiece& s, - size_type pos = 0) const { - return internal::find_first_not_of(*this, s, pos); - } - size_type find_first_not_of(value_type c, size_type pos = 0) const { - return internal::find_first_not_of(*this, c, pos); - } - - // find_last_of: Find the last occurence of one of a set of characters. - size_type find_last_of(const BasicStringPiece& s, - size_type pos = BasicStringPiece::npos) const { - return internal::find_last_of(*this, s, pos); - } - size_type find_last_of(value_type c, - size_type pos = BasicStringPiece::npos) const { - return rfind(c, pos); - } - - // find_last_not_of: Find the last occurence not of a set of characters. - size_type find_last_not_of(const BasicStringPiece& s, - size_type pos = BasicStringPiece::npos) const { - return internal::find_last_not_of(*this, s, pos); - } - size_type find_last_not_of(value_type c, - size_type pos = BasicStringPiece::npos) const { - return internal::find_last_not_of(*this, c, pos); - } - - // substr. - BasicStringPiece substr(size_type pos, - size_type n = BasicStringPiece::npos) const { - return internal::substr(*this, pos, n); - } - - protected: - const value_type* ptr_; - size_type length_; -}; - -template <typename STRING_TYPE> -const typename BasicStringPiece<STRING_TYPE>::size_type -BasicStringPiece<STRING_TYPE>::npos = - typename BasicStringPiece<STRING_TYPE>::size_type(-1); - -// MSVC doesn't like complex extern templates and DLLs. -#if !defined(COMPILER_MSVC) -extern template class BASE_EXPORT BasicStringPiece<std::string>; -extern template class BASE_EXPORT BasicStringPiece<string16>; -#endif - -// StingPiece operators -------------------------------------------------------- - -BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y); - -inline bool operator!=(const StringPiece& x, const StringPiece& y) { - return !(x == y); -} - -inline bool operator<(const StringPiece& x, const StringPiece& y) { - const int r = StringPiece::wordmemcmp( - x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); - return ((r < 0) || ((r == 0) && (x.size() < y.size()))); -} - -inline bool operator>(const StringPiece& x, const StringPiece& y) { - return y < x; -} - -inline bool operator<=(const StringPiece& x, const StringPiece& y) { - return !(x > y); -} - -inline bool operator>=(const StringPiece& x, const StringPiece& y) { - return !(x < y); -} - -// StringPiece16 operators ----------------------------------------------------- - -inline bool operator==(const StringPiece16& x, const StringPiece16& y) { - if (x.size() != y.size()) - return false; - - return StringPiece16::wordmemcmp(x.data(), y.data(), x.size()) == 0; -} - -inline bool operator!=(const StringPiece16& x, const StringPiece16& y) { - return !(x == y); -} - -inline bool operator<(const StringPiece16& x, const StringPiece16& y) { - const int r = StringPiece16::wordmemcmp( - x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); - return ((r < 0) || ((r == 0) && (x.size() < y.size()))); -} - -inline bool operator>(const StringPiece16& x, const StringPiece16& y) { - return y < x; -} - -inline bool operator<=(const StringPiece16& x, const StringPiece16& y) { - return !(x > y); -} - -inline bool operator>=(const StringPiece16& x, const StringPiece16& y) { - return !(x < y); -} - -BASE_EXPORT std::ostream& operator<<(std::ostream& o, - const StringPiece& piece); - -} // namespace base - -// Hashing --------------------------------------------------------------------- - -// We provide appropriate hash functions so StringPiece and StringPiece16 can -// be used as keys in hash sets and maps. - -// This hash function is copied from base/containers/hash_tables.h. We don't -// use the ones already defined for string and string16 directly because it -// would require the string constructors to be called, which we don't want. -#define HASH_STRING_PIECE(StringPieceType, string_piece) \ - std::size_t result = 0; \ - for (StringPieceType::const_iterator i = string_piece.begin(); \ - i != string_piece.end(); ++i) \ - result = (result * 131) + *i; \ - return result; \ - -namespace BASE_HASH_NAMESPACE { - -template<> -struct hash<base::StringPiece> { - std::size_t operator()(const base::StringPiece& sp) const { - HASH_STRING_PIECE(base::StringPiece, sp); - } -}; -template<> -struct hash<base::StringPiece16> { - std::size_t operator()(const base::StringPiece16& sp16) const { - HASH_STRING_PIECE(base::StringPiece16, sp16); - } -}; - -} // namespace BASE_HASH_NAMESPACE - -#endif // BASE_STRINGS_STRING_PIECE_H_ diff --git a/security/sandbox/chromium/base/strings/string_split.cc b/security/sandbox/chromium/base/strings/string_split.cc deleted file mode 100644 index 6c949b989..000000000 --- a/security/sandbox/chromium/base/strings/string_split.cc +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/string_split.h" - -#include <stddef.h> - -#include "base/logging.h" -#include "base/strings/string_util.h" -#include "base/third_party/icu/icu_utf.h" - -namespace base { - -namespace { - -// PieceToOutputType converts a StringPiece as needed to a given output type, -// which is either the same type of StringPiece (a NOP) or the corresponding -// non-piece string type. -// -// The default converter is a NOP, it works when the OutputType is the -// correct StringPiece. -template<typename Str, typename OutputType> -OutputType PieceToOutputType(BasicStringPiece<Str> piece) { - return piece; -} -template<> // Convert StringPiece to std::string -std::string PieceToOutputType<std::string, std::string>(StringPiece piece) { - return piece.as_string(); -} -template<> // Convert StringPiece16 to string16. -string16 PieceToOutputType<string16, string16>(StringPiece16 piece) { - return piece.as_string(); -} - -// Returns either the ASCII or UTF-16 whitespace. -template<typename Str> BasicStringPiece<Str> WhitespaceForType(); -template<> StringPiece16 WhitespaceForType<string16>() { - return kWhitespaceUTF16; -} -template<> StringPiece WhitespaceForType<std::string>() { - return kWhitespaceASCII; -} - -// Optimize the single-character case to call find() on the string instead, -// since this is the common case and can be made faster. This could have been -// done with template specialization too, but would have been less clear. -// -// There is no corresponding FindFirstNotOf because StringPiece already -// implements these different versions that do the optimized searching. -size_t FindFirstOf(StringPiece piece, char c, size_t pos) { - return piece.find(c, pos); -} -size_t FindFirstOf(StringPiece16 piece, char16 c, size_t pos) { - return piece.find(c, pos); -} -size_t FindFirstOf(StringPiece piece, StringPiece one_of, size_t pos) { - return piece.find_first_of(one_of, pos); -} -size_t FindFirstOf(StringPiece16 piece, StringPiece16 one_of, size_t pos) { - return piece.find_first_of(one_of, pos); -} - -// General string splitter template. Can take 8- or 16-bit input, can produce -// the corresponding string or StringPiece output, and can take single- or -// multiple-character delimiters. -// -// DelimiterType is either a character (Str::value_type) or a string piece of -// multiple characters (BasicStringPiece<Str>). StringPiece has a version of -// find for both of these cases, and the single-character version is the most -// common and can be implemented faster, which is why this is a template. -template<typename Str, typename OutputStringType, typename DelimiterType> -static std::vector<OutputStringType> SplitStringT( - BasicStringPiece<Str> str, - DelimiterType delimiter, - WhitespaceHandling whitespace, - SplitResult result_type) { - std::vector<OutputStringType> result; - if (str.empty()) - return result; - - size_t start = 0; - while (start != Str::npos) { - size_t end = FindFirstOf(str, delimiter, start); - - BasicStringPiece<Str> piece; - if (end == Str::npos) { - piece = str.substr(start); - start = Str::npos; - } else { - piece = str.substr(start, end - start); - start = end + 1; - } - - if (whitespace == TRIM_WHITESPACE) - piece = TrimString(piece, WhitespaceForType<Str>(), TRIM_ALL); - - if (result_type == SPLIT_WANT_ALL || !piece.empty()) - result.push_back(PieceToOutputType<Str, OutputStringType>(piece)); - } - return result; -} - -bool AppendStringKeyValue(StringPiece input, - char delimiter, - StringPairs* result) { - // Always append a new item regardless of success (it might be empty). The - // below code will copy the strings directly into the result pair. - result->resize(result->size() + 1); - auto& result_pair = result->back(); - - // Find the delimiter. - size_t end_key_pos = input.find_first_of(delimiter); - if (end_key_pos == std::string::npos) { - DVLOG(1) << "cannot find delimiter in: " << input; - return false; // No delimiter. - } - input.substr(0, end_key_pos).CopyToString(&result_pair.first); - - // Find the value string. - StringPiece remains = input.substr(end_key_pos, input.size() - end_key_pos); - size_t begin_value_pos = remains.find_first_not_of(delimiter); - if (begin_value_pos == StringPiece::npos) { - DVLOG(1) << "cannot parse value from input: " << input; - return false; // No value. - } - remains.substr(begin_value_pos, remains.size() - begin_value_pos) - .CopyToString(&result_pair.second); - - return true; -} - -template <typename Str, typename OutputStringType> -void SplitStringUsingSubstrT(BasicStringPiece<Str> input, - BasicStringPiece<Str> delimiter, - WhitespaceHandling whitespace, - SplitResult result_type, - std::vector<OutputStringType>* result) { - using Piece = BasicStringPiece<Str>; - using size_type = typename Piece::size_type; - - result->clear(); - for (size_type begin_index = 0, end_index = 0; end_index != Piece::npos; - begin_index = end_index + delimiter.size()) { - end_index = input.find(delimiter, begin_index); - Piece term = end_index == Piece::npos - ? input.substr(begin_index) - : input.substr(begin_index, end_index - begin_index); - - if (whitespace == TRIM_WHITESPACE) - term = TrimString(term, WhitespaceForType<Str>(), TRIM_ALL); - - if (result_type == SPLIT_WANT_ALL || !term.empty()) - result->push_back(PieceToOutputType<Str, OutputStringType>(term)); - } -} - -} // namespace - -std::vector<std::string> SplitString(StringPiece input, - StringPiece separators, - WhitespaceHandling whitespace, - SplitResult result_type) { - if (separators.size() == 1) { - return SplitStringT<std::string, std::string, char>( - input, separators[0], whitespace, result_type); - } - return SplitStringT<std::string, std::string, StringPiece>( - input, separators, whitespace, result_type); -} - -std::vector<string16> SplitString(StringPiece16 input, - StringPiece16 separators, - WhitespaceHandling whitespace, - SplitResult result_type) { - if (separators.size() == 1) { - return SplitStringT<string16, string16, char16>( - input, separators[0], whitespace, result_type); - } - return SplitStringT<string16, string16, StringPiece16>( - input, separators, whitespace, result_type); -} - -std::vector<StringPiece> SplitStringPiece(StringPiece input, - StringPiece separators, - WhitespaceHandling whitespace, - SplitResult result_type) { - if (separators.size() == 1) { - return SplitStringT<std::string, StringPiece, char>( - input, separators[0], whitespace, result_type); - } - return SplitStringT<std::string, StringPiece, StringPiece>( - input, separators, whitespace, result_type); -} - -std::vector<StringPiece16> SplitStringPiece(StringPiece16 input, - StringPiece16 separators, - WhitespaceHandling whitespace, - SplitResult result_type) { - if (separators.size() == 1) { - return SplitStringT<string16, StringPiece16, char16>( - input, separators[0], whitespace, result_type); - } - return SplitStringT<string16, StringPiece16, StringPiece16>( - input, separators, whitespace, result_type); -} - -bool SplitStringIntoKeyValuePairs(StringPiece input, - char key_value_delimiter, - char key_value_pair_delimiter, - StringPairs* key_value_pairs) { - key_value_pairs->clear(); - - std::vector<StringPiece> pairs = SplitStringPiece( - input, std::string(1, key_value_pair_delimiter), - TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY); - key_value_pairs->reserve(pairs.size()); - - bool success = true; - for (const StringPiece& pair : pairs) { - if (!AppendStringKeyValue(pair, key_value_delimiter, key_value_pairs)) { - // Don't return here, to allow for pairs without associated - // value or key; just record that the split failed. - success = false; - } - } - return success; -} - -void SplitStringUsingSubstr(StringPiece16 input, - StringPiece16 delimiter, - std::vector<string16>* result) { - SplitStringUsingSubstrT(input, delimiter, TRIM_WHITESPACE, SPLIT_WANT_ALL, - result); -} - -void SplitStringUsingSubstr(StringPiece input, - StringPiece delimiter, - std::vector<std::string>* result) { - SplitStringUsingSubstrT(input, delimiter, TRIM_WHITESPACE, SPLIT_WANT_ALL, - result); -} - -std::vector<StringPiece16> SplitStringPieceUsingSubstr( - StringPiece16 input, - StringPiece16 delimiter, - WhitespaceHandling whitespace, - SplitResult result_type) { - std::vector<StringPiece16> result; - SplitStringUsingSubstrT(input, delimiter, whitespace, result_type, &result); - return result; -} - -std::vector<StringPiece> SplitStringPieceUsingSubstr( - StringPiece input, - StringPiece delimiter, - WhitespaceHandling whitespace, - SplitResult result_type) { - std::vector<StringPiece> result; - SplitStringUsingSubstrT(input, delimiter, whitespace, result_type, &result); - return result; -} - -} // namespace base diff --git a/security/sandbox/chromium/base/strings/string_split.h b/security/sandbox/chromium/base/strings/string_split.h deleted file mode 100644 index ec9f24604..000000000 --- a/security/sandbox/chromium/base/strings/string_split.h +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_STRINGS_STRING_SPLIT_H_ -#define BASE_STRINGS_STRING_SPLIT_H_ - -#include <string> -#include <utility> -#include <vector> - -#include "base/base_export.h" -#include "base/strings/string16.h" -#include "base/strings/string_piece.h" - -namespace base { - -enum WhitespaceHandling { - KEEP_WHITESPACE, - TRIM_WHITESPACE, -}; - -enum SplitResult { - // Strictly return all results. - // - // If the input is ",," and the separator is ',' this will return a - // vector of three empty strings. - SPLIT_WANT_ALL, - - // Only nonempty results will be added to the results. Multiple separators - // will be coalesced. Separators at the beginning and end of the input will - // be ignored. With TRIM_WHITESPACE, whitespace-only results will be dropped. - // - // If the input is ",," and the separator is ',', this will return an empty - // vector. - SPLIT_WANT_NONEMPTY, -}; - -// Split the given string on ANY of the given separators, returning copies of -// the result. -// -// To split on either commas or semicolons, keeping all whitespace: -// -// std::vector<std::string> tokens = base::SplitString( -// input, ",;", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); -BASE_EXPORT std::vector<std::string> SplitString( - StringPiece input, - StringPiece separators, - WhitespaceHandling whitespace, - SplitResult result_type); -BASE_EXPORT std::vector<string16> SplitString( - StringPiece16 input, - StringPiece16 separators, - WhitespaceHandling whitespace, - SplitResult result_type); - -// Like SplitString above except it returns a vector of StringPieces which -// reference the original buffer without copying. Although you have to be -// careful to keep the original string unmodified, this provides an efficient -// way to iterate through tokens in a string. -// -// To iterate through all whitespace-separated tokens in an input string: -// -// for (const auto& cur : -// base::SplitStringPiece(input, base::kWhitespaceASCII, -// base::KEEP_WHITESPACE, -// base::SPLIT_WANT_NONEMPTY)) { -// ... -BASE_EXPORT std::vector<StringPiece> SplitStringPiece( - StringPiece input, - StringPiece separators, - WhitespaceHandling whitespace, - SplitResult result_type); -BASE_EXPORT std::vector<StringPiece16> SplitStringPiece( - StringPiece16 input, - StringPiece16 separators, - WhitespaceHandling whitespace, - SplitResult result_type); - -using StringPairs = std::vector<std::pair<std::string, std::string>>; - -// Splits |line| into key value pairs according to the given delimiters and -// removes whitespace leading each key and trailing each value. Returns true -// only if each pair has a non-empty key and value. |key_value_pairs| will -// include ("","") pairs for entries without |key_value_delimiter|. -BASE_EXPORT bool SplitStringIntoKeyValuePairs(StringPiece input, - char key_value_delimiter, - char key_value_pair_delimiter, - StringPairs* key_value_pairs); - -// Similar to SplitString, but use a substring delimiter instead of a list of -// characters that are all possible delimiters. -// -// TODO(brettw) this should probably be changed and expanded to provide a -// mirror of the SplitString[Piece] API above, just with the different -// delimiter handling. -BASE_EXPORT void SplitStringUsingSubstr(StringPiece16 input, - StringPiece16 delimiter, - std::vector<string16>* result); -BASE_EXPORT void SplitStringUsingSubstr(StringPiece input, - StringPiece delimiter, - std::vector<std::string>* result); - -// Like SplitStringUsingSubstr above except it returns a vector of StringPieces -// which reference the original buffer without copying. Although you have to be -// careful to keep the original string unmodified, this provides an efficient -// way to iterate through tokens in a string. -// -// To iterate through all newline-separated tokens in an input string: -// -// for (const auto& cur : -// base::SplitStringUsingSubstr(input, "\r\n", -// base::KEEP_WHITESPACE, -// base::SPLIT_WANT_NONEMPTY)) { -// ... -BASE_EXPORT std::vector<StringPiece16> SplitStringPieceUsingSubstr( - StringPiece16 input, - StringPiece16 delimiter, - WhitespaceHandling whitespace, - SplitResult result_type); -BASE_EXPORT std::vector<StringPiece> SplitStringPieceUsingSubstr( - StringPiece input, - StringPiece delimiter, - WhitespaceHandling whitespace, - SplitResult result_type); - -} // namespace base - -#endif // BASE_STRINGS_STRING_SPLIT_H_ diff --git a/security/sandbox/chromium/base/strings/string_util.cc b/security/sandbox/chromium/base/strings/string_util.cc deleted file mode 100644 index e8000abd4..000000000 --- a/security/sandbox/chromium/base/strings/string_util.cc +++ /dev/null @@ -1,1001 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/string_util.h" - -#include <ctype.h> -#include <errno.h> -#include <math.h> -#include <stdarg.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <wchar.h> -#include <wctype.h> - -#include <algorithm> -#include <limits> -#include <vector> - -#include "base/logging.h" -#include "base/macros.h" -#include "base/memory/singleton.h" -#include "base/strings/string_split.h" -#include "base/strings/utf_string_conversion_utils.h" -#include "base/strings/utf_string_conversions.h" -#include "base/third_party/icu/icu_utf.h" -#include "build/build_config.h" - -namespace base { - -namespace { - -// Force the singleton used by EmptyString[16] to be a unique type. This -// prevents other code that might accidentally use Singleton<string> from -// getting our internal one. -struct EmptyStrings { - EmptyStrings() {} - const std::string s; - const string16 s16; - - static EmptyStrings* GetInstance() { - return Singleton<EmptyStrings>::get(); - } -}; - -// Used by ReplaceStringPlaceholders to track the position in the string of -// replaced parameters. -struct ReplacementOffset { - ReplacementOffset(uintptr_t parameter, size_t offset) - : parameter(parameter), - offset(offset) {} - - // Index of the parameter. - uintptr_t parameter; - - // Starting position in the string. - size_t offset; -}; - -static bool CompareParameter(const ReplacementOffset& elem1, - const ReplacementOffset& elem2) { - return elem1.parameter < elem2.parameter; -} - -// Assuming that a pointer is the size of a "machine word", then -// uintptr_t is an integer type that is also a machine word. -typedef uintptr_t MachineWord; -const uintptr_t kMachineWordAlignmentMask = sizeof(MachineWord) - 1; - -inline bool IsAlignedToMachineWord(const void* pointer) { - return !(reinterpret_cast<MachineWord>(pointer) & kMachineWordAlignmentMask); -} - -template<typename T> inline T* AlignToMachineWord(T* pointer) { - return reinterpret_cast<T*>(reinterpret_cast<MachineWord>(pointer) & - ~kMachineWordAlignmentMask); -} - -template<size_t size, typename CharacterType> struct NonASCIIMask; -template<> struct NonASCIIMask<4, char16> { - static inline uint32_t value() { return 0xFF80FF80U; } -}; -template<> struct NonASCIIMask<4, char> { - static inline uint32_t value() { return 0x80808080U; } -}; -template<> struct NonASCIIMask<8, char16> { - static inline uint64_t value() { return 0xFF80FF80FF80FF80ULL; } -}; -template<> struct NonASCIIMask<8, char> { - static inline uint64_t value() { return 0x8080808080808080ULL; } -}; -#if defined(WCHAR_T_IS_UTF32) -template<> struct NonASCIIMask<4, wchar_t> { - static inline uint32_t value() { return 0xFFFFFF80U; } -}; -template<> struct NonASCIIMask<8, wchar_t> { - static inline uint64_t value() { return 0xFFFFFF80FFFFFF80ULL; } -}; -#endif // WCHAR_T_IS_UTF32 - -} // namespace - -bool IsWprintfFormatPortable(const wchar_t* format) { - for (const wchar_t* position = format; *position != '\0'; ++position) { - if (*position == '%') { - bool in_specification = true; - bool modifier_l = false; - while (in_specification) { - // Eat up characters until reaching a known specifier. - if (*++position == '\0') { - // The format string ended in the middle of a specification. Call - // it portable because no unportable specifications were found. The - // string is equally broken on all platforms. - return true; - } - - if (*position == 'l') { - // 'l' is the only thing that can save the 's' and 'c' specifiers. - modifier_l = true; - } else if (((*position == 's' || *position == 'c') && !modifier_l) || - *position == 'S' || *position == 'C' || *position == 'F' || - *position == 'D' || *position == 'O' || *position == 'U') { - // Not portable. - return false; - } - - if (wcschr(L"diouxXeEfgGaAcspn%", *position)) { - // Portable, keep scanning the rest of the format string. - in_specification = false; - } - } - } - } - - return true; -} - -namespace { - -template<typename StringType> -StringType ToLowerASCIIImpl(BasicStringPiece<StringType> str) { - StringType ret; - ret.reserve(str.size()); - for (size_t i = 0; i < str.size(); i++) - ret.push_back(ToLowerASCII(str[i])); - return ret; -} - -template<typename StringType> -StringType ToUpperASCIIImpl(BasicStringPiece<StringType> str) { - StringType ret; - ret.reserve(str.size()); - for (size_t i = 0; i < str.size(); i++) - ret.push_back(ToUpperASCII(str[i])); - return ret; -} - -} // namespace - -std::string ToLowerASCII(StringPiece str) { - return ToLowerASCIIImpl<std::string>(str); -} - -string16 ToLowerASCII(StringPiece16 str) { - return ToLowerASCIIImpl<string16>(str); -} - -std::string ToUpperASCII(StringPiece str) { - return ToUpperASCIIImpl<std::string>(str); -} - -string16 ToUpperASCII(StringPiece16 str) { - return ToUpperASCIIImpl<string16>(str); -} - -template<class StringType> -int CompareCaseInsensitiveASCIIT(BasicStringPiece<StringType> a, - BasicStringPiece<StringType> b) { - // Find the first characters that aren't equal and compare them. If the end - // of one of the strings is found before a nonequal character, the lengths - // of the strings are compared. - size_t i = 0; - while (i < a.length() && i < b.length()) { - typename StringType::value_type lower_a = ToLowerASCII(a[i]); - typename StringType::value_type lower_b = ToLowerASCII(b[i]); - if (lower_a < lower_b) - return -1; - if (lower_a > lower_b) - return 1; - i++; - } - - // End of one string hit before finding a different character. Expect the - // common case to be "strings equal" at this point so check that first. - if (a.length() == b.length()) - return 0; - - if (a.length() < b.length()) - return -1; - return 1; -} - -int CompareCaseInsensitiveASCII(StringPiece a, StringPiece b) { - return CompareCaseInsensitiveASCIIT<std::string>(a, b); -} - -int CompareCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b) { - return CompareCaseInsensitiveASCIIT<string16>(a, b); -} - -bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b) { - if (a.length() != b.length()) - return false; - return CompareCaseInsensitiveASCIIT<std::string>(a, b) == 0; -} - -bool EqualsCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b) { - if (a.length() != b.length()) - return false; - return CompareCaseInsensitiveASCIIT<string16>(a, b) == 0; -} - -const std::string& EmptyString() { - return EmptyStrings::GetInstance()->s; -} - -const string16& EmptyString16() { - return EmptyStrings::GetInstance()->s16; -} - -template<typename STR> -bool ReplaceCharsT(const STR& input, - const STR& replace_chars, - const STR& replace_with, - STR* output) { - bool removed = false; - size_t replace_length = replace_with.length(); - - *output = input; - - size_t found = output->find_first_of(replace_chars); - while (found != STR::npos) { - removed = true; - output->replace(found, 1, replace_with); - found = output->find_first_of(replace_chars, found + replace_length); - } - - return removed; -} - -bool ReplaceChars(const string16& input, - const StringPiece16& replace_chars, - const string16& replace_with, - string16* output) { - return ReplaceCharsT(input, replace_chars.as_string(), replace_with, output); -} - -bool ReplaceChars(const std::string& input, - const StringPiece& replace_chars, - const std::string& replace_with, - std::string* output) { - return ReplaceCharsT(input, replace_chars.as_string(), replace_with, output); -} - -bool RemoveChars(const string16& input, - const StringPiece16& remove_chars, - string16* output) { - return ReplaceChars(input, remove_chars.as_string(), string16(), output); -} - -bool RemoveChars(const std::string& input, - const StringPiece& remove_chars, - std::string* output) { - return ReplaceChars(input, remove_chars.as_string(), std::string(), output); -} - -template<typename Str> -TrimPositions TrimStringT(const Str& input, - BasicStringPiece<Str> trim_chars, - TrimPositions positions, - Str* output) { - // Find the edges of leading/trailing whitespace as desired. Need to use - // a StringPiece version of input to be able to call find* on it with the - // StringPiece version of trim_chars (normally the trim_chars will be a - // constant so avoid making a copy). - BasicStringPiece<Str> input_piece(input); - const size_t last_char = input.length() - 1; - const size_t first_good_char = (positions & TRIM_LEADING) ? - input_piece.find_first_not_of(trim_chars) : 0; - const size_t last_good_char = (positions & TRIM_TRAILING) ? - input_piece.find_last_not_of(trim_chars) : last_char; - - // When the string was all trimmed, report that we stripped off characters - // from whichever position the caller was interested in. For empty input, we - // stripped no characters, but we still need to clear |output|. - if (input.empty() || - (first_good_char == Str::npos) || (last_good_char == Str::npos)) { - bool input_was_empty = input.empty(); // in case output == &input - output->clear(); - return input_was_empty ? TRIM_NONE : positions; - } - - // Trim. - *output = - input.substr(first_good_char, last_good_char - first_good_char + 1); - - // Return where we trimmed from. - return static_cast<TrimPositions>( - ((first_good_char == 0) ? TRIM_NONE : TRIM_LEADING) | - ((last_good_char == last_char) ? TRIM_NONE : TRIM_TRAILING)); -} - -bool TrimString(const string16& input, - StringPiece16 trim_chars, - string16* output) { - return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE; -} - -bool TrimString(const std::string& input, - StringPiece trim_chars, - std::string* output) { - return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE; -} - -template<typename Str> -BasicStringPiece<Str> TrimStringPieceT(BasicStringPiece<Str> input, - BasicStringPiece<Str> trim_chars, - TrimPositions positions) { - size_t begin = (positions & TRIM_LEADING) ? - input.find_first_not_of(trim_chars) : 0; - size_t end = (positions & TRIM_TRAILING) ? - input.find_last_not_of(trim_chars) + 1 : input.size(); - return input.substr(begin, end - begin); -} - -StringPiece16 TrimString(StringPiece16 input, - const StringPiece16& trim_chars, - TrimPositions positions) { - return TrimStringPieceT(input, trim_chars, positions); -} - -StringPiece TrimString(StringPiece input, - const StringPiece& trim_chars, - TrimPositions positions) { - return TrimStringPieceT(input, trim_chars, positions); -} - -void TruncateUTF8ToByteSize(const std::string& input, - const size_t byte_size, - std::string* output) { - DCHECK(output); - if (byte_size > input.length()) { - *output = input; - return; - } - DCHECK_LE(byte_size, - static_cast<uint32_t>(std::numeric_limits<int32_t>::max())); - // Note: This cast is necessary because CBU8_NEXT uses int32_ts. - int32_t truncation_length = static_cast<int32_t>(byte_size); - int32_t char_index = truncation_length - 1; - const char* data = input.data(); - - // Using CBU8, we will move backwards from the truncation point - // to the beginning of the string looking for a valid UTF8 - // character. Once a full UTF8 character is found, we will - // truncate the string to the end of that character. - while (char_index >= 0) { - int32_t prev = char_index; - base_icu::UChar32 code_point = 0; - CBU8_NEXT(data, char_index, truncation_length, code_point); - if (!IsValidCharacter(code_point) || - !IsValidCodepoint(code_point)) { - char_index = prev - 1; - } else { - break; - } - } - - if (char_index >= 0 ) - *output = input.substr(0, char_index); - else - output->clear(); -} - -TrimPositions TrimWhitespace(const string16& input, - TrimPositions positions, - string16* output) { - return TrimStringT(input, StringPiece16(kWhitespaceUTF16), positions, output); -} - -StringPiece16 TrimWhitespace(StringPiece16 input, - TrimPositions positions) { - return TrimStringPieceT(input, StringPiece16(kWhitespaceUTF16), positions); -} - -TrimPositions TrimWhitespaceASCII(const std::string& input, - TrimPositions positions, - std::string* output) { - return TrimStringT(input, StringPiece(kWhitespaceASCII), positions, output); -} - -StringPiece TrimWhitespaceASCII(StringPiece input, TrimPositions positions) { - return TrimStringPieceT(input, StringPiece(kWhitespaceASCII), positions); -} - -template<typename STR> -STR CollapseWhitespaceT(const STR& text, - bool trim_sequences_with_line_breaks) { - STR result; - result.resize(text.size()); - - // Set flags to pretend we're already in a trimmed whitespace sequence, so we - // will trim any leading whitespace. - bool in_whitespace = true; - bool already_trimmed = true; - - int chars_written = 0; - for (typename STR::const_iterator i(text.begin()); i != text.end(); ++i) { - if (IsUnicodeWhitespace(*i)) { - if (!in_whitespace) { - // Reduce all whitespace sequences to a single space. - in_whitespace = true; - result[chars_written++] = L' '; - } - if (trim_sequences_with_line_breaks && !already_trimmed && - ((*i == '\n') || (*i == '\r'))) { - // Whitespace sequences containing CR or LF are eliminated entirely. - already_trimmed = true; - --chars_written; - } - } else { - // Non-whitespace chracters are copied straight across. - in_whitespace = false; - already_trimmed = false; - result[chars_written++] = *i; - } - } - - if (in_whitespace && !already_trimmed) { - // Any trailing whitespace is eliminated. - --chars_written; - } - - result.resize(chars_written); - return result; -} - -string16 CollapseWhitespace(const string16& text, - bool trim_sequences_with_line_breaks) { - return CollapseWhitespaceT(text, trim_sequences_with_line_breaks); -} - -std::string CollapseWhitespaceASCII(const std::string& text, - bool trim_sequences_with_line_breaks) { - return CollapseWhitespaceT(text, trim_sequences_with_line_breaks); -} - -bool ContainsOnlyChars(const StringPiece& input, - const StringPiece& characters) { - return input.find_first_not_of(characters) == StringPiece::npos; -} - -bool ContainsOnlyChars(const StringPiece16& input, - const StringPiece16& characters) { - return input.find_first_not_of(characters) == StringPiece16::npos; -} - -template <class Char> -inline bool DoIsStringASCII(const Char* characters, size_t length) { - MachineWord all_char_bits = 0; - const Char* end = characters + length; - - // Prologue: align the input. - while (!IsAlignedToMachineWord(characters) && characters != end) { - all_char_bits |= *characters; - ++characters; - } - - // Compare the values of CPU word size. - const Char* word_end = AlignToMachineWord(end); - const size_t loop_increment = sizeof(MachineWord) / sizeof(Char); - while (characters < word_end) { - all_char_bits |= *(reinterpret_cast<const MachineWord*>(characters)); - characters += loop_increment; - } - - // Process the remaining bytes. - while (characters != end) { - all_char_bits |= *characters; - ++characters; - } - - MachineWord non_ascii_bit_mask = - NonASCIIMask<sizeof(MachineWord), Char>::value(); - return !(all_char_bits & non_ascii_bit_mask); -} - -bool IsStringASCII(const StringPiece& str) { - return DoIsStringASCII(str.data(), str.length()); -} - -bool IsStringASCII(const StringPiece16& str) { - return DoIsStringASCII(str.data(), str.length()); -} - -bool IsStringASCII(const string16& str) { - return DoIsStringASCII(str.data(), str.length()); -} - -#if defined(WCHAR_T_IS_UTF32) -bool IsStringASCII(const std::wstring& str) { - return DoIsStringASCII(str.data(), str.length()); -} -#endif - -bool IsStringUTF8(const StringPiece& str) { - const char *src = str.data(); - int32_t src_len = static_cast<int32_t>(str.length()); - int32_t char_index = 0; - - while (char_index < src_len) { - int32_t code_point; - CBU8_NEXT(src, char_index, src_len, code_point); - if (!IsValidCharacter(code_point)) - return false; - } - return true; -} - -// Implementation note: Normally this function will be called with a hardcoded -// constant for the lowercase_ascii parameter. Constructing a StringPiece from -// a C constant requires running strlen, so the result will be two passes -// through the buffers, one to file the length of lowercase_ascii, and one to -// compare each letter. -// -// This function could have taken a const char* to avoid this and only do one -// pass through the string. But the strlen is faster than the case-insensitive -// compares and lets us early-exit in the case that the strings are different -// lengths (will often be the case for non-matches). So whether one approach or -// the other will be faster depends on the case. -// -// The hardcoded strings are typically very short so it doesn't matter, and the -// string piece gives additional flexibility for the caller (doesn't have to be -// null terminated) so we choose the StringPiece route. -template<typename Str> -static inline bool DoLowerCaseEqualsASCII(BasicStringPiece<Str> str, - StringPiece lowercase_ascii) { - if (str.size() != lowercase_ascii.size()) - return false; - for (size_t i = 0; i < str.size(); i++) { - if (ToLowerASCII(str[i]) != lowercase_ascii[i]) - return false; - } - return true; -} - -bool LowerCaseEqualsASCII(StringPiece str, StringPiece lowercase_ascii) { - return DoLowerCaseEqualsASCII<std::string>(str, lowercase_ascii); -} - -bool LowerCaseEqualsASCII(StringPiece16 str, StringPiece lowercase_ascii) { - return DoLowerCaseEqualsASCII<string16>(str, lowercase_ascii); -} - -bool EqualsASCII(StringPiece16 str, StringPiece ascii) { - if (str.length() != ascii.length()) - return false; - return std::equal(ascii.begin(), ascii.end(), str.begin()); -} - -template<typename Str> -bool StartsWithT(BasicStringPiece<Str> str, - BasicStringPiece<Str> search_for, - CompareCase case_sensitivity) { - if (search_for.size() > str.size()) - return false; - - BasicStringPiece<Str> source = str.substr(0, search_for.size()); - - switch (case_sensitivity) { - case CompareCase::SENSITIVE: - return source == search_for; - - case CompareCase::INSENSITIVE_ASCII: - return std::equal( - search_for.begin(), search_for.end(), - source.begin(), - CaseInsensitiveCompareASCII<typename Str::value_type>()); - - default: - NOTREACHED(); - return false; - } -} - -bool StartsWith(StringPiece str, - StringPiece search_for, - CompareCase case_sensitivity) { - return StartsWithT<std::string>(str, search_for, case_sensitivity); -} - -bool StartsWith(StringPiece16 str, - StringPiece16 search_for, - CompareCase case_sensitivity) { - return StartsWithT<string16>(str, search_for, case_sensitivity); -} - -template <typename Str> -bool EndsWithT(BasicStringPiece<Str> str, - BasicStringPiece<Str> search_for, - CompareCase case_sensitivity) { - if (search_for.size() > str.size()) - return false; - - BasicStringPiece<Str> source = str.substr(str.size() - search_for.size(), - search_for.size()); - - switch (case_sensitivity) { - case CompareCase::SENSITIVE: - return source == search_for; - - case CompareCase::INSENSITIVE_ASCII: - return std::equal( - source.begin(), source.end(), - search_for.begin(), - CaseInsensitiveCompareASCII<typename Str::value_type>()); - - default: - NOTREACHED(); - return false; - } -} - -bool EndsWith(StringPiece str, - StringPiece search_for, - CompareCase case_sensitivity) { - return EndsWithT<std::string>(str, search_for, case_sensitivity); -} - -bool EndsWith(StringPiece16 str, - StringPiece16 search_for, - CompareCase case_sensitivity) { - return EndsWithT<string16>(str, search_for, case_sensitivity); -} - -char HexDigitToInt(wchar_t c) { - DCHECK(IsHexDigit(c)); - if (c >= '0' && c <= '9') - return static_cast<char>(c - '0'); - if (c >= 'A' && c <= 'F') - return static_cast<char>(c - 'A' + 10); - if (c >= 'a' && c <= 'f') - return static_cast<char>(c - 'a' + 10); - return 0; -} - -bool IsUnicodeWhitespace(wchar_t c) { - // kWhitespaceWide is a NULL-terminated string - for (const wchar_t* cur = kWhitespaceWide; *cur; ++cur) { - if (*cur == c) - return true; - } - return false; -} - -static const char* const kByteStringsUnlocalized[] = { - " B", - " kB", - " MB", - " GB", - " TB", - " PB" -}; - -string16 FormatBytesUnlocalized(int64_t bytes) { - double unit_amount = static_cast<double>(bytes); - size_t dimension = 0; - const int kKilo = 1024; - while (unit_amount >= kKilo && - dimension < arraysize(kByteStringsUnlocalized) - 1) { - unit_amount /= kKilo; - dimension++; - } - - char buf[64]; - if (bytes != 0 && dimension > 0 && unit_amount < 100) { - base::snprintf(buf, arraysize(buf), "%.1lf%s", unit_amount, - kByteStringsUnlocalized[dimension]); - } else { - base::snprintf(buf, arraysize(buf), "%.0lf%s", unit_amount, - kByteStringsUnlocalized[dimension]); - } - - return ASCIIToUTF16(buf); -} - -// Runs in O(n) time in the length of |str|. -template<class StringType> -void DoReplaceSubstringsAfterOffset(StringType* str, - size_t offset, - BasicStringPiece<StringType> find_this, - BasicStringPiece<StringType> replace_with, - bool replace_all) { - DCHECK(!find_this.empty()); - - // If the find string doesn't appear, there's nothing to do. - offset = str->find(find_this.data(), offset, find_this.size()); - if (offset == StringType::npos) - return; - - // If we're only replacing one instance, there's no need to do anything - // complicated. - size_t find_length = find_this.length(); - if (!replace_all) { - str->replace(offset, find_length, replace_with.data(), replace_with.size()); - return; - } - - // If the find and replace strings are the same length, we can simply use - // replace() on each instance, and finish the entire operation in O(n) time. - size_t replace_length = replace_with.length(); - if (find_length == replace_length) { - do { - str->replace(offset, find_length, - replace_with.data(), replace_with.size()); - offset = str->find(find_this.data(), offset + replace_length, - find_this.size()); - } while (offset != StringType::npos); - return; - } - - // Since the find and replace strings aren't the same length, a loop like the - // one above would be O(n^2) in the worst case, as replace() will shift the - // entire remaining string each time. We need to be more clever to keep - // things O(n). - // - // If we're shortening the string, we can alternate replacements with shifting - // forward the intervening characters using memmove(). - size_t str_length = str->length(); - if (find_length > replace_length) { - size_t write_offset = offset; - do { - if (replace_length) { - str->replace(write_offset, replace_length, - replace_with.data(), replace_with.size()); - write_offset += replace_length; - } - size_t read_offset = offset + find_length; - offset = std::min( - str->find(find_this.data(), read_offset, find_this.size()), - str_length); - size_t length = offset - read_offset; - if (length) { - memmove(&(*str)[write_offset], &(*str)[read_offset], - length * sizeof(typename StringType::value_type)); - write_offset += length; - } - } while (offset < str_length); - str->resize(write_offset); - return; - } - - // We're lengthening the string. We can use alternating replacements and - // memmove() calls like above, but we need to precalculate the final string - // length and then expand from back-to-front to avoid overwriting the string - // as we're reading it, needing to shift, or having to copy to a second string - // temporarily. - size_t first_match = offset; - - // First, calculate the final length and resize the string. - size_t final_length = str_length; - size_t expansion = replace_length - find_length; - size_t current_match; - do { - final_length += expansion; - // Minor optimization: save this offset into |current_match|, so that on - // exit from the loop, |current_match| will point at the last instance of - // the find string, and we won't need to find() it again immediately. - current_match = offset; - offset = str->find(find_this.data(), offset + find_length, - find_this.size()); - } while (offset != StringType::npos); - str->resize(final_length); - - // Now do the replacement loop, working backwards through the string. - for (size_t prev_match = str_length, write_offset = final_length; ; - current_match = str->rfind(find_this.data(), current_match - 1, - find_this.size())) { - size_t read_offset = current_match + find_length; - size_t length = prev_match - read_offset; - if (length) { - write_offset -= length; - memmove(&(*str)[write_offset], &(*str)[read_offset], - length * sizeof(typename StringType::value_type)); - } - write_offset -= replace_length; - str->replace(write_offset, replace_length, - replace_with.data(), replace_with.size()); - if (current_match == first_match) - return; - prev_match = current_match; - } -} - -void ReplaceFirstSubstringAfterOffset(string16* str, - size_t start_offset, - StringPiece16 find_this, - StringPiece16 replace_with) { - DoReplaceSubstringsAfterOffset<string16>( - str, start_offset, find_this, replace_with, false); // Replace first. -} - -void ReplaceFirstSubstringAfterOffset(std::string* str, - size_t start_offset, - StringPiece find_this, - StringPiece replace_with) { - DoReplaceSubstringsAfterOffset<std::string>( - str, start_offset, find_this, replace_with, false); // Replace first. -} - -void ReplaceSubstringsAfterOffset(string16* str, - size_t start_offset, - StringPiece16 find_this, - StringPiece16 replace_with) { - DoReplaceSubstringsAfterOffset<string16>( - str, start_offset, find_this, replace_with, true); // Replace all. -} - -void ReplaceSubstringsAfterOffset(std::string* str, - size_t start_offset, - StringPiece find_this, - StringPiece replace_with) { - DoReplaceSubstringsAfterOffset<std::string>( - str, start_offset, find_this, replace_with, true); // Replace all. -} - -template <class string_type> -inline typename string_type::value_type* WriteIntoT(string_type* str, - size_t length_with_null) { - DCHECK_GT(length_with_null, 1u); - str->reserve(length_with_null); - str->resize(length_with_null - 1); - return &((*str)[0]); -} - -char* WriteInto(std::string* str, size_t length_with_null) { - return WriteIntoT(str, length_with_null); -} - -char16* WriteInto(string16* str, size_t length_with_null) { - return WriteIntoT(str, length_with_null); -} - -template<typename STR> -static STR JoinStringT(const std::vector<STR>& parts, - BasicStringPiece<STR> sep) { - if (parts.empty()) - return STR(); - - STR result(parts[0]); - auto iter = parts.begin(); - ++iter; - - for (; iter != parts.end(); ++iter) { - sep.AppendToString(&result); - result += *iter; - } - - return result; -} - -std::string JoinString(const std::vector<std::string>& parts, - StringPiece separator) { - return JoinStringT(parts, separator); -} - -string16 JoinString(const std::vector<string16>& parts, - StringPiece16 separator) { - return JoinStringT(parts, separator); -} - -template<class FormatStringType, class OutStringType> -OutStringType DoReplaceStringPlaceholders( - const FormatStringType& format_string, - const std::vector<OutStringType>& subst, - std::vector<size_t>* offsets) { - size_t substitutions = subst.size(); - - size_t sub_length = 0; - for (const auto& cur : subst) - sub_length += cur.length(); - - OutStringType formatted; - formatted.reserve(format_string.length() + sub_length); - - std::vector<ReplacementOffset> r_offsets; - for (auto i = format_string.begin(); i != format_string.end(); ++i) { - if ('$' == *i) { - if (i + 1 != format_string.end()) { - ++i; - DCHECK('$' == *i || '1' <= *i) << "Invalid placeholder: " << *i; - if ('$' == *i) { - while (i != format_string.end() && '$' == *i) { - formatted.push_back('$'); - ++i; - } - --i; - } else { - uintptr_t index = 0; - while (i != format_string.end() && '0' <= *i && *i <= '9') { - index *= 10; - index += *i - '0'; - ++i; - } - --i; - index -= 1; - if (offsets) { - ReplacementOffset r_offset(index, - static_cast<int>(formatted.size())); - r_offsets.insert(std::lower_bound(r_offsets.begin(), - r_offsets.end(), - r_offset, - &CompareParameter), - r_offset); - } - if (index < substitutions) - formatted.append(subst.at(index)); - } - } - } else { - formatted.push_back(*i); - } - } - if (offsets) { - for (const auto& cur : r_offsets) - offsets->push_back(cur.offset); - } - return formatted; -} - -string16 ReplaceStringPlaceholders(const string16& format_string, - const std::vector<string16>& subst, - std::vector<size_t>* offsets) { - return DoReplaceStringPlaceholders(format_string, subst, offsets); -} - -std::string ReplaceStringPlaceholders(const StringPiece& format_string, - const std::vector<std::string>& subst, - std::vector<size_t>* offsets) { - return DoReplaceStringPlaceholders(format_string, subst, offsets); -} - -string16 ReplaceStringPlaceholders(const string16& format_string, - const string16& a, - size_t* offset) { - std::vector<size_t> offsets; - std::vector<string16> subst; - subst.push_back(a); - string16 result = ReplaceStringPlaceholders(format_string, subst, &offsets); - - DCHECK_EQ(1U, offsets.size()); - if (offset) - *offset = offsets[0]; - return result; -} - -// The following code is compatible with the OpenBSD lcpy interface. See: -// http://www.gratisoft.us/todd/papers/strlcpy.html -// ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/{wcs,str}lcpy.c - -namespace { - -template <typename CHAR> -size_t lcpyT(CHAR* dst, const CHAR* src, size_t dst_size) { - for (size_t i = 0; i < dst_size; ++i) { - if ((dst[i] = src[i]) == 0) // We hit and copied the terminating NULL. - return i; - } - - // We were left off at dst_size. We over copied 1 byte. Null terminate. - if (dst_size != 0) - dst[dst_size - 1] = 0; - - // Count the rest of the |src|, and return it's length in characters. - while (src[dst_size]) ++dst_size; - return dst_size; -} - -} // namespace - -size_t strlcpy(char* dst, const char* src, size_t dst_size) { - return lcpyT<char>(dst, src, dst_size); -} -size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) { - return lcpyT<wchar_t>(dst, src, dst_size); -} - -} // namespace base diff --git a/security/sandbox/chromium/base/strings/string_util.h b/security/sandbox/chromium/base/strings/string_util.h deleted file mode 100644 index e369f294d..000000000 --- a/security/sandbox/chromium/base/strings/string_util.h +++ /dev/null @@ -1,461 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// This file defines utility functions for working with strings. - -#ifndef BASE_STRINGS_STRING_UTIL_H_ -#define BASE_STRINGS_STRING_UTIL_H_ - -#include <ctype.h> -#include <stdarg.h> // va_list -#include <stddef.h> -#include <stdint.h> - -#include <string> -#include <vector> - -#include "base/base_export.h" -#include "base/compiler_specific.h" -#include "base/strings/string16.h" -#include "base/strings/string_piece.h" // For implicit conversions. -#include "build/build_config.h" - -namespace base { - -// C standard-library functions that aren't cross-platform are provided as -// "base::...", and their prototypes are listed below. These functions are -// then implemented as inline calls to the platform-specific equivalents in the -// platform-specific headers. - -// Wrapper for vsnprintf that always null-terminates and always returns the -// number of characters that would be in an untruncated formatted -// string, even when truncation occurs. -int vsnprintf(char* buffer, size_t size, const char* format, va_list arguments) - PRINTF_FORMAT(3, 0); - -// Some of these implementations need to be inlined. - -// We separate the declaration from the implementation of this inline -// function just so the PRINTF_FORMAT works. -inline int snprintf(char* buffer, - size_t size, - _Printf_format_string_ const char* format, - ...) PRINTF_FORMAT(3, 4); -inline int snprintf(char* buffer, - size_t size, - _Printf_format_string_ const char* format, - ...) { - va_list arguments; - va_start(arguments, format); - int result = vsnprintf(buffer, size, format, arguments); - va_end(arguments); - return result; -} - -// BSD-style safe and consistent string copy functions. -// Copies |src| to |dst|, where |dst_size| is the total allocated size of |dst|. -// Copies at most |dst_size|-1 characters, and always NULL terminates |dst|, as -// long as |dst_size| is not 0. Returns the length of |src| in characters. -// If the return value is >= dst_size, then the output was truncated. -// NOTE: All sizes are in number of characters, NOT in bytes. -BASE_EXPORT size_t strlcpy(char* dst, const char* src, size_t dst_size); -BASE_EXPORT size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size); - -// Scan a wprintf format string to determine whether it's portable across a -// variety of systems. This function only checks that the conversion -// specifiers used by the format string are supported and have the same meaning -// on a variety of systems. It doesn't check for other errors that might occur -// within a format string. -// -// Nonportable conversion specifiers for wprintf are: -// - 's' and 'c' without an 'l' length modifier. %s and %c operate on char -// data on all systems except Windows, which treat them as wchar_t data. -// Use %ls and %lc for wchar_t data instead. -// - 'S' and 'C', which operate on wchar_t data on all systems except Windows, -// which treat them as char data. Use %ls and %lc for wchar_t data -// instead. -// - 'F', which is not identified by Windows wprintf documentation. -// - 'D', 'O', and 'U', which are deprecated and not available on all systems. -// Use %ld, %lo, and %lu instead. -// -// Note that there is no portable conversion specifier for char data when -// working with wprintf. -// -// This function is intended to be called from base::vswprintf. -BASE_EXPORT bool IsWprintfFormatPortable(const wchar_t* format); - -// ASCII-specific tolower. The standard library's tolower is locale sensitive, -// so we don't want to use it here. -inline char ToLowerASCII(char c) { - return (c >= 'A' && c <= 'Z') ? (c + ('a' - 'A')) : c; -} -inline char16 ToLowerASCII(char16 c) { - return (c >= 'A' && c <= 'Z') ? (c + ('a' - 'A')) : c; -} - -// ASCII-specific toupper. The standard library's toupper is locale sensitive, -// so we don't want to use it here. -inline char ToUpperASCII(char c) { - return (c >= 'a' && c <= 'z') ? (c + ('A' - 'a')) : c; -} -inline char16 ToUpperASCII(char16 c) { - return (c >= 'a' && c <= 'z') ? (c + ('A' - 'a')) : c; -} - -// Converts the given string to it's ASCII-lowercase equivalent. -BASE_EXPORT std::string ToLowerASCII(StringPiece str); -BASE_EXPORT string16 ToLowerASCII(StringPiece16 str); - -// Converts the given string to it's ASCII-uppercase equivalent. -BASE_EXPORT std::string ToUpperASCII(StringPiece str); -BASE_EXPORT string16 ToUpperASCII(StringPiece16 str); - -// Functor for case-insensitive ASCII comparisons for STL algorithms like -// std::search. -// -// Note that a full Unicode version of this functor is not possible to write -// because case mappings might change the number of characters, depend on -// context (combining accents), and require handling UTF-16. If you need -// proper Unicode support, use base::i18n::ToLower/FoldCase and then just -// use a normal operator== on the result. -template<typename Char> struct CaseInsensitiveCompareASCII { - public: - bool operator()(Char x, Char y) const { - return ToLowerASCII(x) == ToLowerASCII(y); - } -}; - -// Like strcasecmp for case-insensitive ASCII characters only. Returns: -// -1 (a < b) -// 0 (a == b) -// 1 (a > b) -// (unlike strcasecmp which can return values greater or less than 1/-1). For -// full Unicode support, use base::i18n::ToLower or base::i18h::FoldCase -// and then just call the normal string operators on the result. -BASE_EXPORT int CompareCaseInsensitiveASCII(StringPiece a, StringPiece b); -BASE_EXPORT int CompareCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b); - -// Equality for ASCII case-insensitive comparisons. For full Unicode support, -// use base::i18n::ToLower or base::i18h::FoldCase and then compare with either -// == or !=. -BASE_EXPORT bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b); -BASE_EXPORT bool EqualsCaseInsensitiveASCII(StringPiece16 a, StringPiece16 b); - -// These threadsafe functions return references to globally unique empty -// strings. -// -// It is likely faster to construct a new empty string object (just a few -// instructions to set the length to 0) than to get the empty string singleton -// returned by these functions (which requires threadsafe singleton access). -// -// Therefore, DO NOT USE THESE AS A GENERAL-PURPOSE SUBSTITUTE FOR DEFAULT -// CONSTRUCTORS. There is only one case where you should use these: functions -// which need to return a string by reference (e.g. as a class member -// accessor), and don't have an empty string to use (e.g. in an error case). -// These should not be used as initializers, function arguments, or return -// values for functions which return by value or outparam. -BASE_EXPORT const std::string& EmptyString(); -BASE_EXPORT const string16& EmptyString16(); - -// Contains the set of characters representing whitespace in the corresponding -// encoding. Null-terminated. The ASCII versions are the whitespaces as defined -// by HTML5, and don't include control characters. -BASE_EXPORT extern const wchar_t kWhitespaceWide[]; // Includes Unicode. -BASE_EXPORT extern const char16 kWhitespaceUTF16[]; // Includes Unicode. -BASE_EXPORT extern const char kWhitespaceASCII[]; -BASE_EXPORT extern const char16 kWhitespaceASCIIAs16[]; // No unicode. - -// Null-terminated string representing the UTF-8 byte order mark. -BASE_EXPORT extern const char kUtf8ByteOrderMark[]; - -// Removes characters in |remove_chars| from anywhere in |input|. Returns true -// if any characters were removed. |remove_chars| must be null-terminated. -// NOTE: Safe to use the same variable for both |input| and |output|. -BASE_EXPORT bool RemoveChars(const string16& input, - const StringPiece16& remove_chars, - string16* output); -BASE_EXPORT bool RemoveChars(const std::string& input, - const StringPiece& remove_chars, - std::string* output); - -// Replaces characters in |replace_chars| from anywhere in |input| with -// |replace_with|. Each character in |replace_chars| will be replaced with -// the |replace_with| string. Returns true if any characters were replaced. -// |replace_chars| must be null-terminated. -// NOTE: Safe to use the same variable for both |input| and |output|. -BASE_EXPORT bool ReplaceChars(const string16& input, - const StringPiece16& replace_chars, - const string16& replace_with, - string16* output); -BASE_EXPORT bool ReplaceChars(const std::string& input, - const StringPiece& replace_chars, - const std::string& replace_with, - std::string* output); - -enum TrimPositions { - TRIM_NONE = 0, - TRIM_LEADING = 1 << 0, - TRIM_TRAILING = 1 << 1, - TRIM_ALL = TRIM_LEADING | TRIM_TRAILING, -}; - -// Removes characters in |trim_chars| from the beginning and end of |input|. -// The 8-bit version only works on 8-bit characters, not UTF-8. -// -// It is safe to use the same variable for both |input| and |output| (this is -// the normal usage to trim in-place). -BASE_EXPORT bool TrimString(const string16& input, - StringPiece16 trim_chars, - string16* output); -BASE_EXPORT bool TrimString(const std::string& input, - StringPiece trim_chars, - std::string* output); - -// StringPiece versions of the above. The returned pieces refer to the original -// buffer. -BASE_EXPORT StringPiece16 TrimString(StringPiece16 input, - const StringPiece16& trim_chars, - TrimPositions positions); -BASE_EXPORT StringPiece TrimString(StringPiece input, - const StringPiece& trim_chars, - TrimPositions positions); - -// Truncates a string to the nearest UTF-8 character that will leave -// the string less than or equal to the specified byte size. -BASE_EXPORT void TruncateUTF8ToByteSize(const std::string& input, - const size_t byte_size, - std::string* output); - -// Trims any whitespace from either end of the input string. -// -// The StringPiece versions return a substring referencing the input buffer. -// The ASCII versions look only for ASCII whitespace. -// -// The std::string versions return where whitespace was found. -// NOTE: Safe to use the same variable for both input and output. -BASE_EXPORT TrimPositions TrimWhitespace(const string16& input, - TrimPositions positions, - string16* output); -BASE_EXPORT StringPiece16 TrimWhitespace(StringPiece16 input, - TrimPositions positions); -BASE_EXPORT TrimPositions TrimWhitespaceASCII(const std::string& input, - TrimPositions positions, - std::string* output); -BASE_EXPORT StringPiece TrimWhitespaceASCII(StringPiece input, - TrimPositions positions); - -// Searches for CR or LF characters. Removes all contiguous whitespace -// strings that contain them. This is useful when trying to deal with text -// copied from terminals. -// Returns |text|, with the following three transformations: -// (1) Leading and trailing whitespace is trimmed. -// (2) If |trim_sequences_with_line_breaks| is true, any other whitespace -// sequences containing a CR or LF are trimmed. -// (3) All other whitespace sequences are converted to single spaces. -BASE_EXPORT string16 CollapseWhitespace( - const string16& text, - bool trim_sequences_with_line_breaks); -BASE_EXPORT std::string CollapseWhitespaceASCII( - const std::string& text, - bool trim_sequences_with_line_breaks); - -// Returns true if |input| is empty or contains only characters found in -// |characters|. -BASE_EXPORT bool ContainsOnlyChars(const StringPiece& input, - const StringPiece& characters); -BASE_EXPORT bool ContainsOnlyChars(const StringPiece16& input, - const StringPiece16& characters); - -// Returns true if the specified string matches the criteria. How can a wide -// string be 8-bit or UTF8? It contains only characters that are < 256 (in the -// first case) or characters that use only 8-bits and whose 8-bit -// representation looks like a UTF-8 string (the second case). -// -// Note that IsStringUTF8 checks not only if the input is structurally -// valid but also if it doesn't contain any non-character codepoint -// (e.g. U+FFFE). It's done on purpose because all the existing callers want -// to have the maximum 'discriminating' power from other encodings. If -// there's a use case for just checking the structural validity, we have to -// add a new function for that. -// -// IsStringASCII assumes the input is likely all ASCII, and does not leave early -// if it is not the case. -BASE_EXPORT bool IsStringUTF8(const StringPiece& str); -BASE_EXPORT bool IsStringASCII(const StringPiece& str); -BASE_EXPORT bool IsStringASCII(const StringPiece16& str); -// A convenience adaptor for WebStrings, as they don't convert into -// StringPieces directly. -BASE_EXPORT bool IsStringASCII(const string16& str); -#if defined(WCHAR_T_IS_UTF32) -BASE_EXPORT bool IsStringASCII(const std::wstring& str); -#endif - -// Compare the lower-case form of the given string against the given -// previously-lower-cased ASCII string (typically a constant). -BASE_EXPORT bool LowerCaseEqualsASCII(StringPiece str, - StringPiece lowecase_ascii); -BASE_EXPORT bool LowerCaseEqualsASCII(StringPiece16 str, - StringPiece lowecase_ascii); - -// Performs a case-sensitive string compare of the given 16-bit string against -// the given 8-bit ASCII string (typically a constant). The behavior is -// undefined if the |ascii| string is not ASCII. -BASE_EXPORT bool EqualsASCII(StringPiece16 str, StringPiece ascii); - -// Indicates case sensitivity of comparisons. Only ASCII case insensitivity -// is supported. Full Unicode case-insensitive conversions would need to go in -// base/i18n so it can use ICU. -// -// If you need to do Unicode-aware case-insensitive StartsWith/EndsWith, it's -// best to call base::i18n::ToLower() or base::i18n::FoldCase() (see -// base/i18n/case_conversion.h for usage advice) on the arguments, and then use -// the results to a case-sensitive comparison. -enum class CompareCase { - SENSITIVE, - INSENSITIVE_ASCII, -}; - -BASE_EXPORT bool StartsWith(StringPiece str, - StringPiece search_for, - CompareCase case_sensitivity); -BASE_EXPORT bool StartsWith(StringPiece16 str, - StringPiece16 search_for, - CompareCase case_sensitivity); -BASE_EXPORT bool EndsWith(StringPiece str, - StringPiece search_for, - CompareCase case_sensitivity); -BASE_EXPORT bool EndsWith(StringPiece16 str, - StringPiece16 search_for, - CompareCase case_sensitivity); - -// Determines the type of ASCII character, independent of locale (the C -// library versions will change based on locale). -template <typename Char> -inline bool IsAsciiWhitespace(Char c) { - return c == ' ' || c == '\r' || c == '\n' || c == '\t'; -} -template <typename Char> -inline bool IsAsciiAlpha(Char c) { - return ((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')); -} -template <typename Char> -inline bool IsAsciiDigit(Char c) { - return c >= '0' && c <= '9'; -} - -template <typename Char> -inline bool IsHexDigit(Char c) { - return (c >= '0' && c <= '9') || - (c >= 'A' && c <= 'F') || - (c >= 'a' && c <= 'f'); -} - -// Returns the integer corresponding to the given hex character. For example: -// '4' -> 4 -// 'a' -> 10 -// 'B' -> 11 -// Assumes the input is a valid hex character. DCHECKs in debug builds if not. -BASE_EXPORT char HexDigitToInt(wchar_t c); - -// Returns true if it's a Unicode whitespace character. -BASE_EXPORT bool IsUnicodeWhitespace(wchar_t c); - -// Return a byte string in human-readable format with a unit suffix. Not -// appropriate for use in any UI; use of FormatBytes and friends in ui/base is -// highly recommended instead. TODO(avi): Figure out how to get callers to use -// FormatBytes instead; remove this. -BASE_EXPORT string16 FormatBytesUnlocalized(int64_t bytes); - -// Starting at |start_offset| (usually 0), replace the first instance of -// |find_this| with |replace_with|. -BASE_EXPORT void ReplaceFirstSubstringAfterOffset( - base::string16* str, - size_t start_offset, - StringPiece16 find_this, - StringPiece16 replace_with); -BASE_EXPORT void ReplaceFirstSubstringAfterOffset( - std::string* str, - size_t start_offset, - StringPiece find_this, - StringPiece replace_with); - -// Starting at |start_offset| (usually 0), look through |str| and replace all -// instances of |find_this| with |replace_with|. -// -// This does entire substrings; use std::replace in <algorithm> for single -// characters, for example: -// std::replace(str.begin(), str.end(), 'a', 'b'); -BASE_EXPORT void ReplaceSubstringsAfterOffset( - string16* str, - size_t start_offset, - StringPiece16 find_this, - StringPiece16 replace_with); -BASE_EXPORT void ReplaceSubstringsAfterOffset( - std::string* str, - size_t start_offset, - StringPiece find_this, - StringPiece replace_with); - -// Reserves enough memory in |str| to accommodate |length_with_null| characters, -// sets the size of |str| to |length_with_null - 1| characters, and returns a -// pointer to the underlying contiguous array of characters. This is typically -// used when calling a function that writes results into a character array, but -// the caller wants the data to be managed by a string-like object. It is -// convenient in that is can be used inline in the call, and fast in that it -// avoids copying the results of the call from a char* into a string. -// -// |length_with_null| must be at least 2, since otherwise the underlying string -// would have size 0, and trying to access &((*str)[0]) in that case can result -// in a number of problems. -// -// Internally, this takes linear time because the resize() call 0-fills the -// underlying array for potentially all -// (|length_with_null - 1| * sizeof(string_type::value_type)) bytes. Ideally we -// could avoid this aspect of the resize() call, as we expect the caller to -// immediately write over this memory, but there is no other way to set the size -// of the string, and not doing that will mean people who access |str| rather -// than str.c_str() will get back a string of whatever size |str| had on entry -// to this function (probably 0). -BASE_EXPORT char* WriteInto(std::string* str, size_t length_with_null); -BASE_EXPORT char16* WriteInto(string16* str, size_t length_with_null); -#ifndef OS_WIN -BASE_EXPORT wchar_t* WriteInto(std::wstring* str, size_t length_with_null); -#endif - -// Does the opposite of SplitString(). -BASE_EXPORT std::string JoinString(const std::vector<std::string>& parts, - StringPiece separator); -BASE_EXPORT string16 JoinString(const std::vector<string16>& parts, - StringPiece16 separator); - -// Replace $1-$2-$3..$9 in the format string with |a|-|b|-|c|..|i| respectively. -// Additionally, any number of consecutive '$' characters is replaced by that -// number less one. Eg $$->$, $$$->$$, etc. The offsets parameter here can be -// NULL. This only allows you to use up to nine replacements. -BASE_EXPORT string16 ReplaceStringPlaceholders( - const string16& format_string, - const std::vector<string16>& subst, - std::vector<size_t>* offsets); - -BASE_EXPORT std::string ReplaceStringPlaceholders( - const StringPiece& format_string, - const std::vector<std::string>& subst, - std::vector<size_t>* offsets); - -// Single-string shortcut for ReplaceStringHolders. |offset| may be NULL. -BASE_EXPORT string16 ReplaceStringPlaceholders(const string16& format_string, - const string16& a, - size_t* offset); - -} // namespace base - -#if defined(OS_WIN) -#include "base/strings/string_util_win.h" -#elif defined(OS_POSIX) -#include "base/strings/string_util_posix.h" -#else -#error Define string operations appropriately for your platform -#endif - -#endif // BASE_STRINGS_STRING_UTIL_H_ diff --git a/security/sandbox/chromium/base/strings/string_util_constants.cc b/security/sandbox/chromium/base/strings/string_util_constants.cc deleted file mode 100644 index aba1b12b8..000000000 --- a/security/sandbox/chromium/base/strings/string_util_constants.cc +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/string_util.h" - -namespace base { - -#define WHITESPACE_UNICODE \ - 0x0009, /* CHARACTER TABULATION */ \ - 0x000A, /* LINE FEED (LF) */ \ - 0x000B, /* LINE TABULATION */ \ - 0x000C, /* FORM FEED (FF) */ \ - 0x000D, /* CARRIAGE RETURN (CR) */ \ - 0x0020, /* SPACE */ \ - 0x0085, /* NEXT LINE (NEL) */ \ - 0x00A0, /* NO-BREAK SPACE */ \ - 0x1680, /* OGHAM SPACE MARK */ \ - 0x2000, /* EN QUAD */ \ - 0x2001, /* EM QUAD */ \ - 0x2002, /* EN SPACE */ \ - 0x2003, /* EM SPACE */ \ - 0x2004, /* THREE-PER-EM SPACE */ \ - 0x2005, /* FOUR-PER-EM SPACE */ \ - 0x2006, /* SIX-PER-EM SPACE */ \ - 0x2007, /* FIGURE SPACE */ \ - 0x2008, /* PUNCTUATION SPACE */ \ - 0x2009, /* THIN SPACE */ \ - 0x200A, /* HAIR SPACE */ \ - 0x2028, /* LINE SEPARATOR */ \ - 0x2029, /* PARAGRAPH SEPARATOR */ \ - 0x202F, /* NARROW NO-BREAK SPACE */ \ - 0x205F, /* MEDIUM MATHEMATICAL SPACE */ \ - 0x3000, /* IDEOGRAPHIC SPACE */ \ - 0 - -const wchar_t kWhitespaceWide[] = { - WHITESPACE_UNICODE -}; - -const char16 kWhitespaceUTF16[] = { - WHITESPACE_UNICODE -}; - -const char kWhitespaceASCII[] = { - 0x09, // CHARACTER TABULATION - 0x0A, // LINE FEED (LF) - 0x0B, // LINE TABULATION - 0x0C, // FORM FEED (FF) - 0x0D, // CARRIAGE RETURN (CR) - 0x20, // SPACE - 0 -}; - -const char16 kWhitespaceASCIIAs16[] = { - 0x09, // CHARACTER TABULATION - 0x0A, // LINE FEED (LF) - 0x0B, // LINE TABULATION - 0x0C, // FORM FEED (FF) - 0x0D, // CARRIAGE RETURN (CR) - 0x20, // SPACE - 0 -}; - -const char kUtf8ByteOrderMark[] = "\xEF\xBB\xBF"; - -} // namespace base diff --git a/security/sandbox/chromium/base/strings/string_util_posix.h b/security/sandbox/chromium/base/strings/string_util_posix.h deleted file mode 100644 index 8299118e1..000000000 --- a/security/sandbox/chromium/base/strings/string_util_posix.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_STRINGS_STRING_UTIL_POSIX_H_ -#define BASE_STRINGS_STRING_UTIL_POSIX_H_ - -#include <stdarg.h> -#include <stddef.h> -#include <stdio.h> -#include <string.h> -#include <wchar.h> - -#include "base/logging.h" - -namespace base { - -// Chromium code style is to not use malloc'd strings; this is only for use -// for interaction with APIs that require it. -inline char* strdup(const char* str) { - return ::strdup(str); -} - -inline int vsnprintf(char* buffer, size_t size, - const char* format, va_list arguments) { - return ::vsnprintf(buffer, size, format, arguments); -} - -inline int vswprintf(wchar_t* buffer, size_t size, - const wchar_t* format, va_list arguments) { - DCHECK(IsWprintfFormatPortable(format)); - return ::vswprintf(buffer, size, format, arguments); -} - -} // namespace base - -#endif // BASE_STRINGS_STRING_UTIL_POSIX_H_ diff --git a/security/sandbox/chromium/base/strings/string_util_win.h b/security/sandbox/chromium/base/strings/string_util_win.h deleted file mode 100644 index 7f260bfc8..000000000 --- a/security/sandbox/chromium/base/strings/string_util_win.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_STRINGS_STRING_UTIL_WIN_H_ -#define BASE_STRINGS_STRING_UTIL_WIN_H_ - -#include <stdarg.h> -#include <stddef.h> -#include <stdio.h> -#include <string.h> -#include <wchar.h> - -#include "base/logging.h" - -namespace base { - -// Chromium code style is to not use malloc'd strings; this is only for use -// for interaction with APIs that require it. -inline char* strdup(const char* str) { - return _strdup(str); -} - -inline int vsnprintf(char* buffer, size_t size, - const char* format, va_list arguments) { - int length = vsnprintf_s(buffer, size, size - 1, format, arguments); - if (length < 0) - return _vscprintf(format, arguments); - return length; -} - -inline int vswprintf(wchar_t* buffer, size_t size, - const wchar_t* format, va_list arguments) { - DCHECK(IsWprintfFormatPortable(format)); - - int length = _vsnwprintf_s(buffer, size, size - 1, format, arguments); - if (length < 0) - return _vscwprintf(format, arguments); - return length; -} - -} // namespace base - -#endif // BASE_STRINGS_STRING_UTIL_WIN_H_ diff --git a/security/sandbox/chromium/base/strings/stringprintf.cc b/security/sandbox/chromium/base/strings/stringprintf.cc deleted file mode 100644 index 415845d61..000000000 --- a/security/sandbox/chromium/base/strings/stringprintf.cc +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/stringprintf.h" - -#include <errno.h> -#include <stddef.h> - -#include <vector> - -#include "base/macros.h" -#include "base/scoped_clear_errno.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" - -namespace base { - -namespace { - -// Overloaded wrappers around vsnprintf and vswprintf. The buf_size parameter -// is the size of the buffer. These return the number of characters in the -// formatted string excluding the NUL terminator. If the buffer is not -// large enough to accommodate the formatted string without truncation, they -// return the number of characters that would be in the fully-formatted string -// (vsnprintf, and vswprintf on Windows), or -1 (vswprintf on POSIX platforms). -inline int vsnprintfT(char* buffer, - size_t buf_size, - const char* format, - va_list argptr) { - return base::vsnprintf(buffer, buf_size, format, argptr); -} - -#if defined(OS_WIN) -inline int vsnprintfT(wchar_t* buffer, - size_t buf_size, - const wchar_t* format, - va_list argptr) { - return base::vswprintf(buffer, buf_size, format, argptr); -} -#endif - -// Templatized backend for StringPrintF/StringAppendF. This does not finalize -// the va_list, the caller is expected to do that. -template <class StringType> -static void StringAppendVT(StringType* dst, - const typename StringType::value_type* format, - va_list ap) { - // First try with a small fixed size buffer. - // This buffer size should be kept in sync with StringUtilTest.GrowBoundary - // and StringUtilTest.StringPrintfBounds. - typename StringType::value_type stack_buf[1024]; - - va_list ap_copy; - va_copy(ap_copy, ap); - -#if !defined(OS_WIN) - ScopedClearErrno clear_errno; -#endif - int result = vsnprintfT(stack_buf, arraysize(stack_buf), format, ap_copy); - va_end(ap_copy); - - if (result >= 0 && result < static_cast<int>(arraysize(stack_buf))) { - // It fit. - dst->append(stack_buf, result); - return; - } - - // Repeatedly increase buffer size until it fits. - int mem_length = arraysize(stack_buf); - while (true) { - if (result < 0) { -#if defined(OS_WIN) - // On Windows, vsnprintfT always returns the number of characters in a - // fully-formatted string, so if we reach this point, something else is - // wrong and no amount of buffer-doubling is going to fix it. - return; -#else - if (errno != 0 && errno != EOVERFLOW) - return; - // Try doubling the buffer size. - mem_length *= 2; -#endif - } else { - // We need exactly "result + 1" characters. - mem_length = result + 1; - } - - if (mem_length > 32 * 1024 * 1024) { - // That should be plenty, don't try anything larger. This protects - // against huge allocations when using vsnprintfT implementations that - // return -1 for reasons other than overflow without setting errno. - DLOG(WARNING) << "Unable to printf the requested string due to size."; - return; - } - - std::vector<typename StringType::value_type> mem_buf(mem_length); - - // NOTE: You can only use a va_list once. Since we're in a while loop, we - // need to make a new copy each time so we don't use up the original. - va_copy(ap_copy, ap); - result = vsnprintfT(&mem_buf[0], mem_length, format, ap_copy); - va_end(ap_copy); - - if ((result >= 0) && (result < mem_length)) { - // It fit. - dst->append(&mem_buf[0], result); - return; - } - } -} - -} // namespace - -std::string StringPrintf(const char* format, ...) { - va_list ap; - va_start(ap, format); - std::string result; - StringAppendV(&result, format, ap); - va_end(ap); - return result; -} - -#if defined(OS_WIN) -std::wstring StringPrintf(const wchar_t* format, ...) { - va_list ap; - va_start(ap, format); - std::wstring result; - StringAppendV(&result, format, ap); - va_end(ap); - return result; -} -#endif - -std::string StringPrintV(const char* format, va_list ap) { - std::string result; - StringAppendV(&result, format, ap); - return result; -} - -const std::string& SStringPrintf(std::string* dst, const char* format, ...) { - va_list ap; - va_start(ap, format); - dst->clear(); - StringAppendV(dst, format, ap); - va_end(ap); - return *dst; -} - -#if defined(OS_WIN) -const std::wstring& SStringPrintf(std::wstring* dst, - const wchar_t* format, ...) { - va_list ap; - va_start(ap, format); - dst->clear(); - StringAppendV(dst, format, ap); - va_end(ap); - return *dst; -} -#endif - -void StringAppendF(std::string* dst, const char* format, ...) { - va_list ap; - va_start(ap, format); - StringAppendV(dst, format, ap); - va_end(ap); -} - -#if defined(OS_WIN) -void StringAppendF(std::wstring* dst, const wchar_t* format, ...) { - va_list ap; - va_start(ap, format); - StringAppendV(dst, format, ap); - va_end(ap); -} -#endif - -void StringAppendV(std::string* dst, const char* format, va_list ap) { - StringAppendVT(dst, format, ap); -} - -#if defined(OS_WIN) -void StringAppendV(std::wstring* dst, const wchar_t* format, va_list ap) { - StringAppendVT(dst, format, ap); -} -#endif - -} // namespace base diff --git a/security/sandbox/chromium/base/strings/stringprintf.h b/security/sandbox/chromium/base/strings/stringprintf.h deleted file mode 100644 index 7a75d89e1..000000000 --- a/security/sandbox/chromium/base/strings/stringprintf.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_STRINGS_STRINGPRINTF_H_ -#define BASE_STRINGS_STRINGPRINTF_H_ - -#include <stdarg.h> // va_list - -#include <string> - -#include "base/base_export.h" -#include "base/compiler_specific.h" -#include "build/build_config.h" - -namespace base { - -// Return a C++ string given printf-like input. -BASE_EXPORT std::string StringPrintf(_Printf_format_string_ const char* format, - ...) - PRINTF_FORMAT(1, 2) WARN_UNUSED_RESULT; -#if defined(OS_WIN) -BASE_EXPORT std::wstring StringPrintf( - _Printf_format_string_ const wchar_t* format, - ...) WPRINTF_FORMAT(1, 2) WARN_UNUSED_RESULT; -#endif - -// Return a C++ string given vprintf-like input. -BASE_EXPORT std::string StringPrintV(const char* format, va_list ap) - PRINTF_FORMAT(1, 0) WARN_UNUSED_RESULT; - -// Store result into a supplied string and return it. -BASE_EXPORT const std::string& SStringPrintf( - std::string* dst, - _Printf_format_string_ const char* format, - ...) PRINTF_FORMAT(2, 3); -#if defined(OS_WIN) -BASE_EXPORT const std::wstring& SStringPrintf( - std::wstring* dst, - _Printf_format_string_ const wchar_t* format, - ...) WPRINTF_FORMAT(2, 3); -#endif - -// Append result to a supplied string. -BASE_EXPORT void StringAppendF(std::string* dst, - _Printf_format_string_ const char* format, - ...) PRINTF_FORMAT(2, 3); -#if defined(OS_WIN) -BASE_EXPORT void StringAppendF(std::wstring* dst, - _Printf_format_string_ const wchar_t* format, - ...) WPRINTF_FORMAT(2, 3); -#endif - -// Lower-level routine that takes a va_list and appends to a specified -// string. All other routines are just convenience wrappers around it. -BASE_EXPORT void StringAppendV(std::string* dst, const char* format, va_list ap) - PRINTF_FORMAT(2, 0); -#if defined(OS_WIN) -BASE_EXPORT void StringAppendV(std::wstring* dst, - const wchar_t* format, va_list ap) - WPRINTF_FORMAT(2, 0); -#endif - -} // namespace base - -#endif // BASE_STRINGS_STRINGPRINTF_H_ diff --git a/security/sandbox/chromium/base/strings/utf_string_conversion_utils.cc b/security/sandbox/chromium/base/strings/utf_string_conversion_utils.cc deleted file mode 100644 index 3101a6028..000000000 --- a/security/sandbox/chromium/base/strings/utf_string_conversion_utils.cc +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/utf_string_conversion_utils.h" - -#include "base/third_party/icu/icu_utf.h" - -namespace base { - -// ReadUnicodeCharacter -------------------------------------------------------- - -bool ReadUnicodeCharacter(const char* src, - int32_t src_len, - int32_t* char_index, - uint32_t* code_point_out) { - // U8_NEXT expects to be able to use -1 to signal an error, so we must - // use a signed type for code_point. But this function returns false - // on error anyway, so code_point_out is unsigned. - int32_t code_point; - CBU8_NEXT(src, *char_index, src_len, code_point); - *code_point_out = static_cast<uint32_t>(code_point); - - // The ICU macro above moves to the next char, we want to point to the last - // char consumed. - (*char_index)--; - - // Validate the decoded value. - return IsValidCodepoint(code_point); -} - -bool ReadUnicodeCharacter(const char16* src, - int32_t src_len, - int32_t* char_index, - uint32_t* code_point) { - if (CBU16_IS_SURROGATE(src[*char_index])) { - if (!CBU16_IS_SURROGATE_LEAD(src[*char_index]) || - *char_index + 1 >= src_len || - !CBU16_IS_TRAIL(src[*char_index + 1])) { - // Invalid surrogate pair. - return false; - } - - // Valid surrogate pair. - *code_point = CBU16_GET_SUPPLEMENTARY(src[*char_index], - src[*char_index + 1]); - (*char_index)++; - } else { - // Not a surrogate, just one 16-bit word. - *code_point = src[*char_index]; - } - - return IsValidCodepoint(*code_point); -} - -#if defined(WCHAR_T_IS_UTF32) -bool ReadUnicodeCharacter(const wchar_t* src, - int32_t src_len, - int32_t* char_index, - uint32_t* code_point) { - // Conversion is easy since the source is 32-bit. - *code_point = src[*char_index]; - - // Validate the value. - return IsValidCodepoint(*code_point); -} -#endif // defined(WCHAR_T_IS_UTF32) - -// WriteUnicodeCharacter ------------------------------------------------------- - -size_t WriteUnicodeCharacter(uint32_t code_point, std::string* output) { - if (code_point <= 0x7f) { - // Fast path the common case of one byte. - output->push_back(static_cast<char>(code_point)); - return 1; - } - - - // CBU8_APPEND_UNSAFE can append up to 4 bytes. - size_t char_offset = output->length(); - size_t original_char_offset = char_offset; - output->resize(char_offset + CBU8_MAX_LENGTH); - - CBU8_APPEND_UNSAFE(&(*output)[0], char_offset, code_point); - - // CBU8_APPEND_UNSAFE will advance our pointer past the inserted character, so - // it will represent the new length of the string. - output->resize(char_offset); - return char_offset - original_char_offset; -} - -size_t WriteUnicodeCharacter(uint32_t code_point, string16* output) { - if (CBU16_LENGTH(code_point) == 1) { - // Thie code point is in the Basic Multilingual Plane (BMP). - output->push_back(static_cast<char16>(code_point)); - return 1; - } - // Non-BMP characters use a double-character encoding. - size_t char_offset = output->length(); - output->resize(char_offset + CBU16_MAX_LENGTH); - CBU16_APPEND_UNSAFE(&(*output)[0], char_offset, code_point); - return CBU16_MAX_LENGTH; -} - -// Generalized Unicode converter ----------------------------------------------- - -template<typename CHAR> -void PrepareForUTF8Output(const CHAR* src, - size_t src_len, - std::string* output) { - output->clear(); - if (src_len == 0) - return; - if (src[0] < 0x80) { - // Assume that the entire input will be ASCII. - output->reserve(src_len); - } else { - // Assume that the entire input is non-ASCII and will have 3 bytes per char. - output->reserve(src_len * 3); - } -} - -// Instantiate versions we know callers will need. -template void PrepareForUTF8Output(const wchar_t*, size_t, std::string*); -template void PrepareForUTF8Output(const char16*, size_t, std::string*); - -template<typename STRING> -void PrepareForUTF16Or32Output(const char* src, - size_t src_len, - STRING* output) { - output->clear(); - if (src_len == 0) - return; - if (static_cast<unsigned char>(src[0]) < 0x80) { - // Assume the input is all ASCII, which means 1:1 correspondence. - output->reserve(src_len); - } else { - // Otherwise assume that the UTF-8 sequences will have 2 bytes for each - // character. - output->reserve(src_len / 2); - } -} - -// Instantiate versions we know callers will need. -template void PrepareForUTF16Or32Output(const char*, size_t, std::wstring*); -template void PrepareForUTF16Or32Output(const char*, size_t, string16*); - -} // namespace base diff --git a/security/sandbox/chromium/base/strings/utf_string_conversion_utils.h b/security/sandbox/chromium/base/strings/utf_string_conversion_utils.h deleted file mode 100644 index c71640453..000000000 --- a/security/sandbox/chromium/base/strings/utf_string_conversion_utils.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_STRINGS_UTF_STRING_CONVERSION_UTILS_H_ -#define BASE_STRINGS_UTF_STRING_CONVERSION_UTILS_H_ - -// This should only be used by the various UTF string conversion files. - -#include <stddef.h> -#include <stdint.h> - -#include "base/base_export.h" -#include "base/strings/string16.h" - -namespace base { - -inline bool IsValidCodepoint(uint32_t code_point) { - // Excludes the surrogate code points ([0xD800, 0xDFFF]) and - // codepoints larger than 0x10FFFF (the highest codepoint allowed). - // Non-characters and unassigned codepoints are allowed. - return code_point < 0xD800u || - (code_point >= 0xE000u && code_point <= 0x10FFFFu); -} - -inline bool IsValidCharacter(uint32_t code_point) { - // Excludes non-characters (U+FDD0..U+FDEF, and all codepoints ending in - // 0xFFFE or 0xFFFF) from the set of valid code points. - return code_point < 0xD800u || (code_point >= 0xE000u && - code_point < 0xFDD0u) || (code_point > 0xFDEFu && - code_point <= 0x10FFFFu && (code_point & 0xFFFEu) != 0xFFFEu); -} - -// ReadUnicodeCharacter -------------------------------------------------------- - -// Reads a UTF-8 stream, placing the next code point into the given output -// |*code_point|. |src| represents the entire string to read, and |*char_index| -// is the character offset within the string to start reading at. |*char_index| -// will be updated to index the last character read, such that incrementing it -// (as in a for loop) will take the reader to the next character. -// -// Returns true on success. On false, |*code_point| will be invalid. -BASE_EXPORT bool ReadUnicodeCharacter(const char* src, - int32_t src_len, - int32_t* char_index, - uint32_t* code_point_out); - -// Reads a UTF-16 character. The usage is the same as the 8-bit version above. -BASE_EXPORT bool ReadUnicodeCharacter(const char16* src, - int32_t src_len, - int32_t* char_index, - uint32_t* code_point); - -#if defined(WCHAR_T_IS_UTF32) -// Reads UTF-32 character. The usage is the same as the 8-bit version above. -BASE_EXPORT bool ReadUnicodeCharacter(const wchar_t* src, - int32_t src_len, - int32_t* char_index, - uint32_t* code_point); -#endif // defined(WCHAR_T_IS_UTF32) - -// WriteUnicodeCharacter ------------------------------------------------------- - -// Appends a UTF-8 character to the given 8-bit string. Returns the number of -// bytes written. -BASE_EXPORT size_t WriteUnicodeCharacter(uint32_t code_point, - std::string* output); - -// Appends the given code point as a UTF-16 character to the given 16-bit -// string. Returns the number of 16-bit values written. -BASE_EXPORT size_t WriteUnicodeCharacter(uint32_t code_point, string16* output); - -#if defined(WCHAR_T_IS_UTF32) -// Appends the given UTF-32 character to the given 32-bit string. Returns the -// number of 32-bit values written. -inline size_t WriteUnicodeCharacter(uint32_t code_point, std::wstring* output) { - // This is the easy case, just append the character. - output->push_back(code_point); - return 1; -} -#endif // defined(WCHAR_T_IS_UTF32) - -// Generalized Unicode converter ----------------------------------------------- - -// Guesses the length of the output in UTF-8 in bytes, clears that output -// string, and reserves that amount of space. We assume that the input -// character types are unsigned, which will be true for UTF-16 and -32 on our -// systems. -template<typename CHAR> -void PrepareForUTF8Output(const CHAR* src, size_t src_len, std::string* output); - -// Prepares an output buffer (containing either UTF-16 or -32 data) given some -// UTF-8 input that will be converted to it. See PrepareForUTF8Output(). -template<typename STRING> -void PrepareForUTF16Or32Output(const char* src, size_t src_len, STRING* output); - -} // namespace base - -#endif // BASE_STRINGS_UTF_STRING_CONVERSION_UTILS_H_ diff --git a/security/sandbox/chromium/base/strings/utf_string_conversions.cc b/security/sandbox/chromium/base/strings/utf_string_conversions.cc deleted file mode 100644 index 6b17eacd6..000000000 --- a/security/sandbox/chromium/base/strings/utf_string_conversions.cc +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/strings/utf_string_conversions.h" - -#include <stdint.h> - -#include "base/strings/string_piece.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversion_utils.h" -#include "build/build_config.h" - -namespace base { - -namespace { - -// Generalized Unicode converter ----------------------------------------------- - -// Converts the given source Unicode character type to the given destination -// Unicode character type as a STL string. The given input buffer and size -// determine the source, and the given output STL string will be replaced by -// the result. -template<typename SRC_CHAR, typename DEST_STRING> -bool ConvertUnicode(const SRC_CHAR* src, - size_t src_len, - DEST_STRING* output) { - // ICU requires 32-bit numbers. - bool success = true; - int32_t src_len32 = static_cast<int32_t>(src_len); - for (int32_t i = 0; i < src_len32; i++) { - uint32_t code_point; - if (ReadUnicodeCharacter(src, src_len32, &i, &code_point)) { - WriteUnicodeCharacter(code_point, output); - } else { - WriteUnicodeCharacter(0xFFFD, output); - success = false; - } - } - - return success; -} - -} // namespace - -// UTF-8 <-> Wide -------------------------------------------------------------- - -bool WideToUTF8(const wchar_t* src, size_t src_len, std::string* output) { - if (IsStringASCII(std::wstring(src, src_len))) { - output->assign(src, src + src_len); - return true; - } else { - PrepareForUTF8Output(src, src_len, output); - return ConvertUnicode(src, src_len, output); - } -} - -std::string WideToUTF8(const std::wstring& wide) { - if (IsStringASCII(wide)) { - return std::string(wide.data(), wide.data() + wide.length()); - } - - std::string ret; - PrepareForUTF8Output(wide.data(), wide.length(), &ret); - ConvertUnicode(wide.data(), wide.length(), &ret); - return ret; -} - -bool UTF8ToWide(const char* src, size_t src_len, std::wstring* output) { - if (IsStringASCII(StringPiece(src, src_len))) { - output->assign(src, src + src_len); - return true; - } else { - PrepareForUTF16Or32Output(src, src_len, output); - return ConvertUnicode(src, src_len, output); - } -} - -std::wstring UTF8ToWide(StringPiece utf8) { - if (IsStringASCII(utf8)) { - return std::wstring(utf8.begin(), utf8.end()); - } - - std::wstring ret; - PrepareForUTF16Or32Output(utf8.data(), utf8.length(), &ret); - ConvertUnicode(utf8.data(), utf8.length(), &ret); - return ret; -} - -// UTF-16 <-> Wide ------------------------------------------------------------- - -#if defined(WCHAR_T_IS_UTF16) - -// When wide == UTF-16, then conversions are a NOP. -bool WideToUTF16(const wchar_t* src, size_t src_len, string16* output) { - output->assign(src, src_len); - return true; -} - -string16 WideToUTF16(const std::wstring& wide) { - return wide; -} - -bool UTF16ToWide(const char16* src, size_t src_len, std::wstring* output) { - output->assign(src, src_len); - return true; -} - -std::wstring UTF16ToWide(const string16& utf16) { - return utf16; -} - -#elif defined(WCHAR_T_IS_UTF32) - -bool WideToUTF16(const wchar_t* src, size_t src_len, string16* output) { - output->clear(); - // Assume that normally we won't have any non-BMP characters so the counts - // will be the same. - output->reserve(src_len); - return ConvertUnicode(src, src_len, output); -} - -string16 WideToUTF16(const std::wstring& wide) { - string16 ret; - WideToUTF16(wide.data(), wide.length(), &ret); - return ret; -} - -bool UTF16ToWide(const char16* src, size_t src_len, std::wstring* output) { - output->clear(); - // Assume that normally we won't have any non-BMP characters so the counts - // will be the same. - output->reserve(src_len); - return ConvertUnicode(src, src_len, output); -} - -std::wstring UTF16ToWide(const string16& utf16) { - std::wstring ret; - UTF16ToWide(utf16.data(), utf16.length(), &ret); - return ret; -} - -#endif // defined(WCHAR_T_IS_UTF32) - -// UTF16 <-> UTF8 -------------------------------------------------------------- - -#if defined(WCHAR_T_IS_UTF32) - -bool UTF8ToUTF16(const char* src, size_t src_len, string16* output) { - if (IsStringASCII(StringPiece(src, src_len))) { - output->assign(src, src + src_len); - return true; - } else { - PrepareForUTF16Or32Output(src, src_len, output); - return ConvertUnicode(src, src_len, output); - } -} - -string16 UTF8ToUTF16(StringPiece utf8) { - if (IsStringASCII(utf8)) { - return string16(utf8.begin(), utf8.end()); - } - - string16 ret; - PrepareForUTF16Or32Output(utf8.data(), utf8.length(), &ret); - // Ignore the success flag of this call, it will do the best it can for - // invalid input, which is what we want here. - ConvertUnicode(utf8.data(), utf8.length(), &ret); - return ret; -} - -bool UTF16ToUTF8(const char16* src, size_t src_len, std::string* output) { - if (IsStringASCII(StringPiece16(src, src_len))) { - output->assign(src, src + src_len); - return true; - } else { - PrepareForUTF8Output(src, src_len, output); - return ConvertUnicode(src, src_len, output); - } -} - -std::string UTF16ToUTF8(StringPiece16 utf16) { - if (IsStringASCII(utf16)) { - return std::string(utf16.begin(), utf16.end()); - } - - std::string ret; - // Ignore the success flag of this call, it will do the best it can for - // invalid input, which is what we want here. - UTF16ToUTF8(utf16.data(), utf16.length(), &ret); - return ret; -} - -#elif defined(WCHAR_T_IS_UTF16) -// Easy case since we can use the "wide" versions we already wrote above. - -bool UTF8ToUTF16(const char* src, size_t src_len, string16* output) { - return UTF8ToWide(src, src_len, output); -} - -string16 UTF8ToUTF16(StringPiece utf8) { - return UTF8ToWide(utf8); -} - -bool UTF16ToUTF8(const char16* src, size_t src_len, std::string* output) { - return WideToUTF8(src, src_len, output); -} - -std::string UTF16ToUTF8(StringPiece16 utf16) { - if (IsStringASCII(utf16)) - return std::string(utf16.data(), utf16.data() + utf16.length()); - - std::string ret; - PrepareForUTF8Output(utf16.data(), utf16.length(), &ret); - ConvertUnicode(utf16.data(), utf16.length(), &ret); - return ret; -} - -#endif - -string16 ASCIIToUTF16(StringPiece ascii) { - DCHECK(IsStringASCII(ascii)) << ascii; - return string16(ascii.begin(), ascii.end()); -} - -std::string UTF16ToASCII(StringPiece16 utf16) { - DCHECK(IsStringASCII(utf16)) << UTF16ToUTF8(utf16); - return std::string(utf16.begin(), utf16.end()); -} - -} // namespace base diff --git a/security/sandbox/chromium/base/strings/utf_string_conversions.h b/security/sandbox/chromium/base/strings/utf_string_conversions.h deleted file mode 100644 index 2995f4cbc..000000000 --- a/security/sandbox/chromium/base/strings/utf_string_conversions.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_STRINGS_UTF_STRING_CONVERSIONS_H_ -#define BASE_STRINGS_UTF_STRING_CONVERSIONS_H_ - -#include <stddef.h> - -#include <string> - -#include "base/base_export.h" -#include "base/strings/string16.h" -#include "base/strings/string_piece.h" - -namespace base { - -// These convert between UTF-8, -16, and -32 strings. They are potentially slow, -// so avoid unnecessary conversions. The low-level versions return a boolean -// indicating whether the conversion was 100% valid. In this case, it will still -// do the best it can and put the result in the output buffer. The versions that -// return strings ignore this error and just return the best conversion -// possible. -BASE_EXPORT bool WideToUTF8(const wchar_t* src, size_t src_len, - std::string* output); -BASE_EXPORT std::string WideToUTF8(const std::wstring& wide); -BASE_EXPORT bool UTF8ToWide(const char* src, size_t src_len, - std::wstring* output); -BASE_EXPORT std::wstring UTF8ToWide(StringPiece utf8); - -BASE_EXPORT bool WideToUTF16(const wchar_t* src, size_t src_len, - string16* output); -BASE_EXPORT string16 WideToUTF16(const std::wstring& wide); -BASE_EXPORT bool UTF16ToWide(const char16* src, size_t src_len, - std::wstring* output); -BASE_EXPORT std::wstring UTF16ToWide(const string16& utf16); - -BASE_EXPORT bool UTF8ToUTF16(const char* src, size_t src_len, string16* output); -BASE_EXPORT string16 UTF8ToUTF16(StringPiece utf8); -BASE_EXPORT bool UTF16ToUTF8(const char16* src, size_t src_len, - std::string* output); -BASE_EXPORT std::string UTF16ToUTF8(StringPiece16 utf16); - -// This converts an ASCII string, typically a hardcoded constant, to a UTF16 -// string. -BASE_EXPORT string16 ASCIIToUTF16(StringPiece ascii); - -// Converts to 7-bit ASCII by truncating. The result must be known to be ASCII -// beforehand. -BASE_EXPORT std::string UTF16ToASCII(StringPiece16 utf16); - -} // namespace base - -#endif // BASE_STRINGS_UTF_STRING_CONVERSIONS_H_ diff --git a/security/sandbox/chromium/base/synchronization/condition_variable.h b/security/sandbox/chromium/base/synchronization/condition_variable.h deleted file mode 100644 index a41b2ba5a..000000000 --- a/security/sandbox/chromium/base/synchronization/condition_variable.h +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// ConditionVariable wraps pthreads condition variable synchronization or, on -// Windows, simulates it. This functionality is very helpful for having -// several threads wait for an event, as is common with a thread pool managed -// by a master. The meaning of such an event in the (worker) thread pool -// scenario is that additional tasks are now available for processing. It is -// used in Chrome in the DNS prefetching system to notify worker threads that -// a queue now has items (tasks) which need to be tended to. A related use -// would have a pool manager waiting on a ConditionVariable, waiting for a -// thread in the pool to announce (signal) that there is now more room in a -// (bounded size) communications queue for the manager to deposit tasks, or, -// as a second example, that the queue of tasks is completely empty and all -// workers are waiting. -// -// USAGE NOTE 1: spurious signal events are possible with this and -// most implementations of condition variables. As a result, be -// *sure* to retest your condition before proceeding. The following -// is a good example of doing this correctly: -// -// while (!work_to_be_done()) Wait(...); -// -// In contrast do NOT do the following: -// -// if (!work_to_be_done()) Wait(...); // Don't do this. -// -// Especially avoid the above if you are relying on some other thread only -// issuing a signal up *if* there is work-to-do. There can/will -// be spurious signals. Recheck state on waiting thread before -// assuming the signal was intentional. Caveat caller ;-). -// -// USAGE NOTE 2: Broadcast() frees up all waiting threads at once, -// which leads to contention for the locks they all held when they -// called Wait(). This results in POOR performance. A much better -// approach to getting a lot of threads out of Wait() is to have each -// thread (upon exiting Wait()) call Signal() to free up another -// Wait'ing thread. Look at condition_variable_unittest.cc for -// both examples. -// -// Broadcast() can be used nicely during teardown, as it gets the job -// done, and leaves no sleeping threads... and performance is less -// critical at that point. -// -// The semantics of Broadcast() are carefully crafted so that *all* -// threads that were waiting when the request was made will indeed -// get signaled. Some implementations mess up, and don't signal them -// all, while others allow the wait to be effectively turned off (for -// a while while waiting threads come around). This implementation -// appears correct, as it will not "lose" any signals, and will guarantee -// that all threads get signaled by Broadcast(). -// -// This implementation offers support for "performance" in its selection of -// which thread to revive. Performance, in direct contrast with "fairness," -// assures that the thread that most recently began to Wait() is selected by -// Signal to revive. Fairness would (if publicly supported) assure that the -// thread that has Wait()ed the longest is selected. The default policy -// may improve performance, as the selected thread may have a greater chance of -// having some of its stack data in various CPU caches. -// -// For a discussion of the many very subtle implementation details, see the FAQ -// at the end of condition_variable_win.cc. - -#ifndef BASE_SYNCHRONIZATION_CONDITION_VARIABLE_H_ -#define BASE_SYNCHRONIZATION_CONDITION_VARIABLE_H_ - -#include "base/base_export.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/synchronization/lock.h" -#include "build/build_config.h" - -#if defined(OS_POSIX) -#include <pthread.h> -#endif - -namespace base { - -class ConditionVarImpl; -class TimeDelta; - -class BASE_EXPORT ConditionVariable { - public: - // Construct a cv for use with ONLY one user lock. - explicit ConditionVariable(Lock* user_lock); - - ~ConditionVariable(); - - // Wait() releases the caller's critical section atomically as it starts to - // sleep, and the reacquires it when it is signaled. - void Wait(); - void TimedWait(const TimeDelta& max_time); - - // Broadcast() revives all waiting threads. - void Broadcast(); - // Signal() revives one waiting thread. - void Signal(); - - private: - -#if defined(OS_WIN) - ConditionVarImpl* impl_; -#elif defined(OS_POSIX) - pthread_cond_t condition_; - pthread_mutex_t* user_mutex_; -#if DCHECK_IS_ON() - base::Lock* user_lock_; // Needed to adjust shadow lock state on wait. -#endif - -#endif - - DISALLOW_COPY_AND_ASSIGN(ConditionVariable); -}; - -} // namespace base - -#endif // BASE_SYNCHRONIZATION_CONDITION_VARIABLE_H_ diff --git a/security/sandbox/chromium/base/synchronization/condition_variable_posix.cc b/security/sandbox/chromium/base/synchronization/condition_variable_posix.cc deleted file mode 100644 index d86fd180e..000000000 --- a/security/sandbox/chromium/base/synchronization/condition_variable_posix.cc +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/synchronization/condition_variable.h" - -#include <errno.h> -#include <stdint.h> -#include <sys/time.h> - -#include "base/synchronization/lock.h" -#include "base/threading/thread_restrictions.h" -#include "base/time/time.h" -#include "build/build_config.h" - -namespace base { - -ConditionVariable::ConditionVariable(Lock* user_lock) - : user_mutex_(user_lock->lock_.native_handle()) -#if DCHECK_IS_ON() - , user_lock_(user_lock) -#endif -{ - int rv = 0; - // http://crbug.com/293736 - // NaCl doesn't support monotonic clock based absolute deadlines. - // On older Android platform versions, it's supported through the - // non-standard pthread_cond_timedwait_monotonic_np. Newer platform - // versions have pthread_condattr_setclock. - // Mac can use relative time deadlines. -#if !defined(OS_MACOSX) && !defined(OS_NACL) && \ - !(defined(OS_ANDROID) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)) - pthread_condattr_t attrs; - rv = pthread_condattr_init(&attrs); - DCHECK_EQ(0, rv); - pthread_condattr_setclock(&attrs, CLOCK_MONOTONIC); - rv = pthread_cond_init(&condition_, &attrs); - pthread_condattr_destroy(&attrs); -#else - rv = pthread_cond_init(&condition_, NULL); -#endif - DCHECK_EQ(0, rv); -} - -ConditionVariable::~ConditionVariable() { -#if defined(OS_MACOSX) - // This hack is necessary to avoid a fatal pthreads subsystem bug in the - // Darwin kernel. http://crbug.com/517681. - { - base::Lock lock; - base::AutoLock l(lock); - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 1; - pthread_cond_timedwait_relative_np(&condition_, lock.lock_.native_handle(), - &ts); - } -#endif - - int rv = pthread_cond_destroy(&condition_); - DCHECK_EQ(0, rv); -} - -void ConditionVariable::Wait() { - base::ThreadRestrictions::AssertWaitAllowed(); -#if DCHECK_IS_ON() - user_lock_->CheckHeldAndUnmark(); -#endif - int rv = pthread_cond_wait(&condition_, user_mutex_); - DCHECK_EQ(0, rv); -#if DCHECK_IS_ON() - user_lock_->CheckUnheldAndMark(); -#endif -} - -void ConditionVariable::TimedWait(const TimeDelta& max_time) { - base::ThreadRestrictions::AssertWaitAllowed(); - int64_t usecs = max_time.InMicroseconds(); - struct timespec relative_time; - relative_time.tv_sec = usecs / Time::kMicrosecondsPerSecond; - relative_time.tv_nsec = - (usecs % Time::kMicrosecondsPerSecond) * Time::kNanosecondsPerMicrosecond; - -#if DCHECK_IS_ON() - user_lock_->CheckHeldAndUnmark(); -#endif - -#if defined(OS_MACOSX) - int rv = pthread_cond_timedwait_relative_np( - &condition_, user_mutex_, &relative_time); -#else - // The timeout argument to pthread_cond_timedwait is in absolute time. - struct timespec absolute_time; -#if defined(OS_NACL) - // See comment in constructor for why this is different in NaCl. - struct timeval now; - gettimeofday(&now, NULL); - absolute_time.tv_sec = now.tv_sec; - absolute_time.tv_nsec = now.tv_usec * Time::kNanosecondsPerMicrosecond; -#else - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - absolute_time.tv_sec = now.tv_sec; - absolute_time.tv_nsec = now.tv_nsec; -#endif - - absolute_time.tv_sec += relative_time.tv_sec; - absolute_time.tv_nsec += relative_time.tv_nsec; - absolute_time.tv_sec += absolute_time.tv_nsec / Time::kNanosecondsPerSecond; - absolute_time.tv_nsec %= Time::kNanosecondsPerSecond; - DCHECK_GE(absolute_time.tv_sec, now.tv_sec); // Overflow paranoia - -#if defined(OS_ANDROID) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC) - int rv = pthread_cond_timedwait_monotonic_np( - &condition_, user_mutex_, &absolute_time); -#else - int rv = pthread_cond_timedwait(&condition_, user_mutex_, &absolute_time); -#endif // OS_ANDROID && HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC -#endif // OS_MACOSX - - DCHECK(rv == 0 || rv == ETIMEDOUT); -#if DCHECK_IS_ON() - user_lock_->CheckUnheldAndMark(); -#endif -} - -void ConditionVariable::Broadcast() { - int rv = pthread_cond_broadcast(&condition_); - DCHECK_EQ(0, rv); -} - -void ConditionVariable::Signal() { - int rv = pthread_cond_signal(&condition_); - DCHECK_EQ(0, rv); -} - -} // namespace base diff --git a/security/sandbox/chromium/base/synchronization/lock.cc b/security/sandbox/chromium/base/synchronization/lock.cc deleted file mode 100644 index 03297ada5..000000000 --- a/security/sandbox/chromium/base/synchronization/lock.cc +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file is used for debugging assertion support. The Lock class -// is functionally a wrapper around the LockImpl class, so the only -// real intelligence in the class is in the debugging logic. - -#include "base/synchronization/lock.h" - -#if DCHECK_IS_ON() - -namespace base { - -Lock::Lock() : lock_() { -} - -Lock::~Lock() { - DCHECK(owning_thread_ref_.is_null()); -} - -void Lock::AssertAcquired() const { - DCHECK(owning_thread_ref_ == PlatformThread::CurrentRef()); -} - -void Lock::CheckHeldAndUnmark() { - DCHECK(owning_thread_ref_ == PlatformThread::CurrentRef()); - owning_thread_ref_ = PlatformThreadRef(); -} - -void Lock::CheckUnheldAndMark() { - DCHECK(owning_thread_ref_.is_null()); - owning_thread_ref_ = PlatformThread::CurrentRef(); -} - -} // namespace base - -#endif // DCHECK_IS_ON() diff --git a/security/sandbox/chromium/base/synchronization/lock.h b/security/sandbox/chromium/base/synchronization/lock.h deleted file mode 100644 index f7dd35dcc..000000000 --- a/security/sandbox/chromium/base/synchronization/lock.h +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_SYNCHRONIZATION_LOCK_H_ -#define BASE_SYNCHRONIZATION_LOCK_H_ - -#include "base/base_export.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/synchronization/lock_impl.h" -#include "base/threading/platform_thread.h" -#include "build/build_config.h" - -namespace base { - -// A convenient wrapper for an OS specific critical section. The only real -// intelligence in this class is in debug mode for the support for the -// AssertAcquired() method. -class BASE_EXPORT Lock { - public: -#if !DCHECK_IS_ON() - // Optimized wrapper implementation - Lock() : lock_() {} - ~Lock() {} - void Acquire() { lock_.Lock(); } - void Release() { lock_.Unlock(); } - - // If the lock is not held, take it and return true. If the lock is already - // held by another thread, immediately return false. This must not be called - // by a thread already holding the lock (what happens is undefined and an - // assertion may fail). - bool Try() { return lock_.Try(); } - - // Null implementation if not debug. - void AssertAcquired() const {} -#else - Lock(); - ~Lock(); - - // NOTE: Although windows critical sections support recursive locks, we do not - // allow this, and we will commonly fire a DCHECK() if a thread attempts to - // acquire the lock a second time (while already holding it). - void Acquire() { - lock_.Lock(); - CheckUnheldAndMark(); - } - void Release() { - CheckHeldAndUnmark(); - lock_.Unlock(); - } - - bool Try() { - bool rv = lock_.Try(); - if (rv) { - CheckUnheldAndMark(); - } - return rv; - } - - void AssertAcquired() const; -#endif // DCHECK_IS_ON() - -#if defined(OS_POSIX) - // The posix implementation of ConditionVariable needs to be able - // to see our lock and tweak our debugging counters, as it releases - // and acquires locks inside of pthread_cond_{timed,}wait. - friend class ConditionVariable; -#elif defined(OS_WIN) - // The Windows Vista implementation of ConditionVariable needs the - // native handle of the critical section. - friend class WinVistaCondVar; -#endif - - private: -#if DCHECK_IS_ON() - // Members and routines taking care of locks assertions. - // Note that this checks for recursive locks and allows them - // if the variable is set. This is allowed by the underlying implementation - // on windows but not on Posix, so we're doing unneeded checks on Posix. - // It's worth it to share the code. - void CheckHeldAndUnmark(); - void CheckUnheldAndMark(); - - // All private data is implicitly protected by lock_. - // Be VERY careful to only access members under that lock. - base::PlatformThreadRef owning_thread_ref_; -#endif // DCHECK_IS_ON() - - // Platform specific underlying lock implementation. - internal::LockImpl lock_; - - DISALLOW_COPY_AND_ASSIGN(Lock); -}; - -// A helper class that acquires the given Lock while the AutoLock is in scope. -class AutoLock { - public: - struct AlreadyAcquired {}; - - explicit AutoLock(Lock& lock) : lock_(lock) { - lock_.Acquire(); - } - - AutoLock(Lock& lock, const AlreadyAcquired&) : lock_(lock) { - lock_.AssertAcquired(); - } - - ~AutoLock() { - lock_.AssertAcquired(); - lock_.Release(); - } - - private: - Lock& lock_; - DISALLOW_COPY_AND_ASSIGN(AutoLock); -}; - -// AutoUnlock is a helper that will Release() the |lock| argument in the -// constructor, and re-Acquire() it in the destructor. -class AutoUnlock { - public: - explicit AutoUnlock(Lock& lock) : lock_(lock) { - // We require our caller to have the lock. - lock_.AssertAcquired(); - lock_.Release(); - } - - ~AutoUnlock() { - lock_.Acquire(); - } - - private: - Lock& lock_; - DISALLOW_COPY_AND_ASSIGN(AutoUnlock); -}; - -} // namespace base - -#endif // BASE_SYNCHRONIZATION_LOCK_H_ diff --git a/security/sandbox/chromium/base/synchronization/lock_impl.h b/security/sandbox/chromium/base/synchronization/lock_impl.h deleted file mode 100644 index ed85987b3..000000000 --- a/security/sandbox/chromium/base/synchronization/lock_impl.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_SYNCHRONIZATION_LOCK_IMPL_H_ -#define BASE_SYNCHRONIZATION_LOCK_IMPL_H_ - -#include "base/base_export.h" -#include "base/macros.h" -#include "build/build_config.h" - -#if defined(OS_WIN) -#include <windows.h> -#elif defined(OS_POSIX) -#include <pthread.h> -#endif - -namespace base { -namespace internal { - -// This class implements the underlying platform-specific spin-lock mechanism -// used for the Lock class. Most users should not use LockImpl directly, but -// should instead use Lock. -class BASE_EXPORT LockImpl { - public: -#if defined(OS_WIN) - typedef CRITICAL_SECTION NativeHandle; -#elif defined(OS_POSIX) - typedef pthread_mutex_t NativeHandle; -#endif - - LockImpl(); - ~LockImpl(); - - // If the lock is not held, take it and return true. If the lock is already - // held by something else, immediately return false. - bool Try(); - - // Take the lock, blocking until it is available if necessary. - void Lock(); - - // Release the lock. This must only be called by the lock's holder: after - // a successful call to Try, or a call to Lock. - void Unlock(); - - // Return the native underlying lock. - // TODO(awalker): refactor lock and condition variables so that this is - // unnecessary. - NativeHandle* native_handle() { return &native_handle_; } - - private: - NativeHandle native_handle_; - - DISALLOW_COPY_AND_ASSIGN(LockImpl); -}; - -} // namespace internal -} // namespace base - -#endif // BASE_SYNCHRONIZATION_LOCK_IMPL_H_ diff --git a/security/sandbox/chromium/base/synchronization/lock_impl_posix.cc b/security/sandbox/chromium/base/synchronization/lock_impl_posix.cc deleted file mode 100644 index 5619adaf5..000000000 --- a/security/sandbox/chromium/base/synchronization/lock_impl_posix.cc +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/synchronization/lock_impl.h" - -#include <errno.h> -#include <string.h> - -#include "base/logging.h" - -namespace base { -namespace internal { - -LockImpl::LockImpl() { -#ifndef NDEBUG - // In debug, setup attributes for lock error checking. - pthread_mutexattr_t mta; - int rv = pthread_mutexattr_init(&mta); - DCHECK_EQ(rv, 0) << ". " << strerror(rv); - rv = pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_ERRORCHECK); - DCHECK_EQ(rv, 0) << ". " << strerror(rv); - rv = pthread_mutex_init(&native_handle_, &mta); - DCHECK_EQ(rv, 0) << ". " << strerror(rv); - rv = pthread_mutexattr_destroy(&mta); - DCHECK_EQ(rv, 0) << ". " << strerror(rv); -#else - // In release, go with the default lock attributes. - pthread_mutex_init(&native_handle_, NULL); -#endif -} - -LockImpl::~LockImpl() { - int rv = pthread_mutex_destroy(&native_handle_); - DCHECK_EQ(rv, 0) << ". " << strerror(rv); -} - -bool LockImpl::Try() { - int rv = pthread_mutex_trylock(&native_handle_); - DCHECK(rv == 0 || rv == EBUSY) << ". " << strerror(rv); - return rv == 0; -} - -void LockImpl::Lock() { - int rv = pthread_mutex_lock(&native_handle_); - DCHECK_EQ(rv, 0) << ". " << strerror(rv); -} - -void LockImpl::Unlock() { - int rv = pthread_mutex_unlock(&native_handle_); - DCHECK_EQ(rv, 0) << ". " << strerror(rv); -} - -} // namespace internal -} // namespace base diff --git a/security/sandbox/chromium/base/synchronization/lock_impl_win.cc b/security/sandbox/chromium/base/synchronization/lock_impl_win.cc deleted file mode 100644 index fbc1bdd46..000000000 --- a/security/sandbox/chromium/base/synchronization/lock_impl_win.cc +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/synchronization/lock_impl.h" - -namespace base { -namespace internal { - -LockImpl::LockImpl() { - // The second parameter is the spin count, for short-held locks it avoid the - // contending thread from going to sleep which helps performance greatly. - ::InitializeCriticalSectionAndSpinCount(&native_handle_, 2000); -} - -LockImpl::~LockImpl() { - ::DeleteCriticalSection(&native_handle_); -} - -bool LockImpl::Try() { - if (::TryEnterCriticalSection(&native_handle_) != FALSE) { - return true; - } - return false; -} - -void LockImpl::Lock() { - ::EnterCriticalSection(&native_handle_); -} - -void LockImpl::Unlock() { - ::LeaveCriticalSection(&native_handle_); -} - -} // namespace internal -} // namespace base diff --git a/security/sandbox/chromium/base/synchronization/waitable_event.h b/security/sandbox/chromium/base/synchronization/waitable_event.h deleted file mode 100644 index b5d91d00b..000000000 --- a/security/sandbox/chromium/base/synchronization/waitable_event.h +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_SYNCHRONIZATION_WAITABLE_EVENT_H_ -#define BASE_SYNCHRONIZATION_WAITABLE_EVENT_H_ - -#include <stddef.h> - -#include "base/base_export.h" -#include "base/macros.h" -#include "build/build_config.h" - -#if defined(OS_WIN) -#include "base/win/scoped_handle.h" -#endif - -#if defined(OS_POSIX) -#include <list> -#include <utility> -#include "base/memory/ref_counted.h" -#include "base/synchronization/lock.h" -#endif - -namespace base { - -class TimeDelta; - -// A WaitableEvent can be a useful thread synchronization tool when you want to -// allow one thread to wait for another thread to finish some work. For -// non-Windows systems, this can only be used from within a single address -// space. -// -// Use a WaitableEvent when you would otherwise use a Lock+ConditionVariable to -// protect a simple boolean value. However, if you find yourself using a -// WaitableEvent in conjunction with a Lock to wait for a more complex state -// change (e.g., for an item to be added to a queue), then you should probably -// be using a ConditionVariable instead of a WaitableEvent. -// -// NOTE: On Windows, this class provides a subset of the functionality afforded -// by a Windows event object. This is intentional. If you are writing Windows -// specific code and you need other features of a Windows event, then you might -// be better off just using an Windows event directly. -class BASE_EXPORT WaitableEvent { - public: - // If manual_reset is true, then to set the event state to non-signaled, a - // consumer must call the Reset method. If this parameter is false, then the - // system automatically resets the event state to non-signaled after a single - // waiting thread has been released. - WaitableEvent(bool manual_reset, bool initially_signaled); - -#if defined(OS_WIN) - // Create a WaitableEvent from an Event HANDLE which has already been - // created. This objects takes ownership of the HANDLE and will close it when - // deleted. - explicit WaitableEvent(win::ScopedHandle event_handle); -#endif - - ~WaitableEvent(); - - // Put the event in the un-signaled state. - void Reset(); - - // Put the event in the signaled state. Causing any thread blocked on Wait - // to be woken up. - void Signal(); - - // Returns true if the event is in the signaled state, else false. If this - // is not a manual reset event, then this test will cause a reset. - bool IsSignaled(); - - // Wait indefinitely for the event to be signaled. Wait's return "happens - // after" |Signal| has completed. This means that it's safe for a - // WaitableEvent to synchronise its own destruction, like this: - // - // WaitableEvent *e = new WaitableEvent; - // SendToOtherThread(e); - // e->Wait(); - // delete e; - void Wait(); - - // Wait up until max_time has passed for the event to be signaled. Returns - // true if the event was signaled. If this method returns false, then it - // does not necessarily mean that max_time was exceeded. - // - // TimedWait can synchronise its own destruction like |Wait|. - bool TimedWait(const TimeDelta& max_time); - -#if defined(OS_WIN) - HANDLE handle() const { return handle_.Get(); } -#endif - - // Wait, synchronously, on multiple events. - // waitables: an array of WaitableEvent pointers - // count: the number of elements in @waitables - // - // returns: the index of a WaitableEvent which has been signaled. - // - // You MUST NOT delete any of the WaitableEvent objects while this wait is - // happening, however WaitMany's return "happens after" the |Signal| call - // that caused it has completed, like |Wait|. - static size_t WaitMany(WaitableEvent** waitables, size_t count); - - // For asynchronous waiting, see WaitableEventWatcher - - // This is a private helper class. It's here because it's used by friends of - // this class (such as WaitableEventWatcher) to be able to enqueue elements - // of the wait-list - class Waiter { - public: - // Signal the waiter to wake up. - // - // Consider the case of a Waiter which is in multiple WaitableEvent's - // wait-lists. Each WaitableEvent is automatic-reset and two of them are - // signaled at the same time. Now, each will wake only the first waiter in - // the wake-list before resetting. However, if those two waiters happen to - // be the same object (as can happen if another thread didn't have a chance - // to dequeue the waiter from the other wait-list in time), two auto-resets - // will have happened, but only one waiter has been signaled! - // - // Because of this, a Waiter may "reject" a wake by returning false. In - // this case, the auto-reset WaitableEvent shouldn't act as if anything has - // been notified. - virtual bool Fire(WaitableEvent* signaling_event) = 0; - - // Waiters may implement this in order to provide an extra condition for - // two Waiters to be considered equal. In WaitableEvent::Dequeue, if the - // pointers match then this function is called as a final check. See the - // comments in ~Handle for why. - virtual bool Compare(void* tag) = 0; - - protected: - virtual ~Waiter() {} - }; - - private: - friend class WaitableEventWatcher; - -#if defined(OS_WIN) - win::ScopedHandle handle_; -#else - // On Windows, one can close a HANDLE which is currently being waited on. The - // MSDN documentation says that the resulting behaviour is 'undefined', but - // it doesn't crash. However, if we were to include the following members - // directly then, on POSIX, one couldn't use WaitableEventWatcher to watch an - // event which gets deleted. This mismatch has bitten us several times now, - // so we have a kernel of the WaitableEvent, which is reference counted. - // WaitableEventWatchers may then take a reference and thus match the Windows - // behaviour. - struct WaitableEventKernel : - public RefCountedThreadSafe<WaitableEventKernel> { - public: - WaitableEventKernel(bool manual_reset, bool initially_signaled); - - bool Dequeue(Waiter* waiter, void* tag); - - base::Lock lock_; - const bool manual_reset_; - bool signaled_; - std::list<Waiter*> waiters_; - - private: - friend class RefCountedThreadSafe<WaitableEventKernel>; - ~WaitableEventKernel(); - }; - - typedef std::pair<WaitableEvent*, size_t> WaiterAndIndex; - - // When dealing with arrays of WaitableEvent*, we want to sort by the address - // of the WaitableEvent in order to have a globally consistent locking order. - // In that case we keep them, in sorted order, in an array of pairs where the - // second element is the index of the WaitableEvent in the original, - // unsorted, array. - static size_t EnqueueMany(WaiterAndIndex* waitables, - size_t count, Waiter* waiter); - - bool SignalAll(); - bool SignalOne(); - void Enqueue(Waiter* waiter); - - scoped_refptr<WaitableEventKernel> kernel_; -#endif - - DISALLOW_COPY_AND_ASSIGN(WaitableEvent); -}; - -} // namespace base - -#endif // BASE_SYNCHRONIZATION_WAITABLE_EVENT_H_ diff --git a/security/sandbox/chromium/base/synchronization/waitable_event_posix.cc b/security/sandbox/chromium/base/synchronization/waitable_event_posix.cc deleted file mode 100644 index 64d4376fe..000000000 --- a/security/sandbox/chromium/base/synchronization/waitable_event_posix.cc +++ /dev/null @@ -1,417 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stddef.h> - -#include <algorithm> -#include <vector> - -#include "base/logging.h" -#include "base/synchronization/condition_variable.h" -#include "base/synchronization/lock.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/thread_restrictions.h" - -// ----------------------------------------------------------------------------- -// A WaitableEvent on POSIX is implemented as a wait-list. Currently we don't -// support cross-process events (where one process can signal an event which -// others are waiting on). Because of this, we can avoid having one thread per -// listener in several cases. -// -// The WaitableEvent maintains a list of waiters, protected by a lock. Each -// waiter is either an async wait, in which case we have a Task and the -// MessageLoop to run it on, or a blocking wait, in which case we have the -// condition variable to signal. -// -// Waiting involves grabbing the lock and adding oneself to the wait list. Async -// waits can be canceled, which means grabbing the lock and removing oneself -// from the list. -// -// Waiting on multiple events is handled by adding a single, synchronous wait to -// the wait-list of many events. An event passes a pointer to itself when -// firing a waiter and so we can store that pointer to find out which event -// triggered. -// ----------------------------------------------------------------------------- - -namespace base { - -// ----------------------------------------------------------------------------- -// This is just an abstract base class for waking the two types of waiters -// ----------------------------------------------------------------------------- -WaitableEvent::WaitableEvent(bool manual_reset, bool initially_signaled) - : kernel_(new WaitableEventKernel(manual_reset, initially_signaled)) { -} - -WaitableEvent::~WaitableEvent() { -} - -void WaitableEvent::Reset() { - base::AutoLock locked(kernel_->lock_); - kernel_->signaled_ = false; -} - -void WaitableEvent::Signal() { - base::AutoLock locked(kernel_->lock_); - - if (kernel_->signaled_) - return; - - if (kernel_->manual_reset_) { - SignalAll(); - kernel_->signaled_ = true; - } else { - // In the case of auto reset, if no waiters were woken, we remain - // signaled. - if (!SignalOne()) - kernel_->signaled_ = true; - } -} - -bool WaitableEvent::IsSignaled() { - base::AutoLock locked(kernel_->lock_); - - const bool result = kernel_->signaled_; - if (result && !kernel_->manual_reset_) - kernel_->signaled_ = false; - return result; -} - -// ----------------------------------------------------------------------------- -// Synchronous waits - -// ----------------------------------------------------------------------------- -// This is a synchronous waiter. The thread is waiting on the given condition -// variable and the fired flag in this object. -// ----------------------------------------------------------------------------- -class SyncWaiter : public WaitableEvent::Waiter { - public: - SyncWaiter() - : fired_(false), - signaling_event_(NULL), - lock_(), - cv_(&lock_) { - } - - bool Fire(WaitableEvent* signaling_event) override { - base::AutoLock locked(lock_); - - if (fired_) - return false; - - fired_ = true; - signaling_event_ = signaling_event; - - cv_.Broadcast(); - - // Unlike AsyncWaiter objects, SyncWaiter objects are stack-allocated on - // the blocking thread's stack. There is no |delete this;| in Fire. The - // SyncWaiter object is destroyed when it goes out of scope. - - return true; - } - - WaitableEvent* signaling_event() const { - return signaling_event_; - } - - // --------------------------------------------------------------------------- - // These waiters are always stack allocated and don't delete themselves. Thus - // there's no problem and the ABA tag is the same as the object pointer. - // --------------------------------------------------------------------------- - bool Compare(void* tag) override { return this == tag; } - - // --------------------------------------------------------------------------- - // Called with lock held. - // --------------------------------------------------------------------------- - bool fired() const { - return fired_; - } - - // --------------------------------------------------------------------------- - // During a TimedWait, we need a way to make sure that an auto-reset - // WaitableEvent doesn't think that this event has been signaled between - // unlocking it and removing it from the wait-list. Called with lock held. - // --------------------------------------------------------------------------- - void Disable() { - fired_ = true; - } - - base::Lock* lock() { - return &lock_; - } - - base::ConditionVariable* cv() { - return &cv_; - } - - private: - bool fired_; - WaitableEvent* signaling_event_; // The WaitableEvent which woke us - base::Lock lock_; - base::ConditionVariable cv_; -}; - -void WaitableEvent::Wait() { - bool result = TimedWait(TimeDelta::FromSeconds(-1)); - DCHECK(result) << "TimedWait() should never fail with infinite timeout"; -} - -bool WaitableEvent::TimedWait(const TimeDelta& max_time) { - base::ThreadRestrictions::AssertWaitAllowed(); - const TimeTicks end_time(TimeTicks::Now() + max_time); - const bool finite_time = max_time.ToInternalValue() >= 0; - - kernel_->lock_.Acquire(); - if (kernel_->signaled_) { - if (!kernel_->manual_reset_) { - // In this case we were signaled when we had no waiters. Now that - // someone has waited upon us, we can automatically reset. - kernel_->signaled_ = false; - } - - kernel_->lock_.Release(); - return true; - } - - SyncWaiter sw; - sw.lock()->Acquire(); - - Enqueue(&sw); - kernel_->lock_.Release(); - // We are violating locking order here by holding the SyncWaiter lock but not - // the WaitableEvent lock. However, this is safe because we don't lock @lock_ - // again before unlocking it. - - for (;;) { - const TimeTicks current_time(TimeTicks::Now()); - - if (sw.fired() || (finite_time && current_time >= end_time)) { - const bool return_value = sw.fired(); - - // We can't acquire @lock_ before releasing the SyncWaiter lock (because - // of locking order), however, in between the two a signal could be fired - // and @sw would accept it, however we will still return false, so the - // signal would be lost on an auto-reset WaitableEvent. Thus we call - // Disable which makes sw::Fire return false. - sw.Disable(); - sw.lock()->Release(); - - // This is a bug that has been enshrined in the interface of - // WaitableEvent now: |Dequeue| is called even when |sw.fired()| is true, - // even though it'll always return false in that case. However, taking - // the lock ensures that |Signal| has completed before we return and - // means that a WaitableEvent can synchronise its own destruction. - kernel_->lock_.Acquire(); - kernel_->Dequeue(&sw, &sw); - kernel_->lock_.Release(); - - return return_value; - } - - if (finite_time) { - const TimeDelta max_wait(end_time - current_time); - sw.cv()->TimedWait(max_wait); - } else { - sw.cv()->Wait(); - } - } -} - -// ----------------------------------------------------------------------------- -// Synchronous waiting on multiple objects. - -static bool // StrictWeakOrdering -cmp_fst_addr(const std::pair<WaitableEvent*, unsigned> &a, - const std::pair<WaitableEvent*, unsigned> &b) { - return a.first < b.first; -} - -// static -size_t WaitableEvent::WaitMany(WaitableEvent** raw_waitables, - size_t count) { - base::ThreadRestrictions::AssertWaitAllowed(); - DCHECK(count) << "Cannot wait on no events"; - - // We need to acquire the locks in a globally consistent order. Thus we sort - // the array of waitables by address. We actually sort a pairs so that we can - // map back to the original index values later. - std::vector<std::pair<WaitableEvent*, size_t> > waitables; - waitables.reserve(count); - for (size_t i = 0; i < count; ++i) - waitables.push_back(std::make_pair(raw_waitables[i], i)); - - DCHECK_EQ(count, waitables.size()); - - sort(waitables.begin(), waitables.end(), cmp_fst_addr); - - // The set of waitables must be distinct. Since we have just sorted by - // address, we can check this cheaply by comparing pairs of consecutive - // elements. - for (size_t i = 0; i < waitables.size() - 1; ++i) { - DCHECK(waitables[i].first != waitables[i+1].first); - } - - SyncWaiter sw; - - const size_t r = EnqueueMany(&waitables[0], count, &sw); - if (r) { - // One of the events is already signaled. The SyncWaiter has not been - // enqueued anywhere. EnqueueMany returns the count of remaining waitables - // when the signaled one was seen, so the index of the signaled event is - // @count - @r. - return waitables[count - r].second; - } - - // At this point, we hold the locks on all the WaitableEvents and we have - // enqueued our waiter in them all. - sw.lock()->Acquire(); - // Release the WaitableEvent locks in the reverse order - for (size_t i = 0; i < count; ++i) { - waitables[count - (1 + i)].first->kernel_->lock_.Release(); - } - - for (;;) { - if (sw.fired()) - break; - - sw.cv()->Wait(); - } - sw.lock()->Release(); - - // The address of the WaitableEvent which fired is stored in the SyncWaiter. - WaitableEvent *const signaled_event = sw.signaling_event(); - // This will store the index of the raw_waitables which fired. - size_t signaled_index = 0; - - // Take the locks of each WaitableEvent in turn (except the signaled one) and - // remove our SyncWaiter from the wait-list - for (size_t i = 0; i < count; ++i) { - if (raw_waitables[i] != signaled_event) { - raw_waitables[i]->kernel_->lock_.Acquire(); - // There's no possible ABA issue with the address of the SyncWaiter here - // because it lives on the stack. Thus the tag value is just the pointer - // value again. - raw_waitables[i]->kernel_->Dequeue(&sw, &sw); - raw_waitables[i]->kernel_->lock_.Release(); - } else { - // By taking this lock here we ensure that |Signal| has completed by the - // time we return, because |Signal| holds this lock. This matches the - // behaviour of |Wait| and |TimedWait|. - raw_waitables[i]->kernel_->lock_.Acquire(); - raw_waitables[i]->kernel_->lock_.Release(); - signaled_index = i; - } - } - - return signaled_index; -} - -// ----------------------------------------------------------------------------- -// If return value == 0: -// The locks of the WaitableEvents have been taken in order and the Waiter has -// been enqueued in the wait-list of each. None of the WaitableEvents are -// currently signaled -// else: -// None of the WaitableEvent locks are held. The Waiter has not been enqueued -// in any of them and the return value is the index of the first WaitableEvent -// which was signaled, from the end of the array. -// ----------------------------------------------------------------------------- -// static -size_t WaitableEvent::EnqueueMany - (std::pair<WaitableEvent*, size_t>* waitables, - size_t count, Waiter* waiter) { - if (!count) - return 0; - - waitables[0].first->kernel_->lock_.Acquire(); - if (waitables[0].first->kernel_->signaled_) { - if (!waitables[0].first->kernel_->manual_reset_) - waitables[0].first->kernel_->signaled_ = false; - waitables[0].first->kernel_->lock_.Release(); - return count; - } - - const size_t r = EnqueueMany(waitables + 1, count - 1, waiter); - if (r) { - waitables[0].first->kernel_->lock_.Release(); - } else { - waitables[0].first->Enqueue(waiter); - } - - return r; -} - -// ----------------------------------------------------------------------------- - - -// ----------------------------------------------------------------------------- -// Private functions... - -WaitableEvent::WaitableEventKernel::WaitableEventKernel(bool manual_reset, - bool initially_signaled) - : manual_reset_(manual_reset), - signaled_(initially_signaled) { -} - -WaitableEvent::WaitableEventKernel::~WaitableEventKernel() { -} - -// ----------------------------------------------------------------------------- -// Wake all waiting waiters. Called with lock held. -// ----------------------------------------------------------------------------- -bool WaitableEvent::SignalAll() { - bool signaled_at_least_one = false; - - for (std::list<Waiter*>::iterator - i = kernel_->waiters_.begin(); i != kernel_->waiters_.end(); ++i) { - if ((*i)->Fire(this)) - signaled_at_least_one = true; - } - - kernel_->waiters_.clear(); - return signaled_at_least_one; -} - -// --------------------------------------------------------------------------- -// Try to wake a single waiter. Return true if one was woken. Called with lock -// held. -// --------------------------------------------------------------------------- -bool WaitableEvent::SignalOne() { - for (;;) { - if (kernel_->waiters_.empty()) - return false; - - const bool r = (*kernel_->waiters_.begin())->Fire(this); - kernel_->waiters_.pop_front(); - if (r) - return true; - } -} - -// ----------------------------------------------------------------------------- -// Add a waiter to the list of those waiting. Called with lock held. -// ----------------------------------------------------------------------------- -void WaitableEvent::Enqueue(Waiter* waiter) { - kernel_->waiters_.push_back(waiter); -} - -// ----------------------------------------------------------------------------- -// Remove a waiter from the list of those waiting. Return true if the waiter was -// actually removed. Called with lock held. -// ----------------------------------------------------------------------------- -bool WaitableEvent::WaitableEventKernel::Dequeue(Waiter* waiter, void* tag) { - for (std::list<Waiter*>::iterator - i = waiters_.begin(); i != waiters_.end(); ++i) { - if (*i == waiter && (*i)->Compare(tag)) { - waiters_.erase(i); - return true; - } - } - - return false; -} - -// ----------------------------------------------------------------------------- - -} // namespace base diff --git a/security/sandbox/chromium/base/task_runner.h b/security/sandbox/chromium/base/task_runner.h deleted file mode 100644 index 6dd82ccac..000000000 --- a/security/sandbox/chromium/base/task_runner.h +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_TASK_RUNNER_H_ -#define BASE_TASK_RUNNER_H_ - -#include <stddef.h> - -#include "base/base_export.h" -#include "base/callback_forward.h" -#include "base/memory/ref_counted.h" -#include "base/time/time.h" - -namespace tracked_objects { -class Location; -} // namespace tracked_objects - -namespace base { - -struct TaskRunnerTraits; - -// A TaskRunner is an object that runs posted tasks (in the form of -// Closure objects). The TaskRunner interface provides a way of -// decoupling task posting from the mechanics of how each task will be -// run. TaskRunner provides very weak guarantees as to how posted -// tasks are run (or if they're run at all). In particular, it only -// guarantees: -// -// - Posting a task will not run it synchronously. That is, no -// Post*Task method will call task.Run() directly. -// -// - Increasing the delay can only delay when the task gets run. -// That is, increasing the delay may not affect when the task gets -// run, or it could make it run later than it normally would, but -// it won't make it run earlier than it normally would. -// -// TaskRunner does not guarantee the order in which posted tasks are -// run, whether tasks overlap, or whether they're run on a particular -// thread. Also it does not guarantee a memory model for shared data -// between tasks. (In other words, you should use your own -// synchronization/locking primitives if you need to share data -// between tasks.) -// -// Implementations of TaskRunner should be thread-safe in that all -// methods must be safe to call on any thread. Ownership semantics -// for TaskRunners are in general not clear, which is why the -// interface itself is RefCountedThreadSafe. -// -// Some theoretical implementations of TaskRunner: -// -// - A TaskRunner that uses a thread pool to run posted tasks. -// -// - A TaskRunner that, for each task, spawns a non-joinable thread -// to run that task and immediately quit. -// -// - A TaskRunner that stores the list of posted tasks and has a -// method Run() that runs each runnable task in random order. -class BASE_EXPORT TaskRunner - : public RefCountedThreadSafe<TaskRunner, TaskRunnerTraits> { - public: - // Posts the given task to be run. Returns true if the task may be - // run at some point in the future, and false if the task definitely - // will not be run. - // - // Equivalent to PostDelayedTask(from_here, task, 0). - bool PostTask(const tracked_objects::Location& from_here, - const Closure& task); - - // Like PostTask, but tries to run the posted task only after - // |delay_ms| has passed. - // - // It is valid for an implementation to ignore |delay_ms|; that is, - // to have PostDelayedTask behave the same as PostTask. - virtual bool PostDelayedTask(const tracked_objects::Location& from_here, - const Closure& task, - base::TimeDelta delay) = 0; - - // Returns true if the current thread is a thread on which a task - // may be run, and false if no task will be run on the current - // thread. - // - // It is valid for an implementation to always return true, or in - // general to use 'true' as a default value. - virtual bool RunsTasksOnCurrentThread() const = 0; - - // Posts |task| on the current TaskRunner. On completion, |reply| - // is posted to the thread that called PostTaskAndReply(). Both - // |task| and |reply| are guaranteed to be deleted on the thread - // from which PostTaskAndReply() is invoked. This allows objects - // that must be deleted on the originating thread to be bound into - // the |task| and |reply| Closures. In particular, it can be useful - // to use WeakPtr<> in the |reply| Closure so that the reply - // operation can be canceled. See the following pseudo-code: - // - // class DataBuffer : public RefCountedThreadSafe<DataBuffer> { - // public: - // // Called to add data into a buffer. - // void AddData(void* buf, size_t length); - // ... - // }; - // - // - // class DataLoader : public SupportsWeakPtr<DataLoader> { - // public: - // void GetData() { - // scoped_refptr<DataBuffer> buffer = new DataBuffer(); - // target_thread_.task_runner()->PostTaskAndReply( - // FROM_HERE, - // base::Bind(&DataBuffer::AddData, buffer), - // base::Bind(&DataLoader::OnDataReceived, AsWeakPtr(), buffer)); - // } - // - // private: - // void OnDataReceived(scoped_refptr<DataBuffer> buffer) { - // // Do something with buffer. - // } - // }; - // - // - // Things to notice: - // * Results of |task| are shared with |reply| by binding a shared argument - // (a DataBuffer instance). - // * The DataLoader object has no special thread safety. - // * The DataLoader object can be deleted while |task| is still running, - // and the reply will cancel itself safely because it is bound to a - // WeakPtr<>. - bool PostTaskAndReply(const tracked_objects::Location& from_here, - const Closure& task, - const Closure& reply); - - protected: - friend struct TaskRunnerTraits; - - // Only the Windows debug build seems to need this: see - // http://crbug.com/112250. - friend class RefCountedThreadSafe<TaskRunner, TaskRunnerTraits>; - - TaskRunner(); - virtual ~TaskRunner(); - - // Called when this object should be destroyed. By default simply - // deletes |this|, but can be overridden to do something else, like - // delete on a certain thread. - virtual void OnDestruct() const; -}; - -struct BASE_EXPORT TaskRunnerTraits { - static void Destruct(const TaskRunner* task_runner); -}; - -} // namespace base - -#endif // BASE_TASK_RUNNER_H_ diff --git a/security/sandbox/chromium/base/template_util.h b/security/sandbox/chromium/base/template_util.h deleted file mode 100644 index d58807a77..000000000 --- a/security/sandbox/chromium/base/template_util.h +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_TEMPLATE_UTIL_H_ -#define BASE_TEMPLATE_UTIL_H_ - -#include <stddef.h> - -#include "build/build_config.h" - -namespace base { - -// template definitions from tr1 - -template<class T, T v> -struct integral_constant { - static const T value = v; - typedef T value_type; - typedef integral_constant<T, v> type; -}; - -template <class T, T v> const T integral_constant<T, v>::value; - -typedef integral_constant<bool, true> true_type; -typedef integral_constant<bool, false> false_type; - -template <class T> struct is_pointer : false_type {}; -template <class T> struct is_pointer<T*> : true_type {}; - -// Member function pointer detection. This is built-in to C++ 11's stdlib, and -// we can remove this when we switch to it. -template<typename T> -struct is_member_function_pointer : false_type {}; - -template <typename R, typename Z, typename... A> -struct is_member_function_pointer<R(Z::*)(A...)> : true_type {}; -template <typename R, typename Z, typename... A> -struct is_member_function_pointer<R(Z::*)(A...) const> : true_type {}; - - -template <class T, class U> struct is_same : public false_type {}; -template <class T> struct is_same<T,T> : true_type {}; - -template<class> struct is_array : public false_type {}; -template<class T, size_t n> struct is_array<T[n]> : public true_type {}; -template<class T> struct is_array<T[]> : public true_type {}; - -template <class T> struct is_non_const_reference : false_type {}; -template <class T> struct is_non_const_reference<T&> : true_type {}; -template <class T> struct is_non_const_reference<const T&> : false_type {}; - -template <class T> struct is_const : false_type {}; -template <class T> struct is_const<const T> : true_type {}; - -template <class T> struct is_void : false_type {}; -template <> struct is_void<void> : true_type {}; - -namespace internal { - -// Types YesType and NoType are guaranteed such that sizeof(YesType) < -// sizeof(NoType). -typedef char YesType; - -struct NoType { - YesType dummy[2]; -}; - -// This class is an implementation detail for is_convertible, and you -// don't need to know how it works to use is_convertible. For those -// who care: we declare two different functions, one whose argument is -// of type To and one with a variadic argument list. We give them -// return types of different size, so we can use sizeof to trick the -// compiler into telling us which function it would have chosen if we -// had called it with an argument of type From. See Alexandrescu's -// _Modern C++ Design_ for more details on this sort of trick. - -struct ConvertHelper { - template <typename To> - static YesType Test(To); - - template <typename To> - static NoType Test(...); - - template <typename From> - static From& Create(); -}; - -// Used to determine if a type is a struct/union/class. Inspired by Boost's -// is_class type_trait implementation. -struct IsClassHelper { - template <typename C> - static YesType Test(void(C::*)(void)); - - template <typename C> - static NoType Test(...); -}; - -} // namespace internal - -// Inherits from true_type if From is convertible to To, false_type otherwise. -// -// Note that if the type is convertible, this will be a true_type REGARDLESS -// of whether or not the conversion would emit a warning. -template <typename From, typename To> -struct is_convertible - : integral_constant<bool, - sizeof(internal::ConvertHelper::Test<To>( - internal::ConvertHelper::Create<From>())) == - sizeof(internal::YesType)> { -}; - -template <typename T> -struct is_class - : integral_constant<bool, - sizeof(internal::IsClassHelper::Test<T>(0)) == - sizeof(internal::YesType)> { -}; - -} // namespace base - -#endif // BASE_TEMPLATE_UTIL_H_ diff --git a/security/sandbox/chromium/base/third_party/dmg_fp/LICENSE b/security/sandbox/chromium/base/third_party/dmg_fp/LICENSE deleted file mode 100644 index 716f1ef2b..000000000 --- a/security/sandbox/chromium/base/third_party/dmg_fp/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -/**************************************************************** - * - * The author of this software is David M. Gay. - * - * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - ***************************************************************/ diff --git a/security/sandbox/chromium/base/third_party/dmg_fp/dmg_fp.h b/security/sandbox/chromium/base/third_party/dmg_fp/dmg_fp.h deleted file mode 100644 index 4795397ec..000000000 --- a/security/sandbox/chromium/base/third_party/dmg_fp/dmg_fp.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_DMG_FP_H_ -#define THIRD_PARTY_DMG_FP_H_ - -namespace dmg_fp { - -// Return a nearest machine number to the input decimal -// string (or set errno to ERANGE). With IEEE arithmetic, ties are -// broken by the IEEE round-even rule. Otherwise ties are broken by -// biased rounding (add half and chop). -double strtod(const char* s00, char** se); - -// Convert double to ASCII string. For meaning of parameters -// see dtoa.cc file. -char* dtoa(double d, int mode, int ndigits, - int* decpt, int* sign, char** rve); - -// Must be used to free values returned by dtoa. -void freedtoa(char* s); - -// Store the closest decimal approximation to x in b (null terminated). -// Returns a pointer to b. It is sufficient for |b| to be 32 characters. -char* g_fmt(char* b, double x); - -} // namespace dmg_fp - -#endif // THIRD_PARTY_DMG_FP_H_ diff --git a/security/sandbox/chromium/base/third_party/dmg_fp/dtoa.cc b/security/sandbox/chromium/base/third_party/dmg_fp/dtoa.cc deleted file mode 100644 index 502c16cc7..000000000 --- a/security/sandbox/chromium/base/third_party/dmg_fp/dtoa.cc +++ /dev/null @@ -1,4234 +0,0 @@ -/**************************************************************** - * - * The author of this software is David M. Gay. - * - * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - ***************************************************************/ - -/* Please send bug reports to David M. Gay (dmg at acm dot org, - * with " at " changed at "@" and " dot " changed to "."). */ - -/* On a machine with IEEE extended-precision registers, it is - * necessary to specify double-precision (53-bit) rounding precision - * before invoking strtod or dtoa. If the machine uses (the equivalent - * of) Intel 80x87 arithmetic, the call - * _control87(PC_53, MCW_PC); - * does this with many compilers. Whether this or another call is - * appropriate depends on the compiler; for this to work, it may be - * necessary to #include "float.h" or another system-dependent header - * file. - */ - -/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. - * - * This strtod returns a nearest machine number to the input decimal - * string (or sets errno to ERANGE). With IEEE arithmetic, ties are - * broken by the IEEE round-even rule. Otherwise ties are broken by - * biased rounding (add half and chop). - * - * Inspired loosely by William D. Clinger's paper "How to Read Floating - * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * - * 1. We only require IEEE, IBM, or VAX double-precision - * arithmetic (not IEEE double-extended). - * 2. We get by with floating-point arithmetic in a case that - * Clinger missed -- when we're computing d * 10^n - * for a small integer d and the integer n is not too - * much larger than 22 (the maximum integer k for which - * we can represent 10^k exactly), we may be able to - * compute (d*10^k) * 10^(e-k) with just one roundoff. - * 3. Rather than a bit-at-a-time adjustment of the binary - * result in the hard case, we use floating-point - * arithmetic to determine the adjustment to within - * one bit; only in really hard cases do we need to - * compute a second residual. - * 4. Because of 3., we don't need a large table of powers of 10 - * for ten-to-e (just some small tables, e.g. of 10^k - * for 0 <= k <= 22). - */ - -/* - * #define IEEE_8087 for IEEE-arithmetic machines where the least - * significant byte has the lowest address. - * #define IEEE_MC68k for IEEE-arithmetic machines where the most - * significant byte has the lowest address. - * #define Long int on machines with 32-bit ints and 64-bit longs. - * #define IBM for IBM mainframe-style floating-point arithmetic. - * #define VAX for VAX-style floating-point arithmetic (D_floating). - * #define No_leftright to omit left-right logic in fast floating-point - * computation of dtoa. - * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and strtod and dtoa should round accordingly. Unless Trust_FLT_ROUNDS - * is also #defined, fegetround() will be queried for the rounding mode. - * Note that both FLT_ROUNDS and fegetround() are specified by the C99 - * standard (and are specified to be consistent, with fesetround() - * affecting the value of FLT_ROUNDS), but that some (Linux) systems - * do not work correctly in this regard, so using fegetround() is more - * portable than using FLT_FOUNDS directly. - * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and Honor_FLT_ROUNDS is not #defined. - * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines - * that use extended-precision instructions to compute rounded - * products and quotients) with IBM. - * #define ROUND_BIASED for IEEE-format with biased rounding. - * #define Inaccurate_Divide for IEEE-format with correctly rounded - * products but inaccurate quotients, e.g., for Intel i860. - * #define NO_LONG_LONG on machines that do not have a "long long" - * integer type (of >= 64 bits). On such machines, you can - * #define Just_16 to store 16 bits per 32-bit Long when doing - * high-precision integer arithmetic. Whether this speeds things - * up or slows things down depends on the machine and the number - * being converted. If long long is available and the name is - * something other than "long long", #define Llong to be the name, - * and if "unsigned Llong" does not work as an unsigned version of - * Llong, #define #ULLong to be the corresponding unsigned type. - * #define KR_headers for old-style C function headers. - * #define Bad_float_h if your system lacks a float.h or if it does not - * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, - * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. - * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) - * if memory is available and otherwise does something you deem - * appropriate. If MALLOC is undefined, malloc will be invoked - * directly -- and assumed always to succeed. Similarly, if you - * want something other than the system's free() to be called to - * recycle memory acquired from MALLOC, #define FREE to be the - * name of the alternate routine. (FREE or free is only called in - * pathological cases, e.g., in a dtoa call after a dtoa return in - * mode 3 with thousands of digits requested.) - * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making - * memory allocations from a private pool of memory when possible. - * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, - * unless #defined to be a different length. This default length - * suffices to get rid of MALLOC calls except for unusual cases, - * such as decimal-to-binary conversion of a very long string of - * digits. The longest string dtoa can return is about 751 bytes - * long. For conversions by strtod of strings of 800 digits and - * all dtoa conversions in single-threaded executions with 8-byte - * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte - * pointers, PRIVATE_MEM >= 7112 appears adequate. - * #define NO_INFNAN_CHECK if you do not wish to have INFNAN_CHECK - * #defined automatically on IEEE systems. On such systems, - * when INFNAN_CHECK is #defined, strtod checks - * for Infinity and NaN (case insensitively). On some systems - * (e.g., some HP systems), it may be necessary to #define NAN_WORD0 - * appropriately -- to the most significant word of a quiet NaN. - * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) - * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, - * strtod also accepts (case insensitively) strings of the form - * NaN(x), where x is a string of hexadecimal digits and spaces; - * if there is only one string of hexadecimal digits, it is taken - * for the 52 fraction bits of the resulting NaN; if there are two - * or more strings of hex digits, the first is for the high 20 bits, - * the second and subsequent for the low 32 bits, with intervening - * white space ignored; but if this results in none of the 52 - * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 - * and NAN_WORD1 are used instead. - * #define MULTIPLE_THREADS if the system offers preemptively scheduled - * multiple threads. In this case, you must provide (or suitably - * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed - * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed - * in pow5mult, ensures lazy evaluation of only one copy of high - * powers of 5; omitting this lock would introduce a small - * probability of wasting memory, but would otherwise be harmless.) - * You must also invoke freedtoa(s) to free the value s returned by - * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. - * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that - * avoids underflows on inputs whose result does not underflow. - * If you #define NO_IEEE_Scale on a machine that uses IEEE-format - * floating-point numbers and flushes underflows to zero rather - * than implementing gradual underflow, then you must also #define - * Sudden_Underflow. - * #define USE_LOCALE to use the current locale's decimal_point value. - * #define SET_INEXACT if IEEE arithmetic is being used and extra - * computation should be done to set the inexact flag when the - * result is inexact and avoid setting inexact when the result - * is exact. In this case, dtoa.c must be compiled in - * an environment, perhaps provided by #include "dtoa.c" in a - * suitable wrapper, that defines two functions, - * int get_inexact(void); - * void clear_inexact(void); - * such that get_inexact() returns a nonzero value if the - * inexact bit is already set, and clear_inexact() sets the - * inexact bit to 0. When SET_INEXACT is #defined, strtod - * also does extra computations to set the underflow and overflow - * flags when appropriate (i.e., when the result is tiny and - * inexact or when it is a numeric value rounded to +-infinity). - * #define NO_ERRNO if strtod should not assign errno = ERANGE when - * the result overflows to +-Infinity or underflows to 0. - * #define NO_HEX_FP to omit recognition of hexadecimal floating-point - * values by strtod. - * #define NO_STRTOD_BIGCOMP (on IEEE-arithmetic systems only for now) - * to disable logic for "fast" testing of very long input strings - * to strtod. This testing proceeds by initially truncating the - * input string, then if necessary comparing the whole string with - * a decimal expansion to decide close cases. This logic is only - * used for input more than STRTOD_DIGLIM digits long (default 40). - */ - -#define IEEE_8087 -#define NO_HEX_FP - -#ifndef Long -#if __LP64__ -#define Long int -#else -#define Long long -#endif -#endif -#ifndef ULong -typedef unsigned Long ULong; -#endif - -#ifdef DEBUG -#include "stdio.h" -#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} -#endif - -#include "stdlib.h" -#include "string.h" - -#ifdef USE_LOCALE -#include "locale.h" -#endif - -#ifdef Honor_FLT_ROUNDS -#ifndef Trust_FLT_ROUNDS -#include <fenv.h> -#endif -#endif - -#ifdef MALLOC -#ifdef KR_headers -extern char *MALLOC(); -#else -extern void *MALLOC(size_t); -#endif -#else -#define MALLOC malloc -#endif - -#ifndef Omit_Private_Memory -#ifndef PRIVATE_MEM -#define PRIVATE_MEM 2304 -#endif -#define PRIVATE_mem ((unsigned)((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))) -static double private_mem[PRIVATE_mem], *pmem_next = private_mem; -#endif - -#undef IEEE_Arith -#undef Avoid_Underflow -#ifdef IEEE_MC68k -#define IEEE_Arith -#endif -#ifdef IEEE_8087 -#define IEEE_Arith -#endif - -#ifdef IEEE_Arith -#ifndef NO_INFNAN_CHECK -#undef INFNAN_CHECK -#define INFNAN_CHECK -#endif -#else -#undef INFNAN_CHECK -#define NO_STRTOD_BIGCOMP -#endif - -#include "errno.h" - -#ifdef Bad_float_h - -#ifdef IEEE_Arith -#define DBL_DIG 15 -#define DBL_MAX_10_EXP 308 -#define DBL_MAX_EXP 1024 -#define FLT_RADIX 2 -#endif /*IEEE_Arith*/ - -#ifdef IBM -#define DBL_DIG 16 -#define DBL_MAX_10_EXP 75 -#define DBL_MAX_EXP 63 -#define FLT_RADIX 16 -#define DBL_MAX 7.2370055773322621e+75 -#endif - -#ifdef VAX -#define DBL_DIG 16 -#define DBL_MAX_10_EXP 38 -#define DBL_MAX_EXP 127 -#define FLT_RADIX 2 -#define DBL_MAX 1.7014118346046923e+38 -#endif - -#ifndef LONG_MAX -#define LONG_MAX 2147483647 -#endif - -#else /* ifndef Bad_float_h */ -#include "float.h" -#endif /* Bad_float_h */ - -#ifndef __MATH_H__ -#include "math.h" -#endif - -namespace dmg_fp { - -#ifndef CONST -#ifdef KR_headers -#define CONST /* blank */ -#else -#define CONST const -#endif -#endif - -#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 -Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. -#endif - -typedef union { double d; ULong L[2]; } U; - -#ifdef IEEE_8087 -#define word0(x) (x)->L[1] -#define word1(x) (x)->L[0] -#else -#define word0(x) (x)->L[0] -#define word1(x) (x)->L[1] -#endif -#define dval(x) (x)->d - -#ifndef STRTOD_DIGLIM -#define STRTOD_DIGLIM 40 -#endif - -#ifdef DIGLIM_DEBUG -extern int strtod_diglim; -#else -#define strtod_diglim STRTOD_DIGLIM -#endif - -/* The following definition of Storeinc is appropriate for MIPS processors. - * An alternative that might be better on some machines is - * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) - */ -#if defined(IEEE_8087) + defined(VAX) -#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ -((unsigned short *)a)[0] = (unsigned short)c, a++) -#else -#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ -((unsigned short *)a)[1] = (unsigned short)c, a++) -#endif - -/* #define P DBL_MANT_DIG */ -/* Ten_pmax = floor(P*log(2)/log(5)) */ -/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ -/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ -/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ - -#ifdef IEEE_Arith -#define Exp_shift 20 -#define Exp_shift1 20 -#define Exp_msk1 0x100000 -#define Exp_msk11 0x100000 -#define Exp_mask 0x7ff00000 -#define P 53 -#define Nbits 53 -#define Bias 1023 -#define Emax 1023 -#define Emin (-1022) -#define Exp_1 0x3ff00000 -#define Exp_11 0x3ff00000 -#define Ebits 11 -#define Frac_mask 0xfffff -#define Frac_mask1 0xfffff -#define Ten_pmax 22 -#define Bletch 0x10 -#define Bndry_mask 0xfffff -#define Bndry_mask1 0xfffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 1 -#define Tiny0 0 -#define Tiny1 1 -#define Quick_max 14 -#define Int_max 14 -#ifndef NO_IEEE_Scale -#define Avoid_Underflow -#ifdef Flush_Denorm /* debugging option */ -#undef Sudden_Underflow -#endif -#endif - -#ifndef Flt_Rounds -#ifdef FLT_ROUNDS -#define Flt_Rounds FLT_ROUNDS -#else -#define Flt_Rounds 1 -#endif -#endif /*Flt_Rounds*/ - -#ifdef Honor_FLT_ROUNDS -#undef Check_FLT_ROUNDS -#define Check_FLT_ROUNDS -#else -#define Rounding Flt_Rounds -#endif - -#else /* ifndef IEEE_Arith */ -#undef Check_FLT_ROUNDS -#undef Honor_FLT_ROUNDS -#undef SET_INEXACT -#undef Sudden_Underflow -#define Sudden_Underflow -#ifdef IBM -#undef Flt_Rounds -#define Flt_Rounds 0 -#define Exp_shift 24 -#define Exp_shift1 24 -#define Exp_msk1 0x1000000 -#define Exp_msk11 0x1000000 -#define Exp_mask 0x7f000000 -#define P 14 -#define Nbits 56 -#define Bias 65 -#define Emax 248 -#define Emin (-260) -#define Exp_1 0x41000000 -#define Exp_11 0x41000000 -#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ -#define Frac_mask 0xffffff -#define Frac_mask1 0xffffff -#define Bletch 4 -#define Ten_pmax 22 -#define Bndry_mask 0xefffff -#define Bndry_mask1 0xffffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 4 -#define Tiny0 0x100000 -#define Tiny1 0 -#define Quick_max 14 -#define Int_max 15 -#else /* VAX */ -#undef Flt_Rounds -#define Flt_Rounds 1 -#define Exp_shift 23 -#define Exp_shift1 7 -#define Exp_msk1 0x80 -#define Exp_msk11 0x800000 -#define Exp_mask 0x7f80 -#define P 56 -#define Nbits 56 -#define Bias 129 -#define Emax 126 -#define Emin (-129) -#define Exp_1 0x40800000 -#define Exp_11 0x4080 -#define Ebits 8 -#define Frac_mask 0x7fffff -#define Frac_mask1 0xffff007f -#define Ten_pmax 24 -#define Bletch 2 -#define Bndry_mask 0xffff007f -#define Bndry_mask1 0xffff007f -#define LSB 0x10000 -#define Sign_bit 0x8000 -#define Log2P 1 -#define Tiny0 0x80 -#define Tiny1 0 -#define Quick_max 15 -#define Int_max 15 -#endif /* IBM, VAX */ -#endif /* IEEE_Arith */ - -#ifndef IEEE_Arith -#define ROUND_BIASED -#endif - -#ifdef RND_PRODQUOT -#define rounded_product(a,b) a = rnd_prod(a, b) -#define rounded_quotient(a,b) a = rnd_quot(a, b) -#ifdef KR_headers -extern double rnd_prod(), rnd_quot(); -#else -extern double rnd_prod(double, double), rnd_quot(double, double); -#endif -#else -#define rounded_product(a,b) a *= b -#define rounded_quotient(a,b) a /= b -#endif - -#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) -#define Big1 0xffffffff - -#ifndef Pack_32 -#define Pack_32 -#endif - -typedef struct BCinfo BCinfo; - struct -BCinfo { int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflchk; }; - -#ifdef KR_headers -#define FFFFFFFF ((((unsigned long)0xffff)<<16)|(unsigned long)0xffff) -#else -#define FFFFFFFF 0xffffffffUL -#endif - -#ifdef NO_LONG_LONG -#undef ULLong -#ifdef Just_16 -#undef Pack_32 -/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. - * This makes some inner loops simpler and sometimes saves work - * during multiplications, but it often seems to make things slightly - * slower. Hence the default is now to store 32 bits per Long. - */ -#endif -#else /* long long available */ -#ifndef Llong -#define Llong long long -#endif -#ifndef ULLong -#define ULLong unsigned Llong -#endif -#endif /* NO_LONG_LONG */ - -#ifndef MULTIPLE_THREADS -#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ -#define FREE_DTOA_LOCK(n) /*nothing*/ -#endif - -#define Kmax 7 - -double strtod(const char *s00, char **se); -char *dtoa(double d, int mode, int ndigits, - int *decpt, int *sign, char **rve); - - struct -Bigint { - struct Bigint *next; - int k, maxwds, sign, wds; - ULong x[1]; - }; - - typedef struct Bigint Bigint; - - static Bigint *freelist[Kmax+1]; - - static Bigint * -Balloc -#ifdef KR_headers - (k) int k; -#else - (int k) -#endif -{ - int x; - Bigint *rv; -#ifndef Omit_Private_Memory - unsigned int len; -#endif - - ACQUIRE_DTOA_LOCK(0); - /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ - /* but this case seems very unlikely. */ - if (k <= Kmax && freelist[k]) { - rv = freelist[k]; - freelist[k] = rv->next; - } - else { - x = 1 << k; -#ifdef Omit_Private_Memory - rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); -#else - len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) - /sizeof(double); - if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { - rv = (Bigint*)pmem_next; - pmem_next += len; - } - else - rv = (Bigint*)MALLOC(len*sizeof(double)); -#endif - rv->k = k; - rv->maxwds = x; - } - FREE_DTOA_LOCK(0); - rv->sign = rv->wds = 0; - return rv; - } - - static void -Bfree -#ifdef KR_headers - (v) Bigint *v; -#else - (Bigint *v) -#endif -{ - if (v) { - if (v->k > Kmax) -#ifdef FREE - FREE((void*)v); -#else - free((void*)v); -#endif - else { - ACQUIRE_DTOA_LOCK(0); - v->next = freelist[v->k]; - freelist[v->k] = v; - FREE_DTOA_LOCK(0); - } - } - } - -#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ -y->wds*sizeof(Long) + 2*sizeof(int)) - - static Bigint * -multadd -#ifdef KR_headers - (b, m, a) Bigint *b; int m, a; -#else - (Bigint *b, int m, int a) /* multiply by m and add a */ -#endif -{ - int i, wds; -#ifdef ULLong - ULong *x; - ULLong carry, y; -#else - ULong carry, *x, y; -#ifdef Pack_32 - ULong xi, z; -#endif -#endif - Bigint *b1; - - wds = b->wds; - x = b->x; - i = 0; - carry = a; - do { -#ifdef ULLong - y = *x * (ULLong)m + carry; - carry = y >> 32; - *x++ = y & FFFFFFFF; -#else -#ifdef Pack_32 - xi = *x; - y = (xi & 0xffff) * m + carry; - z = (xi >> 16) * m + (y >> 16); - carry = z >> 16; - *x++ = (z << 16) + (y & 0xffff); -#else - y = *x * m + carry; - carry = y >> 16; - *x++ = y & 0xffff; -#endif -#endif - } - while(++i < wds); - if (carry) { - if (wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1, b); - Bfree(b); - b = b1; - } - b->x[wds++] = (ULong)carry; - b->wds = wds; - } - return b; - } - - static Bigint * -s2b -#ifdef KR_headers - (s, nd0, nd, y9, dplen) CONST char *s; int nd0, nd, dplen; ULong y9; -#else - (CONST char *s, int nd0, int nd, ULong y9, int dplen) -#endif -{ - Bigint *b; - int i, k; - Long x, y; - - x = (nd + 8) / 9; - for(k = 0, y = 1; x > y; y <<= 1, k++) ; -#ifdef Pack_32 - b = Balloc(k); - b->x[0] = y9; - b->wds = 1; -#else - b = Balloc(k+1); - b->x[0] = y9 & 0xffff; - b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; -#endif - - i = 9; - if (9 < nd0) { - s += 9; - do b = multadd(b, 10, *s++ - '0'); - while(++i < nd0); - s += dplen; - } - else - s += dplen + 9; - for(; i < nd; i++) - b = multadd(b, 10, *s++ - '0'); - return b; - } - - static int -hi0bits -#ifdef KR_headers - (x) ULong x; -#else - (ULong x) -#endif -{ - int k = 0; - - if (!(x & 0xffff0000)) { - k = 16; - x <<= 16; - } - if (!(x & 0xff000000)) { - k += 8; - x <<= 8; - } - if (!(x & 0xf0000000)) { - k += 4; - x <<= 4; - } - if (!(x & 0xc0000000)) { - k += 2; - x <<= 2; - } - if (!(x & 0x80000000)) { - k++; - if (!(x & 0x40000000)) - return 32; - } - return k; - } - - static int -lo0bits -#ifdef KR_headers - (y) ULong *y; -#else - (ULong *y) -#endif -{ - int k; - ULong x = *y; - - if (x & 7) { - if (x & 1) - return 0; - if (x & 2) { - *y = x >> 1; - return 1; - } - *y = x >> 2; - return 2; - } - k = 0; - if (!(x & 0xffff)) { - k = 16; - x >>= 16; - } - if (!(x & 0xff)) { - k += 8; - x >>= 8; - } - if (!(x & 0xf)) { - k += 4; - x >>= 4; - } - if (!(x & 0x3)) { - k += 2; - x >>= 2; - } - if (!(x & 1)) { - k++; - x >>= 1; - if (!x) - return 32; - } - *y = x; - return k; - } - - static Bigint * -i2b -#ifdef KR_headers - (i) int i; -#else - (int i) -#endif -{ - Bigint *b; - - b = Balloc(1); - b->x[0] = i; - b->wds = 1; - return b; - } - - static Bigint * -mult -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - Bigint *c; - int k, wa, wb, wc; - ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; - ULong y; -#ifdef ULLong - ULLong carry, z; -#else - ULong carry, z; -#ifdef Pack_32 - ULong z2; -#endif -#endif - - if (a->wds < b->wds) { - c = a; - a = b; - b = c; - } - k = a->k; - wa = a->wds; - wb = b->wds; - wc = wa + wb; - if (wc > a->maxwds) - k++; - c = Balloc(k); - for(x = c->x, xa = x + wc; x < xa; x++) - *x = 0; - xa = a->x; - xae = xa + wa; - xb = b->x; - xbe = xb + wb; - xc0 = c->x; -#ifdef ULLong - for(; xb < xbe; xc0++) { - y = *xb++; - if (y) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * (ULLong)y + *xc + carry; - carry = z >> 32; - *xc++ = z & FFFFFFFF; - } - while(x < xae); - *xc = (ULong)carry; - } - } -#else -#ifdef Pack_32 - for(; xb < xbe; xb++, xc0++) { - if (y = *xb & 0xffff) { - x = xa; - xc = xc0; - carry = 0; - do { - z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; - carry = z >> 16; - z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; - carry = z2 >> 16; - Storeinc(xc, z2, z); - } - while(x < xae); - *xc = carry; - } - if (y = *xb >> 16) { - x = xa; - xc = xc0; - carry = 0; - z2 = *xc; - do { - z = (*x & 0xffff) * y + (*xc >> 16) + carry; - carry = z >> 16; - Storeinc(xc, z, z2); - z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; - carry = z2 >> 16; - } - while(x < xae); - *xc = z2; - } - } -#else - for(; xb < xbe; xc0++) { - if (y = *xb++) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * y + *xc + carry; - carry = z >> 16; - *xc++ = z & 0xffff; - } - while(x < xae); - *xc = carry; - } - } -#endif -#endif - for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; - c->wds = wc; - return c; - } - - static Bigint *p5s; - - static Bigint * -pow5mult -#ifdef KR_headers - (b, k) Bigint *b; int k; -#else - (Bigint *b, int k) -#endif -{ - Bigint *b1, *p5, *p51; - int i; - static int p05[3] = { 5, 25, 125 }; - - i = k & 3; - if (i) - b = multadd(b, p05[i-1], 0); - - if (!(k >>= 2)) - return b; - p5 = p5s; - if (!p5) { - /* first time */ -#ifdef MULTIPLE_THREADS - ACQUIRE_DTOA_LOCK(1); - p5 = p5s; - if (!p5) { - p5 = p5s = i2b(625); - p5->next = 0; - } - FREE_DTOA_LOCK(1); -#else - p5 = p5s = i2b(625); - p5->next = 0; -#endif - } - for(;;) { - if (k & 1) { - b1 = mult(b, p5); - Bfree(b); - b = b1; - } - if (!(k >>= 1)) - break; - p51 = p5->next; - if (!p51) { -#ifdef MULTIPLE_THREADS - ACQUIRE_DTOA_LOCK(1); - p51 = p5->next; - if (!p51) { - p51 = p5->next = mult(p5,p5); - p51->next = 0; - } - FREE_DTOA_LOCK(1); -#else - p51 = p5->next = mult(p5,p5); - p51->next = 0; -#endif - } - p5 = p51; - } - return b; - } - - static Bigint * -lshift -#ifdef KR_headers - (b, k) Bigint *b; int k; -#else - (Bigint *b, int k) -#endif -{ - int i, k1, n, n1; - Bigint *b1; - ULong *x, *x1, *xe, z; - -#ifdef Pack_32 - n = k >> 5; -#else - n = k >> 4; -#endif - k1 = b->k; - n1 = n + b->wds + 1; - for(i = b->maxwds; n1 > i; i <<= 1) - k1++; - b1 = Balloc(k1); - x1 = b1->x; - for(i = 0; i < n; i++) - *x1++ = 0; - x = b->x; - xe = x + b->wds; -#ifdef Pack_32 - if (k &= 0x1f) { - k1 = 32 - k; - z = 0; - do { - *x1++ = *x << k | z; - z = *x++ >> k1; - } - while(x < xe); - *x1 = z; - if (*x1) - ++n1; - } -#else - if (k &= 0xf) { - k1 = 16 - k; - z = 0; - do { - *x1++ = *x << k & 0xffff | z; - z = *x++ >> k1; - } - while(x < xe); - if (*x1 = z) - ++n1; - } -#endif - else do - *x1++ = *x++; - while(x < xe); - b1->wds = n1 - 1; - Bfree(b); - return b1; - } - - static int -cmp -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - ULong *xa, *xa0, *xb, *xb0; - int i, j; - - i = a->wds; - j = b->wds; -#ifdef DEBUG - if (i > 1 && !a->x[i-1]) - Bug("cmp called with a->x[a->wds-1] == 0"); - if (j > 1 && !b->x[j-1]) - Bug("cmp called with b->x[b->wds-1] == 0"); -#endif - if (i -= j) - return i; - xa0 = a->x; - xa = xa0 + j; - xb0 = b->x; - xb = xb0 + j; - for(;;) { - if (*--xa != *--xb) - return *xa < *xb ? -1 : 1; - if (xa <= xa0) - break; - } - return 0; - } - - static Bigint * -diff -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - Bigint *c; - int i, wa, wb; - ULong *xa, *xae, *xb, *xbe, *xc; -#ifdef ULLong - ULLong borrow, y; -#else - ULong borrow, y; -#ifdef Pack_32 - ULong z; -#endif -#endif - - i = cmp(a,b); - if (!i) { - c = Balloc(0); - c->wds = 1; - c->x[0] = 0; - return c; - } - if (i < 0) { - c = a; - a = b; - b = c; - i = 1; - } - else - i = 0; - c = Balloc(a->k); - c->sign = i; - wa = a->wds; - xa = a->x; - xae = xa + wa; - wb = b->wds; - xb = b->x; - xbe = xb + wb; - xc = c->x; - borrow = 0; -#ifdef ULLong - do { - y = (ULLong)*xa++ - *xb++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = y & FFFFFFFF; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = y & FFFFFFFF; - } -#else -#ifdef Pack_32 - do { - y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } - while(xb < xbe); - while(xa < xae) { - y = (*xa & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } -#else - do { - y = *xa++ - *xb++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } -#endif -#endif - while(!*--xc) - wa--; - c->wds = wa; - return c; - } - - static double -ulp -#ifdef KR_headers - (x) U *x; -#else - (U *x) -#endif -{ - Long L; - U u; - - L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; -#ifndef Avoid_Underflow -#ifndef Sudden_Underflow - if (L > 0) { -#endif -#endif -#ifdef IBM - L |= Exp_msk1 >> 4; -#endif - word0(&u) = L; - word1(&u) = 0; -#ifndef Avoid_Underflow -#ifndef Sudden_Underflow - } - else { - L = -L >> Exp_shift; - if (L < Exp_shift) { - word0(&u) = 0x80000 >> L; - word1(&u) = 0; - } - else { - word0(&u) = 0; - L -= Exp_shift; - word1(&u) = L >= 31 ? 1 : 1 << 31 - L; - } - } -#endif -#endif - return dval(&u); - } - - static double -b2d -#ifdef KR_headers - (a, e) Bigint *a; int *e; -#else - (Bigint *a, int *e) -#endif -{ - ULong *xa, *xa0, w, y, z; - int k; - U d; -#ifdef VAX - ULong d0, d1; -#else -#define d0 word0(&d) -#define d1 word1(&d) -#endif - - xa0 = a->x; - xa = xa0 + a->wds; - y = *--xa; -#ifdef DEBUG - if (!y) Bug("zero y in b2d"); -#endif - k = hi0bits(y); - *e = 32 - k; -#ifdef Pack_32 - if (k < Ebits) { - d0 = Exp_1 | y >> (Ebits - k); - w = xa > xa0 ? *--xa : 0; - d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - if (k -= Ebits) { - d0 = Exp_1 | y << k | z >> (32 - k); - y = xa > xa0 ? *--xa : 0; - d1 = z << k | y >> (32 - k); - } - else { - d0 = Exp_1 | y; - d1 = z; - } -#else - if (k < Ebits + 16) { - z = xa > xa0 ? *--xa : 0; - d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; - w = xa > xa0 ? *--xa : 0; - y = xa > xa0 ? *--xa : 0; - d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - w = xa > xa0 ? *--xa : 0; - k -= Ebits + 16; - d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; - y = xa > xa0 ? *--xa : 0; - d1 = w << k + 16 | y << k; -#endif - ret_d: -#ifdef VAX - word0(&d) = d0 >> 16 | d0 << 16; - word1(&d) = d1 >> 16 | d1 << 16; -#else -#undef d0 -#undef d1 -#endif - return dval(&d); - } - - static Bigint * -d2b -#ifdef KR_headers - (d, e, bits) U *d; int *e, *bits; -#else - (U *d, int *e, int *bits) -#endif -{ - Bigint *b; - int de, k; - ULong *x, y, z; -#ifndef Sudden_Underflow - int i; -#endif -#ifdef VAX - ULong d0, d1; - d0 = word0(d) >> 16 | word0(d) << 16; - d1 = word1(d) >> 16 | word1(d) << 16; -#else -#define d0 word0(d) -#define d1 word1(d) -#endif - -#ifdef Pack_32 - b = Balloc(1); -#else - b = Balloc(2); -#endif - x = b->x; - - z = d0 & Frac_mask; - d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ -#ifdef Sudden_Underflow - de = (int)(d0 >> Exp_shift); -#ifndef IBM - z |= Exp_msk11; -#endif -#else - de = (int)(d0 >> Exp_shift); - if (de) - z |= Exp_msk1; -#endif -#ifdef Pack_32 - y = d1; - if (y) { - k = lo0bits(&y); - if (k) { - x[0] = y | z << (32 - k); - z >>= k; - } - else - x[0] = y; - x[1] = z; - b->wds = x[1] ? 2 : 1; -#ifndef Sudden_Underflow - i = b->wds; -#endif - } - else { - k = lo0bits(&z); - x[0] = z; -#ifndef Sudden_Underflow - i = -#endif - b->wds = 1; - k += 32; - } -#else - if (y = d1) { - if (k = lo0bits(&y)) - if (k >= 16) { - x[0] = y | z << 32 - k & 0xffff; - x[1] = z >> k - 16 & 0xffff; - x[2] = z >> k; - i = 2; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16 | z << 16 - k & 0xffff; - x[2] = z >> k & 0xffff; - x[3] = z >> k+16; - i = 3; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16; - x[2] = z & 0xffff; - x[3] = z >> 16; - i = 3; - } - } - else { -#ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - if (k >= 16) { - x[0] = z; - i = 0; - } - else { - x[0] = z & 0xffff; - x[1] = z >> 16; - i = 1; - } - k += 32; - } - while(!x[i]) - --i; - b->wds = i + 1; -#endif -#ifndef Sudden_Underflow - if (de) { -#endif -#ifdef IBM - *e = (de - Bias - (P-1) << 2) + k; - *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); -#else - *e = de - Bias - (P-1) + k; - *bits = P - k; -#endif -#ifndef Sudden_Underflow - } - else { - *e = de - Bias - (P-1) + 1 + k; -#ifdef Pack_32 - *bits = 32*i - hi0bits(x[i-1]); -#else - *bits = (i+2)*16 - hi0bits(x[i]); -#endif - } -#endif - return b; - } -#undef d0 -#undef d1 - - static double -ratio -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else - (Bigint *a, Bigint *b) -#endif -{ - U da, db; - int k, ka, kb; - - dval(&da) = b2d(a, &ka); - dval(&db) = b2d(b, &kb); -#ifdef Pack_32 - k = ka - kb + 32*(a->wds - b->wds); -#else - k = ka - kb + 16*(a->wds - b->wds); -#endif -#ifdef IBM - if (k > 0) { - word0(&da) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(&da) *= 1 << k; - } - else { - k = -k; - word0(&db) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(&db) *= 1 << k; - } -#else - if (k > 0) - word0(&da) += k*Exp_msk1; - else { - k = -k; - word0(&db) += k*Exp_msk1; - } -#endif - return dval(&da) / dval(&db); - } - - static CONST double -tens[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22 -#ifdef VAX - , 1e23, 1e24 -#endif - }; - - static CONST double -#ifdef IEEE_Arith -bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, -#ifdef Avoid_Underflow - 9007199254740992.*9007199254740992.e-256 - /* = 2^106 * 1e-256 */ -#else - 1e-256 -#endif - }; -/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ -/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ -#define Scale_Bit 0x10 -#define n_bigtens 5 -#else -#ifdef IBM -bigtens[] = { 1e16, 1e32, 1e64 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; -#define n_bigtens 3 -#else -bigtens[] = { 1e16, 1e32 }; -static CONST double tinytens[] = { 1e-16, 1e-32 }; -#define n_bigtens 2 -#endif -#endif - -#undef Need_Hexdig -#ifdef INFNAN_CHECK -#ifndef No_Hex_NaN -#define Need_Hexdig -#endif -#endif - -#ifndef Need_Hexdig -#ifndef NO_HEX_FP -#define Need_Hexdig -#endif -#endif - -#ifdef Need_Hexdig /*{*/ -static unsigned char hexdig[256]; - - static void -#ifdef KR_headers -htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc; -#else -htinit(unsigned char *h, unsigned char *s, int inc) -#endif -{ - int i, j; - for(i = 0; (j = s[i]) !=0; i++) - h[j] = (unsigned char)(i + inc); - } - - static void -#ifdef KR_headers -hexdig_init() -#else -hexdig_init(void) -#endif -{ -#define USC (unsigned char *) - htinit(hexdig, USC "0123456789", 0x10); - htinit(hexdig, USC "abcdef", 0x10 + 10); - htinit(hexdig, USC "ABCDEF", 0x10 + 10); - } -#endif /* } Need_Hexdig */ - -#ifdef INFNAN_CHECK - -#ifndef NAN_WORD0 -#define NAN_WORD0 0x7ff80000 -#endif - -#ifndef NAN_WORD1 -#define NAN_WORD1 0 -#endif - - static int -match -#ifdef KR_headers - (sp, t) char **sp, *t; -#else - (CONST char **sp, CONST char *t) -#endif -{ - int c, d; - CONST char *s = *sp; - - for(d = *t++; d; d = *t++) { - if ((c = *++s) >= 'A' && c <= 'Z') - c += 'a' - 'A'; - if (c != d) - return 0; - } - *sp = s + 1; - return 1; - } - -#ifndef No_Hex_NaN - static void -hexnan -#ifdef KR_headers - (rvp, sp) U *rvp; CONST char **sp; -#else - (U *rvp, CONST char **sp) -#endif -{ - ULong c, x[2]; - CONST char *s; - int c1, havedig, udx0, xshift; - - if (!hexdig['0']) - hexdig_init(); - x[0] = x[1] = 0; - havedig = xshift = 0; - udx0 = 1; - s = *sp; - /* allow optional initial 0x or 0X */ - for(c = *(CONST unsigned char*)(s+1); c && c <= ' '; c = *(CONST unsigned char*)(s+1)) - ++s; - if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')) - s += 2; - for(c = *(CONST unsigned char*)++s; c; c = *(CONST unsigned char*)++s) { - c1 = hexdig[c]; - if (c1) - c = c1 & 0xf; - else if (c <= ' ') { - if (udx0 && havedig) { - udx0 = 0; - xshift = 1; - } - continue; - } -#ifdef GDTOA_NON_PEDANTIC_NANCHECK - else if (/*(*/ c == ')' && havedig) { - *sp = s + 1; - break; - } - else - return; /* invalid form: don't change *sp */ -#else - else { - do { - if (/*(*/ c == ')') { - *sp = s + 1; - break; - } - c = *++s; - } while(c); - break; - } -#endif - havedig = 1; - if (xshift) { - xshift = 0; - x[0] = x[1]; - x[1] = 0; - } - if (udx0) - x[0] = (x[0] << 4) | (x[1] >> 28); - x[1] = (x[1] << 4) | c; - } - if ((x[0] &= 0xfffff) || x[1]) { - word0(rvp) = Exp_mask | x[0]; - word1(rvp) = x[1]; - } - } -#endif /*No_Hex_NaN*/ -#endif /* INFNAN_CHECK */ - -#ifdef Pack_32 -#define ULbits 32 -#define kshift 5 -#define kmask 31 -#else -#define ULbits 16 -#define kshift 4 -#define kmask 15 -#endif -#ifndef NO_HEX_FP /*{*/ - - static void -#ifdef KR_headers -rshift(b, k) Bigint *b; int k; -#else -rshift(Bigint *b, int k) -#endif -{ - ULong *x, *x1, *xe, y; - int n; - - x = x1 = b->x; - n = k >> kshift; - if (n < b->wds) { - xe = x + b->wds; - x += n; - if (k &= kmask) { - n = 32 - k; - y = *x++ >> k; - while(x < xe) { - *x1++ = (y | (*x << n)) & 0xffffffff; - y = *x++ >> k; - } - if ((*x1 = y) !=0) - x1++; - } - else - while(x < xe) - *x1++ = *x++; - } - if ((b->wds = x1 - b->x) == 0) - b->x[0] = 0; - } - - static ULong -#ifdef KR_headers -any_on(b, k) Bigint *b; int k; -#else -any_on(Bigint *b, int k) -#endif -{ - int n, nwds; - ULong *x, *x0, x1, x2; - - x = b->x; - nwds = b->wds; - n = k >> kshift; - if (n > nwds) - n = nwds; - else if (n < nwds && (k &= kmask)) { - x1 = x2 = x[n]; - x1 >>= k; - x1 <<= k; - if (x1 != x2) - return 1; - } - x0 = x; - x += n; - while(x > x0) - if (*--x) - return 1; - return 0; - } - -enum { /* rounding values: same as FLT_ROUNDS */ - Round_zero = 0, - Round_near = 1, - Round_up = 2, - Round_down = 3 - }; - - static Bigint * -#ifdef KR_headers -increment(b) Bigint *b; -#else -increment(Bigint *b) -#endif -{ - ULong *x, *xe; - Bigint *b1; - - x = b->x; - xe = x + b->wds; - do { - if (*x < (ULong)0xffffffffL) { - ++*x; - return b; - } - *x++ = 0; - } while(x < xe); - { - if (b->wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1,b); - Bfree(b); - b = b1; - } - b->x[b->wds++] = 1; - } - return b; - } - - void -#ifdef KR_headers -gethex(sp, rvp, rounding, sign) - CONST char **sp; U *rvp; int rounding, sign; -#else -gethex( CONST char **sp, U *rvp, int rounding, int sign) -#endif -{ - Bigint *b; - CONST unsigned char *decpt, *s0, *s, *s1; - Long e, e1; - ULong L, lostbits, *x; - int big, denorm, esign, havedig, k, n, nbits, up, zret; -#ifdef IBM - int j; -#endif - enum { -#ifdef IEEE_Arith /*{{*/ - emax = 0x7fe - Bias - P + 1, - emin = Emin - P + 1 -#else /*}{*/ - emin = Emin - P, -#ifdef VAX - emax = 0x7ff - Bias - P + 1 -#endif -#ifdef IBM - emax = 0x7f - Bias - P -#endif -#endif /*}}*/ - }; -#ifdef USE_LOCALE - int i; -#ifdef NO_LOCALE_CACHE - const unsigned char *decimalpoint = (unsigned char*) - localeconv()->decimal_point; -#else - const unsigned char *decimalpoint; - static unsigned char *decimalpoint_cache; - if (!(s0 = decimalpoint_cache)) { - s0 = (unsigned char*)localeconv()->decimal_point; - if ((decimalpoint_cache = (unsigned char*) - MALLOC(strlen((CONST char*)s0) + 1))) { - strcpy((char*)decimalpoint_cache, (CONST char*)s0); - s0 = decimalpoint_cache; - } - } - decimalpoint = s0; -#endif -#endif - - if (!hexdig['0']) - hexdig_init(); - havedig = 0; - s0 = *(CONST unsigned char **)sp + 2; - while(s0[havedig] == '0') - havedig++; - s0 += havedig; - s = s0; - decpt = 0; - zret = 0; - e = 0; - if (hexdig[*s]) - havedig++; - else { - zret = 1; -#ifdef USE_LOCALE - for(i = 0; decimalpoint[i]; ++i) { - if (s[i] != decimalpoint[i]) - goto pcheck; - } - decpt = s += i; -#else - if (*s != '.') - goto pcheck; - decpt = ++s; -#endif - if (!hexdig[*s]) - goto pcheck; - while(*s == '0') - s++; - if (hexdig[*s]) - zret = 0; - havedig = 1; - s0 = s; - } - while(hexdig[*s]) - s++; -#ifdef USE_LOCALE - if (*s == *decimalpoint && !decpt) { - for(i = 1; decimalpoint[i]; ++i) { - if (s[i] != decimalpoint[i]) - goto pcheck; - } - decpt = s += i; -#else - if (*s == '.' && !decpt) { - decpt = ++s; -#endif - while(hexdig[*s]) - s++; - }/*}*/ - if (decpt) - e = -(((Long)(s-decpt)) << 2); - pcheck: - s1 = s; - big = esign = 0; - switch(*s) { - case 'p': - case 'P': - switch(*++s) { - case '-': - esign = 1; - /* no break */ - case '+': - s++; - } - if ((n = hexdig[*s]) == 0 || n > 0x19) { - s = s1; - break; - } - e1 = n - 0x10; - while((n = hexdig[*++s]) !=0 && n <= 0x19) { - if (e1 & 0xf8000000) - big = 1; - e1 = 10*e1 + n - 0x10; - } - if (esign) - e1 = -e1; - e += e1; - } - *sp = (char*)s; - if (!havedig) - *sp = (char*)s0 - 1; - if (zret) - goto retz1; - if (big) { - if (esign) { -#ifdef IEEE_Arith - switch(rounding) { - case Round_up: - if (sign) - break; - goto ret_tiny; - case Round_down: - if (!sign) - break; - goto ret_tiny; - } -#endif - goto retz; -#ifdef IEEE_Arith - ret_tiny: -#ifndef NO_ERRNO - errno = ERANGE; -#endif - word0(rvp) = 0; - word1(rvp) = 1; - return; -#endif /* IEEE_Arith */ - } - switch(rounding) { - case Round_near: - goto ovfl1; - case Round_up: - if (!sign) - goto ovfl1; - goto ret_big; - case Round_down: - if (sign) - goto ovfl1; - goto ret_big; - } - ret_big: - word0(rvp) = Big0; - word1(rvp) = Big1; - return; - } - n = s1 - s0 - 1; - for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1) - k++; - b = Balloc(k); - x = b->x; - n = 0; - L = 0; -#ifdef USE_LOCALE - for(i = 0; decimalpoint[i+1]; ++i); -#endif - while(s1 > s0) { -#ifdef USE_LOCALE - if (*--s1 == decimalpoint[i]) { - s1 -= i; - continue; - } -#else - if (*--s1 == '.') - continue; -#endif - if (n == ULbits) { - *x++ = L; - L = 0; - n = 0; - } - L |= (hexdig[*s1] & 0x0f) << n; - n += 4; - } - *x++ = L; - b->wds = n = x - b->x; - n = ULbits*n - hi0bits(L); - nbits = Nbits; - lostbits = 0; - x = b->x; - if (n > nbits) { - n -= nbits; - if (any_on(b,n)) { - lostbits = 1; - k = n - 1; - if (x[k>>kshift] & 1 << (k & kmask)) { - lostbits = 2; - if (k > 0 && any_on(b,k)) - lostbits = 3; - } - } - rshift(b, n); - e += n; - } - else if (n < nbits) { - n = nbits - n; - b = lshift(b, n); - e -= n; - x = b->x; - } - if (e > Emax) { - ovfl: - Bfree(b); - ovfl1: -#ifndef NO_ERRNO - errno = ERANGE; -#endif - word0(rvp) = Exp_mask; - word1(rvp) = 0; - return; - } - denorm = 0; - if (e < emin) { - denorm = 1; - n = emin - e; - if (n >= nbits) { -#ifdef IEEE_Arith /*{*/ - switch (rounding) { - case Round_near: - if (n == nbits && (n < 2 || any_on(b,n-1))) - goto ret_tiny; - break; - case Round_up: - if (!sign) - goto ret_tiny; - break; - case Round_down: - if (sign) - goto ret_tiny; - } -#endif /* } IEEE_Arith */ - Bfree(b); - retz: -#ifndef NO_ERRNO - errno = ERANGE; -#endif - retz1: - rvp->d = 0.; - return; - } - k = n - 1; - if (lostbits) - lostbits = 1; - else if (k > 0) - lostbits = any_on(b,k); - if (x[k>>kshift] & 1 << (k & kmask)) - lostbits |= 2; - nbits -= n; - rshift(b,n); - e = emin; - } - if (lostbits) { - up = 0; - switch(rounding) { - case Round_zero: - break; - case Round_near: - if (lostbits & 2 - && (lostbits & 1) | (x[0] & 1)) - up = 1; - break; - case Round_up: - up = 1 - sign; - break; - case Round_down: - up = sign; - } - if (up) { - k = b->wds; - b = increment(b); - x = b->x; - if (denorm) { -#if 0 - if (nbits == Nbits - 1 - && x[nbits >> kshift] & 1 << (nbits & kmask)) - denorm = 0; /* not currently used */ -#endif - } - else if (b->wds > k - || ((n = nbits & kmask) !=0 - && hi0bits(x[k-1]) < 32-n)) { - rshift(b,1); - if (++e > Emax) - goto ovfl; - } - } - } -#ifdef IEEE_Arith - if (denorm) - word0(rvp) = b->wds > 1 ? b->x[1] & ~0x100000 : 0; - else - word0(rvp) = (b->x[1] & ~0x100000) | ((e + 0x3ff + 52) << 20); - word1(rvp) = b->x[0]; -#endif -#ifdef IBM - if ((j = e & 3)) { - k = b->x[0] & ((1 << j) - 1); - rshift(b,j); - if (k) { - switch(rounding) { - case Round_up: - if (!sign) - increment(b); - break; - case Round_down: - if (sign) - increment(b); - break; - case Round_near: - j = 1 << (j-1); - if (k & j && ((k & (j-1)) | lostbits)) - increment(b); - } - } - } - e >>= 2; - word0(rvp) = b->x[1] | ((e + 65 + 13) << 24); - word1(rvp) = b->x[0]; -#endif -#ifdef VAX - /* The next two lines ignore swap of low- and high-order 2 bytes. */ - /* word0(rvp) = (b->x[1] & ~0x800000) | ((e + 129 + 55) << 23); */ - /* word1(rvp) = b->x[0]; */ - word0(rvp) = ((b->x[1] & ~0x800000) >> 16) | ((e + 129 + 55) << 7) | (b->x[1] << 16); - word1(rvp) = (b->x[0] >> 16) | (b->x[0] << 16); -#endif - Bfree(b); - } -#endif /*}!NO_HEX_FP*/ - - static int -#ifdef KR_headers -dshift(b, p2) Bigint *b; int p2; -#else -dshift(Bigint *b, int p2) -#endif -{ - int rv = hi0bits(b->x[b->wds-1]) - 4; - if (p2 > 0) - rv -= p2; - return rv & kmask; - } - - static int -quorem -#ifdef KR_headers - (b, S) Bigint *b, *S; -#else - (Bigint *b, Bigint *S) -#endif -{ - int n; - ULong *bx, *bxe, q, *sx, *sxe; -#ifdef ULLong - ULLong borrow, carry, y, ys; -#else - ULong borrow, carry, y, ys; -#ifdef Pack_32 - ULong si, z, zs; -#endif -#endif - - n = S->wds; -#ifdef DEBUG - /*debug*/ if (b->wds > n) - /*debug*/ Bug("oversize b in quorem"); -#endif - if (b->wds < n) - return 0; - sx = S->x; - sxe = sx + --n; - bx = b->x; - bxe = bx + n; - q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ -#ifdef DEBUG - /*debug*/ if (q > 9) - /*debug*/ Bug("oversized quotient in quorem"); -#endif - if (q) { - borrow = 0; - carry = 0; - do { -#ifdef ULLong - ys = *sx++ * (ULLong)q + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; -#else -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) * q + carry; - zs = (si >> 16) * q + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#else - ys = *sx++ * q + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } - while(sx <= sxe); - if (!*bxe) { - bx = b->x; - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - if (cmp(b, S) >= 0) { - q++; - borrow = 0; - carry = 0; - bx = b->x; - sx = S->x; - do { -#ifdef ULLong - ys = *sx++ + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; -#else -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) + carry; - zs = (si >> 16) + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#else - ys = *sx++ + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } - while(sx <= sxe); - bx = b->x; - bxe = bx + n; - if (!*bxe) { - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - return q; - } - -#ifndef NO_STRTOD_BIGCOMP - - static void -bigcomp -#ifdef KR_headers - (rv, s0, bc) - U *rv; CONST char *s0; BCinfo *bc; -#else - (U *rv, CONST char *s0, BCinfo *bc) -#endif -{ - Bigint *b, *d; - int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase; - - dsign = bc->dsign; - nd = bc->nd; - nd0 = bc->nd0; - p5 = nd + bc->e0 - 1; - dd = speccase = 0; -#ifndef Sudden_Underflow - if (rv->d == 0.) { /* special case: value near underflow-to-zero */ - /* threshold was rounded to zero */ - b = i2b(1); - p2 = Emin - P + 1; - bbits = 1; -#ifdef Avoid_Underflow - word0(rv) = (P+2) << Exp_shift; -#else - word1(rv) = 1; -#endif - i = 0; -#ifdef Honor_FLT_ROUNDS - if (bc->rounding == 1) -#endif - { - speccase = 1; - --p2; - dsign = 0; - goto have_i; - } - } - else -#endif - b = d2b(rv, &p2, &bbits); -#ifdef Avoid_Underflow - p2 -= bc->scale; -#endif - /* floor(log2(rv)) == bbits - 1 + p2 */ - /* Check for denormal case. */ - i = P - bbits; - if (i > (j = P - Emin - 1 + p2)) { -#ifdef Sudden_Underflow - Bfree(b); - b = i2b(1); - p2 = Emin; - i = P - 1; -#ifdef Avoid_Underflow - word0(rv) = (1 + bc->scale) << Exp_shift; -#else - word0(rv) = Exp_msk1; -#endif - word1(rv) = 0; -#else - i = j; -#endif - } -#ifdef Honor_FLT_ROUNDS - if (bc->rounding != 1) { - if (i > 0) - b = lshift(b, i); - if (dsign) - b = increment(b); - } - else -#endif - { - b = lshift(b, ++i); - b->x[0] |= 1; - } -#ifndef Sudden_Underflow - have_i: -#endif - p2 -= p5 + i; - d = i2b(1); - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - */ - if (p5 > 0) - d = pow5mult(d, p5); - else if (p5 < 0) - b = pow5mult(b, -p5); - if (p2 > 0) { - b2 = p2; - d2 = 0; - } - else { - b2 = 0; - d2 = -p2; - } - i = dshift(d, d2); - if ((b2 += i) > 0) - b = lshift(b, b2); - if ((d2 += i) > 0) - d = lshift(d, d2); - - /* Now b/d = exactly half-way between the two floating-point values */ - /* on either side of the input string. Compute first digit of b/d. */ - - dig = quorem(b,d); - if (!dig) { - b = multadd(b, 10, 0); /* very unlikely */ - dig = quorem(b,d); - } - - /* Compare b/d with s0 */ - - for(i = 0; i < nd0; ) { - dd = s0[i++] - '0' - dig; - if (dd) - goto ret; - if (!b->x[0] && b->wds == 1) { - if (i < nd) - dd = 1; - goto ret; - } - b = multadd(b, 10, 0); - dig = quorem(b,d); - } - for(j = bc->dp1; i++ < nd;) { - dd = s0[j++] - '0' - dig; - if (dd) - goto ret; - if (!b->x[0] && b->wds == 1) { - if (i < nd) - dd = 1; - goto ret; - } - b = multadd(b, 10, 0); - dig = quorem(b,d); - } - if (b->x[0] || b->wds > 1) - dd = -1; - ret: - Bfree(b); - Bfree(d); -#ifdef Honor_FLT_ROUNDS - if (bc->rounding != 1) { - if (dd < 0) { - if (bc->rounding == 0) { - if (!dsign) - goto retlow1; - } - else if (dsign) - goto rethi1; - } - else if (dd > 0) { - if (bc->rounding == 0) { - if (dsign) - goto rethi1; - goto ret1; - } - if (!dsign) - goto rethi1; - dval(rv) += 2.*ulp(rv); - } - else { - bc->inexact = 0; - if (dsign) - goto rethi1; - } - } - else -#endif - if (speccase) { - if (dd <= 0) - rv->d = 0.; - } - else if (dd < 0) { - if (!dsign) /* does not happen for round-near */ -retlow1: - dval(rv) -= ulp(rv); - } - else if (dd > 0) { - if (dsign) { - rethi1: - dval(rv) += ulp(rv); - } - } - else { - /* Exact half-way case: apply round-even rule. */ - if (word1(rv) & 1) { - if (dsign) - goto rethi1; - goto retlow1; - } - } - -#ifdef Honor_FLT_ROUNDS - ret1: -#endif - return; - } -#endif /* NO_STRTOD_BIGCOMP */ - - double -strtod -#ifdef KR_headers - (s00, se) CONST char *s00; char **se; -#else - (CONST char *s00, char **se) -#endif -{ - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1; - int esign, i, j, k, nd, nd0, nf, nz, nz0, sign; - CONST char *s, *s0, *s1; - double aadj, aadj1; - Long L; - U aadj2, adj, rv, rv0; - ULong y, z; - BCinfo bc; - Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; -#ifdef SET_INEXACT - int oldinexact; -#endif -#ifdef Honor_FLT_ROUNDS /*{*/ -#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ - bc.rounding = Flt_Rounds; -#else /*}{*/ - bc.rounding = 1; - switch(fegetround()) { - case FE_TOWARDZERO: bc.rounding = 0; break; - case FE_UPWARD: bc.rounding = 2; break; - case FE_DOWNWARD: bc.rounding = 3; - } -#endif /*}}*/ -#endif /*}*/ -#ifdef USE_LOCALE - CONST char *s2; -#endif - - sign = nz0 = nz = bc.dplen = bc.uflchk = 0; - dval(&rv) = 0.; - for(s = s00;;s++) switch(*s) { - case '-': - sign = 1; - /* no break */ - case '+': - if (*++s) - goto break2; - /* no break */ - case 0: - goto ret0; - case '\t': - case '\n': - case '\v': - case '\f': - case '\r': - case ' ': - continue; - default: - goto break2; - } - break2: - if (*s == '0') { -#ifndef NO_HEX_FP /*{*/ - switch(s[1]) { - case 'x': - case 'X': -#ifdef Honor_FLT_ROUNDS - gethex(&s, &rv, bc.rounding, sign); -#else - gethex(&s, &rv, 1, sign); -#endif - goto ret; - } -#endif /*}*/ - nz0 = 1; - while(*++s == '0') ; - if (!*s) - goto ret; - } - s0 = s; - y = z = 0; - for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) - if (nd < 9) - y = 10*y + c - '0'; - else if (nd < 16) - z = 10*z + c - '0'; - nd0 = nd; - bc.dp0 = bc.dp1 = s - s0; -#ifdef USE_LOCALE - s1 = localeconv()->decimal_point; - if (c == *s1) { - c = '.'; - if (*++s1) { - s2 = s; - for(;;) { - if (*++s2 != *s1) { - c = 0; - break; - } - if (!*++s1) { - s = s2; - break; - } - } - } - } -#endif - if (c == '.') { - c = *++s; - bc.dp1 = s - s0; - bc.dplen = bc.dp1 - bc.dp0; - if (!nd) { - for(; c == '0'; c = *++s) - nz++; - if (c > '0' && c <= '9') { - s0 = s; - nf += nz; - nz = 0; - goto have_dig; - } - goto dig_done; - } - for(; c >= '0' && c <= '9'; c = *++s) { - have_dig: - nz++; - if (c -= '0') { - nf += nz; - for(i = 1; i < nz; i++) - if (nd++ < 9) - y *= 10; - else if (nd <= DBL_DIG + 1) - z *= 10; - if (nd++ < 9) - y = 10*y + c; - else if (nd <= DBL_DIG + 1) - z = 10*z + c; - nz = 0; - } - } - } - dig_done: - e = 0; - if (c == 'e' || c == 'E') { - if (!nd && !nz && !nz0) { - goto ret0; - } - s00 = s; - esign = 0; - switch(c = *++s) { - case '-': - esign = 1; - case '+': - c = *++s; - } - if (c >= '0' && c <= '9') { - while(c == '0') - c = *++s; - if (c > '0' && c <= '9') { - L = c - '0'; - s1 = s; - while((c = *++s) >= '0' && c <= '9') - L = 10*L + c - '0'; - if (s - s1 > 8 || L > 19999) - /* Avoid confusion from exponents - * so large that e might overflow. - */ - e = 19999; /* safe for 16 bit ints */ - else - e = (int)L; - if (esign) - e = -e; - } - else - e = 0; - } - else - s = s00; - } - if (!nd) { - if (!nz && !nz0) { -#ifdef INFNAN_CHECK - /* Check for Nan and Infinity */ - if (!bc.dplen) - switch(c) { - case 'i': - case 'I': - if (match(&s,"nf")) { - --s; - if (!match(&s,"inity")) - ++s; - word0(&rv) = 0x7ff00000; - word1(&rv) = 0; - goto ret; - } - break; - case 'n': - case 'N': - if (match(&s, "an")) { - word0(&rv) = NAN_WORD0; - word1(&rv) = NAN_WORD1; -#ifndef No_Hex_NaN - if (*s == '(') /*)*/ - hexnan(&rv, &s); -#endif - goto ret; - } - } -#endif /* INFNAN_CHECK */ - ret0: - s = s00; - sign = 0; - } - goto ret; - } - bc.e0 = e1 = e -= nf; - - /* Now we have nd0 digits, starting at s0, followed by a - * decimal point, followed by nd-nd0 digits. The number we're - * after is the integer represented by those digits times - * 10**e */ - - if (!nd0) - nd0 = nd; - k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(&rv) = y; - if (k > 9) { -#ifdef SET_INEXACT - if (k > DBL_DIG) - oldinexact = get_inexact(); -#endif - dval(&rv) = tens[k - 9] * dval(&rv) + z; - } - bd0 = 0; - if (nd <= DBL_DIG -#ifndef RND_PRODQUOT -#ifndef Honor_FLT_ROUNDS - && Flt_Rounds == 1 -#endif -#endif - ) { - if (!e) - goto ret; - if (e > 0) { - if (e <= Ten_pmax) { -#ifdef VAX - goto vax_ovfl_check; -#else -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv.d = -rv.d; - sign = 0; - } -#endif - /* rv = */ rounded_product(dval(&rv), tens[e]); - goto ret; -#endif - } - i = DBL_DIG - nd; - if (e <= Ten_pmax + i) { - /* A fancier test would sometimes let us do - * this for larger i values. - */ -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv.d = -rv.d; - sign = 0; - } -#endif - e -= i; - dval(&rv) *= tens[i]; -#ifdef VAX - /* VAX exponent range is so narrow we must - * worry about overflow here... - */ - vax_ovfl_check: - word0(&rv) -= P*Exp_msk1; - /* rv = */ rounded_product(dval(&rv), tens[e]); - if ((word0(&rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) - goto ovfl; - word0(&rv) += P*Exp_msk1; -#else - /* rv = */ rounded_product(dval(&rv), tens[e]); -#endif - goto ret; - } - } -#ifndef Inaccurate_Divide - else if (e >= -Ten_pmax) { -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv.d = -rv.d; - sign = 0; - } -#endif - /* rv = */ rounded_quotient(dval(&rv), tens[-e]); - goto ret; - } -#endif - } - e1 += nd - k; - -#ifdef IEEE_Arith -#ifdef SET_INEXACT - bc.inexact = 1; - if (k <= DBL_DIG) - oldinexact = get_inexact(); -#endif -#ifdef Avoid_Underflow - bc.scale = 0; -#endif -#ifdef Honor_FLT_ROUNDS - if (bc.rounding >= 2) { - if (sign) - bc.rounding = bc.rounding == 2 ? 0 : 2; - else - if (bc.rounding != 2) - bc.rounding = 0; - } -#endif -#endif /*IEEE_Arith*/ - - /* Get starting approximation = rv * 10**e1 */ - - if (e1 > 0) { - i = e1 & 15; - if (i) - dval(&rv) *= tens[i]; - if (e1 &= ~15) { - if (e1 > DBL_MAX_10_EXP) { - ovfl: -#ifndef NO_ERRNO - errno = ERANGE; -#endif - /* Can't trust HUGE_VAL */ -#ifdef IEEE_Arith -#ifdef Honor_FLT_ROUNDS - switch(bc.rounding) { - case 0: /* toward 0 */ - case 3: /* toward -infinity */ - word0(&rv) = Big0; - word1(&rv) = Big1; - break; - default: - word0(&rv) = Exp_mask; - word1(&rv) = 0; - } -#else /*Honor_FLT_ROUNDS*/ - word0(&rv) = Exp_mask; - word1(&rv) = 0; -#endif /*Honor_FLT_ROUNDS*/ -#ifdef SET_INEXACT - /* set overflow bit */ - dval(&rv0) = 1e300; - dval(&rv0) *= dval(&rv0); -#endif -#else /*IEEE_Arith*/ - word0(&rv) = Big0; - word1(&rv) = Big1; -#endif /*IEEE_Arith*/ - goto ret; - } - e1 >>= 4; - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= bigtens[j]; - /* The last multiplication could overflow. */ - word0(&rv) -= P*Exp_msk1; - dval(&rv) *= bigtens[j]; - if ((z = word0(&rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-P)) - goto ovfl; - if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { - /* set to largest number */ - /* (Can't trust DBL_MAX) */ - word0(&rv) = Big0; - word1(&rv) = Big1; - } - else - word0(&rv) += P*Exp_msk1; - } - } - else if (e1 < 0) { - e1 = -e1; - i = e1 & 15; - if (i) - dval(&rv) /= tens[i]; - if (e1 >>= 4) { - if (e1 >= 1 << n_bigtens) - goto undfl; -#ifdef Avoid_Underflow - if (e1 & Scale_Bit) - bc.scale = 2*P; - for(j = 0; e1 > 0; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= tinytens[j]; - if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) - >> Exp_shift)) > 0) { - /* scaled rv is denormal; clear j low bits */ - if (j >= 32) { - word1(&rv) = 0; - if (j >= 53) - word0(&rv) = (P+2)*Exp_msk1; - else - word0(&rv) &= 0xffffffff << (j-32); - } - else - word1(&rv) &= 0xffffffff << j; - } -#else - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= tinytens[j]; - /* The last multiplication could underflow. */ - dval(&rv0) = dval(&rv); - dval(&rv) *= tinytens[j]; - if (!dval(&rv)) { - dval(&rv) = 2.*dval(&rv0); - dval(&rv) *= tinytens[j]; -#endif - if (!dval(&rv)) { - undfl: - dval(&rv) = 0.; -#ifndef NO_ERRNO - errno = ERANGE; -#endif - goto ret; - } -#ifndef Avoid_Underflow - word0(&rv) = Tiny0; - word1(&rv) = Tiny1; - /* The refinement below will clean - * this approximation up. - */ - } -#endif - } - } - - /* Now the hard part -- adjusting rv to the correct value.*/ - - /* Put digits into bd: true value = bd * 10^e */ - - bc.nd = nd; -#ifndef NO_STRTOD_BIGCOMP - bc.nd0 = nd0; /* Only needed if nd > strtod_diglim, but done here */ - /* to silence an erroneous warning about bc.nd0 */ - /* possibly not being initialized. */ - if (nd > strtod_diglim) { - /* ASSERT(strtod_diglim >= 18); 18 == one more than the */ - /* minimum number of decimal digits to distinguish double values */ - /* in IEEE arithmetic. */ - i = j = 18; - if (i > nd0) - j += bc.dplen; - for(;;) { - if (--j <= bc.dp1 && j >= bc.dp0) - j = bc.dp0 - 1; - if (s0[j] != '0') - break; - --i; - } - e += nd - i; - nd = i; - if (nd0 > nd) - nd0 = nd; - if (nd < 9) { /* must recompute y */ - y = 0; - for(i = 0; i < nd0; ++i) - y = 10*y + s0[i] - '0'; - for(j = bc.dp1; i < nd; ++i) - y = 10*y + s0[j++] - '0'; - } - } -#endif - bd0 = s2b(s0, nd0, nd, y, bc.dplen); - - for(;;) { - bd = Balloc(bd0->k); - Bcopy(bd, bd0); - bb = d2b(&rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ - bs = i2b(1); - - if (e >= 0) { - bb2 = bb5 = 0; - bd2 = bd5 = e; - } - else { - bb2 = bb5 = -e; - bd2 = bd5 = 0; - } - if (bbe >= 0) - bb2 += bbe; - else - bd2 -= bbe; - bs2 = bb2; -#ifdef Honor_FLT_ROUNDS - if (bc.rounding != 1) - bs2++; -#endif -#ifdef Avoid_Underflow - j = bbe - bc.scale; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; -#else /*Avoid_Underflow*/ -#ifdef Sudden_Underflow -#ifdef IBM - j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); -#else - j = P + 1 - bbbits; -#endif -#else /*Sudden_Underflow*/ - j = bbe; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - bb2 += j; - bd2 += j; -#ifdef Avoid_Underflow - bd2 += bc.scale; -#endif - i = bb2 < bd2 ? bb2 : bd2; - if (i > bs2) - i = bs2; - if (i > 0) { - bb2 -= i; - bd2 -= i; - bs2 -= i; - } - if (bb5 > 0) { - bs = pow5mult(bs, bb5); - bb1 = mult(bs, bb); - Bfree(bb); - bb = bb1; - } - if (bb2 > 0) - bb = lshift(bb, bb2); - if (bd5 > 0) - bd = pow5mult(bd, bd5); - if (bd2 > 0) - bd = lshift(bd, bd2); - if (bs2 > 0) - bs = lshift(bs, bs2); - delta = diff(bb, bd); - bc.dsign = delta->sign; - delta->sign = 0; - i = cmp(delta, bs); -#ifndef NO_STRTOD_BIGCOMP - if (bc.nd > nd && i <= 0) { - if (bc.dsign) - break; /* Must use bigcomp(). */ -#ifdef Honor_FLT_ROUNDS - if (bc.rounding != 1) { - if (i < 0) - break; - } - else -#endif - { - bc.nd = nd; - i = -1; /* Discarded digits make delta smaller. */ - } - } -#endif -#ifdef Honor_FLT_ROUNDS - if (bc.rounding != 1) { - if (i < 0) { - /* Error is less than an ulp */ - if (!delta->x[0] && delta->wds <= 1) { - /* exact */ -#ifdef SET_INEXACT - bc.inexact = 0; -#endif - break; - } - if (bc.rounding) { - if (bc.dsign) { - adj.d = 1.; - goto apply_adj; - } - } - else if (!bc.dsign) { - adj.d = -1.; - if (!word1(&rv) - && !(word0(&rv) & Frac_mask)) { - y = word0(&rv) & Exp_mask; -#ifdef Avoid_Underflow - if (!bc.scale || y > 2*P*Exp_msk1) -#else - if (y) -#endif - { - delta = lshift(delta,Log2P); - if (cmp(delta, bs) <= 0) - adj.d = -0.5; - } - } - apply_adj: -#ifdef Avoid_Underflow - if (bc.scale && (y = word0(&rv) & Exp_mask) - <= 2*P*Exp_msk1) - word0(&adj) += (2*P+1)*Exp_msk1 - y; -#else -#ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= - P*Exp_msk1) { - word0(&rv) += P*Exp_msk1; - dval(&rv) += adj.d*ulp(dval(&rv)); - word0(&rv) -= P*Exp_msk1; - } - else -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - dval(&rv) += adj.d*ulp(&rv); - } - break; - } - adj.d = ratio(delta, bs); - if (adj.d < 1.) - adj.d = 1.; - if (adj.d <= 0x7ffffffe) { - /* adj = rounding ? ceil(adj) : floor(adj); */ - y = adj.d; - if (y != adj.d) { - if (!((bc.rounding>>1) ^ bc.dsign)) - y++; - adj.d = y; - } - } -#ifdef Avoid_Underflow - if (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(&adj) += (2*P+1)*Exp_msk1 - y; -#else -#ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { - word0(&rv) += P*Exp_msk1; - adj.d *= ulp(dval(&rv)); - if (bc.dsign) - dval(&rv) += adj.d; - else - dval(&rv) -= adj.d; - word0(&rv) -= P*Exp_msk1; - goto cont; - } -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - adj.d *= ulp(&rv); - if (bc.dsign) { - if (word0(&rv) == Big0 && word1(&rv) == Big1) - goto ovfl; - dval(&rv) += adj.d; - } - else - dval(&rv) -= adj.d; - goto cont; - } -#endif /*Honor_FLT_ROUNDS*/ - - if (i < 0) { - /* Error is less than half an ulp -- check for - * special case of mantissa a power of two. - */ - if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask -#ifdef IEEE_Arith -#ifdef Avoid_Underflow - || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 -#else - || (word0(&rv) & Exp_mask) <= Exp_msk1 -#endif -#endif - ) { -#ifdef SET_INEXACT - if (!delta->x[0] && delta->wds <= 1) - bc.inexact = 0; -#endif - break; - } - if (!delta->x[0] && delta->wds <= 1) { - /* exact result */ -#ifdef SET_INEXACT - bc.inexact = 0; -#endif - break; - } - delta = lshift(delta,Log2P); - if (cmp(delta, bs) > 0) - goto drop_down; - break; - } - if (i == 0) { - /* exactly half-way between */ - if (bc.dsign) { - if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 - && word1(&rv) == ( -#ifdef Avoid_Underflow - (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) - ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : -#endif - 0xffffffff)) { - /*boundary case -- increment exponent*/ - word0(&rv) = (word0(&rv) & Exp_mask) - + Exp_msk1 -#ifdef IBM - | Exp_msk1 >> 4 -#endif - ; - word1(&rv) = 0; -#ifdef Avoid_Underflow - bc.dsign = 0; -#endif - break; - } - } - else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { - drop_down: - /* boundary case -- decrement exponent */ -#ifdef Sudden_Underflow /*{{*/ - L = word0(&rv) & Exp_mask; -#ifdef IBM - if (L < Exp_msk1) -#else -#ifdef Avoid_Underflow - if (L <= (bc.scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) -#else - if (L <= Exp_msk1) -#endif /*Avoid_Underflow*/ -#endif /*IBM*/ - { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } - L -= Exp_msk1; -#else /*Sudden_Underflow}{*/ -#ifdef Avoid_Underflow - if (bc.scale) { - L = word0(&rv) & Exp_mask; - if (L <= (2*P+1)*Exp_msk1) { - if (L > (P+2)*Exp_msk1) - /* round even ==> */ - /* accept rv */ - break; - /* rv = smallest denormal */ - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } - } -#endif /*Avoid_Underflow*/ - L = (word0(&rv) & Exp_mask) - Exp_msk1; -#endif /*Sudden_Underflow}}*/ - word0(&rv) = L | Bndry_mask1; - word1(&rv) = 0xffffffff; -#ifdef IBM - goto cont; -#else - break; -#endif - } -#ifndef ROUND_BIASED - if (!(word1(&rv) & LSB)) - break; -#endif - if (bc.dsign) - dval(&rv) += ulp(&rv); -#ifndef ROUND_BIASED - else { - dval(&rv) -= ulp(&rv); -#ifndef Sudden_Underflow - if (!dval(&rv)) { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } -#endif - } -#ifdef Avoid_Underflow - bc.dsign = 1 - bc.dsign; -#endif -#endif - break; - } - if ((aadj = ratio(delta, bs)) <= 2.) { - if (bc.dsign) - aadj = aadj1 = 1.; - else if (word1(&rv) || word0(&rv) & Bndry_mask) { -#ifndef Sudden_Underflow - if (word1(&rv) == Tiny1 && !word0(&rv)) { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } -#endif - aadj = 1.; - aadj1 = -1.; - } - else { - /* special case -- power of FLT_RADIX to be */ - /* rounded down... */ - - if (aadj < 2./FLT_RADIX) - aadj = 1./FLT_RADIX; - else - aadj *= 0.5; - aadj1 = -aadj; - } - } - else { - aadj *= 0.5; - aadj1 = bc.dsign ? aadj : -aadj; -#ifdef Check_FLT_ROUNDS - switch(bc.rounding) { - case 2: /* towards +infinity */ - aadj1 -= 0.5; - break; - case 0: /* towards 0 */ - case 3: /* towards -infinity */ - aadj1 += 0.5; - } -#else - if (Flt_Rounds == 0) - aadj1 += 0.5; -#endif /*Check_FLT_ROUNDS*/ - } - y = word0(&rv) & Exp_mask; - - /* Check for overflow */ - - if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - dval(&rv0) = dval(&rv); - word0(&rv) -= P*Exp_msk1; - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - if ((word0(&rv) & Exp_mask) >= - Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (word0(&rv0) == Big0 && word1(&rv0) == Big1) - goto ovfl; - word0(&rv) = Big0; - word1(&rv) = Big1; - goto cont; - } - else - word0(&rv) += P*Exp_msk1; - } - else { -#ifdef Avoid_Underflow - if (bc.scale && y <= 2*P*Exp_msk1) { - if (aadj <= 0x7fffffff) { - if ((z = (ULong)aadj) <= 0) - z = 1; - aadj = z; - aadj1 = bc.dsign ? aadj : -aadj; - } - dval(&aadj2) = aadj1; - word0(&aadj2) += (2*P+1)*Exp_msk1 - y; - aadj1 = dval(&aadj2); - } - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; -#else -#ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { - dval(&rv0) = dval(&rv); - word0(&rv) += P*Exp_msk1; - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; -#ifdef IBM - if ((word0(&rv) & Exp_mask) < P*Exp_msk1) -#else - if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) -#endif - { - if (word0(&rv0) == Tiny0 - && word1(&rv0) == Tiny1) { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } - word0(&rv) = Tiny0; - word1(&rv) = Tiny1; - goto cont; - } - else - word0(&rv) -= P*Exp_msk1; - } - else { - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - } -#else /*Sudden_Underflow*/ - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., - * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid - * trouble from bits lost to denormalization; - * example: 1.2e-307 . - */ - if (y <= (P-1)*Exp_msk1 && aadj > 1.) { - aadj1 = (double)(int)(aadj + 0.5); - if (!bc.dsign) - aadj1 = -aadj1; - } - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - } - z = word0(&rv) & Exp_mask; -#ifndef SET_INEXACT - if (bc.nd == nd) { -#ifdef Avoid_Underflow - if (!bc.scale) -#endif - if (y == z) { - /* Can we stop now? */ - L = (Long)aadj; - aadj -= L; - /* The tolerances below are conservative. */ - if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask) { - if (aadj < .4999999 || aadj > .5000001) - break; - } - else if (aadj < .4999999/FLT_RADIX) - break; - } - } -#endif - cont: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(delta); - } - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); -#ifndef NO_STRTOD_BIGCOMP - if (bc.nd > nd) - bigcomp(&rv, s0, &bc); -#endif -#ifdef SET_INEXACT - if (bc.inexact) { - if (!oldinexact) { - word0(&rv0) = Exp_1 + (70 << Exp_shift); - word1(&rv0) = 0; - dval(&rv0) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); -#endif -#ifdef Avoid_Underflow - if (bc.scale) { - word0(&rv0) = Exp_1 - 2*P*Exp_msk1; - word1(&rv0) = 0; - dval(&rv) *= dval(&rv0); -#ifndef NO_ERRNO - /* try to avoid the bug of testing an 8087 register value */ -#ifdef IEEE_Arith - if (!(word0(&rv) & Exp_mask)) -#else - if (word0(&rv) == 0 && word1(&rv) == 0) -#endif - errno = ERANGE; -#endif - } -#endif /* Avoid_Underflow */ -#ifdef SET_INEXACT - if (bc.inexact && !(word0(&rv) & Exp_mask)) { - /* set underflow bit */ - dval(&rv0) = 1e-300; - dval(&rv0) *= dval(&rv0); - } -#endif - ret: - if (se) - *se = (char *)s; - return sign ? -dval(&rv) : dval(&rv); - } - -#ifndef MULTIPLE_THREADS - static char *dtoa_result; -#endif - - static char * -#ifdef KR_headers -rv_alloc(i) int i; -#else -rv_alloc(int i) -#endif -{ - int j, k, *r; - - j = sizeof(ULong); - for(k = 0; - sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= (size_t)i; - j <<= 1) - k++; - r = (int*)Balloc(k); - *r = k; - return -#ifndef MULTIPLE_THREADS - dtoa_result = -#endif - (char *)(r+1); - } - - static char * -#ifdef KR_headers -nrv_alloc(s, rve, n) char *s, **rve; int n; -#else -nrv_alloc(CONST char *s, char **rve, int n) -#endif -{ - char *rv, *t; - - t = rv = rv_alloc(n); - for(*t = *s++; *t; *t = *s++) t++; - if (rve) - *rve = t; - return rv; - } - -/* freedtoa(s) must be used to free values s returned by dtoa - * when MULTIPLE_THREADS is #defined. It should be used in all cases, - * but for consistency with earlier versions of dtoa, it is optional - * when MULTIPLE_THREADS is not defined. - */ - - void -#ifdef KR_headers -freedtoa(s) char *s; -#else -freedtoa(char *s) -#endif -{ - Bigint *b = (Bigint *)((int *)s - 1); - b->maxwds = 1 << (b->k = *(int*)b); - Bfree(b); -#ifndef MULTIPLE_THREADS - if (s == dtoa_result) - dtoa_result = 0; -#endif - } - -/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. - * - * Inspired by "How to Print Floating-Point Numbers Accurately" by - * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. - * - * Modifications: - * 1. Rather than iterating, we use a simple numeric overestimate - * to determine k = floor(log10(d)). We scale relevant - * quantities using O(log2(k)) rather than O(k) multiplications. - * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't - * try to generate digits strictly left to right. Instead, we - * compute with fewer bits and propagate the carry if necessary - * when rounding the final digit up. This is often faster. - * 3. Under the assumption that input will be rounded nearest, - * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. - * That is, we allow equality in stopping tests when the - * round-nearest rule will give the same floating-point value - * as would satisfaction of the stopping test with strict - * inequality. - * 4. We remove common factors of powers of 2 from relevant - * quantities. - * 5. When converting floating-point integers less than 1e16, - * we use floating-point arithmetic rather than resorting - * to multiple-precision integers. - * 6. When asked to produce fewer than 15 digits, we first try - * to get by with floating-point arithmetic; we resort to - * multiple-precision integer arithmetic only if we cannot - * guarantee that the floating-point calculation has given - * the correctly rounded result. For k requested digits and - * "uniformly" distributed input, the probability is - * something like 10^(k-15) that we must resort to the Long - * calculation. - */ - - char * -dtoa -#ifdef KR_headers - (dd, mode, ndigits, decpt, sign, rve) - double dd; int mode, ndigits, *decpt, *sign; char **rve; -#else - (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) -#endif -{ - /* Arguments ndigits, decpt, sign are similar to those - of ecvt and fcvt; trailing zeros are suppressed from - the returned string. If not null, *rve is set to point - to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to 9999. - - mode: - 0 ==> shortest string that yields d when read in - and rounded to nearest. - 1 ==> like 0, but with Steele & White stopping rule; - e.g. with IEEE P754 arithmetic , mode 0 gives - 1e23 whereas mode 1 gives 9.999999999999999e22. - 2 ==> max(1,ndigits) significant digits. This gives a - return value similar to that of ecvt, except - that trailing zeros are suppressed. - 3 ==> through ndigits past the decimal point. This - gives a return value similar to that from fcvt, - except that trailing zeros are suppressed, and - ndigits can be negative. - 4,5 ==> similar to 2 and 3, respectively, but (in - round-nearest mode) with the tests of mode 0 to - possibly return a shorter string that rounds to d. - With IEEE arithmetic and compilation with - -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same - as modes 2 and 3 when FLT_ROUNDS != 1. - 6-9 ==> Debugging modes similar to mode - 4: don't try - fast floating-point estimate (if applicable). - - Values of mode other than 0-9 are treated as mode 0. - - Sufficient space is allocated to the return value - to hold the suppressed trailing zeros. - */ - - int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, - j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, - spec_case, try_quick; - Long L; -#ifndef Sudden_Underflow - int denorm; - ULong x; -#endif - Bigint *b, *b1, *delta, *mlo = NULL, *mhi, *S; - U d2, eps, u; - double ds; - char *s, *s0; -#ifdef SET_INEXACT - int inexact, oldinexact; -#endif -#ifdef Honor_FLT_ROUNDS /*{*/ - int Rounding; -#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ - Rounding = Flt_Rounds; -#else /*}{*/ - Rounding = 1; - switch(fegetround()) { - case FE_TOWARDZERO: Rounding = 0; break; - case FE_UPWARD: Rounding = 2; break; - case FE_DOWNWARD: Rounding = 3; - } -#endif /*}}*/ -#endif /*}*/ - -#ifndef MULTIPLE_THREADS - if (dtoa_result) { - freedtoa(dtoa_result); - dtoa_result = 0; - } -#endif - - u.d = dd; - if (word0(&u) & Sign_bit) { - /* set sign for everything, including 0's and NaNs */ - *sign = 1; - word0(&u) &= ~Sign_bit; /* clear sign bit */ - } - else - *sign = 0; - -#if defined(IEEE_Arith) + defined(VAX) -#ifdef IEEE_Arith - if ((word0(&u) & Exp_mask) == Exp_mask) -#else - if (word0(&u) == 0x8000) -#endif - { - /* Infinity or NaN */ - *decpt = 9999; -#ifdef IEEE_Arith - if (!word1(&u) && !(word0(&u) & 0xfffff)) - return nrv_alloc("Infinity", rve, 8); -#endif - return nrv_alloc("NaN", rve, 3); - } -#endif -#ifdef IBM - dval(&u) += 0; /* normalize */ -#endif - if (!dval(&u)) { - *decpt = 1; - return nrv_alloc("0", rve, 1); - } - -#ifdef SET_INEXACT - try_quick = oldinexact = get_inexact(); - inexact = 1; -#endif -#ifdef Honor_FLT_ROUNDS - if (Rounding >= 2) { - if (*sign) - Rounding = Rounding == 2 ? 0 : 2; - else - if (Rounding != 2) - Rounding = 0; - } -#endif - - b = d2b(&u, &be, &bbits); - i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); -#ifndef Sudden_Underflow - if (i) { -#endif - dval(&d2) = dval(&u); - word0(&d2) &= Frac_mask1; - word0(&d2) |= Exp_11; -#ifdef IBM - if (j = 11 - hi0bits(word0(&d2) & Frac_mask)) - dval(&d2) /= 1 << j; -#endif - - /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 - * log10(x) = log(x) / log(10) - * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) - * - * This suggests computing an approximation k to log10(d) by - * - * k = (i - Bias)*0.301029995663981 - * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); - * - * We want k to be too large rather than too small. - * The error in the first-order Taylor series approximation - * is in our favor, so we just round up the constant enough - * to compensate for any error in the multiplication of - * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, - * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, - * adding 1e-13 to the constant term more than suffices. - * Hence we adjust the constant term to 0.1760912590558. - * (We could get a more accurate k by invoking log10, - * but this is probably not worthwhile.) - */ - - i -= Bias; -#ifdef IBM - i <<= 2; - i += j; -#endif -#ifndef Sudden_Underflow - denorm = 0; - } - else { - /* d is denormalized */ - - i = bbits + be + (Bias + (P-1) - 1); - x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32) - : word1(&u) << (32 - i); - dval(&d2) = x; - word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ - i -= (Bias + (P-1) - 1) + 1; - denorm = 1; - } -#endif - ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; - k = (int)ds; - if (ds < 0. && ds != k) - k--; /* want k = floor(ds) */ - k_check = 1; - if (k >= 0 && k <= Ten_pmax) { - if (dval(&u) < tens[k]) - k--; - k_check = 0; - } - j = bbits - i - 1; - if (j >= 0) { - b2 = 0; - s2 = j; - } - else { - b2 = -j; - s2 = 0; - } - if (k >= 0) { - b5 = 0; - s5 = k; - s2 += k; - } - else { - b2 -= k; - b5 = -k; - s5 = 0; - } - if (mode < 0 || mode > 9) - mode = 0; - -#ifndef SET_INEXACT -#ifdef Check_FLT_ROUNDS - try_quick = Rounding == 1; -#else - try_quick = 1; -#endif -#endif /*SET_INEXACT*/ - - if (mode > 5) { - mode -= 4; - try_quick = 0; - } - leftright = 1; - ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ - /* silence erroneous "gcc -Wall" warning. */ - switch(mode) { - case 0: - case 1: - i = 18; - ndigits = 0; - break; - case 2: - leftright = 0; - /* no break */ - case 4: - if (ndigits <= 0) - ndigits = 1; - ilim = ilim1 = i = ndigits; - break; - case 3: - leftright = 0; - /* no break */ - case 5: - i = ndigits + k + 1; - ilim = i; - ilim1 = i - 1; - if (i <= 0) - i = 1; - } - s = s0 = rv_alloc(i); - -#ifdef Honor_FLT_ROUNDS - if (mode > 1 && Rounding != 1) - leftright = 0; -#endif - - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - - /* Try to get by with floating-point arithmetic. */ - - i = 0; - dval(&d2) = dval(&u); - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ - if (k > 0) { - ds = tens[k&0xf]; - j = k >> 4; - if (j & Bletch) { - /* prevent overflows */ - j &= Bletch - 1; - dval(&u) /= bigtens[n_bigtens-1]; - ieps++; - } - for(; j; j >>= 1, i++) - if (j & 1) { - ieps++; - ds *= bigtens[i]; - } - dval(&u) /= ds; - } - else { - j1 = -k; - if (j1) { - dval(&u) *= tens[j1 & 0xf]; - for(j = j1 >> 4; j; j >>= 1, i++) - if (j & 1) { - ieps++; - dval(&u) *= bigtens[i]; - } - } - } - if (k_check && dval(&u) < 1. && ilim > 0) { - if (ilim1 <= 0) - goto fast_failed; - ilim = ilim1; - k--; - dval(&u) *= 10.; - ieps++; - } - dval(&eps) = ieps*dval(&u) + 7.; - word0(&eps) -= (P-1)*Exp_msk1; - if (ilim == 0) { - S = mhi = 0; - dval(&u) -= 5.; - if (dval(&u) > dval(&eps)) - goto one_digit; - if (dval(&u) < -dval(&eps)) - goto no_digits; - goto fast_failed; - } -#ifndef No_leftright - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); - for(i = 0;;) { - L = (long)dval(&u); - dval(&u) -= L; - *s++ = '0' + (char)L; - if (dval(&u) < dval(&eps)) - goto ret1; - if (1. - dval(&u) < dval(&eps)) - goto bump_up; - if (++i >= ilim) - break; - dval(&eps) *= 10.; - dval(&u) *= 10.; - } - } - else { -#endif - /* Generate ilim digits, then fix them up. */ - dval(&eps) *= tens[ilim-1]; - for(i = 1;; i++, dval(&u) *= 10.) { - L = (Long)(dval(&u)); - if (!(dval(&u) -= L)) - ilim = i; - *s++ = '0' + (char)L; - if (i == ilim) { - if (dval(&u) > 0.5 + dval(&eps)) - goto bump_up; - else if (dval(&u) < 0.5 - dval(&eps)) { - while(*--s == '0') {} - s++; - goto ret1; - } - break; - } - } -#ifndef No_leftright - } -#endif - fast_failed: - s = s0; - dval(&u) = dval(&d2); - k = k0; - ilim = ilim0; - } - - /* Do we have a "small" integer? */ - - if (be >= 0 && k <= Int_max) { - /* Yes. */ - ds = tens[k]; - if (ndigits < 0 && ilim <= 0) { - S = mhi = 0; - if (ilim < 0 || dval(&u) <= 5*ds) - goto no_digits; - goto one_digit; - } - for(i = 1; i <= k + 1; i++, dval(&u) *= 10.) { - L = (Long)(dval(&u) / ds); - dval(&u) -= L*ds; -#ifdef Check_FLT_ROUNDS - /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(&u) < 0) { - L--; - dval(&u) += ds; - } -#endif - *s++ = '0' + (char)L; - if (!dval(&u)) { -#ifdef SET_INEXACT - inexact = 0; -#endif - break; - } - if (i == ilim) { -#ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch(Rounding) { - case 0: goto ret1; - case 2: goto bump_up; - } -#endif - dval(&u) += dval(&u); - if (dval(&u) > ds || (dval(&u) == ds && L & 1)) { - bump_up: - while(*--s == '9') - if (s == s0) { - k++; - *s = '0'; - break; - } - ++*s++; - } - break; - } - } - goto ret1; - } - - m2 = b2; - m5 = b5; - mhi = mlo = 0; - if (leftright) { - i = -#ifndef Sudden_Underflow - denorm ? be + (Bias + (P-1) - 1 + 1) : -#endif -#ifdef IBM - 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); -#else - 1 + P - bbits; -#endif - b2 += i; - s2 += i; - mhi = i2b(1); - } - if (m2 > 0 && s2 > 0) { - i = m2 < s2 ? m2 : s2; - b2 -= i; - m2 -= i; - s2 -= i; - } - if (b5 > 0) { - if (leftright) { - if (m5 > 0) { - mhi = pow5mult(mhi, m5); - b1 = mult(mhi, b); - Bfree(b); - b = b1; - } - j = b5 - m5; - if (j) - b = pow5mult(b, j); - } - else - b = pow5mult(b, b5); - } - S = i2b(1); - if (s5 > 0) - S = pow5mult(S, s5); - - /* Check for special case that d is a normalized power of 2. */ - - spec_case = 0; - if ((mode < 2 || leftright) -#ifdef Honor_FLT_ROUNDS - && Rounding == 1 -#endif - ) { - if (!word1(&u) && !(word0(&u) & Bndry_mask) -#ifndef Sudden_Underflow - && word0(&u) & (Exp_mask & ~Exp_msk1) -#endif - ) { - /* The special case */ - b2 += Log2P; - s2 += Log2P; - spec_case = 1; - } - } - - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - * - * Perhaps we should just compute leading 28 bits of S once - * and for all and pass them and a shift to quorem, so it - * can do shifts and ors to compute the numerator for q. - */ -#ifdef Pack_32 - i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f; - if (i) - i = 32 - i; -#define iInc 28 -#else - if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) - i = 16 - i; -#define iInc 12 -#endif - i = dshift(S, s2); - b2 += i; - m2 += i; - s2 += i; - if (b2 > 0) - b = lshift(b, b2); - if (s2 > 0) - S = lshift(S, s2); - if (k_check) { - if (cmp(b,S) < 0) { - k--; - b = multadd(b, 10, 0); /* we botched the k estimate */ - if (leftright) - mhi = multadd(mhi, 10, 0); - ilim = ilim1; - } - } - if (ilim <= 0 && (mode == 3 || mode == 5)) { - if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { - /* no digits, fcvt style */ - no_digits: - k = -1 - ndigits; - goto ret; - } - one_digit: - *s++ = '1'; - k++; - goto ret; - } - if (leftright) { - if (m2 > 0) - mhi = lshift(mhi, m2); - - /* Compute mlo -- check for special case - * that d is a normalized power of 2. - */ - - mlo = mhi; - if (spec_case) { - mhi = Balloc(mhi->k); - Bcopy(mhi, mlo); - mhi = lshift(mhi, Log2P); - } - - for(i = 1;;i++) { - dig = quorem(b,S) + '0'; - /* Do we yet have the shortest decimal string - * that will round to d? - */ - j = cmp(b, mlo); - delta = diff(S, mhi); - j1 = delta->sign ? 1 : cmp(b, delta); - Bfree(delta); -#ifndef ROUND_BIASED - if (j1 == 0 && mode != 1 && !(word1(&u) & 1) -#ifdef Honor_FLT_ROUNDS - && Rounding >= 1 -#endif - ) { - if (dig == '9') - goto round_9_up; - if (j > 0) - dig++; -#ifdef SET_INEXACT - else if (!b->x[0] && b->wds <= 1) - inexact = 0; -#endif - *s++ = (char)dig; - goto ret; - } -#endif - if (j < 0 || (j == 0 && mode != 1 -#ifndef ROUND_BIASED - && !(word1(&u) & 1) -#endif - )) { - if (!b->x[0] && b->wds <= 1) { -#ifdef SET_INEXACT - inexact = 0; -#endif - goto accept_dig; - } -#ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch(Rounding) { - case 0: goto accept_dig; - case 2: goto keep_dig; - } -#endif /*Honor_FLT_ROUNDS*/ - if (j1 > 0) { - b = lshift(b, 1); - j1 = cmp(b, S); - if ((j1 > 0 || (j1 == 0 && dig & 1)) - && dig++ == '9') - goto round_9_up; - } - accept_dig: - *s++ = (char)dig; - goto ret; - } - if (j1 > 0) { -#ifdef Honor_FLT_ROUNDS - if (!Rounding) - goto accept_dig; -#endif - if (dig == '9') { /* possible if i == 1 */ - round_9_up: - *s++ = '9'; - goto roundoff; - } - *s++ = (char)dig + 1; - goto ret; - } -#ifdef Honor_FLT_ROUNDS - keep_dig: -#endif - *s++ = (char)dig; - if (i == ilim) - break; - b = multadd(b, 10, 0); - if (mlo == mhi) - mlo = mhi = multadd(mhi, 10, 0); - else { - mlo = multadd(mlo, 10, 0); - mhi = multadd(mhi, 10, 0); - } - } - } - else - for(i = 1;; i++) { - dig = quorem(b,S) + '0'; - *s++ = (char)dig; - if (!b->x[0] && b->wds <= 1) { -#ifdef SET_INEXACT - inexact = 0; -#endif - goto ret; - } - if (i >= ilim) - break; - b = multadd(b, 10, 0); - } - - /* Round off last digit */ - -#ifdef Honor_FLT_ROUNDS - switch(Rounding) { - case 0: goto trimzeros; - case 2: goto roundoff; - } -#endif - b = lshift(b, 1); - j = cmp(b, S); - if (j > 0 || (j == 0 && dig & 1)) { - roundoff: - while(*--s == '9') - if (s == s0) { - k++; - *s++ = '1'; - goto ret; - } - ++*s++; - } - else { -#ifdef Honor_FLT_ROUNDS - trimzeros: -#endif - while(*--s == '0') {} - s++; - } - ret: - Bfree(S); - if (mhi) { - if (mlo && mlo != mhi) - Bfree(mlo); - Bfree(mhi); - } - ret1: -#ifdef SET_INEXACT - if (inexact) { - if (!oldinexact) { - word0(&u) = Exp_1 + (70 << Exp_shift); - word1(&u) = 0; - dval(&u) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); -#endif - Bfree(b); - *s = 0; - *decpt = k + 1; - if (rve) - *rve = s; - return s0; - } - -} // namespace dmg_fp diff --git a/security/sandbox/chromium/base/third_party/dmg_fp/g_fmt.cc b/security/sandbox/chromium/base/third_party/dmg_fp/g_fmt.cc deleted file mode 100644 index bfa358d15..000000000 --- a/security/sandbox/chromium/base/third_party/dmg_fp/g_fmt.cc +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************** - * - * The author of this software is David M. Gay. - * - * Copyright (c) 1991, 1996 by Lucent Technologies. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - ***************************************************************/ - -/* g_fmt(buf,x) stores the closest decimal approximation to x in buf; - * it suffices to declare buf - * char buf[32]; - */ - -#include "dmg_fp.h" - -namespace dmg_fp { - - char * -g_fmt(register char *b, double x) -{ - register int i, k; - register char *s; - int decpt, j, sign; - char *b0, *s0, *se; - - b0 = b; -#ifdef IGNORE_ZERO_SIGN - if (!x) { - *b++ = '0'; - *b = 0; - goto done; - } -#endif - s = s0 = dtoa(x, 0, 0, &decpt, &sign, &se); - if (sign) - *b++ = '-'; - if (decpt == 9999) /* Infinity or Nan */ { - for(*b = *s++; *b++; *b = *s++) {} - goto done0; - } - if (decpt <= -4 || decpt > se - s + 5) { - *b++ = *s++; - if (*s) { - *b++ = '.'; - for(*b = *s++; *b; *b = *s++) - b++; - } - *b++ = 'e'; - /* sprintf(b, "%+.2d", decpt - 1); */ - if (--decpt < 0) { - *b++ = '-'; - decpt = -decpt; - } - else - *b++ = '+'; - for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10) {} - for(;;) { - i = decpt / k; - *b++ = (char)i + '0'; - if (--j <= 0) - break; - decpt -= i*k; - decpt *= 10; - } - *b = 0; - } - else if (decpt <= 0) { - *b++ = '.'; - for(; decpt < 0; decpt++) - *b++ = '0'; - for(*b = *s++; *b++; *b = *s++) {} - } - else { - for(*b = *s++; *b; *b = *s++) { - b++; - if (--decpt == 0 && *s) - *b++ = '.'; - } - for(; decpt > 0; decpt--) - *b++ = '0'; - *b = 0; - } - done0: - freedtoa(s0); -#ifdef IGNORE_ZERO_SIGN - done: -#endif - return b0; - } - -} // namespace dmg_fp diff --git a/security/sandbox/chromium/base/third_party/dynamic_annotations/LICENSE b/security/sandbox/chromium/base/third_party/dynamic_annotations/LICENSE deleted file mode 100644 index 5c581a939..000000000 --- a/security/sandbox/chromium/base/third_party/dynamic_annotations/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (c) 2008-2009, 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. - * * 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 - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * --- - * Author: Kostya Serebryany - */ diff --git a/security/sandbox/chromium/base/third_party/dynamic_annotations/dynamic_annotations.h b/security/sandbox/chromium/base/third_party/dynamic_annotations/dynamic_annotations.h deleted file mode 100644 index 8d7f05202..000000000 --- a/security/sandbox/chromium/base/third_party/dynamic_annotations/dynamic_annotations.h +++ /dev/null @@ -1,595 +0,0 @@ -/* Copyright (c) 2011, 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. - * * 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 - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* This file defines dynamic annotations for use with dynamic analysis - tool such as valgrind, PIN, etc. - - Dynamic annotation is a source code annotation that affects - the generated code (that is, the annotation is not a comment). - Each such annotation is attached to a particular - instruction and/or to a particular object (address) in the program. - - The annotations that should be used by users are macros in all upper-case - (e.g., ANNOTATE_NEW_MEMORY). - - Actual implementation of these macros may differ depending on the - dynamic analysis tool being used. - - See http://code.google.com/p/data-race-test/ for more information. - - This file supports the following dynamic analysis tools: - - None (DYNAMIC_ANNOTATIONS_ENABLED is not defined or zero). - Macros are defined empty. - - ThreadSanitizer, Helgrind, DRD (DYNAMIC_ANNOTATIONS_ENABLED is 1). - Macros are defined as calls to non-inlinable empty functions - that are intercepted by Valgrind. */ - -#ifndef __DYNAMIC_ANNOTATIONS_H__ -#define __DYNAMIC_ANNOTATIONS_H__ - -#ifndef DYNAMIC_ANNOTATIONS_PREFIX -# define DYNAMIC_ANNOTATIONS_PREFIX -#endif - -#ifndef DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND -# define DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND 1 -#endif - -#ifdef DYNAMIC_ANNOTATIONS_WANT_ATTRIBUTE_WEAK -# ifdef __GNUC__ -# define DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK __attribute__((weak)) -# else -/* TODO(glider): for Windows support we may want to change this macro in order - to prepend __declspec(selectany) to the annotations' declarations. */ -# error weak annotations are not supported for your compiler -# endif -#else -# define DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK -#endif - -/* The following preprocessor magic prepends the value of - DYNAMIC_ANNOTATIONS_PREFIX to annotation function names. */ -#define DYNAMIC_ANNOTATIONS_GLUE0(A, B) A##B -#define DYNAMIC_ANNOTATIONS_GLUE(A, B) DYNAMIC_ANNOTATIONS_GLUE0(A, B) -#define DYNAMIC_ANNOTATIONS_NAME(name) \ - DYNAMIC_ANNOTATIONS_GLUE(DYNAMIC_ANNOTATIONS_PREFIX, name) - -#ifndef DYNAMIC_ANNOTATIONS_ENABLED -# define DYNAMIC_ANNOTATIONS_ENABLED 0 -#endif - -#if DYNAMIC_ANNOTATIONS_ENABLED != 0 - - /* ------------------------------------------------------------- - Annotations useful when implementing condition variables such as CondVar, - using conditional critical sections (Await/LockWhen) and when constructing - user-defined synchronization mechanisms. - - The annotations ANNOTATE_HAPPENS_BEFORE() and ANNOTATE_HAPPENS_AFTER() can - be used to define happens-before arcs in user-defined synchronization - mechanisms: the race detector will infer an arc from the former to the - latter when they share the same argument pointer. - - Example 1 (reference counting): - - void Unref() { - ANNOTATE_HAPPENS_BEFORE(&refcount_); - if (AtomicDecrementByOne(&refcount_) == 0) { - ANNOTATE_HAPPENS_AFTER(&refcount_); - delete this; - } - } - - Example 2 (message queue): - - void MyQueue::Put(Type *e) { - MutexLock lock(&mu_); - ANNOTATE_HAPPENS_BEFORE(e); - PutElementIntoMyQueue(e); - } - - Type *MyQueue::Get() { - MutexLock lock(&mu_); - Type *e = GetElementFromMyQueue(); - ANNOTATE_HAPPENS_AFTER(e); - return e; - } - - Note: when possible, please use the existing reference counting and message - queue implementations instead of inventing new ones. */ - - /* Report that wait on the condition variable at address "cv" has succeeded - and the lock at address "lock" is held. */ - #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarWait)(__FILE__, __LINE__, cv, lock) - - /* Report that wait on the condition variable at "cv" has succeeded. Variant - w/o lock. */ - #define ANNOTATE_CONDVAR_WAIT(cv) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarWait)(__FILE__, __LINE__, cv, NULL) - - /* Report that we are about to signal on the condition variable at address - "cv". */ - #define ANNOTATE_CONDVAR_SIGNAL(cv) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignal)(__FILE__, __LINE__, cv) - - /* Report that we are about to signal_all on the condition variable at address - "cv". */ - #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignalAll)(__FILE__, __LINE__, cv) - - /* Annotations for user-defined synchronization mechanisms. */ - #define ANNOTATE_HAPPENS_BEFORE(obj) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensBefore)(__FILE__, __LINE__, obj) - #define ANNOTATE_HAPPENS_AFTER(obj) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensAfter)(__FILE__, __LINE__, obj) - - /* DEPRECATED. Don't use it. */ - #define ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotatePublishMemoryRange)(__FILE__, __LINE__, \ - pointer, size) - - /* DEPRECATED. Don't use it. */ - #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateUnpublishMemoryRange)(__FILE__, __LINE__, \ - pointer, size) - - /* DEPRECATED. Don't use it. */ - #define ANNOTATE_SWAP_MEMORY_RANGE(pointer, size) \ - do { \ - ANNOTATE_UNPUBLISH_MEMORY_RANGE(pointer, size); \ - ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size); \ - } while (0) - - /* Instruct the tool to create a happens-before arc between mu->Unlock() and - mu->Lock(). This annotation may slow down the race detector and hide real - races. Normally it is used only when it would be difficult to annotate each - of the mutex's critical sections individually using the annotations above. - This annotation makes sense only for hybrid race detectors. For pure - happens-before detectors this is a no-op. For more details see - http://code.google.com/p/data-race-test/wiki/PureHappensBeforeVsHybrid . */ - #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsUsedAsCondVar)(__FILE__, __LINE__, \ - mu) - - /* Opposite to ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX. - Instruct the tool to NOT create h-b arcs between Unlock and Lock, even in - pure happens-before mode. For a hybrid mode this is a no-op. */ - #define ANNOTATE_NOT_HAPPENS_BEFORE_MUTEX(mu) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsNotPHB)(__FILE__, __LINE__, mu) - - /* Deprecated. Use ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX. */ - #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsUsedAsCondVar)(__FILE__, __LINE__, \ - mu) - - /* ------------------------------------------------------------- - Annotations useful when defining memory allocators, or when memory that - was protected in one way starts to be protected in another. */ - - /* Report that a new memory at "address" of size "size" has been allocated. - This might be used when the memory has been retrieved from a free list and - is about to be reused, or when a the locking discipline for a variable - changes. */ - #define ANNOTATE_NEW_MEMORY(address, size) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateNewMemory)(__FILE__, __LINE__, address, \ - size) - - /* ------------------------------------------------------------- - Annotations useful when defining FIFO queues that transfer data between - threads. */ - - /* Report that the producer-consumer queue (such as ProducerConsumerQueue) at - address "pcq" has been created. The ANNOTATE_PCQ_* annotations - should be used only for FIFO queues. For non-FIFO queues use - ANNOTATE_HAPPENS_BEFORE (for put) and ANNOTATE_HAPPENS_AFTER (for get). */ - #define ANNOTATE_PCQ_CREATE(pcq) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQCreate)(__FILE__, __LINE__, pcq) - - /* Report that the queue at address "pcq" is about to be destroyed. */ - #define ANNOTATE_PCQ_DESTROY(pcq) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQDestroy)(__FILE__, __LINE__, pcq) - - /* Report that we are about to put an element into a FIFO queue at address - "pcq". */ - #define ANNOTATE_PCQ_PUT(pcq) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQPut)(__FILE__, __LINE__, pcq) - - /* Report that we've just got an element from a FIFO queue at address - "pcq". */ - #define ANNOTATE_PCQ_GET(pcq) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQGet)(__FILE__, __LINE__, pcq) - - /* ------------------------------------------------------------- - Annotations that suppress errors. It is usually better to express the - program's synchronization using the other annotations, but these can - be used when all else fails. */ - - /* Report that we may have a benign race at "pointer", with size - "sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the - point where "pointer" has been allocated, preferably close to the point - where the race happens. See also ANNOTATE_BENIGN_RACE_STATIC. */ - #define ANNOTATE_BENIGN_RACE(pointer, description) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRaceSized)(__FILE__, __LINE__, \ - pointer, sizeof(*(pointer)), description) - - /* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to - the memory range [address, address+size). */ - #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRaceSized)(__FILE__, __LINE__, \ - address, size, description) - - /* Request the analysis tool to ignore all reads in the current thread - until ANNOTATE_IGNORE_READS_END is called. - Useful to ignore intentional racey reads, while still checking - other reads and all writes. - See also ANNOTATE_UNPROTECTED_READ. */ - #define ANNOTATE_IGNORE_READS_BEGIN() \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsBegin)(__FILE__, __LINE__) - - /* Stop ignoring reads. */ - #define ANNOTATE_IGNORE_READS_END() \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsEnd)(__FILE__, __LINE__) - - /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. */ - #define ANNOTATE_IGNORE_WRITES_BEGIN() \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesBegin)(__FILE__, __LINE__) - - /* Stop ignoring writes. */ - #define ANNOTATE_IGNORE_WRITES_END() \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesEnd)(__FILE__, __LINE__) - - /* Start ignoring all memory accesses (reads and writes). */ - #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ - do {\ - ANNOTATE_IGNORE_READS_BEGIN();\ - ANNOTATE_IGNORE_WRITES_BEGIN();\ - }while(0)\ - - /* Stop ignoring all memory accesses. */ - #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ - do {\ - ANNOTATE_IGNORE_WRITES_END();\ - ANNOTATE_IGNORE_READS_END();\ - }while(0)\ - - /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore synchronization events: - RWLOCK* and CONDVAR*. */ - #define ANNOTATE_IGNORE_SYNC_BEGIN() \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncBegin)(__FILE__, __LINE__) - - /* Stop ignoring sync events. */ - #define ANNOTATE_IGNORE_SYNC_END() \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncEnd)(__FILE__, __LINE__) - - - /* Enable (enable!=0) or disable (enable==0) race detection for all threads. - This annotation could be useful if you want to skip expensive race analysis - during some period of program execution, e.g. during initialization. */ - #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateEnableRaceDetection)(__FILE__, __LINE__, \ - enable) - - /* ------------------------------------------------------------- - Annotations useful for debugging. */ - - /* Request to trace every access to "address". */ - #define ANNOTATE_TRACE_MEMORY(address) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateTraceMemory)(__FILE__, __LINE__, address) - - /* Report the current thread name to a race detector. */ - #define ANNOTATE_THREAD_NAME(name) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateThreadName)(__FILE__, __LINE__, name) - - /* ------------------------------------------------------------- - Annotations useful when implementing locks. They are not - normally needed by modules that merely use locks. - The "lock" argument is a pointer to the lock object. */ - - /* Report that a lock has been created at address "lock". */ - #define ANNOTATE_RWLOCK_CREATE(lock) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockCreate)(__FILE__, __LINE__, lock) - - /* Report that the lock at address "lock" is about to be destroyed. */ - #define ANNOTATE_RWLOCK_DESTROY(lock) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockDestroy)(__FILE__, __LINE__, lock) - - /* Report that the lock at address "lock" has been acquired. - is_w=1 for writer lock, is_w=0 for reader lock. */ - #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockAcquired)(__FILE__, __LINE__, lock, \ - is_w) - - /* Report that the lock at address "lock" is about to be released. */ - #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockReleased)(__FILE__, __LINE__, lock, \ - is_w) - - /* ------------------------------------------------------------- - Annotations useful when implementing barriers. They are not - normally needed by modules that merely use barriers. - The "barrier" argument is a pointer to the barrier object. */ - - /* Report that the "barrier" has been initialized with initial "count". - If 'reinitialization_allowed' is true, initialization is allowed to happen - multiple times w/o calling barrier_destroy() */ - #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierInit)(__FILE__, __LINE__, barrier, \ - count, reinitialization_allowed) - - /* Report that we are about to enter barrier_wait("barrier"). */ - #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitBefore)(__FILE__, __LINE__, \ - barrier) - - /* Report that we just exited barrier_wait("barrier"). */ - #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitAfter)(__FILE__, __LINE__, \ - barrier) - - /* Report that the "barrier" has been destroyed. */ - #define ANNOTATE_BARRIER_DESTROY(barrier) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierDestroy)(__FILE__, __LINE__, \ - barrier) - - /* ------------------------------------------------------------- - Annotations useful for testing race detectors. */ - - /* Report that we expect a race on the variable at "address". - Use only in unit tests for a race detector. */ - #define ANNOTATE_EXPECT_RACE(address, description) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateExpectRace)(__FILE__, __LINE__, address, \ - description) - - #define ANNOTATE_FLUSH_EXPECTED_RACES() \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushExpectedRaces)(__FILE__, __LINE__) - - /* A no-op. Insert where you like to test the interceptors. */ - #define ANNOTATE_NO_OP(arg) \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateNoOp)(__FILE__, __LINE__, arg) - - /* Force the race detector to flush its state. The actual effect depends on - * the implementation of the detector. */ - #define ANNOTATE_FLUSH_STATE() \ - DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushState)(__FILE__, __LINE__) - - -#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ - - #define ANNOTATE_RWLOCK_CREATE(lock) /* empty */ - #define ANNOTATE_RWLOCK_DESTROY(lock) /* empty */ - #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */ - #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */ - #define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) /* */ - #define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) /* empty */ - #define ANNOTATE_BARRIER_WAIT_AFTER(barrier) /* empty */ - #define ANNOTATE_BARRIER_DESTROY(barrier) /* empty */ - #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) /* empty */ - #define ANNOTATE_CONDVAR_WAIT(cv) /* empty */ - #define ANNOTATE_CONDVAR_SIGNAL(cv) /* empty */ - #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) /* empty */ - #define ANNOTATE_HAPPENS_BEFORE(obj) /* empty */ - #define ANNOTATE_HAPPENS_AFTER(obj) /* empty */ - #define ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) /* empty */ - #define ANNOTATE_UNPUBLISH_MEMORY_RANGE(address, size) /* empty */ - #define ANNOTATE_SWAP_MEMORY_RANGE(address, size) /* empty */ - #define ANNOTATE_PCQ_CREATE(pcq) /* empty */ - #define ANNOTATE_PCQ_DESTROY(pcq) /* empty */ - #define ANNOTATE_PCQ_PUT(pcq) /* empty */ - #define ANNOTATE_PCQ_GET(pcq) /* empty */ - #define ANNOTATE_NEW_MEMORY(address, size) /* empty */ - #define ANNOTATE_EXPECT_RACE(address, description) /* empty */ - #define ANNOTATE_FLUSH_EXPECTED_RACES(address, description) /* empty */ - #define ANNOTATE_BENIGN_RACE(address, description) /* empty */ - #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */ - #define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mu) /* empty */ - #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) /* empty */ - #define ANNOTATE_TRACE_MEMORY(arg) /* empty */ - #define ANNOTATE_THREAD_NAME(name) /* empty */ - #define ANNOTATE_IGNORE_READS_BEGIN() /* empty */ - #define ANNOTATE_IGNORE_READS_END() /* empty */ - #define ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ - #define ANNOTATE_IGNORE_WRITES_END() /* empty */ - #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ - #define ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ - #define ANNOTATE_IGNORE_SYNC_BEGIN() /* empty */ - #define ANNOTATE_IGNORE_SYNC_END() /* empty */ - #define ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ - #define ANNOTATE_NO_OP(arg) /* empty */ - #define ANNOTATE_FLUSH_STATE() /* empty */ - -#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ - -/* Use the macros above rather than using these functions directly. */ -#ifdef __cplusplus -extern "C" { -#endif - - -void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockCreate)( - const char *file, int line, - const volatile void *lock) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockDestroy)( - const char *file, int line, - const volatile void *lock) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockAcquired)( - const char *file, int line, - const volatile void *lock, long is_w) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockReleased)( - const char *file, int line, - const volatile void *lock, long is_w) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierInit)( - const char *file, int line, const volatile void *barrier, long count, - long reinitialization_allowed) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitBefore)( - const char *file, int line, - const volatile void *barrier) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitAfter)( - const char *file, int line, - const volatile void *barrier) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierDestroy)( - const char *file, int line, - const volatile void *barrier) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarWait)( - const char *file, int line, const volatile void *cv, - const volatile void *lock) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignal)( - const char *file, int line, - const volatile void *cv) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignalAll)( - const char *file, int line, - const volatile void *cv) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensBefore)( - const char *file, int line, - const volatile void *obj) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensAfter)( - const char *file, int line, - const volatile void *obj) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotatePublishMemoryRange)( - const char *file, int line, - const volatile void *address, long size) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateUnpublishMemoryRange)( - const char *file, int line, - const volatile void *address, long size) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQCreate)( - const char *file, int line, - const volatile void *pcq) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQDestroy)( - const char *file, int line, - const volatile void *pcq) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQPut)( - const char *file, int line, - const volatile void *pcq) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQGet)( - const char *file, int line, - const volatile void *pcq) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateNewMemory)( - const char *file, int line, - const volatile void *mem, long size) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateExpectRace)( - const char *file, int line, const volatile void *mem, - const char *description) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushExpectedRaces)( - const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRace)( - const char *file, int line, const volatile void *mem, - const char *description) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRaceSized)( - const char *file, int line, const volatile void *mem, long size, - const char *description) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsUsedAsCondVar)( - const char *file, int line, - const volatile void *mu) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsNotPHB)( - const char *file, int line, - const volatile void *mu) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateTraceMemory)( - const char *file, int line, - const volatile void *arg) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateThreadName)( - const char *file, int line, - const char *name) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsBegin)( - const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsEnd)( - const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesBegin)( - const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesEnd)( - const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncBegin)( - const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncEnd)( - const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateEnableRaceDetection)( - const char *file, int line, int enable) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateNoOp)( - const char *file, int line, - const volatile void *arg) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -void DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushState)( - const char *file, int line) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; - -#if DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND == 1 -/* Return non-zero value if running under valgrind. - - If "valgrind.h" is included into dynamic_annotations.c, - the regular valgrind mechanism will be used. - See http://valgrind.org/docs/manual/manual-core-adv.html about - RUNNING_ON_VALGRIND and other valgrind "client requests". - The file "valgrind.h" may be obtained by doing - svn co svn://svn.valgrind.org/valgrind/trunk/include - - If for some reason you can't use "valgrind.h" or want to fake valgrind, - there are two ways to make this function return non-zero: - - Use environment variable: export RUNNING_ON_VALGRIND=1 - - Make your tool intercept the function RunningOnValgrind() and - change its return value. - */ -int RunningOnValgrind(void) DYNAMIC_ANNOTATIONS_ATTRIBUTE_WEAK; -#endif /* DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND == 1 */ - -#ifdef __cplusplus -} -#endif - -#if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) - - /* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. - - Instead of doing - ANNOTATE_IGNORE_READS_BEGIN(); - ... = x; - ANNOTATE_IGNORE_READS_END(); - one can use - ... = ANNOTATE_UNPROTECTED_READ(x); */ - template <class T> - inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) { - ANNOTATE_IGNORE_READS_BEGIN(); - T res = x; - ANNOTATE_IGNORE_READS_END(); - return res; - } - /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ - #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ - namespace { \ - class static_var ## _annotator { \ - public: \ - static_var ## _annotator() { \ - ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ - sizeof(static_var), \ - # static_var ": " description); \ - } \ - }; \ - static static_var ## _annotator the ## static_var ## _annotator;\ - } -#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ - - #define ANNOTATE_UNPROTECTED_READ(x) (x) - #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ - -#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ - -#endif /* __DYNAMIC_ANNOTATIONS_H__ */ diff --git a/security/sandbox/chromium/base/third_party/icu/LICENSE b/security/sandbox/chromium/base/third_party/icu/LICENSE deleted file mode 100644 index 40282f494..000000000 --- a/security/sandbox/chromium/base/third_party/icu/LICENSE +++ /dev/null @@ -1,32 +0,0 @@ -ICU License - ICU 1.8.1 and later - -COPYRIGHT AND PERMISSION NOTICE - -Copyright (c) 1995-2009 International Business Machines Corporation and others - -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, and/or sell copies of the Software, and to permit persons -to whom the Software is furnished to do so, provided that the above -copyright notice(s) and this permission notice appear in all copies of -the Software and that both the above copyright notice(s) and this -permission notice appear in supporting documentation. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY -SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER -RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -Except as contained in this notice, the name of a copyright holder -shall not be used in advertising or otherwise to promote the sale, use -or other dealings in this Software without prior written authorization -of the copyright holder. diff --git a/security/sandbox/chromium/base/third_party/icu/icu_utf.cc b/security/sandbox/chromium/base/third_party/icu/icu_utf.cc deleted file mode 100644 index 2b67c5d9c..000000000 --- a/security/sandbox/chromium/base/third_party/icu/icu_utf.cc +++ /dev/null @@ -1,227 +0,0 @@ -/* -****************************************************************************** -* -* Copyright (C) 1999-2006, International Business Machines -* Corporation and others. All Rights Reserved. -* -****************************************************************************** -* file name: utf_impl.c -* encoding: US-ASCII -* tab size: 8 (not used) -* indentation:4 -* -* created on: 1999sep13 -* created by: Markus W. Scherer -* -* This file provides implementation functions for macros in the utfXX.h -* that would otherwise be too long as macros. -*/ - -#include "base/third_party/icu/icu_utf.h" - -namespace base_icu { - -/** - * UTF8_ERROR_VALUE_1 and UTF8_ERROR_VALUE_2 are special error values for UTF-8, - * which need 1 or 2 bytes in UTF-8: - * \code - * U+0015 = NAK = Negative Acknowledge, C0 control character - * U+009f = highest C1 control character - * \endcode - * - * These are used by UTF8_..._SAFE macros so that they can return an error value - * that needs the same number of code units (bytes) as were seen by - * a macro. They should be tested with UTF_IS_ERROR() or UTF_IS_VALID(). - * - * @deprecated ICU 2.4. Obsolete, see utf_old.h. - */ -#define CBUTF8_ERROR_VALUE_1 0x15 - -/** - * See documentation on UTF8_ERROR_VALUE_1 for details. - * - * @deprecated ICU 2.4. Obsolete, see utf_old.h. - */ -#define CBUTF8_ERROR_VALUE_2 0x9f - - -/** - * Error value for all UTFs. This code point value will be set by macros with e> - * checking if an error is detected. - * - * @deprecated ICU 2.4. Obsolete, see utf_old.h. - */ -#define CBUTF_ERROR_VALUE 0xffff - -/* - * This table could be replaced on many machines by - * a few lines of assembler code using an - * "index of first 0-bit from msb" instruction and - * one or two more integer instructions. - * - * For example, on an i386, do something like - * - MOV AL, leadByte - * - NOT AL (8-bit, leave b15..b8==0..0, reverse only b7..b0) - * - MOV AH, 0 - * - BSR BX, AX (16-bit) - * - MOV AX, 6 (result) - * - JZ finish (ZF==1 if leadByte==0xff) - * - SUB AX, BX (result) - * -finish: - * (BSR: Bit Scan Reverse, scans for a 1-bit, starting from the MSB) - * - * In Unicode, all UTF-8 byte sequences with more than 4 bytes are illegal; - * lead bytes above 0xf4 are illegal. - * We keep them in this table for skipping long ISO 10646-UTF-8 sequences. - */ -const uint8_t utf8_countTrailBytes[256] = - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, - 3, 3, /* illegal in Unicode */ - 4, 4, 4, 4, /* illegal in Unicode */ - 5, 5, /* illegal in Unicode */ - 0, 0 /* illegal bytes 0xfe and 0xff */ -}; - -static const UChar32 -utf8_minLegal[4]={ 0, 0x80, 0x800, 0x10000 }; - -static const UChar32 -utf8_errorValue[6]={ - CBUTF8_ERROR_VALUE_1, CBUTF8_ERROR_VALUE_2, CBUTF_ERROR_VALUE, 0x10ffff, - 0x3ffffff, 0x7fffffff -}; - -/* - * Handle the non-inline part of the U8_NEXT() macro and its obsolete sibling - * UTF8_NEXT_CHAR_SAFE(). - * - * The "strict" parameter controls the error behavior: - * <0 "Safe" behavior of U8_NEXT(): All illegal byte sequences yield a negative - * code point result. - * 0 Obsolete "safe" behavior of UTF8_NEXT_CHAR_SAFE(..., FALSE): - * All illegal byte sequences yield a positive code point such that this - * result code point would be encoded with the same number of bytes as - * the illegal sequence. - * >0 Obsolete "strict" behavior of UTF8_NEXT_CHAR_SAFE(..., TRUE): - * Same as the obsolete "safe" behavior, but non-characters are also treated - * like illegal sequences. - * - * The special negative (<0) value -2 is used for lenient treatment of surrogate - * code points as legal. Some implementations use this for roundtripping of - * Unicode 16-bit strings that are not well-formed UTF-16, that is, they - * contain unpaired surrogates. - * - * Note that a UBool is the same as an int8_t. - */ -UChar32 utf8_nextCharSafeBody(const uint8_t* s, - int32_t* pi, - int32_t length, - UChar32 c, - UBool strict) { - int32_t i = *pi; - uint8_t count = CBU8_COUNT_TRAIL_BYTES(c); - if((i)+count<=(length)) { - uint8_t trail, illegal = 0; - - CBU8_MASK_LEAD_BYTE((c), count); - /* count==0 for illegally leading trail bytes and the illegal bytes 0xfe and 0xff */ - switch(count) { - /* each branch falls through to the next one */ - case 5: - case 4: - /* count>=4 is always illegal: no more than 3 trail bytes in Unicode's UTF-8 */ - illegal=1; - break; - case 3: - trail=s[(i)++]; - (c)=((c)<<6)|(trail&0x3f); - if(c<0x110) { - illegal|=(trail&0xc0)^0x80; - } else { - /* code point>0x10ffff, outside Unicode */ - illegal=1; - break; - } - case 2: - trail=s[(i)++]; - (c)=((c)<<6)|(trail&0x3f); - illegal|=(trail&0xc0)^0x80; - case 1: - trail=s[(i)++]; - (c)=((c)<<6)|(trail&0x3f); - illegal|=(trail&0xc0)^0x80; - break; - case 0: - if(strict>=0) { - return CBUTF8_ERROR_VALUE_1; - } else { - return CBU_SENTINEL; - } - /* no default branch to optimize switch() - all values are covered */ - } - - /* - * All the error handling should return a value - * that needs count bytes so that UTF8_GET_CHAR_SAFE() works right. - * - * Starting with Unicode 3.0.1, non-shortest forms are illegal. - * Starting with Unicode 3.2, surrogate code points must not be - * encoded in UTF-8, and there are no irregular sequences any more. - * - * U8_ macros (new in ICU 2.4) return negative values for error conditions. - */ - - /* correct sequence - all trail bytes have (b7..b6)==(10)? */ - /* illegal is also set if count>=4 */ - if(illegal || (c)<utf8_minLegal[count] || (CBU_IS_SURROGATE(c) && strict!=-2)) { - /* error handling */ - uint8_t errorCount = count; - /* don't go beyond this sequence */ - i=*pi; - while(count>0 && CBU8_IS_TRAIL(s[i])) { - ++(i); - --count; - } - if(strict>=0) { - c=utf8_errorValue[errorCount-count]; - } else { - c=CBU_SENTINEL; - } - } else if((strict)>0 && CBU_IS_UNICODE_NONCHAR(c)) { - /* strict: forbid non-characters like U+fffe */ - c=utf8_errorValue[count]; - } - } else /* too few bytes left */ { - /* error handling */ - int32_t i0 = i; - /* don't just set (i)=(length) in case there is an illegal sequence */ - while((i)<(length) && CBU8_IS_TRAIL(s[i])) { - ++(i); - } - if(strict>=0) { - c=utf8_errorValue[i-i0]; - } else { - c=CBU_SENTINEL; - } - } - *pi=i; - return c; -} - -} // namespace base_icu diff --git a/security/sandbox/chromium/base/third_party/icu/icu_utf.h b/security/sandbox/chromium/base/third_party/icu/icu_utf.h deleted file mode 100644 index 4370fdec1..000000000 --- a/security/sandbox/chromium/base/third_party/icu/icu_utf.h +++ /dev/null @@ -1,400 +0,0 @@ -/* -******************************************************************************* -* -* Copyright (C) 1999-2004, International Business Machines -* Corporation and others. All Rights Reserved. -* -******************************************************************************* -* file name: utf.h -* encoding: US-ASCII -* tab size: 8 (not used) -* indentation:4 -* -* created on: 1999sep09 -* created by: Markus W. Scherer -*/ - -#ifndef BASE_THIRD_PARTY_ICU_ICU_UTF_H_ -#define BASE_THIRD_PARTY_ICU_ICU_UTF_H_ - -#include <stdint.h> - -namespace base_icu { - -typedef int32_t UChar32; -typedef uint16_t UChar; -typedef int8_t UBool; - -// General --------------------------------------------------------------------- -// from utf.h - -/** - * This value is intended for sentinel values for APIs that - * (take or) return single code points (UChar32). - * It is outside of the Unicode code point range 0..0x10ffff. - * - * For example, a "done" or "error" value in a new API - * could be indicated with CBU_SENTINEL. - * - * ICU APIs designed before ICU 2.4 usually define service-specific "done" - * values, mostly 0xffff. - * Those may need to be distinguished from - * actual U+ffff text contents by calling functions like - * CharacterIterator::hasNext() or UnicodeString::length(). - * - * @return -1 - * @see UChar32 - * @stable ICU 2.4 - */ -#define CBU_SENTINEL (-1) - -/** - * Is this code point a Unicode noncharacter? - * @param c 32-bit code point - * @return TRUE or FALSE - * @stable ICU 2.4 - */ -#define CBU_IS_UNICODE_NONCHAR(c) \ - ((c) >= 0xfdd0 && ((uint32_t)(c) <= 0xfdef || ((c)&0xfffe) == 0xfffe) && \ - (uint32_t)(c) <= 0x10ffff) - -/** - * Is c a Unicode code point value (0..U+10ffff) - * that can be assigned a character? - * - * Code points that are not characters include: - * - single surrogate code points (U+d800..U+dfff, 2048 code points) - * - the last two code points on each plane (U+__fffe and U+__ffff, 34 code points) - * - U+fdd0..U+fdef (new with Unicode 3.1, 32 code points) - * - the highest Unicode code point value is U+10ffff - * - * This means that all code points below U+d800 are character code points, - * and that boundary is tested first for performance. - * - * @param c 32-bit code point - * @return TRUE or FALSE - * @stable ICU 2.4 - */ -#define CBU_IS_UNICODE_CHAR(c) \ - ((uint32_t)(c) < 0xd800 || \ - ((uint32_t)(c) > 0xdfff && (uint32_t)(c) <= 0x10ffff && \ - !CBU_IS_UNICODE_NONCHAR(c))) - -/** - * Is this code point a surrogate (U+d800..U+dfff)? - * @param c 32-bit code point - * @return TRUE or FALSE - * @stable ICU 2.4 - */ -#define CBU_IS_SURROGATE(c) (((c)&0xfffff800)==0xd800) - -/** - * Assuming c is a surrogate code point (U_IS_SURROGATE(c)), - * is it a lead surrogate? - * @param c 32-bit code point - * @return TRUE or FALSE - * @stable ICU 2.4 - */ -#define CBU_IS_SURROGATE_LEAD(c) (((c)&0x400)==0) - - -// UTF-8 macros ---------------------------------------------------------------- -// from utf8.h - -extern const uint8_t utf8_countTrailBytes[256]; - -/** - * Count the trail bytes for a UTF-8 lead byte. - * @internal - */ -#define CBU8_COUNT_TRAIL_BYTES(leadByte) \ - (base_icu::utf8_countTrailBytes[(uint8_t)leadByte]) - -/** - * Mask a UTF-8 lead byte, leave only the lower bits that form part of the code point value. - * @internal - */ -#define CBU8_MASK_LEAD_BYTE(leadByte, countTrailBytes) ((leadByte)&=(1<<(6-(countTrailBytes)))-1) - -/** - * Does this code unit (byte) encode a code point by itself (US-ASCII 0..0x7f)? - * @param c 8-bit code unit (byte) - * @return TRUE or FALSE - * @stable ICU 2.4 - */ -#define CBU8_IS_SINGLE(c) (((c)&0x80)==0) - -/** - * Is this code unit (byte) a UTF-8 lead byte? - * @param c 8-bit code unit (byte) - * @return TRUE or FALSE - * @stable ICU 2.4 - */ -#define CBU8_IS_LEAD(c) ((uint8_t)((c)-0xc0) < 0x3e) - -/** - * Is this code unit (byte) a UTF-8 trail byte? - * @param c 8-bit code unit (byte) - * @return TRUE or FALSE - * @stable ICU 2.4 - */ -#define CBU8_IS_TRAIL(c) (((c)&0xc0)==0x80) - -/** - * How many code units (bytes) are used for the UTF-8 encoding - * of this Unicode code point? - * @param c 32-bit code point - * @return 1..4, or 0 if c is a surrogate or not a Unicode code point - * @stable ICU 2.4 - */ -#define CBU8_LENGTH(c) \ - ((uint32_t)(c) <= 0x7f \ - ? 1 \ - : ((uint32_t)(c) <= 0x7ff \ - ? 2 \ - : ((uint32_t)(c) <= 0xd7ff \ - ? 3 \ - : ((uint32_t)(c) <= 0xdfff || (uint32_t)(c) > 0x10ffff \ - ? 0 \ - : ((uint32_t)(c) <= 0xffff ? 3 : 4))))) - -/** - * The maximum number of UTF-8 code units (bytes) per Unicode code point (U+0000..U+10ffff). - * @return 4 - * @stable ICU 2.4 - */ -#define CBU8_MAX_LENGTH 4 - -/** - * Function for handling "next code point" with error-checking. - * @internal - */ -UChar32 utf8_nextCharSafeBody(const uint8_t* s, - int32_t* pi, - int32_t length, - UChar32 c, - UBool strict); - -/** - * Get a code point from a string at a code point boundary offset, - * and advance the offset to the next code point boundary. - * (Post-incrementing forward iteration.) - * "Safe" macro, checks for illegal sequences and for string boundaries. - * - * The offset may point to the lead byte of a multi-byte sequence, - * in which case the macro will read the whole sequence. - * If the offset points to a trail byte or an illegal UTF-8 sequence, then - * c is set to a negative value. - * - * @param s const uint8_t * string - * @param i string offset, i<length - * @param length string length - * @param c output UChar32 variable, set to <0 in case of an error - * @see CBU8_NEXT_UNSAFE - * @stable ICU 2.4 - */ -#define CBU8_NEXT(s, i, length, c) \ - { \ - (c) = (s)[(i)++]; \ - if (((uint8_t)(c)) >= 0x80) { \ - if (CBU8_IS_LEAD(c)) { \ - (c) = base_icu::utf8_nextCharSafeBody((const uint8_t*)s, &(i), \ - (int32_t)(length), c, -1); \ - } else { \ - (c) = CBU_SENTINEL; \ - } \ - } \ - } - -/** - * Append a code point to a string, overwriting 1 to 4 bytes. - * The offset points to the current end of the string contents - * and is advanced (post-increment). - * "Unsafe" macro, assumes a valid code point and sufficient space in the - * string. - * Otherwise, the result is undefined. - * - * @param s const uint8_t * string buffer - * @param i string offset - * @param c code point to append - * @see CBU8_APPEND - * @stable ICU 2.4 - */ -#define CBU8_APPEND_UNSAFE(s, i, c) \ - { \ - if ((uint32_t)(c) <= 0x7f) { \ - (s)[(i)++] = (uint8_t)(c); \ - } else { \ - if ((uint32_t)(c) <= 0x7ff) { \ - (s)[(i)++] = (uint8_t)(((c) >> 6) | 0xc0); \ - } else { \ - if ((uint32_t)(c) <= 0xffff) { \ - (s)[(i)++] = (uint8_t)(((c) >> 12) | 0xe0); \ - } else { \ - (s)[(i)++] = (uint8_t)(((c) >> 18) | 0xf0); \ - (s)[(i)++] = (uint8_t)((((c) >> 12) & 0x3f) | 0x80); \ - } \ - (s)[(i)++] = (uint8_t)((((c) >> 6) & 0x3f) | 0x80); \ - } \ - (s)[(i)++] = (uint8_t)(((c)&0x3f) | 0x80); \ - } \ - } - -// UTF-16 macros --------------------------------------------------------------- -// from utf16.h - -/** - * Does this code unit alone encode a code point (BMP, not a surrogate)? - * @param c 16-bit code unit - * @return TRUE or FALSE - * @stable ICU 2.4 - */ -#define CBU16_IS_SINGLE(c) !CBU_IS_SURROGATE(c) - -/** - * Is this code unit a lead surrogate (U+d800..U+dbff)? - * @param c 16-bit code unit - * @return TRUE or FALSE - * @stable ICU 2.4 - */ -#define CBU16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800) - -/** - * Is this code unit a trail surrogate (U+dc00..U+dfff)? - * @param c 16-bit code unit - * @return TRUE or FALSE - * @stable ICU 2.4 - */ -#define CBU16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00) - -/** - * Is this code unit a surrogate (U+d800..U+dfff)? - * @param c 16-bit code unit - * @return TRUE or FALSE - * @stable ICU 2.4 - */ -#define CBU16_IS_SURROGATE(c) CBU_IS_SURROGATE(c) - -/** - * Assuming c is a surrogate code point (U16_IS_SURROGATE(c)), - * is it a lead surrogate? - * @param c 16-bit code unit - * @return TRUE or FALSE - * @stable ICU 2.4 - */ -#define CBU16_IS_SURROGATE_LEAD(c) (((c)&0x400)==0) - -/** - * Helper constant for CBU16_GET_SUPPLEMENTARY. - * @internal - */ -#define CBU16_SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000) - -/** - * Get a supplementary code point value (U+10000..U+10ffff) - * from its lead and trail surrogates. - * The result is undefined if the input values are not - * lead and trail surrogates. - * - * @param lead lead surrogate (U+d800..U+dbff) - * @param trail trail surrogate (U+dc00..U+dfff) - * @return supplementary code point (U+10000..U+10ffff) - * @stable ICU 2.4 - */ -#define CBU16_GET_SUPPLEMENTARY(lead, trail) \ - (((base_icu::UChar32)(lead)<<10UL)+(base_icu::UChar32)(trail)-CBU16_SURROGATE_OFFSET) - - -/** - * Get the lead surrogate (0xd800..0xdbff) for a - * supplementary code point (0x10000..0x10ffff). - * @param supplementary 32-bit code point (U+10000..U+10ffff) - * @return lead surrogate (U+d800..U+dbff) for supplementary - * @stable ICU 2.4 - */ -#define CBU16_LEAD(supplementary) \ - (base_icu::UChar)(((supplementary)>>10)+0xd7c0) - -/** - * Get the trail surrogate (0xdc00..0xdfff) for a - * supplementary code point (0x10000..0x10ffff). - * @param supplementary 32-bit code point (U+10000..U+10ffff) - * @return trail surrogate (U+dc00..U+dfff) for supplementary - * @stable ICU 2.4 - */ -#define CBU16_TRAIL(supplementary) \ - (base_icu::UChar)(((supplementary)&0x3ff)|0xdc00) - -/** - * How many 16-bit code units are used to encode this Unicode code point? (1 or 2) - * The result is not defined if c is not a Unicode code point (U+0000..U+10ffff). - * @param c 32-bit code point - * @return 1 or 2 - * @stable ICU 2.4 - */ -#define CBU16_LENGTH(c) ((uint32_t)(c) <= 0xffff ? 1 : 2) - -/** - * The maximum number of 16-bit code units per Unicode code point (U+0000..U+10ffff). - * @return 2 - * @stable ICU 2.4 - */ -#define CBU16_MAX_LENGTH 2 - -/** - * Get a code point from a string at a code point boundary offset, - * and advance the offset to the next code point boundary. - * (Post-incrementing forward iteration.) - * "Safe" macro, handles unpaired surrogates and checks for string boundaries. - * - * The offset may point to the lead surrogate unit - * for a supplementary code point, in which case the macro will read - * the following trail surrogate as well. - * If the offset points to a trail surrogate or - * to a single, unpaired lead surrogate, then that itself - * will be returned as the code point. - * - * @param s const UChar * string - * @param i string offset, i<length - * @param length string length - * @param c output UChar32 variable - * @stable ICU 2.4 - */ -#define CBU16_NEXT(s, i, length, c) \ - { \ - (c) = (s)[(i)++]; \ - if (CBU16_IS_LEAD(c)) { \ - uint16_t __c2; \ - if ((i) < (length) && CBU16_IS_TRAIL(__c2 = (s)[(i)])) { \ - ++(i); \ - (c) = CBU16_GET_SUPPLEMENTARY((c), __c2); \ - } \ - } \ - } - -/** - * Append a code point to a string, overwriting 1 or 2 code units. - * The offset points to the current end of the string contents - * and is advanced (post-increment). - * "Unsafe" macro, assumes a valid code point and sufficient space in the string. - * Otherwise, the result is undefined. - * - * @param s const UChar * string buffer - * @param i string offset - * @param c code point to append - * @see CBU16_APPEND - * @stable ICU 2.4 - */ -#define CBU16_APPEND_UNSAFE(s, i, c) \ - { \ - if ((uint32_t)(c) <= 0xffff) { \ - (s)[(i)++] = (uint16_t)(c); \ - } else { \ - (s)[(i)++] = (uint16_t)(((c) >> 10) + 0xd7c0); \ - (s)[(i)++] = (uint16_t)(((c)&0x3ff) | 0xdc00); \ - } \ - } - -} // namesapce base_icu - -#endif // BASE_THIRD_PARTY_ICU_ICU_UTF_H_ diff --git a/security/sandbox/chromium/base/third_party/superfasthash/LICENSE b/security/sandbox/chromium/base/third_party/superfasthash/LICENSE deleted file mode 100644 index 3c40a3ecd..000000000 --- a/security/sandbox/chromium/base/third_party/superfasthash/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Paul Hsieh OLD BSD license - -Copyright (c) 2010, Paul Hsieh -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 copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. -* Neither my name, Paul Hsieh, nor the names of any other contributors to the - code use may not 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 A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/security/sandbox/chromium/base/third_party/superfasthash/README.chromium b/security/sandbox/chromium/base/third_party/superfasthash/README.chromium deleted file mode 100644 index d41ed7724..000000000 --- a/security/sandbox/chromium/base/third_party/superfasthash/README.chromium +++ /dev/null @@ -1,29 +0,0 @@ -Name: Paul Hsieh's SuperFastHash -Short Name: SuperFastHash -URL: http://www.azillionmonkeys.com/qed/hash.html -Version: 0 -Date: 2012-02-21 -License: BSD -License File: LICENSE -Security Critical: yes - -Description: -A fast string hashing algorithm. - -Local Modifications: -- Added LICENSE. -- Added license text as a comment to the top of superfasthash.c. -- #include <stdint.h> instead of "pstdint.h". -- #include <stdlib.h>. - -The license is a standard 3-clause BSD license with the following minor changes: - -"nor the names of its contributors may be used" -is replaced with: -"nor the names of any other contributors to the code use may not be used" - -and - -"IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE" -is replaced with: -"IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE" diff --git a/security/sandbox/chromium/base/third_party/superfasthash/superfasthash.c b/security/sandbox/chromium/base/third_party/superfasthash/superfasthash.c deleted file mode 100644 index 6e7687e13..000000000 --- a/security/sandbox/chromium/base/third_party/superfasthash/superfasthash.c +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2010, Paul Hsieh -// 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 copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither my name, Paul Hsieh, nor the names of any other contributors to the -// code use may not 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 A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#include <stdint.h> -#include <stdlib.h> -#undef get16bits -#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ - || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) -#define get16bits(d) (*((const uint16_t *) (d))) -#endif - -#if !defined (get16bits) -#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\ - +(uint32_t)(((const uint8_t *)(d))[0]) ) -#endif - -uint32_t SuperFastHash (const char * data, int len) { -uint32_t hash = len, tmp; -int rem; - - if (len <= 0 || data == NULL) return 0; - - rem = len & 3; - len >>= 2; - - /* Main loop */ - for (;len > 0; len--) { - hash += get16bits (data); - tmp = (get16bits (data+2) << 11) ^ hash; - hash = (hash << 16) ^ tmp; - data += 2*sizeof (uint16_t); - hash += hash >> 11; - } - - /* Handle end cases */ - switch (rem) { - case 3: hash += get16bits (data); - hash ^= hash << 16; - hash ^= ((signed char)data[sizeof (uint16_t)]) << 18; - hash += hash >> 11; - break; - case 2: hash += get16bits (data); - hash ^= hash << 11; - hash += hash >> 17; - break; - case 1: hash += (signed char)*data; - hash ^= hash << 10; - hash += hash >> 1; - } - - /* Force "avalanching" of final 127 bits */ - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - - return hash; -} diff --git a/security/sandbox/chromium/base/third_party/valgrind/LICENSE b/security/sandbox/chromium/base/third_party/valgrind/LICENSE deleted file mode 100644 index 41f677bd1..000000000 --- a/security/sandbox/chromium/base/third_party/valgrind/LICENSE +++ /dev/null @@ -1,39 +0,0 @@ - Notice that the following BSD-style license applies to the Valgrind header - files used by Chromium (valgrind.h and memcheck.h). However, the rest of - Valgrind is licensed under the terms of the GNU General Public License, - version 2, unless otherwise indicated. - - ---------------------------------------------------------------- - - Copyright (C) 2000-2008 Julian Seward. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - - 3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - - 4. The name of the author may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/security/sandbox/chromium/base/third_party/valgrind/valgrind.h b/security/sandbox/chromium/base/third_party/valgrind/valgrind.h deleted file mode 100644 index 0bae0aa13..000000000 --- a/security/sandbox/chromium/base/third_party/valgrind/valgrind.h +++ /dev/null @@ -1,4792 +0,0 @@ -/* -*- c -*- - ---------------------------------------------------------------- - - Notice that the following BSD-style license applies to this one - file (valgrind.h) only. The rest of Valgrind is licensed under the - terms of the GNU General Public License, version 2, unless - otherwise indicated. See the COPYING file in the source - distribution for details. - - ---------------------------------------------------------------- - - This file is part of Valgrind, a dynamic binary instrumentation - framework. - - Copyright (C) 2000-2010 Julian Seward. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - - 3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - - 4. The name of the author may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ---------------------------------------------------------------- - - Notice that the above BSD-style license applies to this one file - (valgrind.h) only. The entire rest of Valgrind is licensed under - the terms of the GNU General Public License, version 2. See the - COPYING file in the source distribution for details. - - ---------------------------------------------------------------- -*/ - - -/* This file is for inclusion into client (your!) code. - - You can use these macros to manipulate and query Valgrind's - execution inside your own programs. - - The resulting executables will still run without Valgrind, just a - little bit more slowly than they otherwise would, but otherwise - unchanged. When not running on valgrind, each client request - consumes very few (eg. 7) instructions, so the resulting performance - loss is negligible unless you plan to execute client requests - millions of times per second. Nevertheless, if that is still a - problem, you can compile with the NVALGRIND symbol defined (gcc - -DNVALGRIND) so that client requests are not even compiled in. */ - -#ifndef __VALGRIND_H -#define __VALGRIND_H - - -/* ------------------------------------------------------------------ */ -/* VERSION NUMBER OF VALGRIND */ -/* ------------------------------------------------------------------ */ - -/* Specify Valgrind's version number, so that user code can - conditionally compile based on our version number. Note that these - were introduced at version 3.6 and so do not exist in version 3.5 - or earlier. The recommended way to use them to check for "version - X.Y or later" is (eg) - -#if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__) \ - && (__VALGRIND_MAJOR__ > 3 \ - || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6)) -*/ -#define __VALGRIND_MAJOR__ 3 -#define __VALGRIND_MINOR__ 6 - - -#include <stdarg.h> - -/* Nb: this file might be included in a file compiled with -ansi. So - we can't use C++ style "//" comments nor the "asm" keyword (instead - use "__asm__"). */ - -/* Derive some tags indicating what the target platform is. Note - that in this file we're using the compiler's CPP symbols for - identifying architectures, which are different to the ones we use - within the rest of Valgrind. Note, __powerpc__ is active for both - 32 and 64-bit PPC, whereas __powerpc64__ is only active for the - latter (on Linux, that is). - - Misc note: how to find out what's predefined in gcc by default: - gcc -Wp,-dM somefile.c -*/ -#undef PLAT_ppc64_aix5 -#undef PLAT_ppc32_aix5 -#undef PLAT_x86_darwin -#undef PLAT_amd64_darwin -#undef PLAT_x86_win32 -#undef PLAT_x86_linux -#undef PLAT_amd64_linux -#undef PLAT_ppc32_linux -#undef PLAT_ppc64_linux -#undef PLAT_arm_linux - -#if defined(_AIX) && defined(__64BIT__) -# define PLAT_ppc64_aix5 1 -#elif defined(_AIX) && !defined(__64BIT__) -# define PLAT_ppc32_aix5 1 -#elif defined(__APPLE__) && defined(__i386__) -# define PLAT_x86_darwin 1 -#elif defined(__APPLE__) && defined(__x86_64__) -# define PLAT_amd64_darwin 1 -#elif defined(__MINGW32__) || defined(__CYGWIN32__) || defined(_WIN32) && defined(_M_IX86) -# define PLAT_x86_win32 1 -#elif defined(__linux__) && defined(__i386__) -# define PLAT_x86_linux 1 -#elif defined(__linux__) && defined(__x86_64__) -# define PLAT_amd64_linux 1 -#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__) -# define PLAT_ppc32_linux 1 -#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) -# define PLAT_ppc64_linux 1 -#elif defined(__linux__) && defined(__arm__) -# define PLAT_arm_linux 1 -#else -/* If we're not compiling for our target platform, don't generate - any inline asms. */ -# if !defined(NVALGRIND) -# define NVALGRIND 1 -# endif -#endif - - -/* ------------------------------------------------------------------ */ -/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */ -/* in here of use to end-users -- skip to the next section. */ -/* ------------------------------------------------------------------ */ - -#if defined(NVALGRIND) - -/* Define NVALGRIND to completely remove the Valgrind magic sequence - from the compiled code (analogous to NDEBUG's effects on - assert()) */ -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - { \ - (_zzq_rlval) = (_zzq_default); \ - } - -#else /* ! NVALGRIND */ - -/* The following defines the magic code sequences which the JITter - spots and handles magically. Don't look too closely at them as - they will rot your brain. - - The assembly code sequences for all architectures is in this one - file. This is because this file must be stand-alone, and we don't - want to have multiple files. - - For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default - value gets put in the return slot, so that everything works when - this is executed not under Valgrind. Args are passed in a memory - block, and so there's no intrinsic limit to the number that could - be passed, but it's currently five. - - The macro args are: - _zzq_rlval result lvalue - _zzq_default default value (result returned when running on real CPU) - _zzq_request request code - _zzq_arg1..5 request params - - The other two macros are used to support function wrapping, and are - a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the - guest's NRADDR pseudo-register and whatever other information is - needed to safely run the call original from the wrapper: on - ppc64-linux, the R2 value at the divert point is also needed. This - information is abstracted into a user-visible type, OrigFn. - - VALGRIND_CALL_NOREDIR_* behaves the same as the following on the - guest, but guarantees that the branch instruction will not be - redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64: - branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a - complete inline asm, since it needs to be combined with more magic - inline asm stuff to be useful. -*/ - -/* ------------------------- x86-{linux,darwin} ---------------- */ - -#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \ - || (defined(PLAT_x86_win32) && defined(__GNUC__)) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "roll $3, %%edi ; roll $13, %%edi\n\t" \ - "roll $29, %%edi ; roll $19, %%edi\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - { volatile unsigned int _zzq_args[6]; \ - volatile unsigned int _zzq_result; \ - _zzq_args[0] = (unsigned int)(_zzq_request); \ - _zzq_args[1] = (unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %EDX = client_request ( %EAX ) */ \ - "xchgl %%ebx,%%ebx" \ - : "=d" (_zzq_result) \ - : "a" (&_zzq_args[0]), "0" (_zzq_default) \ - : "cc", "memory" \ - ); \ - _zzq_rlval = _zzq_result; \ - } - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %EAX = guest_NRADDR */ \ - "xchgl %%ecx,%%ecx" \ - : "=a" (__addr) \ - : \ - : "cc", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_EAX \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* call-noredir *%EAX */ \ - "xchgl %%edx,%%edx\n\t" -#endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) */ - -/* ------------------------- x86-Win32 ------------------------- */ - -#if defined(PLAT_x86_win32) && !defined(__GNUC__) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -#if defined(_MSC_VER) - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - __asm rol edi, 3 __asm rol edi, 13 \ - __asm rol edi, 29 __asm rol edi, 19 - -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - { volatile uintptr_t _zzq_args[6]; \ - volatile unsigned int _zzq_result; \ - _zzq_args[0] = (uintptr_t)(_zzq_request); \ - _zzq_args[1] = (uintptr_t)(_zzq_arg1); \ - _zzq_args[2] = (uintptr_t)(_zzq_arg2); \ - _zzq_args[3] = (uintptr_t)(_zzq_arg3); \ - _zzq_args[4] = (uintptr_t)(_zzq_arg4); \ - _zzq_args[5] = (uintptr_t)(_zzq_arg5); \ - __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %EDX = client_request ( %EAX ) */ \ - __asm xchg ebx,ebx \ - __asm mov _zzq_result, edx \ - } \ - _zzq_rlval = _zzq_result; \ - } - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned int __addr; \ - __asm { __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %EAX = guest_NRADDR */ \ - __asm xchg ecx,ecx \ - __asm mov __addr, eax \ - } \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_EAX ERROR - -#else -#error Unsupported compiler. -#endif - -#endif /* PLAT_x86_win32 */ - -/* ------------------------ amd64-{linux,darwin} --------------- */ - -#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \ - "rolq $61, %%rdi ; rolq $51, %%rdi\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - { volatile unsigned long long int _zzq_args[6]; \ - volatile unsigned long long int _zzq_result; \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %RDX = client_request ( %RAX ) */ \ - "xchgq %%rbx,%%rbx" \ - : "=d" (_zzq_result) \ - : "a" (&_zzq_args[0]), "0" (_zzq_default) \ - : "cc", "memory" \ - ); \ - _zzq_rlval = _zzq_result; \ - } - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %RAX = guest_NRADDR */ \ - "xchgq %%rcx,%%rcx" \ - : "=a" (__addr) \ - : \ - : "cc", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_RAX \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* call-noredir *%RAX */ \ - "xchgq %%rdx,%%rdx\n\t" -#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */ - -/* ------------------------ ppc32-linux ------------------------ */ - -#if defined(PLAT_ppc32_linux) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \ - "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - { unsigned int _zzq_args[6]; \ - unsigned int _zzq_result; \ - unsigned int* _zzq_ptr; \ - _zzq_args[0] = (unsigned int)(_zzq_request); \ - _zzq_args[1] = (unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile("mr 3,%1\n\t" /*default*/ \ - "mr 4,%2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1\n\t" \ - "mr %0,3" /*result*/ \ - : "=b" (_zzq_result) \ - : "b" (_zzq_default), "b" (_zzq_ptr) \ - : "cc", "memory", "r3", "r4"); \ - _zzq_rlval = _zzq_result; \ - } - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - unsigned int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "cc", "memory", "r3" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R11 */ \ - "or 3,3,3\n\t" -#endif /* PLAT_ppc32_linux */ - -/* ------------------------ ppc64-linux ------------------------ */ - -#if defined(PLAT_ppc64_linux) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - unsigned long long int r2; /* what tocptr do we need? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ - "rotldi 0,0,61 ; rotldi 0,0,51\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - { unsigned long long int _zzq_args[6]; \ - register unsigned long long int _zzq_result __asm__("r3"); \ - register unsigned long long int* _zzq_ptr __asm__("r4"); \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1" \ - : "=r" (_zzq_result) \ - : "0" (_zzq_default), "r" (_zzq_ptr) \ - : "cc", "memory"); \ - _zzq_rlval = _zzq_result; \ - } - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - register unsigned long long int __addr __asm__("r3"); \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2" \ - : "=r" (__addr) \ - : \ - : "cc", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR_GPR2 */ \ - "or 4,4,4" \ - : "=r" (__addr) \ - : \ - : "cc", "memory" \ - ); \ - _zzq_orig->r2 = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R11 */ \ - "or 3,3,3\n\t" - -#endif /* PLAT_ppc64_linux */ - -/* ------------------------- arm-linux ------------------------- */ - -#if defined(PLAT_arm_linux) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "mov r12, r12, ror #3 ; mov r12, r12, ror #13 \n\t" \ - "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t" - -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - { volatile unsigned int _zzq_args[6]; \ - volatile unsigned int _zzq_result; \ - _zzq_args[0] = (unsigned int)(_zzq_request); \ - _zzq_args[1] = (unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - __asm__ volatile("mov r3, %1\n\t" /*default*/ \ - "mov r4, %2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* R3 = client_request ( R4 ) */ \ - "orr r10, r10, r10\n\t" \ - "mov %0, r3" /*result*/ \ - : "=r" (_zzq_result) \ - : "r" (_zzq_default), "r" (&_zzq_args[0]) \ - : "cc","memory", "r3", "r4"); \ - _zzq_rlval = _zzq_result; \ - } - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - unsigned int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* R3 = guest_NRADDR */ \ - "orr r11, r11, r11\n\t" \ - "mov %0, r3" \ - : "=r" (__addr) \ - : \ - : "cc", "memory", "r3" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R4 */ \ - "orr r12, r12, r12\n\t" - -#endif /* PLAT_arm_linux */ - -/* ------------------------ ppc32-aix5 ------------------------- */ - -#if defined(PLAT_ppc32_aix5) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - unsigned int r2; /* what tocptr do we need? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \ - "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - { unsigned int _zzq_args[7]; \ - register unsigned int _zzq_result; \ - register unsigned int* _zzq_ptr; \ - _zzq_args[0] = (unsigned int)(_zzq_request); \ - _zzq_args[1] = (unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - _zzq_args[6] = (unsigned int)(_zzq_default); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile("mr 4,%1\n\t" \ - "lwz 3, 24(4)\n\t" \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1\n\t" \ - "mr %0,3" \ - : "=b" (_zzq_result) \ - : "b" (_zzq_ptr) \ - : "r3", "r4", "cc", "memory"); \ - _zzq_rlval = _zzq_result; \ - } - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - register unsigned int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "r3", "cc", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR_GPR2 */ \ - "or 4,4,4\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "r3", "cc", "memory" \ - ); \ - _zzq_orig->r2 = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R11 */ \ - "or 3,3,3\n\t" - -#endif /* PLAT_ppc32_aix5 */ - -/* ------------------------ ppc64-aix5 ------------------------- */ - -#if defined(PLAT_ppc64_aix5) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - unsigned long long int r2; /* what tocptr do we need? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ - "rotldi 0,0,61 ; rotldi 0,0,51\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - { unsigned long long int _zzq_args[7]; \ - register unsigned long long int _zzq_result; \ - register unsigned long long int* _zzq_ptr; \ - _zzq_args[0] = (unsigned int long long)(_zzq_request); \ - _zzq_args[1] = (unsigned int long long)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int long long)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int long long)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int long long)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int long long)(_zzq_arg5); \ - _zzq_args[6] = (unsigned int long long)(_zzq_default); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile("mr 4,%1\n\t" \ - "ld 3, 48(4)\n\t" \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1\n\t" \ - "mr %0,3" \ - : "=b" (_zzq_result) \ - : "b" (_zzq_ptr) \ - : "r3", "r4", "cc", "memory"); \ - _zzq_rlval = _zzq_result; \ - } - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - register unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "r3", "cc", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR_GPR2 */ \ - "or 4,4,4\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "r3", "cc", "memory" \ - ); \ - _zzq_orig->r2 = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R11 */ \ - "or 3,3,3\n\t" - -#endif /* PLAT_ppc64_aix5 */ - -/* Insert assembly code for other platforms here... */ - -#endif /* NVALGRIND */ - - -/* ------------------------------------------------------------------ */ -/* PLATFORM SPECIFICS for FUNCTION WRAPPING. This is all very */ -/* ugly. It's the least-worst tradeoff I can think of. */ -/* ------------------------------------------------------------------ */ - -/* This section defines magic (a.k.a appalling-hack) macros for doing - guaranteed-no-redirection macros, so as to get from function - wrappers to the functions they are wrapping. The whole point is to - construct standard call sequences, but to do the call itself with a - special no-redirect call pseudo-instruction that the JIT - understands and handles specially. This section is long and - repetitious, and I can't see a way to make it shorter. - - The naming scheme is as follows: - - CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc} - - 'W' stands for "word" and 'v' for "void". Hence there are - different macros for calling arity 0, 1, 2, 3, 4, etc, functions, - and for each, the possibility of returning a word-typed result, or - no result. -*/ - -/* Use these to write the name of your wrapper. NOTE: duplicates - VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */ - -/* Use an extra level of macroisation so as to ensure the soname/fnname - args are fully macro-expanded before pasting them together. */ -#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd - -#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \ - VG_CONCAT4(_vgwZU_,soname,_,fnname) - -#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \ - VG_CONCAT4(_vgwZZ_,soname,_,fnname) - -/* Use this macro from within a wrapper function to collect the - context (address and possibly other info) of the original function. - Once you have that you can then use it in one of the CALL_FN_ - macros. The type of the argument _lval is OrigFn. */ -#define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval) - -/* Derivatives of the main macros below, for calling functions - returning void. */ - -#define CALL_FN_v_v(fnptr) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_v(_junk,fnptr); } while (0) - -#define CALL_FN_v_W(fnptr, arg1) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_W(_junk,fnptr,arg1); } while (0) - -#define CALL_FN_v_WW(fnptr, arg1,arg2) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0) - -#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0) - -#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0) - -#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0) - -#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0) - -#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0) - -/* ------------------------- x86-{linux,darwin} ---------------- */ - -#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) - -/* These regs are trashed by the hidden call. No need to mention eax - as gcc can already see that, plus causes gcc to bomb. */ -#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx" - -/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned - long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - "subl $12, %%esp\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $16, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - "subl $8, %%esp\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $16, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - "subl $4, %%esp\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $16, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $16, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - "subl $12, %%esp\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $32, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - "subl $8, %%esp\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $32, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - "subl $4, %%esp\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $32, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $32, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - "subl $12, %%esp\n\t" \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $48, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - "subl $8, %%esp\n\t" \ - "pushl 40(%%eax)\n\t" \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $48, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - "subl $4, %%esp\n\t" \ - "pushl 44(%%eax)\n\t" \ - "pushl 40(%%eax)\n\t" \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $48, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - "pushl 48(%%eax)\n\t" \ - "pushl 44(%%eax)\n\t" \ - "pushl 40(%%eax)\n\t" \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $48, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_x86_linux || PLAT_x86_darwin */ - -/* ------------------------ amd64-{linux,darwin} --------------- */ - -#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) - -/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \ - "rdi", "r8", "r9", "r10", "r11" - -/* This is all pretty complex. It's so as to make stack unwinding - work reliably. See bug 243270. The basic problem is the sub and - add of 128 of %rsp in all of the following macros. If gcc believes - the CFA is in %rsp, then unwinding may fail, because what's at the - CFA is not what gcc "expected" when it constructs the CFIs for the - places where the macros are instantiated. - - But we can't just add a CFI annotation to increase the CFA offset - by 128, to match the sub of 128 from %rsp, because we don't know - whether gcc has chosen %rsp as the CFA at that point, or whether it - has chosen some other register (eg, %rbp). In the latter case, - adding a CFI annotation to change the CFA offset is simply wrong. - - So the solution is to get hold of the CFA using - __builtin_dwarf_cfa(), put it in a known register, and add a - CFI annotation to say what the register is. We choose %rbp for - this (perhaps perversely), because: - - (1) %rbp is already subject to unwinding. If a new register was - chosen then the unwinder would have to unwind it in all stack - traces, which is expensive, and - - (2) %rbp is already subject to precise exception updates in the - JIT. If a new register was chosen, we'd have to have precise - exceptions for it too, which reduces performance of the - generated code. - - However .. one extra complication. We can't just whack the result - of __builtin_dwarf_cfa() into %rbp and then add %rbp to the - list of trashed registers at the end of the inline assembly - fragments; gcc won't allow %rbp to appear in that list. Hence - instead we need to stash %rbp in %r15 for the duration of the asm, - and say that %r15 is trashed instead. gcc seems happy to go with - that. - - Oh .. and this all needs to be conditionalised so that it is - unchanged from before this commit, when compiled with older gccs - that don't support __builtin_dwarf_cfa. Furthermore, since - this header file is freestanding, it has to be independent of - config.h, and so the following conditionalisation cannot depend on - configure time checks. - - Although it's not clear from - 'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)', - this expression excludes Darwin. - .cfi directives in Darwin assembly appear to be completely - different and I haven't investigated how they work. - - For even more entertainment value, note we have to use the - completely undocumented __builtin_dwarf_cfa(), which appears to - really compute the CFA, whereas __builtin_frame_address(0) claims - to but actually doesn't. See - https://bugs.kde.org/show_bug.cgi?id=243270#c47 -*/ -#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM) -# define __FRAME_POINTER \ - ,"r"(__builtin_dwarf_cfa()) -# define VALGRIND_CFI_PROLOGUE \ - "movq %%rbp, %%r15\n\t" \ - "movq %2, %%rbp\n\t" \ - ".cfi_remember_state\n\t" \ - ".cfi_def_cfa rbp, 0\n\t" -# define VALGRIND_CFI_EPILOGUE \ - "movq %%r15, %%rbp\n\t" \ - ".cfi_restore_state\n\t" -#else -# define __FRAME_POINTER -# define VALGRIND_CFI_PROLOGUE -# define VALGRIND_CFI_EPILOGUE -#endif - - -/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned - long) == 8. */ - -/* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_ - macros. In order not to trash the stack redzone, we need to drop - %rsp by 128 before the hidden call, and restore afterwards. The - nastyness is that it is only by luck that the stack still appears - to be unwindable during the hidden call - since then the behaviour - of any routine using this macro does not match what the CFI data - says. Sigh. - - Why is this important? Imagine that a wrapper has a stack - allocated local, and passes to the hidden call, a pointer to it. - Because gcc does not know about the hidden call, it may allocate - that local in the redzone. Unfortunately the hidden call may then - trash it before it comes to use it. So we must step clear of the - redzone, for the duration of the hidden call, to make it safe. - - Probably the same problem afflicts the other redzone-style ABIs too - (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is - self describing (none of this CFI nonsense) so at least messing - with the stack pointer doesn't give a danger of non-unwindable - stack. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "subq $128,%%rsp\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "subq $128,%%rsp\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "subq $128,%%rsp\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "subq $128,%%rsp\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "subq $128,%%rsp\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "subq $128,%%rsp\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "subq $128,%%rsp\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "subq $136,%%rsp\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $8, %%rsp\n" \ - "addq $136,%%rsp\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "subq $128,%%rsp\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $16, %%rsp\n" \ - "addq $128,%%rsp\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "subq $136,%%rsp\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $24, %%rsp\n" \ - "addq $136,%%rsp\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "subq $128,%%rsp\n\t" \ - "pushq 80(%%rax)\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $32, %%rsp\n" \ - "addq $128,%%rsp\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "subq $136,%%rsp\n\t" \ - "pushq 88(%%rax)\n\t" \ - "pushq 80(%%rax)\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $40, %%rsp\n" \ - "addq $136,%%rsp\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "subq $128,%%rsp\n\t" \ - "pushq 96(%%rax)\n\t" \ - "pushq 88(%%rax)\n\t" \ - "pushq 80(%%rax)\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $48, %%rsp\n" \ - "addq $128,%%rsp\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */ - -/* ------------------------ ppc32-linux ------------------------ */ - -#if defined(PLAT_ppc32_linux) - -/* This is useful for finding out about the on-stack stuff: - - extern int f9 ( int,int,int,int,int,int,int,int,int ); - extern int f10 ( int,int,int,int,int,int,int,int,int,int ); - extern int f11 ( int,int,int,int,int,int,int,int,int,int,int ); - extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int ); - - int g9 ( void ) { - return f9(11,22,33,44,55,66,77,88,99); - } - int g10 ( void ) { - return f10(11,22,33,44,55,66,77,88,99,110); - } - int g11 ( void ) { - return f11(11,22,33,44,55,66,77,88,99,110,121); - } - int g12 ( void ) { - return f12(11,22,33,44,55,66,77,88,99,110,121,132); - } -*/ - -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" - -/* These CALL_FN_ macros assume that on ppc32-linux, - sizeof(unsigned long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "addi 1,1,-16\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "addi 1,1,16\n\t" \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "addi 1,1,-16\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,12(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "addi 1,1,16\n\t" \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - _argvec[11] = (unsigned long)arg11; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "addi 1,1,-32\n\t" \ - /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,16(1)\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,12(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "addi 1,1,32\n\t" \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - _argvec[11] = (unsigned long)arg11; \ - _argvec[12] = (unsigned long)arg12; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "addi 1,1,-32\n\t" \ - /* arg12 */ \ - "lwz 3,48(11)\n\t" \ - "stw 3,20(1)\n\t" \ - /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,16(1)\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,12(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "addi 1,1,32\n\t" \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_ppc32_linux */ - -/* ------------------------ ppc64-linux ------------------------ */ - -#if defined(PLAT_ppc64_linux) - -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" - -/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned - long) == 8. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+0]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+1]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+2]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+3]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+4]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+5]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+6]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+7]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+8]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+9]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-128\n\t" /* expand stack frame */ \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - "addi 1,1,128" /* restore frame */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+10]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-128\n\t" /* expand stack frame */ \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - "addi 1,1,128" /* restore frame */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+11]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-144\n\t" /* expand stack frame */ \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - "addi 1,1,144" /* restore frame */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+12]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - _argvec[2+12] = (unsigned long)arg12; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-144\n\t" /* expand stack frame */ \ - /* arg12 */ \ - "ld 3,96(11)\n\t" \ - "std 3,136(1)\n\t" \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - "addi 1,1,144" /* restore frame */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_ppc64_linux */ - -/* ------------------------- arm-linux ------------------------- */ - -#if defined(PLAT_arm_linux) - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14" - -/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned - long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - "mov %0, r0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - "mov %0, r0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - "mov %0, r0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - "mov %0, r0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - "ldr r0, [%1, #20] \n\t" \ - "push {r0} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - "add sp, sp, #4 \n\t" \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "push {r0, r1} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - "add sp, sp, #8 \n\t" \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "push {r0, r1, r2} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - "add sp, sp, #12 \n\t" \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "ldr r3, [%1, #32] \n\t" \ - "push {r0, r1, r2, r3} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - "add sp, sp, #16 \n\t" \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "ldr r3, [%1, #32] \n\t" \ - "ldr r4, [%1, #36] \n\t" \ - "push {r0, r1, r2, r3, r4} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - "add sp, sp, #20 \n\t" \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - "ldr r0, [%1, #40] \n\t" \ - "push {r0} \n\t" \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "ldr r3, [%1, #32] \n\t" \ - "ldr r4, [%1, #36] \n\t" \ - "push {r0, r1, r2, r3, r4} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - "add sp, sp, #24 \n\t" \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - "ldr r0, [%1, #40] \n\t" \ - "ldr r1, [%1, #44] \n\t" \ - "push {r0, r1} \n\t" \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "ldr r3, [%1, #32] \n\t" \ - "ldr r4, [%1, #36] \n\t" \ - "push {r0, r1, r2, r3, r4} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - "add sp, sp, #28 \n\t" \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory",__CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - "ldr r0, [%1, #40] \n\t" \ - "ldr r1, [%1, #44] \n\t" \ - "ldr r2, [%1, #48] \n\t" \ - "push {r0, r1, r2} \n\t" \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "ldr r3, [%1, #32] \n\t" \ - "ldr r4, [%1, #36] \n\t" \ - "push {r0, r1, r2, r3, r4} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - "add sp, sp, #32 \n\t" \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_arm_linux */ - -/* ------------------------ ppc32-aix5 ------------------------- */ - -#if defined(PLAT_ppc32_aix5) - -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" - -/* Expand the stack frame, copying enough info that unwinding - still works. Trashes r3. */ - -#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \ - "addi 1,1,-" #_n_fr "\n\t" \ - "lwz 3," #_n_fr "(1)\n\t" \ - "stw 3,0(1)\n\t" - -#define VG_CONTRACT_FRAME_BY(_n_fr) \ - "addi 1,1," #_n_fr "\n\t" - -/* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned - long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+0]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+1]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+2]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+3]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+4]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+5]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+6]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+7]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+8]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+9]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(64) \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,56(1)\n\t" \ - /* args1-8 */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(64) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+10]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(64) \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,60(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,56(1)\n\t" \ - /* args1-8 */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(64) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+11]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(72) \ - /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,64(1)\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,60(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,56(1)\n\t" \ - /* args1-8 */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(72) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+12]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - _argvec[2+12] = (unsigned long)arg12; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(72) \ - /* arg12 */ \ - "lwz 3,48(11)\n\t" \ - "stw 3,68(1)\n\t" \ - /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,64(1)\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,60(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,56(1)\n\t" \ - /* args1-8 */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(72) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_ppc32_aix5 */ - -/* ------------------------ ppc64-aix5 ------------------------- */ - -#if defined(PLAT_ppc64_aix5) - -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" - -/* Expand the stack frame, copying enough info that unwinding - still works. Trashes r3. */ - -#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \ - "addi 1,1,-" #_n_fr "\n\t" \ - "ld 3," #_n_fr "(1)\n\t" \ - "std 3,0(1)\n\t" - -#define VG_CONTRACT_FRAME_BY(_n_fr) \ - "addi 1,1," #_n_fr "\n\t" - -/* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned - long) == 8. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+0]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+1]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+2]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+3]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+4]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+5]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+6]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+7]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+8]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+9]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(128) \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(128) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+10]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(128) \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(128) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+11]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(144) \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(144) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+12]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - _argvec[2+12] = (unsigned long)arg12; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(144) \ - /* arg12 */ \ - "ld 3,96(11)\n\t" \ - "std 3,136(1)\n\t" \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(144) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_ppc64_aix5 */ - - -/* ------------------------------------------------------------------ */ -/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */ -/* */ -/* ------------------------------------------------------------------ */ - -/* Some request codes. There are many more of these, but most are not - exposed to end-user view. These are the public ones, all of the - form 0x1000 + small_number. - - Core ones are in the range 0x00000000--0x0000ffff. The non-public - ones start at 0x2000. -*/ - -/* These macros are used by tools -- they must be public, but don't - embed them into other programs. */ -#define VG_USERREQ_TOOL_BASE(a,b) \ - ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16)) -#define VG_IS_TOOL_USERREQ(a, b, v) \ - (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000)) - -/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! - This enum comprises an ABI exported by Valgrind to programs - which use client requests. DO NOT CHANGE THE ORDER OF THESE - ENTRIES, NOR DELETE ANY -- add new ones at the end. */ -typedef - enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001, - VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002, - - /* These allow any function to be called from the simulated - CPU but run on the real CPU. Nb: the first arg passed to - the function is always the ThreadId of the running - thread! So CLIENT_CALL0 actually requires a 1 arg - function, etc. */ - VG_USERREQ__CLIENT_CALL0 = 0x1101, - VG_USERREQ__CLIENT_CALL1 = 0x1102, - VG_USERREQ__CLIENT_CALL2 = 0x1103, - VG_USERREQ__CLIENT_CALL3 = 0x1104, - - /* Can be useful in regression testing suites -- eg. can - send Valgrind's output to /dev/null and still count - errors. */ - VG_USERREQ__COUNT_ERRORS = 0x1201, - - /* These are useful and can be interpreted by any tool that - tracks malloc() et al, by using vg_replace_malloc.c. */ - VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301, - VG_USERREQ__FREELIKE_BLOCK = 0x1302, - /* Memory pool support. */ - VG_USERREQ__CREATE_MEMPOOL = 0x1303, - VG_USERREQ__DESTROY_MEMPOOL = 0x1304, - VG_USERREQ__MEMPOOL_ALLOC = 0x1305, - VG_USERREQ__MEMPOOL_FREE = 0x1306, - VG_USERREQ__MEMPOOL_TRIM = 0x1307, - VG_USERREQ__MOVE_MEMPOOL = 0x1308, - VG_USERREQ__MEMPOOL_CHANGE = 0x1309, - VG_USERREQ__MEMPOOL_EXISTS = 0x130a, - - /* Allow printfs to valgrind log. */ - /* The first two pass the va_list argument by value, which - assumes it is the same size as or smaller than a UWord, - which generally isn't the case. Hence are deprecated. - The second two pass the vargs by reference and so are - immune to this problem. */ - /* both :: char* fmt, va_list vargs (DEPRECATED) */ - VG_USERREQ__PRINTF = 0x1401, - VG_USERREQ__PRINTF_BACKTRACE = 0x1402, - /* both :: char* fmt, va_list* vargs */ - VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403, - VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404, - - /* Stack support. */ - VG_USERREQ__STACK_REGISTER = 0x1501, - VG_USERREQ__STACK_DEREGISTER = 0x1502, - VG_USERREQ__STACK_CHANGE = 0x1503, - - /* Wine support */ - VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601, - - /* Querying of debug info. */ - VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701 - } Vg_ClientRequest; - -#if !defined(__GNUC__) -# define __extension__ /* */ -#endif - - -/* - * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind - * client request and whose value equals the client request result. - */ - -#if defined(NVALGRIND) - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - (_zzq_default) - -#else /*defined(NVALGRIND)*/ - -#if defined(_MSC_VER) - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - (vg_VALGRIND_DO_CLIENT_REQUEST_EXPR((uintptr_t)(_zzq_default), \ - (_zzq_request), (uintptr_t)(_zzq_arg1), (uintptr_t)(_zzq_arg2), \ - (uintptr_t)(_zzq_arg3), (uintptr_t)(_zzq_arg4), \ - (uintptr_t)(_zzq_arg5))) - -static __inline unsigned -vg_VALGRIND_DO_CLIENT_REQUEST_EXPR(uintptr_t _zzq_default, - unsigned _zzq_request, uintptr_t _zzq_arg1, - uintptr_t _zzq_arg2, uintptr_t _zzq_arg3, - uintptr_t _zzq_arg4, uintptr_t _zzq_arg5) -{ - unsigned _zzq_rlval; - VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default, _zzq_request, - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5); - return _zzq_rlval; -} - -#else /*defined(_MSC_VER)*/ - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - (__extension__({unsigned int _zzq_rlval; \ - VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - _zzq_rlval; \ - })) - -#endif /*defined(_MSC_VER)*/ - -#endif /*defined(NVALGRIND)*/ - - -/* Returns the number of Valgrinds this code is running under. That - is, 0 if running natively, 1 if running under Valgrind, 2 if - running under Valgrind which is running under another Valgrind, - etc. */ -#define RUNNING_ON_VALGRIND \ - VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */, \ - VG_USERREQ__RUNNING_ON_VALGRIND, \ - 0, 0, 0, 0, 0) \ - - -/* Discard translation of code in the range [_qzz_addr .. _qzz_addr + - _qzz_len - 1]. Useful if you are debugging a JITter or some such, - since it provides a way to make sure valgrind will retranslate the - invalidated area. Returns no value. */ -#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__DISCARD_TRANSLATIONS, \ - _qzz_addr, _qzz_len, 0, 0, 0); \ - } - - -/* These requests are for getting Valgrind itself to print something. - Possibly with a backtrace. This is a really ugly hack. The return value - is the number of characters printed, excluding the "**<pid>** " part at the - start and the backtrace (if present). */ - -#if defined(NVALGRIND) - -# define VALGRIND_PRINTF(...) -# define VALGRIND_PRINTF_BACKTRACE(...) - -#else /* NVALGRIND */ - -#if !defined(_MSC_VER) -/* Modern GCC will optimize the static routine out if unused, - and unused attribute will shut down warnings about it. */ -static int VALGRIND_PRINTF(const char *format, ...) - __attribute__((format(__printf__, 1, 2), __unused__)); -#endif -static int -#if defined(_MSC_VER) -__inline -#endif -VALGRIND_PRINTF(const char *format, ...) -{ - unsigned long _qzz_res; - va_list vargs; - va_start(vargs, format); -#if defined(_MSC_VER) - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, - VG_USERREQ__PRINTF_VALIST_BY_REF, - (uintptr_t)format, - (uintptr_t)&vargs, - 0, 0, 0); -#else - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, - VG_USERREQ__PRINTF_VALIST_BY_REF, - (unsigned long)format, - (unsigned long)&vargs, - 0, 0, 0); -#endif - va_end(vargs); - return (int)_qzz_res; -} - -#if !defined(_MSC_VER) -static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...) - __attribute__((format(__printf__, 1, 2), __unused__)); -#endif -static int -#if defined(_MSC_VER) -__inline -#endif -VALGRIND_PRINTF_BACKTRACE(const char *format, ...) -{ - unsigned long _qzz_res; - va_list vargs; - va_start(vargs, format); -#if defined(_MSC_VER) - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, - VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, - (uintptr_t)format, - (uintptr_t)&vargs, - 0, 0, 0); -#else - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, - VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, - (unsigned long)format, - (unsigned long)&vargs, - 0, 0, 0); -#endif - va_end(vargs); - return (int)_qzz_res; -} - -#endif /* NVALGRIND */ - - -/* These requests allow control to move from the simulated CPU to the - real CPU, calling an arbitary function. - - Note that the current ThreadId is inserted as the first argument. - So this call: - - VALGRIND_NON_SIMD_CALL2(f, arg1, arg2) - - requires f to have this signature: - - Word f(Word tid, Word arg1, Word arg2) - - where "Word" is a word-sized type. - - Note that these client requests are not entirely reliable. For example, - if you call a function with them that subsequently calls printf(), - there's a high chance Valgrind will crash. Generally, your prospects of - these working are made higher if the called function does not refer to - any global variables, and does not refer to any libc or other functions - (printf et al). Any kind of entanglement with libc or dynamic linking is - likely to have a bad outcome, for tricky reasons which we've grappled - with a lot in the past. -*/ -#define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \ - __extension__ \ - ({unsigned long _qyy_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL0, \ - _qyy_fn, \ - 0, 0, 0, 0); \ - _qyy_res; \ - }) - -#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \ - __extension__ \ - ({unsigned long _qyy_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL1, \ - _qyy_fn, \ - _qyy_arg1, 0, 0, 0); \ - _qyy_res; \ - }) - -#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \ - __extension__ \ - ({unsigned long _qyy_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL2, \ - _qyy_fn, \ - _qyy_arg1, _qyy_arg2, 0, 0); \ - _qyy_res; \ - }) - -#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \ - __extension__ \ - ({unsigned long _qyy_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL3, \ - _qyy_fn, \ - _qyy_arg1, _qyy_arg2, \ - _qyy_arg3, 0); \ - _qyy_res; \ - }) - - -/* Counts the number of errors that have been recorded by a tool. Nb: - the tool must record the errors with VG_(maybe_record_error)() or - VG_(unique_error)() for them to be counted. */ -#define VALGRIND_COUNT_ERRORS \ - __extension__ \ - ({unsigned int _qyy_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ - VG_USERREQ__COUNT_ERRORS, \ - 0, 0, 0, 0, 0); \ - _qyy_res; \ - }) - -/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing - when heap blocks are allocated in order to give accurate results. This - happens automatically for the standard allocator functions such as - malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete, - delete[], etc. - - But if your program uses a custom allocator, this doesn't automatically - happen, and Valgrind will not do as well. For example, if you allocate - superblocks with mmap() and then allocates chunks of the superblocks, all - Valgrind's observations will be at the mmap() level and it won't know that - the chunks should be considered separate entities. In Memcheck's case, - that means you probably won't get heap block overrun detection (because - there won't be redzones marked as unaddressable) and you definitely won't - get any leak detection. - - The following client requests allow a custom allocator to be annotated so - that it can be handled accurately by Valgrind. - - VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated - by a malloc()-like function. For Memcheck (an illustrative case), this - does two things: - - - It records that the block has been allocated. This means any addresses - within the block mentioned in error messages will be - identified as belonging to the block. It also means that if the block - isn't freed it will be detected by the leak checker. - - - It marks the block as being addressable and undefined (if 'is_zeroed' is - not set), or addressable and defined (if 'is_zeroed' is set). This - controls how accesses to the block by the program are handled. - - 'addr' is the start of the usable block (ie. after any - redzone), 'sizeB' is its size. 'rzB' is the redzone size if the allocator - can apply redzones -- these are blocks of padding at the start and end of - each block. Adding redzones is recommended as it makes it much more likely - Valgrind will spot block overruns. `is_zeroed' indicates if the memory is - zeroed (or filled with another predictable value), as is the case for - calloc(). - - VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a - heap block -- that will be used by the client program -- is allocated. - It's best to put it at the outermost level of the allocator if possible; - for example, if you have a function my_alloc() which calls - internal_alloc(), and the client request is put inside internal_alloc(), - stack traces relating to the heap block will contain entries for both - my_alloc() and internal_alloc(), which is probably not what you want. - - For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out - custom blocks from within a heap block, B, that has been allocated with - malloc/calloc/new/etc, then block B will be *ignored* during leak-checking - -- the custom blocks will take precedence. - - VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK. For - Memcheck, it does two things: - - - It records that the block has been deallocated. This assumes that the - block was annotated as having been allocated via - VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued. - - - It marks the block as being unaddressable. - - VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a - heap block is deallocated. - - In many cases, these two client requests will not be enough to get your - allocator working well with Memcheck. More specifically, if your allocator - writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call - will be necessary to mark the memory as addressable just before the zeroing - occurs, otherwise you'll get a lot of invalid write errors. For example, - you'll need to do this if your allocator recycles freed blocks, but it - zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK). - Alternatively, if your allocator reuses freed blocks for allocator-internal - data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary. - - Really, what's happening is a blurring of the lines between the client - program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the - memory should be considered unaddressable to the client program, but the - allocator knows more than the rest of the client program and so may be able - to safely access it. Extra client requests are necessary for Valgrind to - understand the distinction between the allocator and the rest of the - program. - - Note: there is currently no VALGRIND_REALLOCLIKE_BLOCK client request; it - has to be emulated with MALLOCLIKE/FREELIKE and memory copying. - - Ignored if addr == 0. -*/ -#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MALLOCLIKE_BLOCK, \ - addr, sizeB, rzB, is_zeroed, 0); \ - } - -/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. - Ignored if addr == 0. -*/ -#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__FREELIKE_BLOCK, \ - addr, rzB, 0, 0, 0); \ - } - -/* Create a memory pool. */ -#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__CREATE_MEMPOOL, \ - pool, rzB, is_zeroed, 0, 0); \ - } - -/* Destroy a memory pool. */ -#define VALGRIND_DESTROY_MEMPOOL(pool) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__DESTROY_MEMPOOL, \ - pool, 0, 0, 0, 0); \ - } - -/* Associate a piece of memory with a memory pool. */ -#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_ALLOC, \ - pool, addr, size, 0, 0); \ - } - -/* Disassociate a piece of memory from a memory pool. */ -#define VALGRIND_MEMPOOL_FREE(pool, addr) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_FREE, \ - pool, addr, 0, 0, 0); \ - } - -/* Disassociate any pieces outside a particular range. */ -#define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_TRIM, \ - pool, addr, size, 0, 0); \ - } - -/* Resize and/or move a piece associated with a memory pool. */ -#define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MOVE_MEMPOOL, \ - poolA, poolB, 0, 0, 0); \ - } - -/* Resize and/or move a piece associated with a memory pool. */ -#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_CHANGE, \ - pool, addrA, addrB, size, 0); \ - } - -/* Return 1 if a mempool exists, else 0. */ -#define VALGRIND_MEMPOOL_EXISTS(pool) \ - __extension__ \ - ({unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_EXISTS, \ - pool, 0, 0, 0, 0); \ - _qzz_res; \ - }) - -/* Mark a piece of memory as being a stack. Returns a stack id. */ -#define VALGRIND_STACK_REGISTER(start, end) \ - __extension__ \ - ({unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__STACK_REGISTER, \ - start, end, 0, 0, 0); \ - _qzz_res; \ - }) - -/* Unmark the piece of memory associated with a stack id as being a - stack. */ -#define VALGRIND_STACK_DEREGISTER(id) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__STACK_DEREGISTER, \ - id, 0, 0, 0, 0); \ - } - -/* Change the start and end address of the stack id. */ -#define VALGRIND_STACK_CHANGE(id, start, end) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__STACK_CHANGE, \ - id, start, end, 0, 0); \ - } - -/* Load PDB debug info for Wine PE image_map. */ -#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__LOAD_PDB_DEBUGINFO, \ - fd, ptr, total_size, delta, 0); \ - } - -/* Map a code address to a source file name and line number. buf64 - must point to a 64-byte buffer in the caller's address space. The - result will be dumped in there and is guaranteed to be zero - terminated. If no info is found, the first byte is set to zero. */ -#define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MAP_IP_TO_SRCLOC, \ - addr, buf64, 0, 0, 0); \ - } - - -#undef PLAT_x86_linux -#undef PLAT_amd64_linux -#undef PLAT_ppc32_linux -#undef PLAT_ppc64_linux -#undef PLAT_arm_linux -#undef PLAT_ppc32_aix5 -#undef PLAT_ppc64_aix5 - -#endif /* __VALGRIND_H */ diff --git a/security/sandbox/chromium/base/threading/platform_thread.h b/security/sandbox/chromium/base/threading/platform_thread.h deleted file mode 100644 index e2b09bcb5..000000000 --- a/security/sandbox/chromium/base/threading/platform_thread.h +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// WARNING: You should *NOT* be using this class directly. PlatformThread is -// the low-level platform-specific abstraction to the OS's threading interface. -// You should instead be using a message-loop driven Thread, see thread.h. - -#ifndef BASE_THREADING_PLATFORM_THREAD_H_ -#define BASE_THREADING_PLATFORM_THREAD_H_ - -#include <stddef.h> - -#include "base/base_export.h" -#include "base/macros.h" -#include "base/time/time.h" -#include "build/build_config.h" - -#if defined(OS_WIN) -#include <windows.h> -#elif defined(OS_POSIX) -#include <pthread.h> -#include <unistd.h> -#endif - -namespace base { - -// Used for logging. Always an integer value. -#if defined(OS_WIN) -typedef DWORD PlatformThreadId; -#elif defined(OS_POSIX) -typedef pid_t PlatformThreadId; -#endif - -// Used for thread checking and debugging. -// Meant to be as fast as possible. -// These are produced by PlatformThread::CurrentRef(), and used to later -// check if we are on the same thread or not by using ==. These are safe -// to copy between threads, but can't be copied to another process as they -// have no meaning there. Also, the internal identifier can be re-used -// after a thread dies, so a PlatformThreadRef cannot be reliably used -// to distinguish a new thread from an old, dead thread. -class PlatformThreadRef { - public: -#if defined(OS_WIN) - typedef DWORD RefType; -#elif defined(OS_POSIX) - typedef pthread_t RefType; -#endif - PlatformThreadRef() - : id_(0) { - } - - explicit PlatformThreadRef(RefType id) - : id_(id) { - } - - bool operator==(PlatformThreadRef other) const { - return id_ == other.id_; - } - - bool is_null() const { - return id_ == 0; - } - private: - RefType id_; -}; - -// Used to operate on threads. -class PlatformThreadHandle { - public: -#if defined(OS_WIN) - typedef void* Handle; -#elif defined(OS_POSIX) - typedef pthread_t Handle; -#endif - - PlatformThreadHandle() : handle_(0) {} - - explicit PlatformThreadHandle(Handle handle) : handle_(handle) {} - - bool is_equal(const PlatformThreadHandle& other) const { - return handle_ == other.handle_; - } - - bool is_null() const { - return !handle_; - } - - Handle platform_handle() const { - return handle_; - } - - private: - Handle handle_; -}; - -const PlatformThreadId kInvalidThreadId(0); - -// Valid values for priority of Thread::Options and SimpleThread::Options, and -// SetCurrentThreadPriority(), listed in increasing order of importance. -enum class ThreadPriority { - // Suitable for threads that shouldn't disrupt high priority work. - BACKGROUND, - // Default priority level. - NORMAL, - // Suitable for threads which generate data for the display (at ~60Hz). - DISPLAY, - // Suitable for low-latency, glitch-resistant audio. - REALTIME_AUDIO, -}; - -// A namespace for low-level thread functions. -class BASE_EXPORT PlatformThread { - public: - // Implement this interface to run code on a background thread. Your - // ThreadMain method will be called on the newly created thread. - class BASE_EXPORT Delegate { - public: - virtual void ThreadMain() = 0; - - protected: - virtual ~Delegate() {} - }; - - // Gets the current thread id, which may be useful for logging purposes. - static PlatformThreadId CurrentId(); - - // Gets the current thread reference, which can be used to check if - // we're on the right thread quickly. - static PlatformThreadRef CurrentRef(); - - // Get the handle representing the current thread. On Windows, this is a - // pseudo handle constant which will always represent the thread using it and - // hence should not be shared with other threads nor be used to differentiate - // the current thread from another. - static PlatformThreadHandle CurrentHandle(); - - // Yield the current thread so another thread can be scheduled. - static void YieldCurrentThread(); - - // Sleeps for the specified duration. - static void Sleep(base::TimeDelta duration); - - // Sets the thread name visible to debuggers/tools. This has no effect - // otherwise. - static void SetName(const std::string& name); - - // Gets the thread name, if previously set by SetName. - static const char* GetName(); - - // Creates a new thread. The |stack_size| parameter can be 0 to indicate - // that the default stack size should be used. Upon success, - // |*thread_handle| will be assigned a handle to the newly created thread, - // and |delegate|'s ThreadMain method will be executed on the newly created - // thread. - // NOTE: When you are done with the thread handle, you must call Join to - // release system resources associated with the thread. You must ensure that - // the Delegate object outlives the thread. - static bool Create(size_t stack_size, - Delegate* delegate, - PlatformThreadHandle* thread_handle) { - return CreateWithPriority(stack_size, delegate, thread_handle, - ThreadPriority::NORMAL); - } - - // CreateWithPriority() does the same thing as Create() except the priority of - // the thread is set based on |priority|. - static bool CreateWithPriority(size_t stack_size, Delegate* delegate, - PlatformThreadHandle* thread_handle, - ThreadPriority priority); - - // CreateNonJoinable() does the same thing as Create() except the thread - // cannot be Join()'d. Therefore, it also does not output a - // PlatformThreadHandle. - static bool CreateNonJoinable(size_t stack_size, Delegate* delegate); - - // Joins with a thread created via the Create function. This function blocks - // the caller until the designated thread exits. This will invalidate - // |thread_handle|. - static void Join(PlatformThreadHandle thread_handle); - - // Toggles the current thread's priority at runtime. A thread may not be able - // to raise its priority back up after lowering it if the process does not - // have a proper permission, e.g. CAP_SYS_NICE on Linux. - // Since changing other threads' priority is not permitted in favor of - // security, this interface is restricted to change only the current thread - // priority (https://crbug.com/399473). - static void SetCurrentThreadPriority(ThreadPriority priority); - - static ThreadPriority GetCurrentThreadPriority(); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(PlatformThread); -}; - -} // namespace base - -#endif // BASE_THREADING_PLATFORM_THREAD_H_ diff --git a/security/sandbox/chromium/base/threading/platform_thread_internal_posix.cc b/security/sandbox/chromium/base/threading/platform_thread_internal_posix.cc deleted file mode 100644 index 9af02044f..000000000 --- a/security/sandbox/chromium/base/threading/platform_thread_internal_posix.cc +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/threading/platform_thread_internal_posix.h" - -#include "base/logging.h" - -namespace base { - -namespace internal { - -int ThreadPriorityToNiceValue(ThreadPriority priority) { - for (const ThreadPriorityToNiceValuePair& pair : - kThreadPriorityToNiceValueMap) { - if (pair.priority == priority) - return pair.nice_value; - } - NOTREACHED() << "Unknown ThreadPriority"; - return 0; -} - -ThreadPriority NiceValueToThreadPriority(int nice_value) { - for (const ThreadPriorityToNiceValuePair& pair : - kThreadPriorityToNiceValueMap) { - if (pair.nice_value == nice_value) - return pair.priority; - } - NOTREACHED() << "Unknown nice value"; - return ThreadPriority::NORMAL; -} - -} // namespace internal - -} // namespace base diff --git a/security/sandbox/chromium/base/threading/platform_thread_internal_posix.h b/security/sandbox/chromium/base/threading/platform_thread_internal_posix.h deleted file mode 100644 index 05a8d1e26..000000000 --- a/security/sandbox/chromium/base/threading/platform_thread_internal_posix.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_THREADING_PLATFORM_THREAD_INTERNAL_POSIX_H_ -#define BASE_THREADING_PLATFORM_THREAD_INTERNAL_POSIX_H_ - -#include "base/threading/platform_thread.h" - -namespace base { - -namespace internal { - -struct ThreadPriorityToNiceValuePair { - ThreadPriority priority; - int nice_value; -}; -extern const ThreadPriorityToNiceValuePair kThreadPriorityToNiceValueMap[4]; - -// Returns the nice value matching |priority| based on the platform-specific -// implementation of kThreadPriorityToNiceValueMap. -int ThreadPriorityToNiceValue(ThreadPriority priority); - -// Returns the ThreadPrioirty matching |nice_value| based on the platform- -// specific implementation of kThreadPriorityToNiceValueMap. -ThreadPriority NiceValueToThreadPriority(int nice_value); - -// Allows platform specific tweaks to the generic POSIX solution for -// SetCurrentThreadPriority. Returns true if the platform-specific -// implementation handled this |priority| change, false if the generic -// implementation should instead proceed. -bool SetCurrentThreadPriorityForPlatform(ThreadPriority priority); - -// Returns true if there is a platform-specific ThreadPriority set on the -// current thread (and returns the actual ThreadPriority via |priority|). -// Returns false otherwise, leaving |priority| untouched. -bool GetCurrentThreadPriorityForPlatform(ThreadPriority* priority); - -} // namespace internal - -} // namespace base - -#endif // BASE_THREADING_PLATFORM_THREAD_INTERNAL_POSIX_H_ diff --git a/security/sandbox/chromium/base/threading/platform_thread_linux.cc b/security/sandbox/chromium/base/threading/platform_thread_linux.cc deleted file mode 100644 index 4057ede94..000000000 --- a/security/sandbox/chromium/base/threading/platform_thread_linux.cc +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/threading/platform_thread.h" - -#include <errno.h> -#include <sched.h> -#include <stddef.h> - -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/threading/platform_thread_internal_posix.h" -#include "base/threading/thread_id_name_manager.h" -#include "base/tracked_objects.h" -#include "build/build_config.h" - -#if !defined(OS_NACL) -#include <pthread.h> -#include <sys/prctl.h> -#include <sys/types.h> -#include <unistd.h> -#endif - -namespace base { - -namespace internal { - -namespace { -#if !defined(OS_NACL) -const struct sched_param kRealTimePrio = {8}; -const struct sched_param kResetPrio = {0}; -#endif -} // namespace - -const ThreadPriorityToNiceValuePair kThreadPriorityToNiceValueMap[4] = { - {ThreadPriority::BACKGROUND, 10}, - {ThreadPriority::NORMAL, 0}, - {ThreadPriority::DISPLAY, -6}, - {ThreadPriority::REALTIME_AUDIO, -10}, -}; - -bool SetCurrentThreadPriorityForPlatform(ThreadPriority priority) { -#if !defined(OS_NACL) - ThreadPriority current_priority; - if (priority != ThreadPriority::REALTIME_AUDIO && - GetCurrentThreadPriorityForPlatform(¤t_priority) && - current_priority == ThreadPriority::REALTIME_AUDIO) { - // If the pthread's round-robin scheduler is already enabled, and the new - // priority will use setpriority() instead, the pthread scheduler should be - // reset to use SCHED_OTHER so that setpriority() just works. - pthread_setschedparam(pthread_self(), SCHED_OTHER, &kResetPrio); - return false; - } - return priority == ThreadPriority::REALTIME_AUDIO && - pthread_setschedparam(pthread_self(), SCHED_RR, &kRealTimePrio) == 0; -#else - return false; -#endif -} - -bool GetCurrentThreadPriorityForPlatform(ThreadPriority* priority) { -#if !defined(OS_NACL) - int maybe_sched_rr = 0; - struct sched_param maybe_realtime_prio = {0}; - if (pthread_getschedparam(pthread_self(), &maybe_sched_rr, - &maybe_realtime_prio) == 0 && - maybe_sched_rr == SCHED_RR && - maybe_realtime_prio.sched_priority == kRealTimePrio.sched_priority) { - *priority = ThreadPriority::REALTIME_AUDIO; - return true; - } -#endif - return false; -} - -} // namespace internal - -// static -void PlatformThread::SetName(const std::string& name) { - ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name); - tracked_objects::ThreadData::InitializeThreadContext(name); - -#if !defined(OS_NACL) - // On linux we can get the thread names to show up in the debugger by setting - // the process name for the LWP. We don't want to do this for the main - // thread because that would rename the process, causing tools like killall - // to stop working. - if (PlatformThread::CurrentId() == getpid()) - return; - - // http://0pointer.de/blog/projects/name-your-threads.html - // Set the name for the LWP (which gets truncated to 15 characters). - // Note that glibc also has a 'pthread_setname_np' api, but it may not be - // available everywhere and it's only benefit over using prctl directly is - // that it can set the name of threads other than the current thread. - int err = prctl(PR_SET_NAME, name.c_str()); - // We expect EPERM failures in sandboxed processes, just ignore those. - if (err < 0 && errno != EPERM) - DPLOG(ERROR) << "prctl(PR_SET_NAME)"; -#endif // !defined(OS_NACL) -} - -void InitThreading() {} - -void InitOnThread() {} - -void TerminateOnThread() {} - -size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) { -#if !defined(THREAD_SANITIZER) - return 0; -#else - // ThreadSanitizer bloats the stack heavily. Evidence has been that the - // default stack size isn't enough for some browser tests. - return 2 * (1 << 23); // 2 times 8192K (the default stack size on Linux). -#endif -} - -} // namespace base diff --git a/security/sandbox/chromium/base/threading/platform_thread_posix.cc b/security/sandbox/chromium/base/threading/platform_thread_posix.cc deleted file mode 100644 index 39a007316..000000000 --- a/security/sandbox/chromium/base/threading/platform_thread_posix.cc +++ /dev/null @@ -1,263 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/threading/platform_thread.h" - -#include <errno.h> -#include <pthread.h> -#include <sched.h> -#include <stddef.h> -#include <stdint.h> -#include <sys/resource.h> -#include <sys/time.h> - -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/threading/platform_thread_internal_posix.h" -#include "base/threading/thread_id_name_manager.h" -#include "base/threading/thread_restrictions.h" -#include "build/build_config.h" - -#if defined(OS_LINUX) -#include <sys/syscall.h> -#elif defined(OS_ANDROID) -#include <sys/types.h> -#endif - -namespace base { - -void InitThreading(); -void InitOnThread(); -void TerminateOnThread(); -size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes); - -namespace { - -struct ThreadParams { - ThreadParams() - : delegate(NULL), joinable(false), priority(ThreadPriority::NORMAL) {} - - PlatformThread::Delegate* delegate; - bool joinable; - ThreadPriority priority; -}; - -void* ThreadFunc(void* params) { - base::InitOnThread(); - - PlatformThread::Delegate* delegate = nullptr; - - { - scoped_ptr<ThreadParams> thread_params(static_cast<ThreadParams*>(params)); - - delegate = thread_params->delegate; - if (!thread_params->joinable) - base::ThreadRestrictions::SetSingletonAllowed(false); - - if (thread_params->priority != ThreadPriority::NORMAL) - PlatformThread::SetCurrentThreadPriority(thread_params->priority); - } - - ThreadIdNameManager::GetInstance()->RegisterThread( - PlatformThread::CurrentHandle().platform_handle(), - PlatformThread::CurrentId()); - - delegate->ThreadMain(); - - ThreadIdNameManager::GetInstance()->RemoveName( - PlatformThread::CurrentHandle().platform_handle(), - PlatformThread::CurrentId()); - - base::TerminateOnThread(); - return NULL; -} - -bool CreateThread(size_t stack_size, - bool joinable, - PlatformThread::Delegate* delegate, - PlatformThreadHandle* thread_handle, - ThreadPriority priority) { - DCHECK(thread_handle); - base::InitThreading(); - - pthread_attr_t attributes; - pthread_attr_init(&attributes); - - // Pthreads are joinable by default, so only specify the detached - // attribute if the thread should be non-joinable. - if (!joinable) - pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED); - - // Get a better default if available. - if (stack_size == 0) - stack_size = base::GetDefaultThreadStackSize(attributes); - - if (stack_size > 0) - pthread_attr_setstacksize(&attributes, stack_size); - - scoped_ptr<ThreadParams> params(new ThreadParams); - params->delegate = delegate; - params->joinable = joinable; - params->priority = priority; - - pthread_t handle; - int err = pthread_create(&handle, &attributes, ThreadFunc, params.get()); - bool success = !err; - if (success) { - // ThreadParams should be deleted on the created thread after used. - ignore_result(params.release()); - } else { - // Value of |handle| is undefined if pthread_create fails. - handle = 0; - errno = err; - PLOG(ERROR) << "pthread_create"; - } - *thread_handle = PlatformThreadHandle(handle); - - pthread_attr_destroy(&attributes); - - return success; -} - -} // namespace - -// static -PlatformThreadId PlatformThread::CurrentId() { - // Pthreads doesn't have the concept of a thread ID, so we have to reach down - // into the kernel. -#if defined(OS_MACOSX) - return pthread_mach_thread_np(pthread_self()); -#elif defined(OS_LINUX) - return syscall(__NR_gettid); -#elif defined(OS_ANDROID) - return gettid(); -#elif defined(OS_SOLARIS) || defined(OS_QNX) - return pthread_self(); -#elif defined(OS_NACL) && defined(__GLIBC__) - return pthread_self(); -#elif defined(OS_NACL) && !defined(__GLIBC__) - // Pointers are 32-bits in NaCl. - return reinterpret_cast<int32_t>(pthread_self()); -#elif defined(OS_POSIX) - return reinterpret_cast<int64_t>(pthread_self()); -#endif -} - -// static -PlatformThreadRef PlatformThread::CurrentRef() { - return PlatformThreadRef(pthread_self()); -} - -// static -PlatformThreadHandle PlatformThread::CurrentHandle() { - return PlatformThreadHandle(pthread_self()); -} - -// static -void PlatformThread::YieldCurrentThread() { - sched_yield(); -} - -// static -void PlatformThread::Sleep(TimeDelta duration) { - struct timespec sleep_time, remaining; - - // Break the duration into seconds and nanoseconds. - // NOTE: TimeDelta's microseconds are int64s while timespec's - // nanoseconds are longs, so this unpacking must prevent overflow. - sleep_time.tv_sec = duration.InSeconds(); - duration -= TimeDelta::FromSeconds(sleep_time.tv_sec); - sleep_time.tv_nsec = duration.InMicroseconds() * 1000; // nanoseconds - - while (nanosleep(&sleep_time, &remaining) == -1 && errno == EINTR) - sleep_time = remaining; -} - -// static -const char* PlatformThread::GetName() { - return ThreadIdNameManager::GetInstance()->GetName(CurrentId()); -} - -// static -bool PlatformThread::CreateWithPriority(size_t stack_size, Delegate* delegate, - PlatformThreadHandle* thread_handle, - ThreadPriority priority) { - return CreateThread(stack_size, true, // joinable thread - delegate, thread_handle, priority); -} - -// static -bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) { - PlatformThreadHandle unused; - - bool result = CreateThread(stack_size, false /* non-joinable thread */, - delegate, &unused, ThreadPriority::NORMAL); - return result; -} - -// static -void PlatformThread::Join(PlatformThreadHandle thread_handle) { - // Joining another thread may block the current thread for a long time, since - // the thread referred to by |thread_handle| may still be running long-lived / - // blocking tasks. - base::ThreadRestrictions::AssertIOAllowed(); - CHECK_EQ(0, pthread_join(thread_handle.platform_handle(), NULL)); -} - -// Mac has its own Set/GetCurrentThreadPriority() implementations. -#if !defined(OS_MACOSX) - -// static -void PlatformThread::SetCurrentThreadPriority(ThreadPriority priority) { -#if defined(OS_NACL) - NOTIMPLEMENTED(); -#else - if (internal::SetCurrentThreadPriorityForPlatform(priority)) - return; - - // setpriority(2) should change the whole thread group's (i.e. process) - // priority. However, as stated in the bugs section of - // http://man7.org/linux/man-pages/man2/getpriority.2.html: "under the current - // Linux/NPTL implementation of POSIX threads, the nice value is a per-thread - // attribute". Also, 0 is prefered to the current thread id since it is - // equivalent but makes sandboxing easier (https://crbug.com/399473). - const int nice_setting = internal::ThreadPriorityToNiceValue(priority); - if (setpriority(PRIO_PROCESS, 0, nice_setting)) { - DVPLOG(1) << "Failed to set nice value of thread (" - << PlatformThread::CurrentId() << ") to " << nice_setting; - } -#endif // defined(OS_NACL) -} - -// static -ThreadPriority PlatformThread::GetCurrentThreadPriority() { -#if defined(OS_NACL) - NOTIMPLEMENTED(); - return ThreadPriority::NORMAL; -#else - // Mirrors SetCurrentThreadPriority()'s implementation. - ThreadPriority platform_specific_priority; - if (internal::GetCurrentThreadPriorityForPlatform( - &platform_specific_priority)) { - return platform_specific_priority; - } - - // Need to clear errno before calling getpriority(): - // http://man7.org/linux/man-pages/man2/getpriority.2.html - errno = 0; - int nice_value = getpriority(PRIO_PROCESS, 0); - if (errno != 0) { - DVPLOG(1) << "Failed to get nice value of thread (" - << PlatformThread::CurrentId() << ")"; - return ThreadPriority::NORMAL; - } - - return internal::NiceValueToThreadPriority(nice_value); -#endif // !defined(OS_NACL) -} - -#endif // !defined(OS_MACOSX) - -} // namespace base diff --git a/security/sandbox/chromium/base/threading/platform_thread_win.cc b/security/sandbox/chromium/base/threading/platform_thread_win.cc deleted file mode 100644 index d5bd9bed0..000000000 --- a/security/sandbox/chromium/base/threading/platform_thread_win.cc +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/threading/platform_thread.h" - -#include <stddef.h> - -#include "base/debug/alias.h" -#include "base/debug/profiler.h" -#include "base/logging.h" -#include "base/threading/thread_id_name_manager.h" -#include "base/threading/thread_restrictions.h" -#include "base/tracked_objects.h" -#include "base/win/scoped_handle.h" -#include "base/win/windows_version.h" - -namespace base { - -namespace { - -// The information on how to set the thread name comes from -// a MSDN article: http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx -const DWORD kVCThreadNameException = 0x406D1388; - -typedef struct tagTHREADNAME_INFO { - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. -} THREADNAME_INFO; - -// This function has try handling, so it is separated out of its caller. -void SetNameInternal(PlatformThreadId thread_id, const char* name) { - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = name; - info.dwThreadID = thread_id; - info.dwFlags = 0; - - __try { - RaiseException(kVCThreadNameException, 0, sizeof(info)/sizeof(DWORD), - reinterpret_cast<DWORD_PTR*>(&info)); - } __except(EXCEPTION_CONTINUE_EXECUTION) { - } -} - -struct ThreadParams { - PlatformThread::Delegate* delegate; - bool joinable; - ThreadPriority priority; -}; - -DWORD __stdcall ThreadFunc(void* params) { - ThreadParams* thread_params = static_cast<ThreadParams*>(params); - PlatformThread::Delegate* delegate = thread_params->delegate; - if (!thread_params->joinable) - base::ThreadRestrictions::SetSingletonAllowed(false); - - if (thread_params->priority != ThreadPriority::NORMAL) - PlatformThread::SetCurrentThreadPriority(thread_params->priority); - - // Retrieve a copy of the thread handle to use as the key in the - // thread name mapping. - PlatformThreadHandle::Handle platform_handle; - BOOL did_dup = DuplicateHandle(GetCurrentProcess(), - GetCurrentThread(), - GetCurrentProcess(), - &platform_handle, - 0, - FALSE, - DUPLICATE_SAME_ACCESS); - - win::ScopedHandle scoped_platform_handle; - - if (did_dup) { - scoped_platform_handle.Set(platform_handle); - ThreadIdNameManager::GetInstance()->RegisterThread( - scoped_platform_handle.Get(), - PlatformThread::CurrentId()); - } - - delete thread_params; - delegate->ThreadMain(); - - if (did_dup) { - ThreadIdNameManager::GetInstance()->RemoveName( - scoped_platform_handle.Get(), - PlatformThread::CurrentId()); - } - - return 0; -} - -// CreateThreadInternal() matches PlatformThread::CreateWithPriority(), except -// that |out_thread_handle| may be nullptr, in which case a non-joinable thread -// is created. -bool CreateThreadInternal(size_t stack_size, - PlatformThread::Delegate* delegate, - PlatformThreadHandle* out_thread_handle, - ThreadPriority priority) { - unsigned int flags = 0; - if (stack_size > 0 && base::win::GetVersion() >= base::win::VERSION_XP) { - flags = STACK_SIZE_PARAM_IS_A_RESERVATION; - } else { - stack_size = 0; - } - - ThreadParams* params = new ThreadParams; - params->delegate = delegate; - params->joinable = out_thread_handle != nullptr; - params->priority = priority; - - // Using CreateThread here vs _beginthreadex makes thread creation a bit - // faster and doesn't require the loader lock to be available. Our code will - // have to work running on CreateThread() threads anyway, since we run code - // on the Windows thread pool, etc. For some background on the difference: - // http://www.microsoft.com/msj/1099/win32/win321099.aspx - void* thread_handle = - ::CreateThread(nullptr, stack_size, ThreadFunc, params, flags, nullptr); - if (!thread_handle) { - delete params; - return false; - } - - if (out_thread_handle) - *out_thread_handle = PlatformThreadHandle(thread_handle); - else - CloseHandle(thread_handle); - return true; -} - -} // namespace - -// static -PlatformThreadId PlatformThread::CurrentId() { - return ::GetCurrentThreadId(); -} - -// static -PlatformThreadRef PlatformThread::CurrentRef() { - return PlatformThreadRef(::GetCurrentThreadId()); -} - -// static -PlatformThreadHandle PlatformThread::CurrentHandle() { - return PlatformThreadHandle(::GetCurrentThread()); -} - -// static -void PlatformThread::YieldCurrentThread() { - ::Sleep(0); -} - -// static -void PlatformThread::Sleep(TimeDelta duration) { - // When measured with a high resolution clock, Sleep() sometimes returns much - // too early. We may need to call it repeatedly to get the desired duration. - TimeTicks end = TimeTicks::Now() + duration; - for (TimeTicks now = TimeTicks::Now(); now < end; now = TimeTicks::Now()) - ::Sleep(static_cast<DWORD>((end - now).InMillisecondsRoundedUp())); -} - -// static -void PlatformThread::SetName(const std::string& name) { - ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name); - - // On Windows only, we don't need to tell the profiler about the "BrokerEvent" - // thread, as it exists only in the chrome.exe image, and never spawns or runs - // tasks (items which could be profiled). This test avoids the notification, - // which would also (as a side effect) initialize the profiler in this unused - // context, including setting up thread local storage, etc. The performance - // impact is not terrible, but there is no reason to do initialize it. - if (name != "BrokerEvent") - tracked_objects::ThreadData::InitializeThreadContext(name); - - // The debugger needs to be around to catch the name in the exception. If - // there isn't a debugger, we are just needlessly throwing an exception. - // If this image file is instrumented, we raise the exception anyway - // to provide the profiler with human-readable thread names. - if (!::IsDebuggerPresent() && !base::debug::IsBinaryInstrumented()) - return; - - SetNameInternal(CurrentId(), name.c_str()); -} - -// static -const char* PlatformThread::GetName() { - return ThreadIdNameManager::GetInstance()->GetName(CurrentId()); -} - -// static -bool PlatformThread::CreateWithPriority(size_t stack_size, Delegate* delegate, - PlatformThreadHandle* thread_handle, - ThreadPriority priority) { - DCHECK(thread_handle); - return CreateThreadInternal(stack_size, delegate, thread_handle, priority); -} - -// static -bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) { - return CreateThreadInternal(stack_size, delegate, nullptr, - ThreadPriority::NORMAL); -} - -// static -void PlatformThread::Join(PlatformThreadHandle thread_handle) { - DCHECK(thread_handle.platform_handle()); - // TODO(willchan): Enable this check once I can get it to work for Windows - // shutdown. - // Joining another thread may block the current thread for a long time, since - // the thread referred to by |thread_handle| may still be running long-lived / - // blocking tasks. -#if 0 - base::ThreadRestrictions::AssertIOAllowed(); -#endif - - // Wait for the thread to exit. It should already have terminated but make - // sure this assumption is valid. - DWORD result = WaitForSingleObject(thread_handle.platform_handle(), INFINITE); - if (result != WAIT_OBJECT_0) { - // Debug info for bug 127931. - DWORD error = GetLastError(); - debug::Alias(&error); - debug::Alias(&result); - CHECK(false); - } - - CloseHandle(thread_handle.platform_handle()); -} - -// static -void PlatformThread::SetCurrentThreadPriority(ThreadPriority priority) { - int desired_priority = THREAD_PRIORITY_ERROR_RETURN; - switch (priority) { - case ThreadPriority::BACKGROUND: - desired_priority = THREAD_PRIORITY_LOWEST; - break; - case ThreadPriority::NORMAL: - desired_priority = THREAD_PRIORITY_NORMAL; - break; - case ThreadPriority::DISPLAY: - desired_priority = THREAD_PRIORITY_ABOVE_NORMAL; - break; - case ThreadPriority::REALTIME_AUDIO: - desired_priority = THREAD_PRIORITY_TIME_CRITICAL; - break; - default: - NOTREACHED() << "Unknown priority."; - break; - } - DCHECK_NE(desired_priority, THREAD_PRIORITY_ERROR_RETURN); - -#ifndef NDEBUG - const BOOL success = -#endif - ::SetThreadPriority(PlatformThread::CurrentHandle().platform_handle(), - desired_priority); - DPLOG_IF(ERROR, !success) << "Failed to set thread priority to " - << desired_priority; -} - -// static -ThreadPriority PlatformThread::GetCurrentThreadPriority() { - int priority = - ::GetThreadPriority(PlatformThread::CurrentHandle().platform_handle()); - switch (priority) { - case THREAD_PRIORITY_LOWEST: - return ThreadPriority::BACKGROUND; - case THREAD_PRIORITY_NORMAL: - return ThreadPriority::NORMAL; - case THREAD_PRIORITY_ABOVE_NORMAL: - return ThreadPriority::DISPLAY; - case THREAD_PRIORITY_TIME_CRITICAL: - return ThreadPriority::REALTIME_AUDIO; - case THREAD_PRIORITY_ERROR_RETURN: - DPCHECK(false) << "GetThreadPriority error"; // Falls through. - default: - NOTREACHED() << "Unexpected priority: " << priority; - return ThreadPriority::NORMAL; - } -} - -} // namespace base diff --git a/security/sandbox/chromium/base/threading/sequenced_worker_pool.h b/security/sandbox/chromium/base/threading/sequenced_worker_pool.h deleted file mode 100644 index ba0e44421..000000000 --- a/security/sandbox/chromium/base/threading/sequenced_worker_pool.h +++ /dev/null @@ -1,384 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_THREADING_SEQUENCED_WORKER_POOL_H_ -#define BASE_THREADING_SEQUENCED_WORKER_POOL_H_ - -#include <stddef.h> - -#include <cstddef> -#include <string> - -#include "base/base_export.h" -#include "base/callback_forward.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/single_thread_task_runner.h" -#include "base/task_runner.h" - -namespace tracked_objects { -class Location; -} // namespace tracked_objects - -namespace base { - -class SingleThreadTaskRunner; - -template <class T> class DeleteHelper; - -class SequencedTaskRunner; - -// A worker thread pool that enforces ordering between sets of tasks. It also -// allows you to specify what should happen to your tasks on shutdown. -// -// To enforce ordering, get a unique sequence token from the pool and post all -// tasks you want to order with the token. All tasks with the same token are -// guaranteed to execute serially, though not necessarily on the same thread. -// This means that: -// -// - No two tasks with the same token will run at the same time. -// -// - Given two tasks T1 and T2 with the same token such that T2 will -// run after T1, then T2 will start after T1 is destroyed. -// -// - If T2 will run after T1, then all memory changes in T1 and T1's -// destruction will be visible to T2. -// -// Example: -// SequencedWorkerPool::SequenceToken token = -// SequencedWorkerPool::GetSequenceToken(); -// pool.PostSequencedWorkerTask(token, SequencedWorkerPool::SKIP_ON_SHUTDOWN, -// FROM_HERE, base::Bind(...)); -// pool.PostSequencedWorkerTask(token, SequencedWorkerPool::SKIP_ON_SHUTDOWN, -// FROM_HERE, base::Bind(...)); -// -// You can make named sequence tokens to make it easier to share a token -// across different components. -// -// You can also post tasks to the pool without ordering using PostWorkerTask. -// These will be executed in an unspecified order. The order of execution -// between tasks with different sequence tokens is also unspecified. -// -// This class may be leaked on shutdown to facilitate fast shutdown. The -// expected usage, however, is to call Shutdown(), which correctly accounts -// for CONTINUE_ON_SHUTDOWN behavior and is required for BLOCK_SHUTDOWN -// behavior. -// -// Implementation note: This does not use a base::WorkerPool since that does -// not enforce shutdown semantics or allow us to specify how many worker -// threads to run. For the typical use case of random background work, we don't -// necessarily want to be super aggressive about creating threads. -// -// Note that SequencedWorkerPool is RefCountedThreadSafe (inherited -// from TaskRunner). -// -// Test-only code should wrap this in a base::SequencedWorkerPoolOwner to avoid -// memory leaks. See http://crbug.com/273800 -class BASE_EXPORT SequencedWorkerPool : public TaskRunner { - public: - // Defines what should happen to a task posted to the worker pool on - // shutdown. - enum WorkerShutdown { - // Tasks posted with this mode which have not run at shutdown will be - // deleted rather than run, and any tasks with this mode running at - // shutdown will be ignored (the worker thread will not be joined). - // - // This option provides a nice way to post stuff you don't want blocking - // shutdown. For example, you might be doing a slow DNS lookup and if it's - // blocked on the OS, you may not want to stop shutdown, since the result - // doesn't really matter at that point. - // - // However, you need to be very careful what you do in your callback when - // you use this option. Since the thread will continue to run until the OS - // terminates the process, the app can be in the process of tearing down - // when you're running. This means any singletons or global objects you - // use may suddenly become invalid out from under you. For this reason, - // it's best to use this only for slow but simple operations like the DNS - // example. - CONTINUE_ON_SHUTDOWN, - - // Tasks posted with this mode that have not started executing at - // shutdown will be deleted rather than executed. However, any tasks that - // have already begun executing when shutdown is called will be allowed - // to continue, and will block shutdown until completion. - // - // Note: Because Shutdown() may block while these tasks are executing, - // care must be taken to ensure that they do not block on the thread that - // called Shutdown(), as this may lead to deadlock. - SKIP_ON_SHUTDOWN, - - // Tasks posted with this mode will block shutdown until they're - // executed. Since this can have significant performance implications, - // use sparingly. - // - // Generally, this should be used only for user data, for example, a task - // writing a preference file. - // - // If a task is posted during shutdown, it will not get run since the - // workers may already be stopped. In this case, the post operation will - // fail (return false) and the task will be deleted. - BLOCK_SHUTDOWN, - }; - - // Opaque identifier that defines sequencing of tasks posted to the worker - // pool. - class BASE_EXPORT SequenceToken { - public: - SequenceToken() : id_(0) {} - ~SequenceToken() {} - - bool Equals(const SequenceToken& other) const { - return id_ == other.id_; - } - - // Returns false if current thread is executing an unsequenced task. - bool IsValid() const { - return id_ != 0; - } - - // Returns a string representation of this token. This method should only be - // used for debugging. - std::string ToString() const; - - private: - friend class SequencedWorkerPool; - - explicit SequenceToken(int id) : id_(id) {} - - int id_; - }; - - // Allows tests to perform certain actions. - class TestingObserver { - public: - virtual ~TestingObserver() {} - virtual void OnHasWork() = 0; - virtual void WillWaitForShutdown() = 0; - virtual void OnDestruct() = 0; - }; - - // Gets the SequencedToken of the current thread. - // If current thread is not a SequencedWorkerPool worker thread or is running - // an unsequenced task, returns an invalid SequenceToken. - static SequenceToken GetSequenceTokenForCurrentThread(); - - // Gets a SequencedTaskRunner for the current thread. If the current thread is - // running an unsequenced task, a new SequenceToken will be generated and set, - // so that the returned SequencedTaskRunner is guaranteed to run tasks after - // the current task has finished running. - static scoped_refptr<SequencedTaskRunner> - GetSequencedTaskRunnerForCurrentThread(); - - // Returns a unique token that can be used to sequence tasks posted to - // PostSequencedWorkerTask(). Valid tokens are always nonzero. - // TODO(bauerb): Rename this to better differentiate from - // GetSequenceTokenForCurrentThread(). - static SequenceToken GetSequenceToken(); - - // Returns the SequencedWorkerPool that owns this thread, or null if the - // current thread is not a SequencedWorkerPool worker thread. - static scoped_refptr<SequencedWorkerPool> GetWorkerPoolForCurrentThread(); - - // When constructing a SequencedWorkerPool, there must be a - // ThreadTaskRunnerHandle on the current thread unless you plan to - // deliberately leak it. - - // Pass the maximum number of threads (they will be lazily created as needed) - // and a prefix for the thread name to aid in debugging. - SequencedWorkerPool(size_t max_threads, - const std::string& thread_name_prefix); - - // Like above, but with |observer| for testing. Does not take ownership of - // |observer|. - SequencedWorkerPool(size_t max_threads, - const std::string& thread_name_prefix, - TestingObserver* observer); - - // Returns the sequence token associated with the given name. Calling this - // function multiple times with the same string will always produce the - // same sequence token. If the name has not been used before, a new token - // will be created. - SequenceToken GetNamedSequenceToken(const std::string& name); - - // Returns a SequencedTaskRunner wrapper which posts to this - // SequencedWorkerPool using the given sequence token. Tasks with nonzero - // delay are posted with SKIP_ON_SHUTDOWN behavior and tasks with zero delay - // are posted with BLOCK_SHUTDOWN behavior. - scoped_refptr<SequencedTaskRunner> GetSequencedTaskRunner( - SequenceToken token); - - // Returns a SequencedTaskRunner wrapper which posts to this - // SequencedWorkerPool using the given sequence token. Tasks with nonzero - // delay are posted with SKIP_ON_SHUTDOWN behavior and tasks with zero delay - // are posted with the given shutdown behavior. - scoped_refptr<SequencedTaskRunner> GetSequencedTaskRunnerWithShutdownBehavior( - SequenceToken token, - WorkerShutdown shutdown_behavior); - - // Returns a TaskRunner wrapper which posts to this SequencedWorkerPool using - // the given shutdown behavior. Tasks with nonzero delay are posted with - // SKIP_ON_SHUTDOWN behavior and tasks with zero delay are posted with the - // given shutdown behavior. - scoped_refptr<TaskRunner> GetTaskRunnerWithShutdownBehavior( - WorkerShutdown shutdown_behavior); - - // Posts the given task for execution in the worker pool. Tasks posted with - // this function will execute in an unspecified order on a background thread. - // Returns true if the task was posted. If your tasks have ordering - // requirements, see PostSequencedWorkerTask(). - // - // This class will attempt to delete tasks that aren't run - // (non-block-shutdown semantics) but can't guarantee that this happens. If - // all worker threads are busy running CONTINUE_ON_SHUTDOWN tasks, there - // will be no workers available to delete these tasks. And there may be - // tasks with the same sequence token behind those CONTINUE_ON_SHUTDOWN - // tasks. Deleting those tasks before the previous one has completed could - // cause nondeterministic crashes because the task could be keeping some - // objects alive which do work in their destructor, which could voilate the - // assumptions of the running task. - // - // The task will be guaranteed to run to completion before shutdown - // (BLOCK_SHUTDOWN semantics). - // - // Returns true if the task was posted successfully. This may fail during - // shutdown regardless of the specified ShutdownBehavior. - bool PostWorkerTask(const tracked_objects::Location& from_here, - const Closure& task); - - // Same as PostWorkerTask but allows a delay to be specified (although doing - // so changes the shutdown behavior). The task will be run after the given - // delay has elapsed. - // - // If the delay is nonzero, the task won't be guaranteed to run to completion - // before shutdown (SKIP_ON_SHUTDOWN semantics) to avoid shutdown hangs. - // If the delay is zero, this behaves exactly like PostWorkerTask, i.e. the - // task will be guaranteed to run to completion before shutdown - // (BLOCK_SHUTDOWN semantics). - bool PostDelayedWorkerTask(const tracked_objects::Location& from_here, - const Closure& task, - TimeDelta delay); - - // Same as PostWorkerTask but allows specification of the shutdown behavior. - bool PostWorkerTaskWithShutdownBehavior( - const tracked_objects::Location& from_here, - const Closure& task, - WorkerShutdown shutdown_behavior); - - // Like PostWorkerTask above, but provides sequencing semantics. This means - // that tasks posted with the same sequence token (see GetSequenceToken()) - // are guaranteed to execute in order. This is useful in cases where you're - // doing operations that may depend on previous ones, like appending to a - // file. - // - // The task will be guaranteed to run to completion before shutdown - // (BLOCK_SHUTDOWN semantics). - // - // Returns true if the task was posted successfully. This may fail during - // shutdown regardless of the specified ShutdownBehavior. - bool PostSequencedWorkerTask(SequenceToken sequence_token, - const tracked_objects::Location& from_here, - const Closure& task); - - // Like PostSequencedWorkerTask above, but allows you to specify a named - // token, which saves an extra call to GetNamedSequenceToken. - bool PostNamedSequencedWorkerTask(const std::string& token_name, - const tracked_objects::Location& from_here, - const Closure& task); - - // Same as PostSequencedWorkerTask but allows a delay to be specified - // (although doing so changes the shutdown behavior). The task will be run - // after the given delay has elapsed. - // - // If the delay is nonzero, the task won't be guaranteed to run to completion - // before shutdown (SKIP_ON_SHUTDOWN semantics) to avoid shutdown hangs. - // If the delay is zero, this behaves exactly like PostSequencedWorkerTask, - // i.e. the task will be guaranteed to run to completion before shutdown - // (BLOCK_SHUTDOWN semantics). - bool PostDelayedSequencedWorkerTask( - SequenceToken sequence_token, - const tracked_objects::Location& from_here, - const Closure& task, - TimeDelta delay); - - // Same as PostSequencedWorkerTask but allows specification of the shutdown - // behavior. - bool PostSequencedWorkerTaskWithShutdownBehavior( - SequenceToken sequence_token, - const tracked_objects::Location& from_here, - const Closure& task, - WorkerShutdown shutdown_behavior); - - // TaskRunner implementation. Forwards to PostDelayedWorkerTask(). - bool PostDelayedTask(const tracked_objects::Location& from_here, - const Closure& task, - TimeDelta delay) override; - bool RunsTasksOnCurrentThread() const override; - - // Returns true if the current thread is processing a task with the given - // sequence_token. - bool IsRunningSequenceOnCurrentThread(SequenceToken sequence_token) const; - - // Returns true if any thread is currently processing a task with the given - // sequence token. Should only be called with a valid sequence token. - bool IsRunningSequence(SequenceToken sequence_token) const; - - // Blocks until all pending tasks are complete. This should only be called in - // unit tests when you want to validate something that should have happened. - // This will not flush delayed tasks; delayed tasks get deleted. - // - // Note that calling this will not prevent other threads from posting work to - // the queue while the calling thread is waiting on Flush(). In this case, - // Flush will return only when there's no more work in the queue. Normally, - // this doesn't come up since in a test, all the work is being posted from - // the main thread. - void FlushForTesting(); - - // Spuriously signal that there is work to be done. - void SignalHasWorkForTesting(); - - // Implements the worker pool shutdown. This should be called during app - // shutdown, and will discard/join with appropriate tasks before returning. - // After this call, subsequent calls to post tasks will fail. - // - // Must be called from the same thread this object was constructed on. - void Shutdown() { Shutdown(0); } - - // A variant that allows an arbitrary number of new blocking tasks to be - // posted during shutdown. The tasks cannot be posted within the execution - // context of tasks whose shutdown behavior is not BLOCKING_SHUTDOWN. Once - // the limit is reached, subsequent calls to post task fail in all cases. - // Must be called from the same thread this object was constructed on. - void Shutdown(int max_new_blocking_tasks_after_shutdown); - - // Check if Shutdown was called for given threading pool. This method is used - // for aborting time consuming operation to avoid blocking shutdown. - // - // Can be called from any thread. - bool IsShutdownInProgress(); - - protected: - ~SequencedWorkerPool() override; - - void OnDestruct() const override; - - private: - friend class RefCountedThreadSafe<SequencedWorkerPool>; - friend class DeleteHelper<SequencedWorkerPool>; - - class Inner; - class Worker; - - const scoped_refptr<SingleThreadTaskRunner> constructor_task_runner_; - - // Avoid pulling in too many headers by putting (almost) everything - // into |inner_|. - const scoped_ptr<Inner> inner_; - - DISALLOW_COPY_AND_ASSIGN(SequencedWorkerPool); -}; - -} // namespace base - -#endif // BASE_THREADING_SEQUENCED_WORKER_POOL_H_ diff --git a/security/sandbox/chromium/base/threading/thread_checker_impl.h b/security/sandbox/chromium/base/threading/thread_checker_impl.h deleted file mode 100644 index c92e143db..000000000 --- a/security/sandbox/chromium/base/threading/thread_checker_impl.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_THREADING_THREAD_CHECKER_IMPL_H_ -#define BASE_THREADING_THREAD_CHECKER_IMPL_H_ - -#include "base/base_export.h" -#include "base/compiler_specific.h" -#include "base/synchronization/lock.h" -#include "base/threading/platform_thread.h" - -namespace base { - -// Real implementation of ThreadChecker, for use in debug mode, or -// for temporary use in release mode (e.g. to CHECK on a threading issue -// seen only in the wild). -// -// Note: You should almost always use the ThreadChecker class to get the -// right version for your build configuration. -class BASE_EXPORT ThreadCheckerImpl { - public: - ThreadCheckerImpl(); - ~ThreadCheckerImpl(); - - bool CalledOnValidThread() const WARN_UNUSED_RESULT; - - // Changes the thread that is checked for in CalledOnValidThread. This may - // be useful when an object may be created on one thread and then used - // exclusively on another thread. - void DetachFromThread(); - - private: - void EnsureThreadIdAssigned() const; - - mutable base::Lock lock_; - // This is mutable so that CalledOnValidThread can set it. - // It's guarded by |lock_|. - mutable PlatformThreadRef valid_thread_id_; -}; - -} // namespace base - -#endif // BASE_THREADING_THREAD_CHECKER_IMPL_H_ diff --git a/security/sandbox/chromium/base/threading/thread_collision_warner.cc b/security/sandbox/chromium/base/threading/thread_collision_warner.cc deleted file mode 100644 index 547e11ca6..000000000 --- a/security/sandbox/chromium/base/threading/thread_collision_warner.cc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/threading/thread_collision_warner.h" - -#include "base/logging.h" -#include "base/threading/platform_thread.h" - -namespace base { - -void DCheckAsserter::warn() { - NOTREACHED() << "Thread Collision"; -} - -static subtle::Atomic32 CurrentThread() { - const PlatformThreadId current_thread_id = PlatformThread::CurrentId(); - // We need to get the thread id into an atomic data type. This might be a - // truncating conversion, but any loss-of-information just increases the - // chance of a fault negative, not a false positive. - const subtle::Atomic32 atomic_thread_id = - static_cast<subtle::Atomic32>(current_thread_id); - - return atomic_thread_id; -} - -void ThreadCollisionWarner::EnterSelf() { - // If the active thread is 0 then I'll write the current thread ID - // if two or more threads arrive here only one will succeed to - // write on valid_thread_id_ the current thread ID. - subtle::Atomic32 current_thread_id = CurrentThread(); - - int previous_value = subtle::NoBarrier_CompareAndSwap(&valid_thread_id_, - 0, - current_thread_id); - if (previous_value != 0 && previous_value != current_thread_id) { - // gotcha! a thread is trying to use the same class and that is - // not current thread. - asserter_->warn(); - } - - subtle::NoBarrier_AtomicIncrement(&counter_, 1); -} - -void ThreadCollisionWarner::Enter() { - subtle::Atomic32 current_thread_id = CurrentThread(); - - if (subtle::NoBarrier_CompareAndSwap(&valid_thread_id_, - 0, - current_thread_id) != 0) { - // gotcha! another thread is trying to use the same class. - asserter_->warn(); - } - - subtle::NoBarrier_AtomicIncrement(&counter_, 1); -} - -void ThreadCollisionWarner::Leave() { - if (subtle::Barrier_AtomicIncrement(&counter_, -1) == 0) { - subtle::NoBarrier_Store(&valid_thread_id_, 0); - } -} - -} // namespace base diff --git a/security/sandbox/chromium/base/threading/thread_collision_warner.h b/security/sandbox/chromium/base/threading/thread_collision_warner.h deleted file mode 100644 index 4699a910d..000000000 --- a/security/sandbox/chromium/base/threading/thread_collision_warner.h +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_THREADING_THREAD_COLLISION_WARNER_H_ -#define BASE_THREADING_THREAD_COLLISION_WARNER_H_ - -#include <memory> - -#include "base/atomicops.h" -#include "base/base_export.h" -#include "base/compiler_specific.h" -#include "base/macros.h" - -// A helper class alongside macros to be used to verify assumptions about thread -// safety of a class. -// -// Example: Queue implementation non thread-safe but still usable if clients -// are synchronized somehow. -// -// In this case the macro DFAKE_SCOPED_LOCK has to be -// used, it checks that if a thread is inside the push/pop then -// noone else is still inside the pop/push -// -// class NonThreadSafeQueue { -// public: -// ... -// void push(int) { DFAKE_SCOPED_LOCK(push_pop_); ... } -// int pop() { DFAKE_SCOPED_LOCK(push_pop_); ... } -// ... -// private: -// DFAKE_MUTEX(push_pop_); -// }; -// -// -// Example: Queue implementation non thread-safe but still usable if clients -// are synchronized somehow, it calls a method to "protect" from -// a "protected" method -// -// In this case the macro DFAKE_SCOPED_RECURSIVE_LOCK -// has to be used, it checks that if a thread is inside the push/pop -// then noone else is still inside the pop/push -// -// class NonThreadSafeQueue { -// public: -// void push(int) { -// DFAKE_SCOPED_LOCK(push_pop_); -// ... -// } -// int pop() { -// DFAKE_SCOPED_RECURSIVE_LOCK(push_pop_); -// bar(); -// ... -// } -// void bar() { DFAKE_SCOPED_RECURSIVE_LOCK(push_pop_); ... } -// ... -// private: -// DFAKE_MUTEX(push_pop_); -// }; -// -// -// Example: Queue implementation not usable even if clients are synchronized, -// so only one thread in the class life cycle can use the two members -// push/pop. -// -// In this case the macro DFAKE_SCOPED_LOCK_THREAD_LOCKED pins the -// specified -// critical section the first time a thread enters push or pop, from -// that time on only that thread is allowed to execute push or pop. -// -// class NonThreadSafeQueue { -// public: -// ... -// void push(int) { DFAKE_SCOPED_LOCK_THREAD_LOCKED(push_pop_); ... } -// int pop() { DFAKE_SCOPED_LOCK_THREAD_LOCKED(push_pop_); ... } -// ... -// private: -// DFAKE_MUTEX(push_pop_); -// }; -// -// -// Example: Class that has to be contructed/destroyed on same thread, it has -// a "shareable" method (with external synchronization) and a not -// shareable method (even with external synchronization). -// -// In this case 3 Critical sections have to be defined -// -// class ExoticClass { -// public: -// ExoticClass() { DFAKE_SCOPED_LOCK_THREAD_LOCKED(ctor_dtor_); ... } -// ~ExoticClass() { DFAKE_SCOPED_LOCK_THREAD_LOCKED(ctor_dtor_); ... } -// -// void Shareable() { DFAKE_SCOPED_LOCK(shareable_section_); ... } -// void NotShareable() { DFAKE_SCOPED_LOCK_THREAD_LOCKED(ctor_dtor_); ... } -// ... -// private: -// DFAKE_MUTEX(ctor_dtor_); -// DFAKE_MUTEX(shareable_section_); -// }; - - -#if !defined(NDEBUG) - -// Defines a class member that acts like a mutex. It is used only as a -// verification tool. -#define DFAKE_MUTEX(obj) \ - mutable base::ThreadCollisionWarner obj -// Asserts the call is never called simultaneously in two threads. Used at -// member function scope. -#define DFAKE_SCOPED_LOCK(obj) \ - base::ThreadCollisionWarner::ScopedCheck s_check_##obj(&obj) -// Asserts the call is never called simultaneously in two threads. Used at -// member function scope. Same as DFAKE_SCOPED_LOCK but allows recursive locks. -#define DFAKE_SCOPED_RECURSIVE_LOCK(obj) \ - base::ThreadCollisionWarner::ScopedRecursiveCheck sr_check_##obj(&obj) -// Asserts the code is always executed in the same thread. -#define DFAKE_SCOPED_LOCK_THREAD_LOCKED(obj) \ - base::ThreadCollisionWarner::Check check_##obj(&obj) - -#else - -#define DFAKE_MUTEX(obj) typedef void InternalFakeMutexType##obj -#define DFAKE_SCOPED_LOCK(obj) ((void)0) -#define DFAKE_SCOPED_RECURSIVE_LOCK(obj) ((void)0) -#define DFAKE_SCOPED_LOCK_THREAD_LOCKED(obj) ((void)0) - -#endif - -namespace base { - -// The class ThreadCollisionWarner uses an Asserter to notify the collision -// AsserterBase is the interfaces and DCheckAsserter is the default asserter -// used. During the unit tests is used another class that doesn't "DCHECK" -// in case of collision (check thread_collision_warner_unittests.cc) -struct BASE_EXPORT AsserterBase { - virtual ~AsserterBase() {} - virtual void warn() = 0; -}; - -struct BASE_EXPORT DCheckAsserter : public AsserterBase { - ~DCheckAsserter() override {} - void warn() override; -}; - -class BASE_EXPORT ThreadCollisionWarner { - public: - // The parameter asserter is there only for test purpose - explicit ThreadCollisionWarner(AsserterBase* asserter = new DCheckAsserter()) - : valid_thread_id_(0), - counter_(0), - asserter_(asserter) {} - - ~ThreadCollisionWarner() { - delete asserter_; - } - - // This class is meant to be used through the macro - // DFAKE_SCOPED_LOCK_THREAD_LOCKED - // it doesn't leave the critical section, as opposed to ScopedCheck, - // because the critical section being pinned is allowed to be used only - // from one thread - class BASE_EXPORT Check { - public: - explicit Check(ThreadCollisionWarner* warner) - : warner_(warner) { - warner_->EnterSelf(); - } - - ~Check() {} - - private: - ThreadCollisionWarner* warner_; - - DISALLOW_COPY_AND_ASSIGN(Check); - }; - - // This class is meant to be used through the macro - // DFAKE_SCOPED_LOCK - class BASE_EXPORT ScopedCheck { - public: - explicit ScopedCheck(ThreadCollisionWarner* warner) - : warner_(warner) { - warner_->Enter(); - } - - ~ScopedCheck() { - warner_->Leave(); - } - - private: - ThreadCollisionWarner* warner_; - - DISALLOW_COPY_AND_ASSIGN(ScopedCheck); - }; - - // This class is meant to be used through the macro - // DFAKE_SCOPED_RECURSIVE_LOCK - class BASE_EXPORT ScopedRecursiveCheck { - public: - explicit ScopedRecursiveCheck(ThreadCollisionWarner* warner) - : warner_(warner) { - warner_->EnterSelf(); - } - - ~ScopedRecursiveCheck() { - warner_->Leave(); - } - - private: - ThreadCollisionWarner* warner_; - - DISALLOW_COPY_AND_ASSIGN(ScopedRecursiveCheck); - }; - - private: - // This method stores the current thread identifier and does a DCHECK - // if a another thread has already done it, it is safe if same thread - // calls this multiple time (recursion allowed). - void EnterSelf(); - - // Same as EnterSelf but recursion is not allowed. - void Enter(); - - // Removes the thread_id stored in order to allow other threads to - // call EnterSelf or Enter. - void Leave(); - - // This stores the thread id that is inside the critical section, if the - // value is 0 then no thread is inside. - volatile subtle::Atomic32 valid_thread_id_; - - // Counter to trace how many time a critical section was "pinned" - // (when allowed) in order to unpin it when counter_ reaches 0. - volatile subtle::Atomic32 counter_; - - // Here only for class unit tests purpose, during the test I need to not - // DCHECK but notify the collision with something else. - AsserterBase* asserter_; - - DISALLOW_COPY_AND_ASSIGN(ThreadCollisionWarner); -}; - -} // namespace base - -#endif // BASE_THREADING_THREAD_COLLISION_WARNER_H_ diff --git a/security/sandbox/chromium/base/threading/thread_id_name_manager.cc b/security/sandbox/chromium/base/threading/thread_id_name_manager.cc deleted file mode 100644 index 56cfa273a..000000000 --- a/security/sandbox/chromium/base/threading/thread_id_name_manager.cc +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/threading/thread_id_name_manager.h" - -#include <stdlib.h> -#include <string.h> - -#include "base/logging.h" -#include "base/memory/singleton.h" -#include "base/strings/string_util.h" - -namespace base { -namespace { - -static const char kDefaultName[] = ""; -static std::string* g_default_name; - -} - -ThreadIdNameManager::ThreadIdNameManager() - : main_process_name_(NULL), - main_process_id_(kInvalidThreadId) { - g_default_name = new std::string(kDefaultName); - - AutoLock locked(lock_); - name_to_interned_name_[kDefaultName] = g_default_name; -} - -ThreadIdNameManager::~ThreadIdNameManager() { -} - -ThreadIdNameManager* ThreadIdNameManager::GetInstance() { - return Singleton<ThreadIdNameManager, - LeakySingletonTraits<ThreadIdNameManager> >::get(); -} - -const char* ThreadIdNameManager::GetDefaultInternedString() { - return g_default_name->c_str(); -} - -void ThreadIdNameManager::RegisterThread(PlatformThreadHandle::Handle handle, - PlatformThreadId id) { - AutoLock locked(lock_); - thread_id_to_handle_[id] = handle; - thread_handle_to_interned_name_[handle] = - name_to_interned_name_[kDefaultName]; -} - -void ThreadIdNameManager::SetName(PlatformThreadId id, - const std::string& name) { - AutoLock locked(lock_); - NameToInternedNameMap::iterator iter = name_to_interned_name_.find(name); - std::string* leaked_str = NULL; - if (iter != name_to_interned_name_.end()) { - leaked_str = iter->second; - } else { - leaked_str = new std::string(name); - name_to_interned_name_[name] = leaked_str; - } - - ThreadIdToHandleMap::iterator id_to_handle_iter = - thread_id_to_handle_.find(id); - - // The main thread of a process will not be created as a Thread object which - // means there is no PlatformThreadHandler registered. - if (id_to_handle_iter == thread_id_to_handle_.end()) { - main_process_name_ = leaked_str; - main_process_id_ = id; - return; - } - thread_handle_to_interned_name_[id_to_handle_iter->second] = leaked_str; -} - -const char* ThreadIdNameManager::GetName(PlatformThreadId id) { - AutoLock locked(lock_); - - if (id == main_process_id_) - return main_process_name_->c_str(); - - ThreadIdToHandleMap::iterator id_to_handle_iter = - thread_id_to_handle_.find(id); - if (id_to_handle_iter == thread_id_to_handle_.end()) - return name_to_interned_name_[kDefaultName]->c_str(); - - ThreadHandleToInternedNameMap::iterator handle_to_name_iter = - thread_handle_to_interned_name_.find(id_to_handle_iter->second); - return handle_to_name_iter->second->c_str(); -} - -void ThreadIdNameManager::RemoveName(PlatformThreadHandle::Handle handle, - PlatformThreadId id) { - AutoLock locked(lock_); - ThreadHandleToInternedNameMap::iterator handle_to_name_iter = - thread_handle_to_interned_name_.find(handle); - - DCHECK(handle_to_name_iter != thread_handle_to_interned_name_.end()); - thread_handle_to_interned_name_.erase(handle_to_name_iter); - - ThreadIdToHandleMap::iterator id_to_handle_iter = - thread_id_to_handle_.find(id); - DCHECK((id_to_handle_iter!= thread_id_to_handle_.end())); - // The given |id| may have been re-used by the system. Make sure the - // mapping points to the provided |handle| before removal. - if (id_to_handle_iter->second != handle) - return; - - thread_id_to_handle_.erase(id_to_handle_iter); -} - -} // namespace base diff --git a/security/sandbox/chromium/base/threading/thread_id_name_manager.h b/security/sandbox/chromium/base/threading/thread_id_name_manager.h deleted file mode 100644 index f469b605e..000000000 --- a/security/sandbox/chromium/base/threading/thread_id_name_manager.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_THREADING_THREAD_ID_NAME_MANAGER_H_ -#define BASE_THREADING_THREAD_ID_NAME_MANAGER_H_ - -#include <map> -#include <string> - -#include "base/base_export.h" -#include "base/macros.h" -#include "base/synchronization/lock.h" -#include "base/threading/platform_thread.h" - -namespace base { - -template <typename T> -struct DefaultSingletonTraits; - -class BASE_EXPORT ThreadIdNameManager { - public: - static ThreadIdNameManager* GetInstance(); - - static const char* GetDefaultInternedString(); - - // Register the mapping between a thread |id| and |handle|. - void RegisterThread(PlatformThreadHandle::Handle handle, PlatformThreadId id); - - // Set the name for the given id. - void SetName(PlatformThreadId id, const std::string& name); - - // Get the name for the given id. - const char* GetName(PlatformThreadId id); - - // Remove the name for the given id. - void RemoveName(PlatformThreadHandle::Handle handle, PlatformThreadId id); - - private: - friend struct DefaultSingletonTraits<ThreadIdNameManager>; - - typedef std::map<PlatformThreadId, PlatformThreadHandle::Handle> - ThreadIdToHandleMap; - typedef std::map<PlatformThreadHandle::Handle, std::string*> - ThreadHandleToInternedNameMap; - typedef std::map<std::string, std::string*> NameToInternedNameMap; - - ThreadIdNameManager(); - ~ThreadIdNameManager(); - - // lock_ protects the name_to_interned_name_, thread_id_to_handle_ and - // thread_handle_to_interned_name_ maps. - Lock lock_; - - NameToInternedNameMap name_to_interned_name_; - ThreadIdToHandleMap thread_id_to_handle_; - ThreadHandleToInternedNameMap thread_handle_to_interned_name_; - - // Treat the main process specially as there is no PlatformThreadHandle. - std::string* main_process_name_; - PlatformThreadId main_process_id_; - - DISALLOW_COPY_AND_ASSIGN(ThreadIdNameManager); -}; - -} // namespace base - -#endif // BASE_THREADING_THREAD_ID_NAME_MANAGER_H_ diff --git a/security/sandbox/chromium/base/threading/thread_local.h b/security/sandbox/chromium/base/threading/thread_local.h deleted file mode 100644 index f40420cd2..000000000 --- a/security/sandbox/chromium/base/threading/thread_local.h +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// WARNING: Thread local storage is a bit tricky to get right. Please make -// sure that this is really the proper solution for what you're trying to -// achieve. Don't prematurely optimize, most likely you can just use a Lock. -// -// These classes implement a wrapper around the platform's TLS storage -// mechanism. On construction, they will allocate a TLS slot, and free the -// TLS slot on destruction. No memory management (creation or destruction) is -// handled. This means for uses of ThreadLocalPointer, you must correctly -// manage the memory yourself, these classes will not destroy the pointer for -// you. There are no at-thread-exit actions taken by these classes. -// -// ThreadLocalPointer<Type> wraps a Type*. It performs no creation or -// destruction, so memory management must be handled elsewhere. The first call -// to Get() on a thread will return NULL. You can update the pointer with a -// call to Set(). -// -// ThreadLocalBoolean wraps a bool. It will default to false if it has never -// been set otherwise with Set(). -// -// Thread Safety: An instance of ThreadLocalStorage is completely thread safe -// once it has been created. If you want to dynamically create an instance, -// you must of course properly deal with safety and race conditions. This -// means a function-level static initializer is generally inappropiate. -// -// In Android, the system TLS is limited, the implementation is backed with -// ThreadLocalStorage. -// -// Example usage: -// // My class is logically attached to a single thread. We cache a pointer -// // on the thread it was created on, so we can implement current(). -// MyClass::MyClass() { -// DCHECK(Singleton<ThreadLocalPointer<MyClass> >::get()->Get() == NULL); -// Singleton<ThreadLocalPointer<MyClass> >::get()->Set(this); -// } -// -// MyClass::~MyClass() { -// DCHECK(Singleton<ThreadLocalPointer<MyClass> >::get()->Get() != NULL); -// Singleton<ThreadLocalPointer<MyClass> >::get()->Set(NULL); -// } -// -// // Return the current MyClass associated with the calling thread, can be -// // NULL if there isn't a MyClass associated. -// MyClass* MyClass::current() { -// return Singleton<ThreadLocalPointer<MyClass> >::get()->Get(); -// } - -#ifndef BASE_THREADING_THREAD_LOCAL_H_ -#define BASE_THREADING_THREAD_LOCAL_H_ - -#include "base/base_export.h" -#include "base/macros.h" -#include "base/threading/thread_local_storage.h" -#include "build/build_config.h" - -#if defined(OS_POSIX) -#include <pthread.h> -#endif - -namespace base { -namespace internal { - -// Helper functions that abstract the cross-platform APIs. Do not use directly. -struct BASE_EXPORT ThreadLocalPlatform { -#if defined(OS_WIN) - typedef unsigned long SlotType; -#elif defined(OS_ANDROID) - typedef ThreadLocalStorage::StaticSlot SlotType; -#elif defined(OS_POSIX) - typedef pthread_key_t SlotType; -#endif - - static void AllocateSlot(SlotType* slot); - static void FreeSlot(SlotType slot); - static void* GetValueFromSlot(SlotType slot); - static void SetValueInSlot(SlotType slot, void* value); -}; - -} // namespace internal - -template <typename Type> -class ThreadLocalPointer { - public: - ThreadLocalPointer() : slot_() { - internal::ThreadLocalPlatform::AllocateSlot(&slot_); - } - - ~ThreadLocalPointer() { - internal::ThreadLocalPlatform::FreeSlot(slot_); - } - - Type* Get() { - return static_cast<Type*>( - internal::ThreadLocalPlatform::GetValueFromSlot(slot_)); - } - - void Set(Type* ptr) { - internal::ThreadLocalPlatform::SetValueInSlot( - slot_, const_cast<void*>(static_cast<const void*>(ptr))); - } - - private: - typedef internal::ThreadLocalPlatform::SlotType SlotType; - - SlotType slot_; - - DISALLOW_COPY_AND_ASSIGN(ThreadLocalPointer<Type>); -}; - -class ThreadLocalBoolean { - public: - ThreadLocalBoolean() {} - ~ThreadLocalBoolean() {} - - bool Get() { - return tlp_.Get() != NULL; - } - - void Set(bool val) { - tlp_.Set(val ? this : NULL); - } - - private: - ThreadLocalPointer<void> tlp_; - - DISALLOW_COPY_AND_ASSIGN(ThreadLocalBoolean); -}; - -} // namespace base - -#endif // BASE_THREADING_THREAD_LOCAL_H_ diff --git a/security/sandbox/chromium/base/threading/thread_local_posix.cc b/security/sandbox/chromium/base/threading/thread_local_posix.cc deleted file mode 100644 index 8bc46ad19..000000000 --- a/security/sandbox/chromium/base/threading/thread_local_posix.cc +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/threading/thread_local.h" - -#include <pthread.h> - -#include "base/logging.h" -#include "build/build_config.h" - -#if !defined(OS_ANDROID) - -namespace base { -namespace internal { - -// static -void ThreadLocalPlatform::AllocateSlot(SlotType* slot) { - int error = pthread_key_create(slot, NULL); - CHECK_EQ(error, 0); -} - -// static -void ThreadLocalPlatform::FreeSlot(SlotType slot) { - int error = pthread_key_delete(slot); - DCHECK_EQ(0, error); -} - -// static -void* ThreadLocalPlatform::GetValueFromSlot(SlotType slot) { - return pthread_getspecific(slot); -} - -// static -void ThreadLocalPlatform::SetValueInSlot(SlotType slot, void* value) { - int error = pthread_setspecific(slot, value); - DCHECK_EQ(error, 0); -} - -} // namespace internal -} // namespace base - -#endif // !defined(OS_ANDROID) diff --git a/security/sandbox/chromium/base/threading/thread_local_storage.h b/security/sandbox/chromium/base/threading/thread_local_storage.h deleted file mode 100644 index 013b0aeff..000000000 --- a/security/sandbox/chromium/base/threading/thread_local_storage.h +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_THREADING_THREAD_LOCAL_STORAGE_H_ -#define BASE_THREADING_THREAD_LOCAL_STORAGE_H_ - -#include "base/atomicops.h" -#include "base/base_export.h" -#include "base/macros.h" -#include "build/build_config.h" - -#if defined(OS_WIN) -#include <windows.h> -#elif defined(OS_POSIX) -#include <pthread.h> -#endif - -namespace base { - -namespace internal { - -// WARNING: You should *NOT* be using this class directly. -// PlatformThreadLocalStorage is low-level abstraction to the OS's TLS -// interface, you should instead be using ThreadLocalStorage::StaticSlot/Slot. -class BASE_EXPORT PlatformThreadLocalStorage { - public: - -#if defined(OS_WIN) - typedef unsigned long TLSKey; - enum : unsigned { TLS_KEY_OUT_OF_INDEXES = TLS_OUT_OF_INDEXES }; -#elif defined(OS_POSIX) - typedef pthread_key_t TLSKey; - // The following is a "reserved key" which is used in our generic Chromium - // ThreadLocalStorage implementation. We expect that an OS will not return - // such a key, but if it is returned (i.e., the OS tries to allocate it) we - // will just request another key. - enum { TLS_KEY_OUT_OF_INDEXES = 0x7FFFFFFF }; -#endif - - // The following methods need to be supported on each OS platform, so that - // the Chromium ThreadLocalStore functionality can be constructed. - // Chromium will use these methods to acquire a single OS slot, and then use - // that to support a much larger number of Chromium slots (independent of the - // OS restrictions). - // The following returns true if it successfully is able to return an OS - // key in |key|. - static bool AllocTLS(TLSKey* key); - // Note: FreeTLS() doesn't have to be called, it is fine with this leak, OS - // might not reuse released slot, you might just reset the TLS value with - // SetTLSValue(). - static void FreeTLS(TLSKey key); - static void SetTLSValue(TLSKey key, void* value); - static void* GetTLSValue(TLSKey key); - - // Each platform (OS implementation) is required to call this method on each - // terminating thread when the thread is about to terminate. This method - // will then call all registered destructors for slots in Chromium - // ThreadLocalStorage, until there are no slot values remaining as having - // been set on this thread. - // Destructors may end up being called multiple times on a terminating - // thread, as other destructors may re-set slots that were previously - // destroyed. -#if defined(OS_WIN) - // Since Windows which doesn't support TLS destructor, the implementation - // should use GetTLSValue() to retrieve the value of TLS slot. - static void OnThreadExit(); -#elif defined(OS_POSIX) - // |Value| is the data stored in TLS slot, The implementation can't use - // GetTLSValue() to retrieve the value of slot as it has already been reset - // in Posix. - static void OnThreadExit(void* value); -#endif -}; - -} // namespace internal - -// Wrapper for thread local storage. This class doesn't do much except provide -// an API for portability. -class BASE_EXPORT ThreadLocalStorage { - public: - - // Prototype for the TLS destructor function, which can be optionally used to - // cleanup thread local storage on thread exit. 'value' is the data that is - // stored in thread local storage. - typedef void (*TLSDestructorFunc)(void* value); - - // StaticSlot uses its own struct initializer-list style static - // initialization, as base's LINKER_INITIALIZED requires a constructor and on - // some compilers (notably gcc 4.4) this still ends up needing runtime - // initialization. - #define TLS_INITIALIZER {0} - - // A key representing one value stored in TLS. - // Initialize like - // ThreadLocalStorage::StaticSlot my_slot = TLS_INITIALIZER; - // If you're not using a static variable, use the convenience class - // ThreadLocalStorage::Slot (below) instead. - struct BASE_EXPORT StaticSlot { - // Set up the TLS slot. Called by the constructor. - // 'destructor' is a pointer to a function to perform per-thread cleanup of - // this object. If set to NULL, no cleanup is done for this TLS slot. - void Initialize(TLSDestructorFunc destructor); - - // Free a previously allocated TLS 'slot'. - // If a destructor was set for this slot, removes - // the destructor so that remaining threads exiting - // will not free data. - void Free(); - - // Get the thread-local value stored in slot 'slot'. - // Values are guaranteed to initially be zero. - void* Get() const; - - // Set the thread-local value stored in slot 'slot' to - // value 'value'. - void Set(void* value); - - bool initialized() const { - return base::subtle::Acquire_Load(&initialized_) != 0; - } - - // The internals of this struct should be considered private. - base::subtle::Atomic32 initialized_; - int slot_; - }; - - // A convenience wrapper around StaticSlot with a constructor. Can be used - // as a member variable. - class BASE_EXPORT Slot : public StaticSlot { - public: - // Calls StaticSlot::Initialize(). - explicit Slot(TLSDestructorFunc destructor = NULL); - - private: - using StaticSlot::initialized_; - using StaticSlot::slot_; - - DISALLOW_COPY_AND_ASSIGN(Slot); - }; - - private: - DISALLOW_COPY_AND_ASSIGN(ThreadLocalStorage); -}; - -} // namespace base - -#endif // BASE_THREADING_THREAD_LOCAL_STORAGE_H_ diff --git a/security/sandbox/chromium/base/threading/thread_local_win.cc b/security/sandbox/chromium/base/threading/thread_local_win.cc deleted file mode 100644 index 1c74e4213..000000000 --- a/security/sandbox/chromium/base/threading/thread_local_win.cc +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/threading/thread_local.h" - -#include <windows.h> - -#include "base/logging.h" - -namespace base { -namespace internal { - -// static -void ThreadLocalPlatform::AllocateSlot(SlotType* slot) { - *slot = TlsAlloc(); - CHECK_NE(*slot, TLS_OUT_OF_INDEXES); -} - -// static -void ThreadLocalPlatform::FreeSlot(SlotType slot) { - if (!TlsFree(slot)) { - NOTREACHED() << "Failed to deallocate tls slot with TlsFree()."; - } -} - -// static -void* ThreadLocalPlatform::GetValueFromSlot(SlotType slot) { - return TlsGetValue(slot); -} - -// static -void ThreadLocalPlatform::SetValueInSlot(SlotType slot, void* value) { - if (!TlsSetValue(slot, value)) { - LOG(FATAL) << "Failed to TlsSetValue()."; - } -} - -} // namespace internal -} // namespace base diff --git a/security/sandbox/chromium/base/threading/thread_restrictions.cc b/security/sandbox/chromium/base/threading/thread_restrictions.cc deleted file mode 100644 index 00306c5ae..000000000 --- a/security/sandbox/chromium/base/threading/thread_restrictions.cc +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/threading/thread_restrictions.h" - -#if ENABLE_THREAD_RESTRICTIONS - -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/threading/thread_local.h" - -namespace base { - -namespace { - -LazyInstance<ThreadLocalBoolean>::Leaky - g_io_disallowed = LAZY_INSTANCE_INITIALIZER; - -LazyInstance<ThreadLocalBoolean>::Leaky - g_singleton_disallowed = LAZY_INSTANCE_INITIALIZER; - -LazyInstance<ThreadLocalBoolean>::Leaky - g_wait_disallowed = LAZY_INSTANCE_INITIALIZER; - -} // namespace - -// static -bool ThreadRestrictions::SetIOAllowed(bool allowed) { - bool previous_disallowed = g_io_disallowed.Get().Get(); - g_io_disallowed.Get().Set(!allowed); - return !previous_disallowed; -} - -// static -void ThreadRestrictions::AssertIOAllowed() { - if (g_io_disallowed.Get().Get()) { - LOG(FATAL) << - "Function marked as IO-only was called from a thread that " - "disallows IO! If this thread really should be allowed to " - "make IO calls, adjust the call to " - "base::ThreadRestrictions::SetIOAllowed() in this thread's " - "startup."; - } -} - -// static -bool ThreadRestrictions::SetSingletonAllowed(bool allowed) { - bool previous_disallowed = g_singleton_disallowed.Get().Get(); - g_singleton_disallowed.Get().Set(!allowed); - return !previous_disallowed; -} - -// static -void ThreadRestrictions::AssertSingletonAllowed() { - if (g_singleton_disallowed.Get().Get()) { - LOG(FATAL) << "LazyInstance/Singleton is not allowed to be used on this " - << "thread. Most likely it's because this thread is not " - << "joinable, so AtExitManager may have deleted the object " - << "on shutdown, leading to a potential shutdown crash."; - } -} - -// static -void ThreadRestrictions::DisallowWaiting() { - g_wait_disallowed.Get().Set(true); -} - -// static -void ThreadRestrictions::AssertWaitAllowed() { - if (g_wait_disallowed.Get().Get()) { - LOG(FATAL) << "Waiting is not allowed to be used on this thread to prevent " - << "jank and deadlock."; - } -} - -bool ThreadRestrictions::SetWaitAllowed(bool allowed) { - bool previous_disallowed = g_wait_disallowed.Get().Get(); - g_wait_disallowed.Get().Set(!allowed); - return !previous_disallowed; -} - -} // namespace base - -#endif // ENABLE_THREAD_RESTRICTIONS diff --git a/security/sandbox/chromium/base/threading/thread_restrictions.h b/security/sandbox/chromium/base/threading/thread_restrictions.h deleted file mode 100644 index eec00fbb7..000000000 --- a/security/sandbox/chromium/base/threading/thread_restrictions.h +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_THREADING_THREAD_RESTRICTIONS_H_ -#define BASE_THREADING_THREAD_RESTRICTIONS_H_ - -#include "base/base_export.h" -#include "base/macros.h" - -// See comment at top of thread_checker.h -#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) -#define ENABLE_THREAD_RESTRICTIONS 1 -#else -#define ENABLE_THREAD_RESTRICTIONS 0 -#endif - -class BrowserProcessImpl; -class HistogramSynchronizer; -class NativeBackendKWallet; -class ScopedAllowWaitForLegacyWebViewApi; - -namespace cc { -class CompletionEvent; -class SingleThreadTaskGraphRunner; -} -namespace chromeos { -class BlockingMethodCaller; -namespace system { -class StatisticsProviderImpl; -} -} -namespace chrome_browser_net { -class Predictor; -} -namespace content { -class BrowserGpuChannelHostFactory; -class BrowserGpuMemoryBufferManager; -class BrowserShutdownProfileDumper; -class BrowserTestBase; -class GpuChannelHost; -class NestedMessagePumpAndroid; -class ScopedAllowWaitForAndroidLayoutTests; -class ScopedAllowWaitForDebugURL; -class SoftwareOutputDeviceMus; -class TextInputClientMac; -class RasterWorkerPool; -} // namespace content -namespace dbus { -class Bus; -} -namespace disk_cache { -class BackendImpl; -class InFlightIO; -} -namespace gles2 { -class CommandBufferClientImpl; -} -namespace mojo { -namespace common { -class MessagePumpMojo; -} -} -namespace mus { -class CommandBufferLocal; -class GpuState; -} -namespace net { -class NetworkChangeNotifierMac; -namespace internal { -class AddressTrackerLinux; -} -} - -namespace remoting { -class AutoThread; -} - -namespace ui { -class WindowResizeHelperMac; -} - -namespace views { -class WindowManagerConnection; -} - -namespace base { - -namespace android { -class JavaHandlerThread; -} - -class SequencedWorkerPool; -class SimpleThread; -class Thread; -class ThreadTestHelper; - -// Certain behavior is disallowed on certain threads. ThreadRestrictions helps -// enforce these rules. Examples of such rules: -// -// * Do not do blocking IO (makes the thread janky) -// * Do not access Singleton/LazyInstance (may lead to shutdown crashes) -// -// Here's more about how the protection works: -// -// 1) If a thread should not be allowed to make IO calls, mark it: -// base::ThreadRestrictions::SetIOAllowed(false); -// By default, threads *are* allowed to make IO calls. -// In Chrome browser code, IO calls should be proxied to the File thread. -// -// 2) If a function makes a call that will go out to disk, check whether the -// current thread is allowed: -// base::ThreadRestrictions::AssertIOAllowed(); -// -// -// Style tip: where should you put AssertIOAllowed checks? It's best -// if you put them as close to the disk access as possible, at the -// lowest level. This rule is simple to follow and helps catch all -// callers. For example, if your function GoDoSomeBlockingDiskCall() -// only calls other functions in Chrome and not fopen(), you should go -// add the AssertIOAllowed checks in the helper functions. - -class BASE_EXPORT ThreadRestrictions { - public: - // Constructing a ScopedAllowIO temporarily allows IO for the current - // thread. Doing this is almost certainly always incorrect. - class BASE_EXPORT ScopedAllowIO { - public: - ScopedAllowIO() { previous_value_ = SetIOAllowed(true); } - ~ScopedAllowIO() { SetIOAllowed(previous_value_); } - private: - // Whether IO is allowed when the ScopedAllowIO was constructed. - bool previous_value_; - - DISALLOW_COPY_AND_ASSIGN(ScopedAllowIO); - }; - - // Constructing a ScopedAllowSingleton temporarily allows accessing for the - // current thread. Doing this is almost always incorrect. - class BASE_EXPORT ScopedAllowSingleton { - public: - ScopedAllowSingleton() { previous_value_ = SetSingletonAllowed(true); } - ~ScopedAllowSingleton() { SetSingletonAllowed(previous_value_); } - private: - // Whether singleton use is allowed when the ScopedAllowSingleton was - // constructed. - bool previous_value_; - - DISALLOW_COPY_AND_ASSIGN(ScopedAllowSingleton); - }; - -#if ENABLE_THREAD_RESTRICTIONS - // Set whether the current thread to make IO calls. - // Threads start out in the *allowed* state. - // Returns the previous value. - static bool SetIOAllowed(bool allowed); - - // Check whether the current thread is allowed to make IO calls, - // and DCHECK if not. See the block comment above the class for - // a discussion of where to add these checks. - static void AssertIOAllowed(); - - // Set whether the current thread can use singletons. Returns the previous - // value. - static bool SetSingletonAllowed(bool allowed); - - // Check whether the current thread is allowed to use singletons (Singleton / - // LazyInstance). DCHECKs if not. - static void AssertSingletonAllowed(); - - // Disable waiting on the current thread. Threads start out in the *allowed* - // state. Returns the previous value. - static void DisallowWaiting(); - - // Check whether the current thread is allowed to wait, and DCHECK if not. - static void AssertWaitAllowed(); -#else - // Inline the empty definitions of these functions so that they can be - // compiled out. - static bool SetIOAllowed(bool allowed) { return true; } - static void AssertIOAllowed() {} - static bool SetSingletonAllowed(bool allowed) { return true; } - static void AssertSingletonAllowed() {} - static void DisallowWaiting() {} - static void AssertWaitAllowed() {} -#endif - - private: - // DO NOT ADD ANY OTHER FRIEND STATEMENTS, talk to jam or brettw first. - // BEGIN ALLOWED USAGE. - friend class content::BrowserShutdownProfileDumper; - friend class content::BrowserTestBase; - friend class content::NestedMessagePumpAndroid; - friend class content::ScopedAllowWaitForAndroidLayoutTests; - friend class content::ScopedAllowWaitForDebugURL; - friend class ::HistogramSynchronizer; - friend class ::ScopedAllowWaitForLegacyWebViewApi; - friend class cc::CompletionEvent; - friend class cc::SingleThreadTaskGraphRunner; - friend class content::RasterWorkerPool; - friend class remoting::AutoThread; - friend class ui::WindowResizeHelperMac; - friend class MessagePumpDefault; - friend class SequencedWorkerPool; - friend class SimpleThread; - friend class Thread; - friend class ThreadTestHelper; - friend class PlatformThread; - friend class android::JavaHandlerThread; - friend class gles2::CommandBufferClientImpl; - friend class mojo::common::MessagePumpMojo; - friend class mus::CommandBufferLocal; - friend class mus::GpuState; - - // END ALLOWED USAGE. - // BEGIN USAGE THAT NEEDS TO BE FIXED. - friend class ::chromeos::BlockingMethodCaller; // http://crbug.com/125360 - friend class ::chromeos::system::StatisticsProviderImpl; // http://crbug.com/125385 - friend class chrome_browser_net::Predictor; // http://crbug.com/78451 - friend class - content::BrowserGpuChannelHostFactory; // http://crbug.com/125248 - friend class - content::BrowserGpuMemoryBufferManager; // http://crbug.com/420368 - friend class content::GpuChannelHost; // http://crbug.com/125264 - friend class content::TextInputClientMac; // http://crbug.com/121917 - friend class dbus::Bus; // http://crbug.com/125222 - friend class disk_cache::BackendImpl; // http://crbug.com/74623 - friend class disk_cache::InFlightIO; // http://crbug.com/74623 - friend class net::internal::AddressTrackerLinux; // http://crbug.com/125097 - friend class net::NetworkChangeNotifierMac; // http://crbug.com/125097 - friend class ::BrowserProcessImpl; // http://crbug.com/125207 - friend class ::NativeBackendKWallet; // http://crbug.com/125331 -#if !defined(OFFICIAL_BUILD) - friend class content::SoftwareOutputDeviceMus; // Interim non-production code -#endif - friend class views::WindowManagerConnection; -// END USAGE THAT NEEDS TO BE FIXED. - -#if ENABLE_THREAD_RESTRICTIONS - static bool SetWaitAllowed(bool allowed); -#else - static bool SetWaitAllowed(bool allowed) { return true; } -#endif - - // Constructing a ScopedAllowWait temporarily allows waiting on the current - // thread. Doing this is almost always incorrect, which is why we limit who - // can use this through friend. If you find yourself needing to use this, find - // another way. Talk to jam or brettw. - class BASE_EXPORT ScopedAllowWait { - public: - ScopedAllowWait() { previous_value_ = SetWaitAllowed(true); } - ~ScopedAllowWait() { SetWaitAllowed(previous_value_); } - private: - // Whether singleton use is allowed when the ScopedAllowWait was - // constructed. - bool previous_value_; - - DISALLOW_COPY_AND_ASSIGN(ScopedAllowWait); - }; - - DISALLOW_IMPLICIT_CONSTRUCTORS(ThreadRestrictions); -}; - -} // namespace base - -#endif // BASE_THREADING_THREAD_RESTRICTIONS_H_ diff --git a/security/sandbox/chromium/base/time/time.cc b/security/sandbox/chromium/base/time/time.cc deleted file mode 100644 index 9188887e2..000000000 --- a/security/sandbox/chromium/base/time/time.cc +++ /dev/null @@ -1,349 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/time/time.h" - -#include <cmath> -#include <ios> -#include <limits> -#include <ostream> -#include <sstream> - -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/strings/stringprintf.h" -#include "base/third_party/nspr/prtime.h" -#include "build/build_config.h" - -namespace base { - -// TimeDelta ------------------------------------------------------------------ - -// static -TimeDelta TimeDelta::Max() { - return TimeDelta(std::numeric_limits<int64_t>::max()); -} - -int TimeDelta::InDays() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<int>::max(); - } - return static_cast<int>(delta_ / Time::kMicrosecondsPerDay); -} - -int TimeDelta::InHours() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<int>::max(); - } - return static_cast<int>(delta_ / Time::kMicrosecondsPerHour); -} - -int TimeDelta::InMinutes() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<int>::max(); - } - return static_cast<int>(delta_ / Time::kMicrosecondsPerMinute); -} - -double TimeDelta::InSecondsF() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<double>::infinity(); - } - return static_cast<double>(delta_) / Time::kMicrosecondsPerSecond; -} - -int64_t TimeDelta::InSeconds() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<int64_t>::max(); - } - return delta_ / Time::kMicrosecondsPerSecond; -} - -double TimeDelta::InMillisecondsF() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<double>::infinity(); - } - return static_cast<double>(delta_) / Time::kMicrosecondsPerMillisecond; -} - -int64_t TimeDelta::InMilliseconds() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<int64_t>::max(); - } - return delta_ / Time::kMicrosecondsPerMillisecond; -} - -int64_t TimeDelta::InMillisecondsRoundedUp() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<int64_t>::max(); - } - return (delta_ + Time::kMicrosecondsPerMillisecond - 1) / - Time::kMicrosecondsPerMillisecond; -} - -int64_t TimeDelta::InMicroseconds() const { - if (is_max()) { - // Preserve max to prevent overflow. - return std::numeric_limits<int64_t>::max(); - } - return delta_; -} - -namespace time_internal { - -int64_t SaturatedAdd(TimeDelta delta, int64_t value) { - CheckedNumeric<int64_t> rv(delta.delta_); - rv += value; - return FromCheckedNumeric(rv); -} - -int64_t SaturatedSub(TimeDelta delta, int64_t value) { - CheckedNumeric<int64_t> rv(delta.delta_); - rv -= value; - return FromCheckedNumeric(rv); -} - -int64_t FromCheckedNumeric(const CheckedNumeric<int64_t> value) { - if (value.IsValid()) - return value.ValueUnsafe(); - - // We could return max/min but we don't really expose what the maximum delta - // is. Instead, return max/(-max), which is something that clients can reason - // about. - // TODO(rvargas) crbug.com/332611: don't use internal values. - int64_t limit = std::numeric_limits<int64_t>::max(); - if (value.validity() == internal::RANGE_UNDERFLOW) - limit = -limit; - return value.ValueOrDefault(limit); -} - -} // namespace time_internal - -std::ostream& operator<<(std::ostream& os, TimeDelta time_delta) { - return os << time_delta.InSecondsF() << "s"; -} - -// Time ----------------------------------------------------------------------- - -// static -Time Time::Max() { - return Time(std::numeric_limits<int64_t>::max()); -} - -// static -Time Time::FromTimeT(time_t tt) { - if (tt == 0) - return Time(); // Preserve 0 so we can tell it doesn't exist. - if (tt == std::numeric_limits<time_t>::max()) - return Max(); - return Time(kTimeTToMicrosecondsOffset) + TimeDelta::FromSeconds(tt); -} - -time_t Time::ToTimeT() const { - if (is_null()) - return 0; // Preserve 0 so we can tell it doesn't exist. - if (is_max()) { - // Preserve max without offset to prevent overflow. - return std::numeric_limits<time_t>::max(); - } - if (std::numeric_limits<int64_t>::max() - kTimeTToMicrosecondsOffset <= us_) { - DLOG(WARNING) << "Overflow when converting base::Time with internal " << - "value " << us_ << " to time_t."; - return std::numeric_limits<time_t>::max(); - } - return (us_ - kTimeTToMicrosecondsOffset) / kMicrosecondsPerSecond; -} - -// static -Time Time::FromDoubleT(double dt) { - if (dt == 0 || std::isnan(dt)) - return Time(); // Preserve 0 so we can tell it doesn't exist. - return Time(kTimeTToMicrosecondsOffset) + TimeDelta::FromSecondsD(dt); -} - -double Time::ToDoubleT() const { - if (is_null()) - return 0; // Preserve 0 so we can tell it doesn't exist. - if (is_max()) { - // Preserve max without offset to prevent overflow. - return std::numeric_limits<double>::infinity(); - } - return (static_cast<double>(us_ - kTimeTToMicrosecondsOffset) / - static_cast<double>(kMicrosecondsPerSecond)); -} - -#if defined(OS_POSIX) -// static -Time Time::FromTimeSpec(const timespec& ts) { - return FromDoubleT(ts.tv_sec + - static_cast<double>(ts.tv_nsec) / - base::Time::kNanosecondsPerSecond); -} -#endif - -// static -Time Time::FromJsTime(double ms_since_epoch) { - // The epoch is a valid time, so this constructor doesn't interpret - // 0 as the null time. - return Time(kTimeTToMicrosecondsOffset) + - TimeDelta::FromMillisecondsD(ms_since_epoch); -} - -double Time::ToJsTime() const { - if (is_null()) { - // Preserve 0 so the invalid result doesn't depend on the platform. - return 0; - } - if (is_max()) { - // Preserve max without offset to prevent overflow. - return std::numeric_limits<double>::infinity(); - } - return (static_cast<double>(us_ - kTimeTToMicrosecondsOffset) / - kMicrosecondsPerMillisecond); -} - -int64_t Time::ToJavaTime() const { - if (is_null()) { - // Preserve 0 so the invalid result doesn't depend on the platform. - return 0; - } - if (is_max()) { - // Preserve max without offset to prevent overflow. - return std::numeric_limits<int64_t>::max(); - } - return ((us_ - kTimeTToMicrosecondsOffset) / - kMicrosecondsPerMillisecond); -} - -// static -Time Time::UnixEpoch() { - Time time; - time.us_ = kTimeTToMicrosecondsOffset; - return time; -} - -Time Time::LocalMidnight() const { - Exploded exploded; - LocalExplode(&exploded); - exploded.hour = 0; - exploded.minute = 0; - exploded.second = 0; - exploded.millisecond = 0; - return FromLocalExploded(exploded); -} - -#if !defined(MOZ_SANDBOX) -// static -bool Time::FromStringInternal(const char* time_string, - bool is_local, - Time* parsed_time) { - DCHECK((time_string != NULL) && (parsed_time != NULL)); - - if (time_string[0] == '\0') - return false; - - PRTime result_time = 0; - PRStatus result = PR_ParseTimeString(time_string, - is_local ? PR_FALSE : PR_TRUE, - &result_time); - if (PR_SUCCESS != result) - return false; - - result_time += kTimeTToMicrosecondsOffset; - *parsed_time = Time(result_time); - return true; -} -#endif - -std::ostream& operator<<(std::ostream& os, Time time) { - Time::Exploded exploded; - time.UTCExplode(&exploded); - // Use StringPrintf because iostreams formatting is painful. - return os << StringPrintf("%04d-%02d-%02d %02d:%02d:%02d.%03d UTC", - exploded.year, - exploded.month, - exploded.day_of_month, - exploded.hour, - exploded.minute, - exploded.second, - exploded.millisecond); -} - -// Local helper class to hold the conversion from Time to TickTime at the -// time of the Unix epoch. -class UnixEpochSingleton { - public: - UnixEpochSingleton() - : unix_epoch_(TimeTicks::Now() - (Time::Now() - Time::UnixEpoch())) {} - - TimeTicks unix_epoch() const { return unix_epoch_; } - - private: - const TimeTicks unix_epoch_; - - DISALLOW_COPY_AND_ASSIGN(UnixEpochSingleton); -}; - -static LazyInstance<UnixEpochSingleton>::Leaky - leaky_unix_epoch_singleton_instance = LAZY_INSTANCE_INITIALIZER; - -// Static -TimeTicks TimeTicks::UnixEpoch() { - return leaky_unix_epoch_singleton_instance.Get().unix_epoch(); -} - -TimeTicks TimeTicks::SnappedToNextTick(TimeTicks tick_phase, - TimeDelta tick_interval) const { - // |interval_offset| is the offset from |this| to the next multiple of - // |tick_interval| after |tick_phase|, possibly negative if in the past. - TimeDelta interval_offset = (tick_phase - *this) % tick_interval; - // If |this| is exactly on the interval (i.e. offset==0), don't adjust. - // Otherwise, if |tick_phase| was in the past, adjust forward to the next - // tick after |this|. - if (!interval_offset.is_zero() && tick_phase < *this) - interval_offset += tick_interval; - return *this + interval_offset; -} - -std::ostream& operator<<(std::ostream& os, TimeTicks time_ticks) { - // This function formats a TimeTicks object as "bogo-microseconds". - // The origin and granularity of the count are platform-specific, and may very - // from run to run. Although bogo-microseconds usually roughly correspond to - // real microseconds, the only real guarantee is that the number never goes - // down during a single run. - const TimeDelta as_time_delta = time_ticks - TimeTicks(); - return os << as_time_delta.InMicroseconds() << " bogo-microseconds"; -} - -std::ostream& operator<<(std::ostream& os, ThreadTicks thread_ticks) { - const TimeDelta as_time_delta = thread_ticks - ThreadTicks(); - return os << as_time_delta.InMicroseconds() << " bogo-thread-microseconds"; -} - -// Time::Exploded ------------------------------------------------------------- - -inline bool is_in_range(int value, int lo, int hi) { - return lo <= value && value <= hi; -} - -bool Time::Exploded::HasValidValues() const { - return is_in_range(month, 1, 12) && - is_in_range(day_of_week, 0, 6) && - is_in_range(day_of_month, 1, 31) && - is_in_range(hour, 0, 23) && - is_in_range(minute, 0, 59) && - is_in_range(second, 0, 60) && - is_in_range(millisecond, 0, 999); -} - -} // namespace base diff --git a/security/sandbox/chromium/base/time/time.h b/security/sandbox/chromium/base/time/time.h deleted file mode 100644 index ea19d7ed9..000000000 --- a/security/sandbox/chromium/base/time/time.h +++ /dev/null @@ -1,768 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Time represents an absolute point in coordinated universal time (UTC), -// internally represented as microseconds (s/1,000,000) since the Windows epoch -// (1601-01-01 00:00:00 UTC). System-dependent clock interface routines are -// defined in time_PLATFORM.cc. Note that values for Time may skew and jump -// around as the operating system makes adjustments to synchronize (e.g., with -// NTP servers). Thus, client code that uses the Time class must account for -// this. -// -// TimeDelta represents a duration of time, internally represented in -// microseconds. -// -// TimeTicks and ThreadTicks represent an abstract time that is most of the time -// incrementing, for use in measuring time durations. Internally, they are -// represented in microseconds. They can not be converted to a human-readable -// time, but are guaranteed not to decrease (unlike the Time class). Note that -// TimeTicks may "stand still" (e.g., if the computer is suspended), and -// ThreadTicks will "stand still" whenever the thread has been de-scheduled by -// the operating system. -// -// All time classes are copyable, assignable, and occupy 64-bits per -// instance. Thus, they can be efficiently passed by-value (as opposed to -// by-reference). -// -// Definitions of operator<< are provided to make these types work with -// DCHECK_EQ() and other log macros. For human-readable formatting, see -// "base/i18n/time_formatting.h". -// -// So many choices! Which time class should you use? Examples: -// -// Time: Interpreting the wall-clock time provided by a remote -// system. Detecting whether cached resources have -// expired. Providing the user with a display of the current date -// and time. Determining the amount of time between events across -// re-boots of the machine. -// -// TimeTicks: Tracking the amount of time a task runs. Executing delayed -// tasks at the right time. Computing presentation timestamps. -// Synchronizing audio and video using TimeTicks as a common -// reference clock (lip-sync). Measuring network round-trip -// latency. -// -// ThreadTicks: Benchmarking how long the current thread has been doing actual -// work. - -#ifndef BASE_TIME_TIME_H_ -#define BASE_TIME_TIME_H_ - -#include <stdint.h> -#include <time.h> - -#include <iosfwd> -#include <limits> - -#include "base/base_export.h" -#include "base/numerics/safe_math.h" -#include "build/build_config.h" - -#if defined(OS_MACOSX) -#include <CoreFoundation/CoreFoundation.h> -// Avoid Mac system header macro leak. -#undef TYPE_BOOL -#endif - -#if defined(OS_POSIX) -#include <unistd.h> -#include <sys/time.h> -#endif - -#if defined(OS_WIN) -// For FILETIME in FromFileTime, until it moves to a new converter class. -// See TODO(iyengar) below. -#include <windows.h> - -#include "base/gtest_prod_util.h" -#endif - -namespace base { - -class TimeDelta; - -// The functions in the time_internal namespace are meant to be used only by the -// time classes and functions. Please use the math operators defined in the -// time classes instead. -namespace time_internal { - -// Add or subtract |value| from a TimeDelta. The int64_t argument and return -// value are in terms of a microsecond timebase. -BASE_EXPORT int64_t SaturatedAdd(TimeDelta delta, int64_t value); -BASE_EXPORT int64_t SaturatedSub(TimeDelta delta, int64_t value); - -// Clamp |value| on overflow and underflow conditions. The int64_t argument and -// return value are in terms of a microsecond timebase. -BASE_EXPORT int64_t FromCheckedNumeric(const CheckedNumeric<int64_t> value); - -} // namespace time_internal - -// TimeDelta ------------------------------------------------------------------ - -class BASE_EXPORT TimeDelta { - public: - TimeDelta() : delta_(0) { - } - - // Converts units of time to TimeDeltas. - static TimeDelta FromDays(int days); - static TimeDelta FromHours(int hours); - static TimeDelta FromMinutes(int minutes); - static TimeDelta FromSeconds(int64_t secs); - static TimeDelta FromMilliseconds(int64_t ms); - static TimeDelta FromSecondsD(double secs); - static TimeDelta FromMillisecondsD(double ms); - static TimeDelta FromMicroseconds(int64_t us); -#if defined(OS_WIN) - static TimeDelta FromQPCValue(LONGLONG qpc_value); -#endif - - // Converts an integer value representing TimeDelta to a class. This is used - // when deserializing a |TimeDelta| structure, using a value known to be - // compatible. It is not provided as a constructor because the integer type - // may be unclear from the perspective of a caller. - static TimeDelta FromInternalValue(int64_t delta) { return TimeDelta(delta); } - - // Returns the maximum time delta, which should be greater than any reasonable - // time delta we might compare it to. Adding or subtracting the maximum time - // delta to a time or another time delta has an undefined result. - static TimeDelta Max(); - - // Returns the internal numeric value of the TimeDelta object. Please don't - // use this and do arithmetic on it, as it is more error prone than using the - // provided operators. - // For serializing, use FromInternalValue to reconstitute. - int64_t ToInternalValue() const { return delta_; } - - // Returns the magnitude (absolute value) of this TimeDelta. - TimeDelta magnitude() const { - // Some toolchains provide an incomplete C++11 implementation and lack an - // int64_t overload for std::abs(). The following is a simple branchless - // implementation: - const int64_t mask = delta_ >> (sizeof(delta_) * 8 - 1); - return TimeDelta((delta_ + mask) ^ mask); - } - - // Returns true if the time delta is zero. - bool is_zero() const { - return delta_ == 0; - } - - // Returns true if the time delta is the maximum time delta. - bool is_max() const { return delta_ == std::numeric_limits<int64_t>::max(); } - -#if defined(OS_POSIX) - struct timespec ToTimeSpec() const; -#endif - - // Returns the time delta in some unit. The F versions return a floating - // point value, the "regular" versions return a rounded-down value. - // - // InMillisecondsRoundedUp() instead returns an integer that is rounded up - // to the next full millisecond. - int InDays() const; - int InHours() const; - int InMinutes() const; - double InSecondsF() const; - int64_t InSeconds() const; - double InMillisecondsF() const; - int64_t InMilliseconds() const; - int64_t InMillisecondsRoundedUp() const; - int64_t InMicroseconds() const; - - TimeDelta& operator=(TimeDelta other) { - delta_ = other.delta_; - return *this; - } - - // Computations with other deltas. - TimeDelta operator+(TimeDelta other) const { - return TimeDelta(time_internal::SaturatedAdd(*this, other.delta_)); - } - TimeDelta operator-(TimeDelta other) const { - return TimeDelta(time_internal::SaturatedSub(*this, other.delta_)); - } - - TimeDelta& operator+=(TimeDelta other) { - return *this = (*this + other); - } - TimeDelta& operator-=(TimeDelta other) { - return *this = (*this - other); - } - TimeDelta operator-() const { - return TimeDelta(-delta_); - } - - // Computations with numeric types. - template<typename T> - TimeDelta operator*(T a) const { - CheckedNumeric<int64_t> rv(delta_); - rv *= a; - return TimeDelta(time_internal::FromCheckedNumeric(rv)); - } - template<typename T> - TimeDelta operator/(T a) const { - CheckedNumeric<int64_t> rv(delta_); - rv /= a; - return TimeDelta(time_internal::FromCheckedNumeric(rv)); - } - template<typename T> - TimeDelta& operator*=(T a) { - return *this = (*this * a); - } - template<typename T> - TimeDelta& operator/=(T a) { - return *this = (*this / a); - } - - int64_t operator/(TimeDelta a) const { return delta_ / a.delta_; } - TimeDelta operator%(TimeDelta a) const { - return TimeDelta(delta_ % a.delta_); - } - - // Comparison operators. - bool operator==(TimeDelta other) const { - return delta_ == other.delta_; - } - bool operator!=(TimeDelta other) const { - return delta_ != other.delta_; - } - bool operator<(TimeDelta other) const { - return delta_ < other.delta_; - } - bool operator<=(TimeDelta other) const { - return delta_ <= other.delta_; - } - bool operator>(TimeDelta other) const { - return delta_ > other.delta_; - } - bool operator>=(TimeDelta other) const { - return delta_ >= other.delta_; - } - - private: - friend int64_t time_internal::SaturatedAdd(TimeDelta delta, int64_t value); - friend int64_t time_internal::SaturatedSub(TimeDelta delta, int64_t value); - - // Constructs a delta given the duration in microseconds. This is private - // to avoid confusion by callers with an integer constructor. Use - // FromSeconds, FromMilliseconds, etc. instead. - explicit TimeDelta(int64_t delta_us) : delta_(delta_us) {} - - // Private method to build a delta from a double. - static TimeDelta FromDouble(double value); - - // Delta in microseconds. - int64_t delta_; -}; - -template<typename T> -inline TimeDelta operator*(T a, TimeDelta td) { - return td * a; -} - -// For logging use only. -BASE_EXPORT std::ostream& operator<<(std::ostream& os, TimeDelta time_delta); - -// Do not reference the time_internal::TimeBase template class directly. Please -// use one of the time subclasses instead, and only reference the public -// TimeBase members via those classes. -namespace time_internal { - -// TimeBase-------------------------------------------------------------------- - -// Provides value storage and comparison/math operations common to all time -// classes. Each subclass provides for strong type-checking to ensure -// semantically meaningful comparison/math of time values from the same clock -// source or timeline. -template<class TimeClass> -class TimeBase { - public: - static const int64_t kHoursPerDay = 24; - static const int64_t kMillisecondsPerSecond = 1000; - static const int64_t kMillisecondsPerDay = - kMillisecondsPerSecond * 60 * 60 * kHoursPerDay; - static const int64_t kMicrosecondsPerMillisecond = 1000; - static const int64_t kMicrosecondsPerSecond = - kMicrosecondsPerMillisecond * kMillisecondsPerSecond; - static const int64_t kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60; - static const int64_t kMicrosecondsPerHour = kMicrosecondsPerMinute * 60; - static const int64_t kMicrosecondsPerDay = - kMicrosecondsPerHour * kHoursPerDay; - static const int64_t kMicrosecondsPerWeek = kMicrosecondsPerDay * 7; - static const int64_t kNanosecondsPerMicrosecond = 1000; - static const int64_t kNanosecondsPerSecond = - kNanosecondsPerMicrosecond * kMicrosecondsPerSecond; - - // Returns true if this object has not been initialized. - // - // Warning: Be careful when writing code that performs math on time values, - // since it's possible to produce a valid "zero" result that should not be - // interpreted as a "null" value. - bool is_null() const { - return us_ == 0; - } - - // Returns true if this object represents the maximum time. - bool is_max() const { return us_ == std::numeric_limits<int64_t>::max(); } - - // For serializing only. Use FromInternalValue() to reconstitute. Please don't - // use this and do arithmetic on it, as it is more error prone than using the - // provided operators. - int64_t ToInternalValue() const { return us_; } - - TimeClass& operator=(TimeClass other) { - us_ = other.us_; - return *(static_cast<TimeClass*>(this)); - } - - // Compute the difference between two times. - TimeDelta operator-(TimeClass other) const { - return TimeDelta::FromMicroseconds(us_ - other.us_); - } - - // Return a new time modified by some delta. - TimeClass operator+(TimeDelta delta) const { - return TimeClass(time_internal::SaturatedAdd(delta, us_)); - } - TimeClass operator-(TimeDelta delta) const { - return TimeClass(-time_internal::SaturatedSub(delta, us_)); - } - - // Modify by some time delta. - TimeClass& operator+=(TimeDelta delta) { - return static_cast<TimeClass&>(*this = (*this + delta)); - } - TimeClass& operator-=(TimeDelta delta) { - return static_cast<TimeClass&>(*this = (*this - delta)); - } - - // Comparison operators - bool operator==(TimeClass other) const { - return us_ == other.us_; - } - bool operator!=(TimeClass other) const { - return us_ != other.us_; - } - bool operator<(TimeClass other) const { - return us_ < other.us_; - } - bool operator<=(TimeClass other) const { - return us_ <= other.us_; - } - bool operator>(TimeClass other) const { - return us_ > other.us_; - } - bool operator>=(TimeClass other) const { - return us_ >= other.us_; - } - - // Converts an integer value representing TimeClass to a class. This is used - // when deserializing a |TimeClass| structure, using a value known to be - // compatible. It is not provided as a constructor because the integer type - // may be unclear from the perspective of a caller. - static TimeClass FromInternalValue(int64_t us) { return TimeClass(us); } - - protected: - explicit TimeBase(int64_t us) : us_(us) {} - - // Time value in a microsecond timebase. - int64_t us_; -}; - -} // namespace time_internal - -template<class TimeClass> -inline TimeClass operator+(TimeDelta delta, TimeClass t) { - return t + delta; -} - -// Time ----------------------------------------------------------------------- - -// Represents a wall clock time in UTC. Values are not guaranteed to be -// monotonically non-decreasing and are subject to large amounts of skew. -class BASE_EXPORT Time : public time_internal::TimeBase<Time> { - public: - // The representation of Jan 1, 1970 UTC in microseconds since the - // platform-dependent epoch. - static const int64_t kTimeTToMicrosecondsOffset; - -#if !defined(OS_WIN) - // On Mac & Linux, this value is the delta from the Windows epoch of 1601 to - // the Posix delta of 1970. This is used for migrating between the old - // 1970-based epochs to the new 1601-based ones. It should be removed from - // this global header and put in the platform-specific ones when we remove the - // migration code. - static const int64_t kWindowsEpochDeltaMicroseconds; -#else - // To avoid overflow in QPC to Microseconds calculations, since we multiply - // by kMicrosecondsPerSecond, then the QPC value should not exceed - // (2^63 - 1) / 1E6. If it exceeds that threshold, we divide then multiply. - enum : int64_t{kQPCOverflowThreshold = 0x8637BD05AF7}; -#endif - - // Represents an exploded time that can be formatted nicely. This is kind of - // like the Win32 SYSTEMTIME structure or the Unix "struct tm" with a few - // additions and changes to prevent errors. - struct BASE_EXPORT Exploded { - int year; // Four digit year "2007" - int month; // 1-based month (values 1 = January, etc.) - int day_of_week; // 0-based day of week (0 = Sunday, etc.) - int day_of_month; // 1-based day of month (1-31) - int hour; // Hour within the current day (0-23) - int minute; // Minute within the current hour (0-59) - int second; // Second within the current minute (0-59 plus leap - // seconds which may take it up to 60). - int millisecond; // Milliseconds within the current second (0-999) - - // A cursory test for whether the data members are within their - // respective ranges. A 'true' return value does not guarantee the - // Exploded value can be successfully converted to a Time value. - bool HasValidValues() const; - }; - - // Contains the NULL time. Use Time::Now() to get the current time. - Time() : TimeBase(0) { - } - - // Returns the time for epoch in Unix-like system (Jan 1, 1970). - static Time UnixEpoch(); - - // Returns the current time. Watch out, the system might adjust its clock - // in which case time will actually go backwards. We don't guarantee that - // times are increasing, or that two calls to Now() won't be the same. - static Time Now(); - - // Returns the maximum time, which should be greater than any reasonable time - // with which we might compare it. - static Time Max(); - - // Returns the current time. Same as Now() except that this function always - // uses system time so that there are no discrepancies between the returned - // time and system time even on virtual environments including our test bot. - // For timing sensitive unittests, this function should be used. - static Time NowFromSystemTime(); - - // Converts to/from time_t in UTC and a Time class. - // TODO(brettw) this should be removed once everybody starts using the |Time| - // class. - static Time FromTimeT(time_t tt); - time_t ToTimeT() const; - - // Converts time to/from a double which is the number of seconds since epoch - // (Jan 1, 1970). Webkit uses this format to represent time. - // Because WebKit initializes double time value to 0 to indicate "not - // initialized", we map it to empty Time object that also means "not - // initialized". - static Time FromDoubleT(double dt); - double ToDoubleT() const; - -#if defined(OS_POSIX) - // Converts the timespec structure to time. MacOS X 10.8.3 (and tentatively, - // earlier versions) will have the |ts|'s tv_nsec component zeroed out, - // having a 1 second resolution, which agrees with - // https://developer.apple.com/legacy/library/#technotes/tn/tn1150.html#HFSPlusDates. - static Time FromTimeSpec(const timespec& ts); -#endif - - // Converts to/from the Javascript convention for times, a number of - // milliseconds since the epoch: - // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/getTime. - static Time FromJsTime(double ms_since_epoch); - double ToJsTime() const; - - // Converts to Java convention for times, a number of - // milliseconds since the epoch. - int64_t ToJavaTime() const; - -#if defined(OS_POSIX) - static Time FromTimeVal(struct timeval t); - struct timeval ToTimeVal() const; -#endif - -#if defined(OS_MACOSX) - static Time FromCFAbsoluteTime(CFAbsoluteTime t); - CFAbsoluteTime ToCFAbsoluteTime() const; -#endif - -#if defined(OS_WIN) - static Time FromFileTime(FILETIME ft); - FILETIME ToFileTime() const; - - // The minimum time of a low resolution timer. This is basically a windows - // constant of ~15.6ms. While it does vary on some older OS versions, we'll - // treat it as static across all windows versions. - static const int kMinLowResolutionThresholdMs = 16; - - // Enable or disable Windows high resolution timer. - static void EnableHighResolutionTimer(bool enable); - - // Activates or deactivates the high resolution timer based on the |activate| - // flag. If the HighResolutionTimer is not Enabled (see - // EnableHighResolutionTimer), this function will return false. Otherwise - // returns true. Each successful activate call must be paired with a - // subsequent deactivate call. - // All callers to activate the high resolution timer must eventually call - // this function to deactivate the high resolution timer. - static bool ActivateHighResolutionTimer(bool activate); - - // Returns true if the high resolution timer is both enabled and activated. - // This is provided for testing only, and is not tracked in a thread-safe - // way. - static bool IsHighResolutionTimerInUse(); -#endif - - // Converts an exploded structure representing either the local time or UTC - // into a Time class. - static Time FromUTCExploded(const Exploded& exploded) { - return FromExploded(false, exploded); - } - static Time FromLocalExploded(const Exploded& exploded) { - return FromExploded(true, exploded); - } - -#if !defined(MOZ_SANDBOX) - // Converts a string representation of time to a Time object. - // An example of a time string which is converted is as below:- - // "Tue, 15 Nov 1994 12:45:26 GMT". If the timezone is not specified - // in the input string, FromString assumes local time and FromUTCString - // assumes UTC. A timezone that cannot be parsed (e.g. "UTC" which is not - // specified in RFC822) is treated as if the timezone is not specified. - // TODO(iyengar) Move the FromString/FromTimeT/ToTimeT/FromFileTime to - // a new time converter class. - static bool FromString(const char* time_string, Time* parsed_time) { - return FromStringInternal(time_string, true, parsed_time); - } - static bool FromUTCString(const char* time_string, Time* parsed_time) { - return FromStringInternal(time_string, false, parsed_time); - } -#endif - - // Fills the given exploded structure with either the local time or UTC from - // this time structure (containing UTC). - void UTCExplode(Exploded* exploded) const { - return Explode(false, exploded); - } - void LocalExplode(Exploded* exploded) const { - return Explode(true, exploded); - } - - // Rounds this time down to the nearest day in local time. It will represent - // midnight on that day. - Time LocalMidnight() const; - - private: - friend class time_internal::TimeBase<Time>; - - explicit Time(int64_t us) : TimeBase(us) {} - - // Explodes the given time to either local time |is_local = true| or UTC - // |is_local = false|. - void Explode(bool is_local, Exploded* exploded) const; - - // Unexplodes a given time assuming the source is either local time - // |is_local = true| or UTC |is_local = false|. - static Time FromExploded(bool is_local, const Exploded& exploded); - -#if !defined(MOZ_SANDBOX) - // Converts a string representation of time to a Time object. - // An example of a time string which is converted is as below:- - // "Tue, 15 Nov 1994 12:45:26 GMT". If the timezone is not specified - // in the input string, local time |is_local = true| or - // UTC |is_local = false| is assumed. A timezone that cannot be parsed - // (e.g. "UTC" which is not specified in RFC822) is treated as if the - // timezone is not specified. - static bool FromStringInternal(const char* time_string, - bool is_local, - Time* parsed_time); -#endif -}; - -// Inline the TimeDelta factory methods, for fast TimeDelta construction. - -// static -inline TimeDelta TimeDelta::FromDays(int days) { - if (days == std::numeric_limits<int>::max()) - return Max(); - return TimeDelta(days * Time::kMicrosecondsPerDay); -} - -// static -inline TimeDelta TimeDelta::FromHours(int hours) { - if (hours == std::numeric_limits<int>::max()) - return Max(); - return TimeDelta(hours * Time::kMicrosecondsPerHour); -} - -// static -inline TimeDelta TimeDelta::FromMinutes(int minutes) { - if (minutes == std::numeric_limits<int>::max()) - return Max(); - return TimeDelta(minutes * Time::kMicrosecondsPerMinute); -} - -// static -inline TimeDelta TimeDelta::FromSeconds(int64_t secs) { - return TimeDelta(secs) * Time::kMicrosecondsPerSecond; -} - -// static -inline TimeDelta TimeDelta::FromMilliseconds(int64_t ms) { - return TimeDelta(ms) * Time::kMicrosecondsPerMillisecond; -} - -// static -inline TimeDelta TimeDelta::FromSecondsD(double secs) { - return FromDouble(secs * Time::kMicrosecondsPerSecond); -} - -// static -inline TimeDelta TimeDelta::FromMillisecondsD(double ms) { - return FromDouble(ms * Time::kMicrosecondsPerMillisecond); -} - -// static -inline TimeDelta TimeDelta::FromMicroseconds(int64_t us) { - return TimeDelta(us); -} - -// static -inline TimeDelta TimeDelta::FromDouble(double value) { - double max_magnitude = std::numeric_limits<int64_t>::max(); - TimeDelta delta = TimeDelta(static_cast<int64_t>(value)); - if (value > max_magnitude) - delta = Max(); - else if (value < -max_magnitude) - delta = -Max(); - return delta; -} - -// For logging use only. -BASE_EXPORT std::ostream& operator<<(std::ostream& os, Time time); - -// TimeTicks ------------------------------------------------------------------ - -// Represents monotonically non-decreasing clock time. -class BASE_EXPORT TimeTicks : public time_internal::TimeBase<TimeTicks> { - public: - TimeTicks() : TimeBase(0) { - } - - // Platform-dependent tick count representing "right now." When - // IsHighResolution() returns false, the resolution of the clock could be - // as coarse as ~15.6ms. Otherwise, the resolution should be no worse than one - // microsecond. - static TimeTicks Now(); - - // Returns true if the high resolution clock is working on this system and - // Now() will return high resolution values. Note that, on systems where the - // high resolution clock works but is deemed inefficient, the low resolution - // clock will be used instead. - static bool IsHighResolution(); - -#if defined(OS_WIN) - // Translates an absolute QPC timestamp into a TimeTicks value. The returned - // value has the same origin as Now(). Do NOT attempt to use this if - // IsHighResolution() returns false. - static TimeTicks FromQPCValue(LONGLONG qpc_value); -#endif - - // Get an estimate of the TimeTick value at the time of the UnixEpoch. Because - // Time and TimeTicks respond differently to user-set time and NTP - // adjustments, this number is only an estimate. Nevertheless, this can be - // useful when you need to relate the value of TimeTicks to a real time and - // date. Note: Upon first invocation, this function takes a snapshot of the - // realtime clock to establish a reference point. This function will return - // the same value for the duration of the application, but will be different - // in future application runs. - static TimeTicks UnixEpoch(); - - // Returns |this| snapped to the next tick, given a |tick_phase| and - // repeating |tick_interval| in both directions. |this| may be before, - // after, or equal to the |tick_phase|. - TimeTicks SnappedToNextTick(TimeTicks tick_phase, - TimeDelta tick_interval) const; - -#if defined(OS_WIN) - protected: - typedef DWORD (*TickFunctionType)(void); - static TickFunctionType SetMockTickFunction(TickFunctionType ticker); -#endif - - private: - friend class time_internal::TimeBase<TimeTicks>; - - // Please use Now() to create a new object. This is for internal use - // and testing. - explicit TimeTicks(int64_t us) : TimeBase(us) {} -}; - -// For logging use only. -BASE_EXPORT std::ostream& operator<<(std::ostream& os, TimeTicks time_ticks); - -// ThreadTicks ---------------------------------------------------------------- - -// Represents a clock, specific to a particular thread, than runs only while the -// thread is running. -class BASE_EXPORT ThreadTicks : public time_internal::TimeBase<ThreadTicks> { - public: - ThreadTicks() : TimeBase(0) { - } - - // Returns true if ThreadTicks::Now() is supported on this system. - static bool IsSupported() { -#if (defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME >= 0)) || \ - (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_ANDROID) - return true; -#elif defined(OS_WIN) - return IsSupportedWin(); -#else - return false; -#endif - } - - // Waits until the initialization is completed. Needs to be guarded with a - // call to IsSupported(). - static void WaitUntilInitialized() { -#if defined(OS_WIN) - WaitUntilInitializedWin(); -#endif - } - - // Returns thread-specific CPU-time on systems that support this feature. - // Needs to be guarded with a call to IsSupported(). Use this timer - // to (approximately) measure how much time the calling thread spent doing - // actual work vs. being de-scheduled. May return bogus results if the thread - // migrates to another CPU between two calls. Returns an empty ThreadTicks - // object until the initialization is completed. If a clock reading is - // absolutely needed, call WaitUntilInitialized() before this method. - static ThreadTicks Now(); - - private: - friend class time_internal::TimeBase<ThreadTicks>; - - // Please use Now() to create a new object. This is for internal use - // and testing. - explicit ThreadTicks(int64_t us) : TimeBase(us) {} - -#if defined(OS_WIN) - FRIEND_TEST_ALL_PREFIXES(TimeTicks, TSCTicksPerSecond); - - // Returns the frequency of the TSC in ticks per second, or 0 if it hasn't - // been measured yet. Needs to be guarded with a call to IsSupported(). - // This method is declared here rather than in the anonymous namespace to - // allow testing. - static double TSCTicksPerSecond(); - - static bool IsSupportedWin(); - static void WaitUntilInitializedWin(); -#endif -}; - -// For logging use only. -BASE_EXPORT std::ostream& operator<<(std::ostream& os, ThreadTicks time_ticks); - -} // namespace base - -#endif // BASE_TIME_TIME_H_ diff --git a/security/sandbox/chromium/base/time/time_posix.cc b/security/sandbox/chromium/base/time/time_posix.cc deleted file mode 100644 index 4aadee618..000000000 --- a/security/sandbox/chromium/base/time/time_posix.cc +++ /dev/null @@ -1,363 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/time/time.h" - -#include <stdint.h> -#include <sys/time.h> -#include <time.h> -#if defined(OS_ANDROID) && !defined(__LP64__) -#include <time64.h> -#endif -#include <unistd.h> - -#include <limits> -#include <ostream> - -#include "base/logging.h" -#include "build/build_config.h" - -#if defined(OS_ANDROID) -#include "base/os_compat_android.h" -#elif defined(OS_NACL) -#include "base/os_compat_nacl.h" -#endif - -#if !defined(OS_MACOSX) -#include "base/lazy_instance.h" -#include "base/synchronization/lock.h" -#endif - -namespace { - -#if !defined(OS_MACOSX) -// This prevents a crash on traversing the environment global and looking up -// the 'TZ' variable in libc. See: crbug.com/390567. -base::LazyInstance<base::Lock>::Leaky - g_sys_time_to_time_struct_lock = LAZY_INSTANCE_INITIALIZER; - -// Define a system-specific SysTime that wraps either to a time_t or -// a time64_t depending on the host system, and associated convertion. -// See crbug.com/162007 -#if defined(OS_ANDROID) && !defined(__LP64__) -typedef time64_t SysTime; - -SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) { - base::AutoLock locked(g_sys_time_to_time_struct_lock.Get()); - if (is_local) - return mktime64(timestruct); - else - return timegm64(timestruct); -} - -void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) { - base::AutoLock locked(g_sys_time_to_time_struct_lock.Get()); - if (is_local) - localtime64_r(&t, timestruct); - else - gmtime64_r(&t, timestruct); -} - -#else // OS_ANDROID && !__LP64__ -typedef time_t SysTime; - -SysTime SysTimeFromTimeStruct(struct tm* timestruct, bool is_local) { - base::AutoLock locked(g_sys_time_to_time_struct_lock.Get()); - if (is_local) - return mktime(timestruct); - else - return timegm(timestruct); -} - -void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) { - base::AutoLock locked(g_sys_time_to_time_struct_lock.Get()); - if (is_local) - localtime_r(&t, timestruct); - else - gmtime_r(&t, timestruct); -} -#endif // OS_ANDROID - -int64_t ConvertTimespecToMicros(const struct timespec& ts) { - base::CheckedNumeric<int64_t> result(ts.tv_sec); - result *= base::Time::kMicrosecondsPerSecond; - result += (ts.tv_nsec / base::Time::kNanosecondsPerMicrosecond); - return result.ValueOrDie(); -} - -// Helper function to get results from clock_gettime() and convert to a -// microsecond timebase. Minimum requirement is MONOTONIC_CLOCK to be supported -// on the system. FreeBSD 6 has CLOCK_MONOTONIC but defines -// _POSIX_MONOTONIC_CLOCK to -1. -#if (defined(OS_POSIX) && \ - defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0) || \ - defined(OS_BSD) || defined(OS_ANDROID) -int64_t ClockNow(clockid_t clk_id) { - struct timespec ts; - if (clock_gettime(clk_id, &ts) != 0) { - NOTREACHED() << "clock_gettime(" << clk_id << ") failed."; - return 0; - } - return ConvertTimespecToMicros(ts); -} -#else // _POSIX_MONOTONIC_CLOCK -#error No usable tick clock function on this platform. -#endif // _POSIX_MONOTONIC_CLOCK -#endif // !defined(OS_MACOSX) - -} // namespace - -namespace base { - -struct timespec TimeDelta::ToTimeSpec() const { - int64_t microseconds = InMicroseconds(); - time_t seconds = 0; - if (microseconds >= Time::kMicrosecondsPerSecond) { - seconds = InSeconds(); - microseconds -= seconds * Time::kMicrosecondsPerSecond; - } - struct timespec result = - {seconds, - static_cast<long>(microseconds * Time::kNanosecondsPerMicrosecond)}; - return result; -} - -#if !defined(OS_MACOSX) -// The Time routines in this file use standard POSIX routines, or almost- -// standard routines in the case of timegm. We need to use a Mach-specific -// function for TimeTicks::Now() on Mac OS X. - -// Time ----------------------------------------------------------------------- - -// Windows uses a Gregorian epoch of 1601. We need to match this internally -// so that our time representations match across all platforms. See bug 14734. -// irb(main):010:0> Time.at(0).getutc() -// => Thu Jan 01 00:00:00 UTC 1970 -// irb(main):011:0> Time.at(-11644473600).getutc() -// => Mon Jan 01 00:00:00 UTC 1601 -static const int64_t kWindowsEpochDeltaSeconds = INT64_C(11644473600); - -// static -const int64_t Time::kWindowsEpochDeltaMicroseconds = - kWindowsEpochDeltaSeconds * Time::kMicrosecondsPerSecond; - -// Some functions in time.cc use time_t directly, so we provide an offset -// to convert from time_t (Unix epoch) and internal (Windows epoch). -// static -const int64_t Time::kTimeTToMicrosecondsOffset = kWindowsEpochDeltaMicroseconds; - -// static -Time Time::Now() { - struct timeval tv; - struct timezone tz = { 0, 0 }; // UTC - if (gettimeofday(&tv, &tz) != 0) { - DCHECK(0) << "Could not determine time of day"; - PLOG(ERROR) << "Call to gettimeofday failed."; - // Return null instead of uninitialized |tv| value, which contains random - // garbage data. This may result in the crash seen in crbug.com/147570. - return Time(); - } - // Combine seconds and microseconds in a 64-bit field containing microseconds - // since the epoch. That's enough for nearly 600 centuries. Adjust from - // Unix (1970) to Windows (1601) epoch. - return Time((tv.tv_sec * kMicrosecondsPerSecond + tv.tv_usec) + - kWindowsEpochDeltaMicroseconds); -} - -// static -Time Time::NowFromSystemTime() { - // Just use Now() because Now() returns the system time. - return Now(); -} - -void Time::Explode(bool is_local, Exploded* exploded) const { - // Time stores times with microsecond resolution, but Exploded only carries - // millisecond resolution, so begin by being lossy. Adjust from Windows - // epoch (1601) to Unix epoch (1970); - int64_t microseconds = us_ - kWindowsEpochDeltaMicroseconds; - // The following values are all rounded towards -infinity. - int64_t milliseconds; // Milliseconds since epoch. - SysTime seconds; // Seconds since epoch. - int millisecond; // Exploded millisecond value (0-999). - if (microseconds >= 0) { - // Rounding towards -infinity <=> rounding towards 0, in this case. - milliseconds = microseconds / kMicrosecondsPerMillisecond; - seconds = milliseconds / kMillisecondsPerSecond; - millisecond = milliseconds % kMillisecondsPerSecond; - } else { - // Round these *down* (towards -infinity). - milliseconds = (microseconds - kMicrosecondsPerMillisecond + 1) / - kMicrosecondsPerMillisecond; - seconds = (milliseconds - kMillisecondsPerSecond + 1) / - kMillisecondsPerSecond; - // Make this nonnegative (and between 0 and 999 inclusive). - millisecond = milliseconds % kMillisecondsPerSecond; - if (millisecond < 0) - millisecond += kMillisecondsPerSecond; - } - - struct tm timestruct; - SysTimeToTimeStruct(seconds, ×truct, is_local); - - exploded->year = timestruct.tm_year + 1900; - exploded->month = timestruct.tm_mon + 1; - exploded->day_of_week = timestruct.tm_wday; - exploded->day_of_month = timestruct.tm_mday; - exploded->hour = timestruct.tm_hour; - exploded->minute = timestruct.tm_min; - exploded->second = timestruct.tm_sec; - exploded->millisecond = millisecond; -} - -// static -Time Time::FromExploded(bool is_local, const Exploded& exploded) { - struct tm timestruct; - timestruct.tm_sec = exploded.second; - timestruct.tm_min = exploded.minute; - timestruct.tm_hour = exploded.hour; - timestruct.tm_mday = exploded.day_of_month; - timestruct.tm_mon = exploded.month - 1; - timestruct.tm_year = exploded.year - 1900; - timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this - timestruct.tm_yday = 0; // mktime/timegm ignore this - timestruct.tm_isdst = -1; // attempt to figure it out -#if !defined(OS_NACL) && !defined(OS_SOLARIS) - timestruct.tm_gmtoff = 0; // not a POSIX field, so mktime/timegm ignore - timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore -#endif - - int64_t milliseconds; - SysTime seconds; - - // Certain exploded dates do not really exist due to daylight saving times, - // and this causes mktime() to return implementation-defined values when - // tm_isdst is set to -1. On Android, the function will return -1, while the - // C libraries of other platforms typically return a liberally-chosen value. - // Handling this requires the special code below. - - // SysTimeFromTimeStruct() modifies the input structure, save current value. - struct tm timestruct0 = timestruct; - - seconds = SysTimeFromTimeStruct(×truct, is_local); - if (seconds == -1) { - // Get the time values with tm_isdst == 0 and 1, then select the closest one - // to UTC 00:00:00 that isn't -1. - timestruct = timestruct0; - timestruct.tm_isdst = 0; - int64_t seconds_isdst0 = SysTimeFromTimeStruct(×truct, is_local); - - timestruct = timestruct0; - timestruct.tm_isdst = 1; - int64_t seconds_isdst1 = SysTimeFromTimeStruct(×truct, is_local); - - // seconds_isdst0 or seconds_isdst1 can be -1 for some timezones. - // E.g. "CLST" (Chile Summer Time) returns -1 for 'tm_isdt == 1'. - if (seconds_isdst0 < 0) - seconds = seconds_isdst1; - else if (seconds_isdst1 < 0) - seconds = seconds_isdst0; - else - seconds = std::min(seconds_isdst0, seconds_isdst1); - } - - // Handle overflow. Clamping the range to what mktime and timegm might - // return is the best that can be done here. It's not ideal, but it's better - // than failing here or ignoring the overflow case and treating each time - // overflow as one second prior to the epoch. - if (seconds == -1 && - (exploded.year < 1969 || exploded.year > 1970)) { - // If exploded.year is 1969 or 1970, take -1 as correct, with the - // time indicating 1 second prior to the epoch. (1970 is allowed to handle - // time zone and DST offsets.) Otherwise, return the most future or past - // time representable. Assumes the time_t epoch is 1970-01-01 00:00:00 UTC. - // - // The minimum and maximum representible times that mktime and timegm could - // return are used here instead of values outside that range to allow for - // proper round-tripping between exploded and counter-type time - // representations in the presence of possible truncation to time_t by - // division and use with other functions that accept time_t. - // - // When representing the most distant time in the future, add in an extra - // 999ms to avoid the time being less than any other possible value that - // this function can return. - - // On Android, SysTime is int64_t, special care must be taken to avoid - // overflows. - const int64_t min_seconds = (sizeof(SysTime) < sizeof(int64_t)) - ? std::numeric_limits<SysTime>::min() - : std::numeric_limits<int32_t>::min(); - const int64_t max_seconds = (sizeof(SysTime) < sizeof(int64_t)) - ? std::numeric_limits<SysTime>::max() - : std::numeric_limits<int32_t>::max(); - if (exploded.year < 1969) { - milliseconds = min_seconds * kMillisecondsPerSecond; - } else { - milliseconds = max_seconds * kMillisecondsPerSecond; - milliseconds += (kMillisecondsPerSecond - 1); - } - } else { - milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond; - } - - // Adjust from Unix (1970) to Windows (1601) epoch. - return Time((milliseconds * kMicrosecondsPerMillisecond) + - kWindowsEpochDeltaMicroseconds); -} - -// TimeTicks ------------------------------------------------------------------ -// static -TimeTicks TimeTicks::Now() { - return TimeTicks(ClockNow(CLOCK_MONOTONIC)); -} - -// static -bool TimeTicks::IsHighResolution() { - return true; -} - -// static -ThreadTicks ThreadTicks::Now() { -#if (defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME >= 0)) || \ - defined(OS_ANDROID) - return ThreadTicks(ClockNow(CLOCK_THREAD_CPUTIME_ID)); -#else - NOTREACHED(); - return ThreadTicks(); -#endif -} - -#endif // !OS_MACOSX - -// static -Time Time::FromTimeVal(struct timeval t) { - DCHECK_LT(t.tv_usec, static_cast<int>(Time::kMicrosecondsPerSecond)); - DCHECK_GE(t.tv_usec, 0); - if (t.tv_usec == 0 && t.tv_sec == 0) - return Time(); - if (t.tv_usec == static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1 && - t.tv_sec == std::numeric_limits<time_t>::max()) - return Max(); - return Time((static_cast<int64_t>(t.tv_sec) * Time::kMicrosecondsPerSecond) + - t.tv_usec + kTimeTToMicrosecondsOffset); -} - -struct timeval Time::ToTimeVal() const { - struct timeval result; - if (is_null()) { - result.tv_sec = 0; - result.tv_usec = 0; - return result; - } - if (is_max()) { - result.tv_sec = std::numeric_limits<time_t>::max(); - result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1; - return result; - } - int64_t us = us_ - kTimeTToMicrosecondsOffset; - result.tv_sec = us / Time::kMicrosecondsPerSecond; - result.tv_usec = us % Time::kMicrosecondsPerSecond; - return result; -} - -} // namespace base diff --git a/security/sandbox/chromium/base/time/time_win.cc b/security/sandbox/chromium/base/time/time_win.cc deleted file mode 100644 index dc968ad63..000000000 --- a/security/sandbox/chromium/base/time/time_win.cc +++ /dev/null @@ -1,616 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - - -// Windows Timer Primer -// -// A good article: http://www.ddj.com/windows/184416651 -// A good mozilla bug: http://bugzilla.mozilla.org/show_bug.cgi?id=363258 -// -// The default windows timer, GetSystemTimeAsFileTime is not very precise. -// It is only good to ~15.5ms. -// -// QueryPerformanceCounter is the logical choice for a high-precision timer. -// However, it is known to be buggy on some hardware. Specifically, it can -// sometimes "jump". On laptops, QPC can also be very expensive to call. -// It's 3-4x slower than timeGetTime() on desktops, but can be 10x slower -// on laptops. A unittest exists which will show the relative cost of various -// timers on any system. -// -// The next logical choice is timeGetTime(). timeGetTime has a precision of -// 1ms, but only if you call APIs (timeBeginPeriod()) which affect all other -// applications on the system. By default, precision is only 15.5ms. -// Unfortunately, we don't want to call timeBeginPeriod because we don't -// want to affect other applications. Further, on mobile platforms, use of -// faster multimedia timers can hurt battery life. See the intel -// article about this here: -// http://softwarecommunity.intel.com/articles/eng/1086.htm -// -// To work around all this, we're going to generally use timeGetTime(). We -// will only increase the system-wide timer if we're not running on battery -// power. - -#include "base/time/time.h" - -#pragma comment(lib, "winmm.lib") -#include <windows.h> -#include <mmsystem.h> -#include <stdint.h> - -#include "base/bit_cast.h" -#include "base/cpu.h" -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/synchronization/lock.h" - -using base::ThreadTicks; -using base::Time; -using base::TimeDelta; -using base::TimeTicks; - -namespace { - -// From MSDN, FILETIME "Contains a 64-bit value representing the number of -// 100-nanosecond intervals since January 1, 1601 (UTC)." -int64_t FileTimeToMicroseconds(const FILETIME& ft) { - // Need to bit_cast to fix alignment, then divide by 10 to convert - // 100-nanoseconds to microseconds. This only works on little-endian - // machines. - return bit_cast<int64_t, FILETIME>(ft) / 10; -} - -void MicrosecondsToFileTime(int64_t us, FILETIME* ft) { - DCHECK_GE(us, 0LL) << "Time is less than 0, negative values are not " - "representable in FILETIME"; - - // Multiply by 10 to convert microseconds to 100-nanoseconds. Bit_cast will - // handle alignment problems. This only works on little-endian machines. - *ft = bit_cast<FILETIME, int64_t>(us * 10); -} - -int64_t CurrentWallclockMicroseconds() { - FILETIME ft; - ::GetSystemTimeAsFileTime(&ft); - return FileTimeToMicroseconds(ft); -} - -// Time between resampling the un-granular clock for this API. 60 seconds. -const int kMaxMillisecondsToAvoidDrift = 60 * Time::kMillisecondsPerSecond; - -int64_t initial_time = 0; -TimeTicks initial_ticks; - -void InitializeClock() { - initial_ticks = TimeTicks::Now(); - initial_time = CurrentWallclockMicroseconds(); -} - -// The two values that ActivateHighResolutionTimer uses to set the systemwide -// timer interrupt frequency on Windows. It controls how precise timers are -// but also has a big impact on battery life. -const int kMinTimerIntervalHighResMs = 1; -const int kMinTimerIntervalLowResMs = 4; -// Track if kMinTimerIntervalHighResMs or kMinTimerIntervalLowResMs is active. -bool g_high_res_timer_enabled = false; -// How many times the high resolution timer has been called. -uint32_t g_high_res_timer_count = 0; -// The lock to control access to the above two variables. -base::LazyInstance<base::Lock>::Leaky g_high_res_lock = - LAZY_INSTANCE_INITIALIZER; - -// Returns a pointer to the QueryThreadCycleTime() function from Windows. -// Can't statically link to it because it is not available on XP. -using QueryThreadCycleTimePtr = decltype(::QueryThreadCycleTime)*; -QueryThreadCycleTimePtr GetQueryThreadCycleTimeFunction() { - static const QueryThreadCycleTimePtr query_thread_cycle_time_fn = - reinterpret_cast<QueryThreadCycleTimePtr>(::GetProcAddress( - ::GetModuleHandle(L"kernel32.dll"), "QueryThreadCycleTime")); - return query_thread_cycle_time_fn; -} - -// Returns the current value of the performance counter. -uint64_t QPCNowRaw() { - LARGE_INTEGER perf_counter_now = {}; - // According to the MSDN documentation for QueryPerformanceCounter(), this - // will never fail on systems that run XP or later. - // https://msdn.microsoft.com/library/windows/desktop/ms644904.aspx - ::QueryPerformanceCounter(&perf_counter_now); - return perf_counter_now.QuadPart; -} - -} // namespace - -// Time ----------------------------------------------------------------------- - -// The internal representation of Time uses FILETIME, whose epoch is 1601-01-01 -// 00:00:00 UTC. ((1970-1601)*365+89)*24*60*60*1000*1000, where 89 is the -// number of leap year days between 1601 and 1970: (1970-1601)/4 excluding -// 1700, 1800, and 1900. -// static -const int64_t Time::kTimeTToMicrosecondsOffset = INT64_C(11644473600000000); - -// static -Time Time::Now() { - if (initial_time == 0) - InitializeClock(); - - // We implement time using the high-resolution timers so that we can get - // timeouts which are smaller than 10-15ms. If we just used - // CurrentWallclockMicroseconds(), we'd have the less-granular timer. - // - // To make this work, we initialize the clock (initial_time) and the - // counter (initial_ctr). To compute the initial time, we can check - // the number of ticks that have elapsed, and compute the delta. - // - // To avoid any drift, we periodically resync the counters to the system - // clock. - while (true) { - TimeTicks ticks = TimeTicks::Now(); - - // Calculate the time elapsed since we started our timer - TimeDelta elapsed = ticks - initial_ticks; - - // Check if enough time has elapsed that we need to resync the clock. - if (elapsed.InMilliseconds() > kMaxMillisecondsToAvoidDrift) { - InitializeClock(); - continue; - } - - return Time(elapsed + Time(initial_time)); - } -} - -// static -Time Time::NowFromSystemTime() { - // Force resync. - InitializeClock(); - return Time(initial_time); -} - -// static -Time Time::FromFileTime(FILETIME ft) { - if (bit_cast<int64_t, FILETIME>(ft) == 0) - return Time(); - if (ft.dwHighDateTime == std::numeric_limits<DWORD>::max() && - ft.dwLowDateTime == std::numeric_limits<DWORD>::max()) - return Max(); - return Time(FileTimeToMicroseconds(ft)); -} - -FILETIME Time::ToFileTime() const { - if (is_null()) - return bit_cast<FILETIME, int64_t>(0); - if (is_max()) { - FILETIME result; - result.dwHighDateTime = std::numeric_limits<DWORD>::max(); - result.dwLowDateTime = std::numeric_limits<DWORD>::max(); - return result; - } - FILETIME utc_ft; - MicrosecondsToFileTime(us_, &utc_ft); - return utc_ft; -} - -// static -void Time::EnableHighResolutionTimer(bool enable) { - base::AutoLock lock(g_high_res_lock.Get()); - if (g_high_res_timer_enabled == enable) - return; - g_high_res_timer_enabled = enable; - if (!g_high_res_timer_count) - return; - // Since g_high_res_timer_count != 0, an ActivateHighResolutionTimer(true) - // was called which called timeBeginPeriod with g_high_res_timer_enabled - // with a value which is the opposite of |enable|. With that information we - // call timeEndPeriod with the same value used in timeBeginPeriod and - // therefore undo the period effect. - if (enable) { - timeEndPeriod(kMinTimerIntervalLowResMs); - timeBeginPeriod(kMinTimerIntervalHighResMs); - } else { - timeEndPeriod(kMinTimerIntervalHighResMs); - timeBeginPeriod(kMinTimerIntervalLowResMs); - } -} - -// static -bool Time::ActivateHighResolutionTimer(bool activating) { - // We only do work on the transition from zero to one or one to zero so we - // can easily undo the effect (if necessary) when EnableHighResolutionTimer is - // called. - const uint32_t max = std::numeric_limits<uint32_t>::max(); - - base::AutoLock lock(g_high_res_lock.Get()); - UINT period = g_high_res_timer_enabled ? kMinTimerIntervalHighResMs - : kMinTimerIntervalLowResMs; - if (activating) { - DCHECK_NE(g_high_res_timer_count, max); - ++g_high_res_timer_count; - if (g_high_res_timer_count == 1) - timeBeginPeriod(period); - } else { - DCHECK_NE(g_high_res_timer_count, 0u); - --g_high_res_timer_count; - if (g_high_res_timer_count == 0) - timeEndPeriod(period); - } - return (period == kMinTimerIntervalHighResMs); -} - -// static -bool Time::IsHighResolutionTimerInUse() { - base::AutoLock lock(g_high_res_lock.Get()); - return g_high_res_timer_enabled && g_high_res_timer_count > 0; -} - -// static -Time Time::FromExploded(bool is_local, const Exploded& exploded) { - // Create the system struct representing our exploded time. It will either be - // in local time or UTC. - SYSTEMTIME st; - st.wYear = static_cast<WORD>(exploded.year); - st.wMonth = static_cast<WORD>(exploded.month); - st.wDayOfWeek = static_cast<WORD>(exploded.day_of_week); - st.wDay = static_cast<WORD>(exploded.day_of_month); - st.wHour = static_cast<WORD>(exploded.hour); - st.wMinute = static_cast<WORD>(exploded.minute); - st.wSecond = static_cast<WORD>(exploded.second); - st.wMilliseconds = static_cast<WORD>(exploded.millisecond); - - FILETIME ft; - bool success = true; - // Ensure that it's in UTC. - if (is_local) { - SYSTEMTIME utc_st; - success = TzSpecificLocalTimeToSystemTime(NULL, &st, &utc_st) && - SystemTimeToFileTime(&utc_st, &ft); - } else { - success = !!SystemTimeToFileTime(&st, &ft); - } - - if (!success) { - NOTREACHED() << "Unable to convert time"; - return Time(0); - } - return Time(FileTimeToMicroseconds(ft)); -} - -void Time::Explode(bool is_local, Exploded* exploded) const { - if (us_ < 0LL) { - // We are not able to convert it to FILETIME. - ZeroMemory(exploded, sizeof(*exploded)); - return; - } - - // FILETIME in UTC. - FILETIME utc_ft; - MicrosecondsToFileTime(us_, &utc_ft); - - // FILETIME in local time if necessary. - bool success = true; - // FILETIME in SYSTEMTIME (exploded). - SYSTEMTIME st = {0}; - if (is_local) { - SYSTEMTIME utc_st; - // We don't use FileTimeToLocalFileTime here, since it uses the current - // settings for the time zone and daylight saving time. Therefore, if it is - // daylight saving time, it will take daylight saving time into account, - // even if the time you are converting is in standard time. - success = FileTimeToSystemTime(&utc_ft, &utc_st) && - SystemTimeToTzSpecificLocalTime(NULL, &utc_st, &st); - } else { - success = !!FileTimeToSystemTime(&utc_ft, &st); - } - - if (!success) { - NOTREACHED() << "Unable to convert time, don't know why"; - ZeroMemory(exploded, sizeof(*exploded)); - return; - } - - exploded->year = st.wYear; - exploded->month = st.wMonth; - exploded->day_of_week = st.wDayOfWeek; - exploded->day_of_month = st.wDay; - exploded->hour = st.wHour; - exploded->minute = st.wMinute; - exploded->second = st.wSecond; - exploded->millisecond = st.wMilliseconds; -} - -// TimeTicks ------------------------------------------------------------------ -namespace { - -// We define a wrapper to adapt between the __stdcall and __cdecl call of the -// mock function, and to avoid a static constructor. Assigning an import to a -// function pointer directly would require setup code to fetch from the IAT. -DWORD timeGetTimeWrapper() { - return timeGetTime(); -} - -DWORD (*g_tick_function)(void) = &timeGetTimeWrapper; - -// Accumulation of time lost due to rollover (in milliseconds). -int64_t g_rollover_ms = 0; - -// The last timeGetTime value we saw, to detect rollover. -DWORD g_last_seen_now = 0; - -// Lock protecting rollover_ms and last_seen_now. -// Note: this is a global object, and we usually avoid these. However, the time -// code is low-level, and we don't want to use Singletons here (it would be too -// easy to use a Singleton without even knowing it, and that may lead to many -// gotchas). Its impact on startup time should be negligible due to low-level -// nature of time code. -base::Lock g_rollover_lock; - -// We use timeGetTime() to implement TimeTicks::Now(). This can be problematic -// because it returns the number of milliseconds since Windows has started, -// which will roll over the 32-bit value every ~49 days. We try to track -// rollover ourselves, which works if TimeTicks::Now() is called at least every -// 49 days. -TimeDelta RolloverProtectedNow() { - base::AutoLock locked(g_rollover_lock); - // We should hold the lock while calling tick_function to make sure that - // we keep last_seen_now stay correctly in sync. - DWORD now = g_tick_function(); - if (now < g_last_seen_now) - g_rollover_ms += 0x100000000I64; // ~49.7 days. - g_last_seen_now = now; - return TimeDelta::FromMilliseconds(now + g_rollover_ms); -} - -// Discussion of tick counter options on Windows: -// -// (1) CPU cycle counter. (Retrieved via RDTSC) -// The CPU counter provides the highest resolution time stamp and is the least -// expensive to retrieve. However, on older CPUs, two issues can affect its -// reliability: First it is maintained per processor and not synchronized -// between processors. Also, the counters will change frequency due to thermal -// and power changes, and stop in some states. -// -// (2) QueryPerformanceCounter (QPC). The QPC counter provides a high- -// resolution (<1 microsecond) time stamp. On most hardware running today, it -// auto-detects and uses the constant-rate RDTSC counter to provide extremely -// efficient and reliable time stamps. -// -// On older CPUs where RDTSC is unreliable, it falls back to using more -// expensive (20X to 40X more costly) alternate clocks, such as HPET or the ACPI -// PM timer, and can involve system calls; and all this is up to the HAL (with -// some help from ACPI). According to -// http://blogs.msdn.com/oldnewthing/archive/2005/09/02/459952.aspx, in the -// worst case, it gets the counter from the rollover interrupt on the -// programmable interrupt timer. In best cases, the HAL may conclude that the -// RDTSC counter runs at a constant frequency, then it uses that instead. On -// multiprocessor machines, it will try to verify the values returned from -// RDTSC on each processor are consistent with each other, and apply a handful -// of workarounds for known buggy hardware. In other words, QPC is supposed to -// give consistent results on a multiprocessor computer, but for older CPUs it -// can be unreliable due bugs in BIOS or HAL. -// -// (3) System time. The system time provides a low-resolution (from ~1 to ~15.6 -// milliseconds) time stamp but is comparatively less expensive to retrieve and -// more reliable. Time::EnableHighResolutionTimer() and -// Time::ActivateHighResolutionTimer() can be called to alter the resolution of -// this timer; and also other Windows applications can alter it, affecting this -// one. - -using NowFunction = TimeDelta (*)(void); - -TimeDelta InitialNowFunction(); - -// See "threading notes" in InitializeNowFunctionPointer() for details on how -// concurrent reads/writes to these globals has been made safe. -NowFunction g_now_function = &InitialNowFunction; -int64_t g_qpc_ticks_per_second = 0; - -// As of January 2015, use of <atomic> is forbidden in Chromium code. This is -// what std::atomic_thread_fence does on Windows on all Intel architectures when -// the memory_order argument is anything but std::memory_order_seq_cst: -#define ATOMIC_THREAD_FENCE(memory_order) _ReadWriteBarrier(); - -TimeDelta QPCValueToTimeDelta(LONGLONG qpc_value) { - // Ensure that the assignment to |g_qpc_ticks_per_second|, made in - // InitializeNowFunctionPointer(), has happened by this point. - ATOMIC_THREAD_FENCE(memory_order_acquire); - - DCHECK_GT(g_qpc_ticks_per_second, 0); - - // If the QPC Value is below the overflow threshold, we proceed with - // simple multiply and divide. - if (qpc_value < Time::kQPCOverflowThreshold) { - return TimeDelta::FromMicroseconds( - qpc_value * Time::kMicrosecondsPerSecond / g_qpc_ticks_per_second); - } - // Otherwise, calculate microseconds in a round about manner to avoid - // overflow and precision issues. - int64_t whole_seconds = qpc_value / g_qpc_ticks_per_second; - int64_t leftover_ticks = qpc_value - (whole_seconds * g_qpc_ticks_per_second); - return TimeDelta::FromMicroseconds( - (whole_seconds * Time::kMicrosecondsPerSecond) + - ((leftover_ticks * Time::kMicrosecondsPerSecond) / - g_qpc_ticks_per_second)); -} - -TimeDelta QPCNow() { - return QPCValueToTimeDelta(QPCNowRaw()); -} - -bool IsBuggyAthlon(const base::CPU& cpu) { - // On Athlon X2 CPUs (e.g. model 15) QueryPerformanceCounter is unreliable. - return cpu.vendor_name() == "AuthenticAMD" && cpu.family() == 15; -} - -void InitializeNowFunctionPointer() { - LARGE_INTEGER ticks_per_sec = {}; - if (!QueryPerformanceFrequency(&ticks_per_sec)) - ticks_per_sec.QuadPart = 0; - - // If Windows cannot provide a QPC implementation, TimeTicks::Now() must use - // the low-resolution clock. - // - // If the QPC implementation is expensive and/or unreliable, TimeTicks::Now() - // will still use the low-resolution clock. A CPU lacking a non-stop time - // counter will cause Windows to provide an alternate QPC implementation that - // works, but is expensive to use. Certain Athlon CPUs are known to make the - // QPC implementation unreliable. - // - // Otherwise, Now uses the high-resolution QPC clock. As of 21 August 2015, - // ~72% of users fall within this category. - NowFunction now_function; - base::CPU cpu; - if (ticks_per_sec.QuadPart <= 0 || - !cpu.has_non_stop_time_stamp_counter() || IsBuggyAthlon(cpu)) { - now_function = &RolloverProtectedNow; - } else { - now_function = &QPCNow; - } - - // Threading note 1: In an unlikely race condition, it's possible for two or - // more threads to enter InitializeNowFunctionPointer() in parallel. This is - // not a problem since all threads should end up writing out the same values - // to the global variables. - // - // Threading note 2: A release fence is placed here to ensure, from the - // perspective of other threads using the function pointers, that the - // assignment to |g_qpc_ticks_per_second| happens before the function pointers - // are changed. - g_qpc_ticks_per_second = ticks_per_sec.QuadPart; - ATOMIC_THREAD_FENCE(memory_order_release); - g_now_function = now_function; -} - -TimeDelta InitialNowFunction() { - InitializeNowFunctionPointer(); - return g_now_function(); -} - -} // namespace - -// static -TimeTicks::TickFunctionType TimeTicks::SetMockTickFunction( - TickFunctionType ticker) { - base::AutoLock locked(g_rollover_lock); - TickFunctionType old = g_tick_function; - g_tick_function = ticker; - g_rollover_ms = 0; - g_last_seen_now = 0; - return old; -} - -// static -TimeTicks TimeTicks::Now() { - return TimeTicks() + g_now_function(); -} - -// static -bool TimeTicks::IsHighResolution() { - if (g_now_function == &InitialNowFunction) - InitializeNowFunctionPointer(); - return g_now_function == &QPCNow; -} - -// static -ThreadTicks ThreadTicks::Now() { - DCHECK(IsSupported()); - - // Get the number of TSC ticks used by the current thread. - ULONG64 thread_cycle_time = 0; - GetQueryThreadCycleTimeFunction()(::GetCurrentThread(), &thread_cycle_time); - - // Get the frequency of the TSC. - double tsc_ticks_per_second = TSCTicksPerSecond(); - if (tsc_ticks_per_second == 0) - return ThreadTicks(); - - // Return the CPU time of the current thread. - double thread_time_seconds = thread_cycle_time / tsc_ticks_per_second; - return ThreadTicks( - static_cast<int64_t>(thread_time_seconds * Time::kMicrosecondsPerSecond)); -} - -// static -bool ThreadTicks::IsSupportedWin() { - static bool is_supported = GetQueryThreadCycleTimeFunction() && - base::CPU().has_non_stop_time_stamp_counter() && - !IsBuggyAthlon(base::CPU()); - return is_supported; -} - -// static -void ThreadTicks::WaitUntilInitializedWin() { - while (TSCTicksPerSecond() == 0) - ::Sleep(10); -} - -double ThreadTicks::TSCTicksPerSecond() { - DCHECK(IsSupported()); - - // The value returned by QueryPerformanceFrequency() cannot be used as the TSC - // frequency, because there is no guarantee that the TSC frequency is equal to - // the performance counter frequency. - - // The TSC frequency is cached in a static variable because it takes some time - // to compute it. - static double tsc_ticks_per_second = 0; - if (tsc_ticks_per_second != 0) - return tsc_ticks_per_second; - - // Increase the thread priority to reduces the chances of having a context - // switch during a reading of the TSC and the performance counter. - int previous_priority = ::GetThreadPriority(::GetCurrentThread()); - ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_HIGHEST); - - // The first time that this function is called, make an initial reading of the - // TSC and the performance counter. - static const uint64_t tsc_initial = __rdtsc(); - static const uint64_t perf_counter_initial = QPCNowRaw(); - - // Make a another reading of the TSC and the performance counter every time - // that this function is called. - uint64_t tsc_now = __rdtsc(); - uint64_t perf_counter_now = QPCNowRaw(); - - // Reset the thread priority. - ::SetThreadPriority(::GetCurrentThread(), previous_priority); - - // Make sure that at least 50 ms elapsed between the 2 readings. The first - // time that this function is called, we don't expect this to be the case. - // Note: The longer the elapsed time between the 2 readings is, the more - // accurate the computed TSC frequency will be. The 50 ms value was - // chosen because local benchmarks show that it allows us to get a - // stddev of less than 1 tick/us between multiple runs. - // Note: According to the MSDN documentation for QueryPerformanceFrequency(), - // this will never fail on systems that run XP or later. - // https://msdn.microsoft.com/library/windows/desktop/ms644905.aspx - LARGE_INTEGER perf_counter_frequency = {}; - ::QueryPerformanceFrequency(&perf_counter_frequency); - DCHECK_GE(perf_counter_now, perf_counter_initial); - uint64_t perf_counter_ticks = perf_counter_now - perf_counter_initial; - double elapsed_time_seconds = - perf_counter_ticks / static_cast<double>(perf_counter_frequency.QuadPart); - - const double kMinimumEvaluationPeriodSeconds = 0.05; - if (elapsed_time_seconds < kMinimumEvaluationPeriodSeconds) - return 0; - - // Compute the frequency of the TSC. - DCHECK_GE(tsc_now, tsc_initial); - uint64_t tsc_ticks = tsc_now - tsc_initial; - tsc_ticks_per_second = tsc_ticks / elapsed_time_seconds; - - return tsc_ticks_per_second; -} - -// static -TimeTicks TimeTicks::FromQPCValue(LONGLONG qpc_value) { - return TimeTicks() + QPCValueToTimeDelta(qpc_value); -} - -// TimeDelta ------------------------------------------------------------------ - -// static -TimeDelta TimeDelta::FromQPCValue(LONGLONG qpc_value) { - return QPCValueToTimeDelta(qpc_value); -} diff --git a/security/sandbox/chromium/base/tuple.h b/security/sandbox/chromium/base/tuple.h deleted file mode 100644 index e5872cc4f..000000000 --- a/security/sandbox/chromium/base/tuple.h +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// A Tuple is a generic templatized container, similar in concept to std::pair -// and std::tuple. The convenient MakeTuple() function takes any number of -// arguments and will construct and return the appropriate Tuple object. The -// functions DispatchToMethod and DispatchToFunction take a function pointer or -// instance and method pointer, and unpack a tuple into arguments to the call. -// -// Tuple elements are copied by value, and stored in the tuple. See the unit -// tests for more details of how/when the values are copied. -// -// Example usage: -// // These two methods of creating a Tuple are identical. -// Tuple<int, const char*> tuple_a(1, "wee"); -// Tuple<int, const char*> tuple_b = MakeTuple(1, "wee"); -// -// void SomeFunc(int a, const char* b) { } -// DispatchToFunction(&SomeFunc, tuple_a); // SomeFunc(1, "wee") -// DispatchToFunction( -// &SomeFunc, MakeTuple(10, "foo")); // SomeFunc(10, "foo") -// -// struct { void SomeMeth(int a, int b, int c) { } } foo; -// DispatchToMethod(&foo, &Foo::SomeMeth, MakeTuple(1, 2, 3)); -// // foo->SomeMeth(1, 2, 3); - -#ifndef BASE_TUPLE_H_ -#define BASE_TUPLE_H_ - -#include <stddef.h> - -#include "base/bind_helpers.h" -#include "build/build_config.h" - -namespace base { - -// Index sequences -// -// Minimal clone of the similarly-named C++14 functionality. - -template <size_t...> -struct IndexSequence {}; - -template <size_t... Ns> -struct MakeIndexSequenceImpl; - -#if defined(_PREFAST_) && defined(OS_WIN) - -// Work around VC++ 2013 /analyze internal compiler error: -// https://connect.microsoft.com/VisualStudio/feedback/details/1053626 - -template <> struct MakeIndexSequenceImpl<0> { - using Type = IndexSequence<>; -}; -template <> struct MakeIndexSequenceImpl<1> { - using Type = IndexSequence<0>; -}; -template <> struct MakeIndexSequenceImpl<2> { - using Type = IndexSequence<0,1>; -}; -template <> struct MakeIndexSequenceImpl<3> { - using Type = IndexSequence<0,1,2>; -}; -template <> struct MakeIndexSequenceImpl<4> { - using Type = IndexSequence<0,1,2,3>; -}; -template <> struct MakeIndexSequenceImpl<5> { - using Type = IndexSequence<0,1,2,3,4>; -}; -template <> struct MakeIndexSequenceImpl<6> { - using Type = IndexSequence<0,1,2,3,4,5>; -}; -template <> struct MakeIndexSequenceImpl<7> { - using Type = IndexSequence<0,1,2,3,4,5,6>; -}; -template <> struct MakeIndexSequenceImpl<8> { - using Type = IndexSequence<0,1,2,3,4,5,6,7>; -}; -template <> struct MakeIndexSequenceImpl<9> { - using Type = IndexSequence<0,1,2,3,4,5,6,7,8>; -}; -template <> struct MakeIndexSequenceImpl<10> { - using Type = IndexSequence<0,1,2,3,4,5,6,7,8,9>; -}; -template <> struct MakeIndexSequenceImpl<11> { - using Type = IndexSequence<0,1,2,3,4,5,6,7,8,9,10>; -}; -template <> struct MakeIndexSequenceImpl<12> { - using Type = IndexSequence<0,1,2,3,4,5,6,7,8,9,10,11>; -}; -template <> struct MakeIndexSequenceImpl<13> { - using Type = IndexSequence<0,1,2,3,4,5,6,7,8,9,10,11,12>; -}; - -#else // defined(WIN) && defined(_PREFAST_) - -template <size_t... Ns> -struct MakeIndexSequenceImpl<0, Ns...> { - using Type = IndexSequence<Ns...>; -}; - -template <size_t N, size_t... Ns> -struct MakeIndexSequenceImpl<N, Ns...> - : MakeIndexSequenceImpl<N - 1, N - 1, Ns...> {}; - -#endif // defined(WIN) && defined(_PREFAST_) - -template <size_t N> -using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::Type; - -// Traits ---------------------------------------------------------------------- -// -// A simple traits class for tuple arguments. -// -// ValueType: the bare, nonref version of a type (same as the type for nonrefs). -// RefType: the ref version of a type (same as the type for refs). -// ParamType: what type to pass to functions (refs should not be constified). - -template <class P> -struct TupleTraits { - typedef P ValueType; - typedef P& RefType; - typedef const P& ParamType; -}; - -template <class P> -struct TupleTraits<P&> { - typedef P ValueType; - typedef P& RefType; - typedef P& ParamType; -}; - -// Tuple ----------------------------------------------------------------------- -// -// This set of classes is useful for bundling 0 or more heterogeneous data types -// into a single variable. The advantage of this is that it greatly simplifies -// function objects that need to take an arbitrary number of parameters; see -// RunnableMethod and IPC::MessageWithTuple. -// -// Tuple<> is supplied to act as a 'void' type. It can be used, for example, -// when dispatching to a function that accepts no arguments (see the -// Dispatchers below). -// Tuple<A> is rarely useful. One such use is when A is non-const ref that you -// want filled by the dispatchee, and the tuple is merely a container for that -// output (a "tier"). See MakeRefTuple and its usages. - -template <typename IxSeq, typename... Ts> -struct TupleBaseImpl; -template <typename... Ts> -using TupleBase = TupleBaseImpl<MakeIndexSequence<sizeof...(Ts)>, Ts...>; -template <size_t N, typename T> -struct TupleLeaf; - -template <typename... Ts> -struct Tuple final : TupleBase<Ts...> { - Tuple() : TupleBase<Ts...>() {} - explicit Tuple(typename TupleTraits<Ts>::ParamType... args) - : TupleBase<Ts...>(args...) {} -}; - -// Avoids ambiguity between Tuple's two constructors. -template <> -struct Tuple<> final {}; - -template <size_t... Ns, typename... Ts> -struct TupleBaseImpl<IndexSequence<Ns...>, Ts...> : TupleLeaf<Ns, Ts>... { - TupleBaseImpl() : TupleLeaf<Ns, Ts>()... {} - explicit TupleBaseImpl(typename TupleTraits<Ts>::ParamType... args) - : TupleLeaf<Ns, Ts>(args)... {} -}; - -template <size_t N, typename T> -struct TupleLeaf { - TupleLeaf() {} - explicit TupleLeaf(typename TupleTraits<T>::ParamType x) : x(x) {} - - T& get() { return x; } - const T& get() const { return x; } - - T x; -}; - -// Tuple getters -------------------------------------------------------------- -// -// Allows accessing an arbitrary tuple element by index. -// -// Example usage: -// base::Tuple<int, double> t2; -// base::get<0>(t2) = 42; -// base::get<1>(t2) = 3.14; - -template <size_t I, typename T> -T& get(TupleLeaf<I, T>& leaf) { - return leaf.get(); -} - -template <size_t I, typename T> -const T& get(const TupleLeaf<I, T>& leaf) { - return leaf.get(); -} - -// Tuple types ---------------------------------------------------------------- -// -// Allows for selection of ValueTuple/RefTuple/ParamTuple without needing the -// definitions of class types the tuple takes as parameters. - -template <typename T> -struct TupleTypes; - -template <typename... Ts> -struct TupleTypes<Tuple<Ts...>> { - using ValueTuple = Tuple<typename TupleTraits<Ts>::ValueType...>; - using RefTuple = Tuple<typename TupleTraits<Ts>::RefType...>; - using ParamTuple = Tuple<typename TupleTraits<Ts>::ParamType...>; -}; - -// Tuple creators ------------------------------------------------------------- -// -// Helper functions for constructing tuples while inferring the template -// argument types. - -template <typename... Ts> -inline Tuple<Ts...> MakeTuple(const Ts&... arg) { - return Tuple<Ts...>(arg...); -} - -// The following set of helpers make what Boost refers to as "Tiers" - a tuple -// of references. - -template <typename... Ts> -inline Tuple<Ts&...> MakeRefTuple(Ts&... arg) { - return Tuple<Ts&...>(arg...); -} - -// Dispatchers ---------------------------------------------------------------- -// -// Helper functions that call the given method on an object, with the unpacked -// tuple arguments. Notice that they all have the same number of arguments, -// so you need only write: -// DispatchToMethod(object, &Object::method, args); -// This is very useful for templated dispatchers, since they don't need to know -// what type |args| is. - -// Non-Static Dispatchers with no out params. - -template <typename ObjT, typename Method, typename... Ts, size_t... Ns> -inline void DispatchToMethodImpl(ObjT* obj, - Method method, - const Tuple<Ts...>& arg, - IndexSequence<Ns...>) { - (obj->*method)(base::internal::UnwrapTraits<Ts>::Unwrap(get<Ns>(arg))...); -} - -template <typename ObjT, typename Method, typename... Ts> -inline void DispatchToMethod(ObjT* obj, - Method method, - const Tuple<Ts...>& arg) { - DispatchToMethodImpl(obj, method, arg, MakeIndexSequence<sizeof...(Ts)>()); -} - -// Static Dispatchers with no out params. - -template <typename Function, typename... Ts, size_t... Ns> -inline void DispatchToFunctionImpl(Function function, - const Tuple<Ts...>& arg, - IndexSequence<Ns...>) { - (*function)(base::internal::UnwrapTraits<Ts>::Unwrap(get<Ns>(arg))...); -} - -template <typename Function, typename... Ts> -inline void DispatchToFunction(Function function, const Tuple<Ts...>& arg) { - DispatchToFunctionImpl(function, arg, MakeIndexSequence<sizeof...(Ts)>()); -} - -// Dispatchers with out parameters. - -template <typename ObjT, - typename Method, - typename... InTs, - typename... OutTs, - size_t... InNs, - size_t... OutNs> -inline void DispatchToMethodImpl(ObjT* obj, - Method method, - const Tuple<InTs...>& in, - Tuple<OutTs...>* out, - IndexSequence<InNs...>, - IndexSequence<OutNs...>) { - (obj->*method)(base::internal::UnwrapTraits<InTs>::Unwrap(get<InNs>(in))..., - &get<OutNs>(*out)...); -} - -template <typename ObjT, typename Method, typename... InTs, typename... OutTs> -inline void DispatchToMethod(ObjT* obj, - Method method, - const Tuple<InTs...>& in, - Tuple<OutTs...>* out) { - DispatchToMethodImpl(obj, method, in, out, - MakeIndexSequence<sizeof...(InTs)>(), - MakeIndexSequence<sizeof...(OutTs)>()); -} - -} // namespace base - -#endif // BASE_TUPLE_H_ diff --git a/security/sandbox/chromium/base/values.h b/security/sandbox/chromium/base/values.h deleted file mode 100644 index 07e5b6c83..000000000 --- a/security/sandbox/chromium/base/values.h +++ /dev/null @@ -1,567 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file specifies a recursive data storage class called Value intended for -// storing settings and other persistable data. -// -// A Value represents something that can be stored in JSON or passed to/from -// JavaScript. As such, it is NOT a generalized variant type, since only the -// types supported by JavaScript/JSON are supported. -// -// IN PARTICULAR this means that there is no support for int64_t or unsigned -// numbers. Writing JSON with such types would violate the spec. If you need -// something like this, either use a double or make a string value containing -// the number you want. - -#ifndef BASE_VALUES_H_ -#define BASE_VALUES_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <iosfwd> -#include <map> -#include <string> -#include <utility> -#include <vector> - -#include "base/base_export.h" -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "base/strings/string16.h" -#include "base/strings/string_piece.h" - -namespace base { - -class BinaryValue; -class DictionaryValue; -class FundamentalValue; -class ListValue; -class StringValue; -class Value; - -typedef std::vector<Value*> ValueVector; -typedef std::map<std::string, Value*> ValueMap; - -// The Value class is the base class for Values. A Value can be instantiated -// via the Create*Value() factory methods, or by directly creating instances of -// the subclasses. -// -// See the file-level comment above for more information. -class BASE_EXPORT Value { - public: - enum Type { - TYPE_NULL = 0, - TYPE_BOOLEAN, - TYPE_INTEGER, - TYPE_DOUBLE, - TYPE_STRING, - TYPE_BINARY, - TYPE_DICTIONARY, - TYPE_LIST - // Note: Do not add more types. See the file-level comment above for why. - }; - - virtual ~Value(); - - static scoped_ptr<Value> CreateNullValue(); - - // Returns the type of the value stored by the current Value object. - // Each type will be implemented by only one subclass of Value, so it's - // safe to use the Type to determine whether you can cast from - // Value* to (Implementing Class)*. Also, a Value object never changes - // its type after construction. - Type GetType() const { return type_; } - - // Returns true if the current object represents a given type. - bool IsType(Type type) const { return type == type_; } - - // These methods allow the convenient retrieval of the contents of the Value. - // If the current object can be converted into the given type, the value is - // returned through the |out_value| parameter and true is returned; - // otherwise, false is returned and |out_value| is unchanged. - virtual bool GetAsBoolean(bool* out_value) const; - virtual bool GetAsInteger(int* out_value) const; - virtual bool GetAsDouble(double* out_value) const; - virtual bool GetAsString(std::string* out_value) const; - virtual bool GetAsString(string16* out_value) const; - virtual bool GetAsString(const StringValue** out_value) const; - virtual bool GetAsBinary(const BinaryValue** out_value) const; - virtual bool GetAsList(ListValue** out_value); - virtual bool GetAsList(const ListValue** out_value) const; - virtual bool GetAsDictionary(DictionaryValue** out_value); - virtual bool GetAsDictionary(const DictionaryValue** out_value) const; - // Note: Do not add more types. See the file-level comment above for why. - - // This creates a deep copy of the entire Value tree, and returns a pointer - // to the copy. The caller gets ownership of the copy, of course. - // - // Subclasses return their own type directly in their overrides; - // this works because C++ supports covariant return types. - virtual Value* DeepCopy() const; - // Preferred version of DeepCopy. TODO(estade): remove the above. - scoped_ptr<Value> CreateDeepCopy() const; - - // Compares if two Value objects have equal contents. - virtual bool Equals(const Value* other) const; - - // Compares if two Value objects have equal contents. Can handle NULLs. - // NULLs are considered equal but different from Value::CreateNullValue(). - static bool Equals(const Value* a, const Value* b); - - protected: - // These aren't safe for end-users, but they are useful for subclasses. - explicit Value(Type type); - Value(const Value& that); - Value& operator=(const Value& that); - - private: - Type type_; -}; - -// FundamentalValue represents the simple fundamental types of values. -class BASE_EXPORT FundamentalValue : public Value { - public: - explicit FundamentalValue(bool in_value); - explicit FundamentalValue(int in_value); - explicit FundamentalValue(double in_value); - ~FundamentalValue() override; - - // Overridden from Value: - bool GetAsBoolean(bool* out_value) const override; - bool GetAsInteger(int* out_value) const override; - // Values of both type TYPE_INTEGER and TYPE_DOUBLE can be obtained as - // doubles. - bool GetAsDouble(double* out_value) const override; - FundamentalValue* DeepCopy() const override; - bool Equals(const Value* other) const override; - - private: - union { - bool boolean_value_; - int integer_value_; - double double_value_; - }; -}; - -class BASE_EXPORT StringValue : public Value { - public: - // Initializes a StringValue with a UTF-8 narrow character string. - explicit StringValue(const std::string& in_value); - - // Initializes a StringValue with a string16. - explicit StringValue(const string16& in_value); - - ~StringValue() override; - - // Returns |value_| as a pointer or reference. - std::string* GetString(); - const std::string& GetString() const; - - // Overridden from Value: - bool GetAsString(std::string* out_value) const override; - bool GetAsString(string16* out_value) const override; - bool GetAsString(const StringValue** out_value) const override; - StringValue* DeepCopy() const override; - bool Equals(const Value* other) const override; - - private: - std::string value_; -}; - -class BASE_EXPORT BinaryValue: public Value { - public: - // Creates a BinaryValue with a null buffer and size of 0. - BinaryValue(); - - // Creates a BinaryValue, taking ownership of the bytes pointed to by - // |buffer|. - BinaryValue(scoped_ptr<char[]> buffer, size_t size); - - ~BinaryValue() override; - - // For situations where you want to keep ownership of your buffer, this - // factory method creates a new BinaryValue by copying the contents of the - // buffer that's passed in. - static BinaryValue* CreateWithCopiedBuffer(const char* buffer, size_t size); - - size_t GetSize() const { return size_; } - - // May return NULL. - char* GetBuffer() { return buffer_.get(); } - const char* GetBuffer() const { return buffer_.get(); } - - // Overridden from Value: - bool GetAsBinary(const BinaryValue** out_value) const override; - BinaryValue* DeepCopy() const override; - bool Equals(const Value* other) const override; - - private: - scoped_ptr<char[]> buffer_; - size_t size_; - - DISALLOW_COPY_AND_ASSIGN(BinaryValue); -}; - -// DictionaryValue provides a key-value dictionary with (optional) "path" -// parsing for recursive access; see the comment at the top of the file. Keys -// are |std::string|s and should be UTF-8 encoded. -class BASE_EXPORT DictionaryValue : public Value { - public: - // Returns |value| if it is a dictionary, nullptr otherwise. - static scoped_ptr<DictionaryValue> From(scoped_ptr<Value> value); - - DictionaryValue(); - ~DictionaryValue() override; - - // Overridden from Value: - bool GetAsDictionary(DictionaryValue** out_value) override; - bool GetAsDictionary(const DictionaryValue** out_value) const override; - - // Returns true if the current dictionary has a value for the given key. - bool HasKey(const std::string& key) const; - - // Returns the number of Values in this dictionary. - size_t size() const { return dictionary_.size(); } - - // Returns whether the dictionary is empty. - bool empty() const { return dictionary_.empty(); } - - // Clears any current contents of this dictionary. - void Clear(); - - // Sets the Value associated with the given path starting from this object. - // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes - // into the next DictionaryValue down. Obviously, "." can't be used - // within a key, but there are no other restrictions on keys. - // If the key at any step of the way doesn't exist, or exists but isn't - // a DictionaryValue, a new DictionaryValue will be created and attached - // to the path in that location. |in_value| must be non-null. - void Set(const std::string& path, scoped_ptr<Value> in_value); - // Deprecated version of the above. TODO(estade): remove. - void Set(const std::string& path, Value* in_value); - - // Convenience forms of Set(). These methods will replace any existing - // value at that path, even if it has a different type. - void SetBoolean(const std::string& path, bool in_value); - void SetInteger(const std::string& path, int in_value); - void SetDouble(const std::string& path, double in_value); - void SetString(const std::string& path, const std::string& in_value); - void SetString(const std::string& path, const string16& in_value); - - // Like Set(), but without special treatment of '.'. This allows e.g. URLs to - // be used as paths. - void SetWithoutPathExpansion(const std::string& key, - scoped_ptr<Value> in_value); - // Deprecated version of the above. TODO(estade): remove. - void SetWithoutPathExpansion(const std::string& key, Value* in_value); - - // Convenience forms of SetWithoutPathExpansion(). - void SetBooleanWithoutPathExpansion(const std::string& path, bool in_value); - void SetIntegerWithoutPathExpansion(const std::string& path, int in_value); - void SetDoubleWithoutPathExpansion(const std::string& path, double in_value); - void SetStringWithoutPathExpansion(const std::string& path, - const std::string& in_value); - void SetStringWithoutPathExpansion(const std::string& path, - const string16& in_value); - - // Gets the Value associated with the given path starting from this object. - // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes - // into the next DictionaryValue down. If the path can be resolved - // successfully, the value for the last key in the path will be returned - // through the |out_value| parameter, and the function will return true. - // Otherwise, it will return false and |out_value| will be untouched. - // Note that the dictionary always owns the value that's returned. - // |out_value| is optional and will only be set if non-NULL. - bool Get(StringPiece path, const Value** out_value) const; - bool Get(StringPiece path, Value** out_value); - - // These are convenience forms of Get(). The value will be retrieved - // and the return value will be true if the path is valid and the value at - // the end of the path can be returned in the form specified. - // |out_value| is optional and will only be set if non-NULL. - bool GetBoolean(const std::string& path, bool* out_value) const; - bool GetInteger(const std::string& path, int* out_value) const; - // Values of both type TYPE_INTEGER and TYPE_DOUBLE can be obtained as - // doubles. - bool GetDouble(const std::string& path, double* out_value) const; - bool GetString(const std::string& path, std::string* out_value) const; - bool GetString(const std::string& path, string16* out_value) const; - bool GetStringASCII(const std::string& path, std::string* out_value) const; - bool GetBinary(const std::string& path, const BinaryValue** out_value) const; - bool GetBinary(const std::string& path, BinaryValue** out_value); - bool GetDictionary(StringPiece path, - const DictionaryValue** out_value) const; - bool GetDictionary(StringPiece path, DictionaryValue** out_value); - bool GetList(const std::string& path, const ListValue** out_value) const; - bool GetList(const std::string& path, ListValue** out_value); - - // Like Get(), but without special treatment of '.'. This allows e.g. URLs to - // be used as paths. - bool GetWithoutPathExpansion(const std::string& key, - const Value** out_value) const; - bool GetWithoutPathExpansion(const std::string& key, Value** out_value); - bool GetBooleanWithoutPathExpansion(const std::string& key, - bool* out_value) const; - bool GetIntegerWithoutPathExpansion(const std::string& key, - int* out_value) const; - bool GetDoubleWithoutPathExpansion(const std::string& key, - double* out_value) const; - bool GetStringWithoutPathExpansion(const std::string& key, - std::string* out_value) const; - bool GetStringWithoutPathExpansion(const std::string& key, - string16* out_value) const; - bool GetDictionaryWithoutPathExpansion( - const std::string& key, - const DictionaryValue** out_value) const; - bool GetDictionaryWithoutPathExpansion(const std::string& key, - DictionaryValue** out_value); - bool GetListWithoutPathExpansion(const std::string& key, - const ListValue** out_value) const; - bool GetListWithoutPathExpansion(const std::string& key, - ListValue** out_value); - - // Removes the Value with the specified path from this dictionary (or one - // of its child dictionaries, if the path is more than just a local key). - // If |out_value| is non-NULL, the removed Value will be passed out via - // |out_value|. If |out_value| is NULL, the removed value will be deleted. - // This method returns true if |path| is a valid path; otherwise it will - // return false and the DictionaryValue object will be unchanged. - virtual bool Remove(const std::string& path, scoped_ptr<Value>* out_value); - - // Like Remove(), but without special treatment of '.'. This allows e.g. URLs - // to be used as paths. - virtual bool RemoveWithoutPathExpansion(const std::string& key, - scoped_ptr<Value>* out_value); - - // Removes a path, clearing out all dictionaries on |path| that remain empty - // after removing the value at |path|. - virtual bool RemovePath(const std::string& path, - scoped_ptr<Value>* out_value); - - // Makes a copy of |this| but doesn't include empty dictionaries and lists in - // the copy. This never returns NULL, even if |this| itself is empty. - scoped_ptr<DictionaryValue> DeepCopyWithoutEmptyChildren() const; - - // Merge |dictionary| into this dictionary. This is done recursively, i.e. any - // sub-dictionaries will be merged as well. In case of key collisions, the - // passed in dictionary takes precedence and data already present will be - // replaced. Values within |dictionary| are deep-copied, so |dictionary| may - // be freed any time after this call. - void MergeDictionary(const DictionaryValue* dictionary); - - // Swaps contents with the |other| dictionary. - virtual void Swap(DictionaryValue* other); - - // This class provides an iterator over both keys and values in the - // dictionary. It can't be used to modify the dictionary. - class BASE_EXPORT Iterator { - public: - explicit Iterator(const DictionaryValue& target); - ~Iterator(); - - bool IsAtEnd() const { return it_ == target_.dictionary_.end(); } - void Advance() { ++it_; } - - const std::string& key() const { return it_->first; } - const Value& value() const { return *it_->second; } - - private: - const DictionaryValue& target_; - ValueMap::const_iterator it_; - }; - - // Overridden from Value: - DictionaryValue* DeepCopy() const override; - // Preferred version of DeepCopy. TODO(estade): remove the above. - scoped_ptr<DictionaryValue> CreateDeepCopy() const; - bool Equals(const Value* other) const override; - - private: - ValueMap dictionary_; - - DISALLOW_COPY_AND_ASSIGN(DictionaryValue); -}; - -// This type of Value represents a list of other Value values. -class BASE_EXPORT ListValue : public Value { - public: - typedef ValueVector::iterator iterator; - typedef ValueVector::const_iterator const_iterator; - - // Returns |value| if it is a list, nullptr otherwise. - static scoped_ptr<ListValue> From(scoped_ptr<Value> value); - - ListValue(); - ~ListValue() override; - - // Clears the contents of this ListValue - void Clear(); - - // Returns the number of Values in this list. - size_t GetSize() const { return list_.size(); } - - // Returns whether the list is empty. - bool empty() const { return list_.empty(); } - - // Sets the list item at the given index to be the Value specified by - // the value given. If the index beyond the current end of the list, null - // Values will be used to pad out the list. - // Returns true if successful, or false if the index was negative or - // the value is a null pointer. - bool Set(size_t index, Value* in_value); - // Preferred version of the above. TODO(estade): remove the above. - bool Set(size_t index, scoped_ptr<Value> in_value); - - // Gets the Value at the given index. Modifies |out_value| (and returns true) - // only if the index falls within the current list range. - // Note that the list always owns the Value passed out via |out_value|. - // |out_value| is optional and will only be set if non-NULL. - bool Get(size_t index, const Value** out_value) const; - bool Get(size_t index, Value** out_value); - - // Convenience forms of Get(). Modifies |out_value| (and returns true) - // only if the index is valid and the Value at that index can be returned - // in the specified form. - // |out_value| is optional and will only be set if non-NULL. - bool GetBoolean(size_t index, bool* out_value) const; - bool GetInteger(size_t index, int* out_value) const; - // Values of both type TYPE_INTEGER and TYPE_DOUBLE can be obtained as - // doubles. - bool GetDouble(size_t index, double* out_value) const; - bool GetString(size_t index, std::string* out_value) const; - bool GetString(size_t index, string16* out_value) const; - bool GetBinary(size_t index, const BinaryValue** out_value) const; - bool GetBinary(size_t index, BinaryValue** out_value); - bool GetDictionary(size_t index, const DictionaryValue** out_value) const; - bool GetDictionary(size_t index, DictionaryValue** out_value); - bool GetList(size_t index, const ListValue** out_value) const; - bool GetList(size_t index, ListValue** out_value); - - // Removes the Value with the specified index from this list. - // If |out_value| is non-NULL, the removed Value AND ITS OWNERSHIP will be - // passed out via |out_value|. If |out_value| is NULL, the removed value will - // be deleted. This method returns true if |index| is valid; otherwise - // it will return false and the ListValue object will be unchanged. - virtual bool Remove(size_t index, scoped_ptr<Value>* out_value); - - // Removes the first instance of |value| found in the list, if any, and - // deletes it. |index| is the location where |value| was found. Returns false - // if not found. - bool Remove(const Value& value, size_t* index); - - // Removes the element at |iter|. If |out_value| is NULL, the value will be - // deleted, otherwise ownership of the value is passed back to the caller. - // Returns an iterator pointing to the location of the element that - // followed the erased element. - iterator Erase(iterator iter, scoped_ptr<Value>* out_value); - - // Appends a Value to the end of the list. - void Append(scoped_ptr<Value> in_value); - // Deprecated version of the above. TODO(estade): remove. - void Append(Value* in_value); - - // Convenience forms of Append. - void AppendBoolean(bool in_value); - void AppendInteger(int in_value); - void AppendDouble(double in_value); - void AppendString(const std::string& in_value); - void AppendString(const string16& in_value); - void AppendStrings(const std::vector<std::string>& in_values); - void AppendStrings(const std::vector<string16>& in_values); - - // Appends a Value if it's not already present. Takes ownership of the - // |in_value|. Returns true if successful, or false if the value was already - // present. If the value was already present the |in_value| is deleted. - bool AppendIfNotPresent(Value* in_value); - - // Insert a Value at index. - // Returns true if successful, or false if the index was out of range. - bool Insert(size_t index, Value* in_value); - - // Searches for the first instance of |value| in the list using the Equals - // method of the Value type. - // Returns a const_iterator to the found item or to end() if none exists. - const_iterator Find(const Value& value) const; - - // Swaps contents with the |other| list. - virtual void Swap(ListValue* other); - - // Iteration. - iterator begin() { return list_.begin(); } - iterator end() { return list_.end(); } - - const_iterator begin() const { return list_.begin(); } - const_iterator end() const { return list_.end(); } - - // Overridden from Value: - bool GetAsList(ListValue** out_value) override; - bool GetAsList(const ListValue** out_value) const override; - ListValue* DeepCopy() const override; - bool Equals(const Value* other) const override; - - // Preferred version of DeepCopy. TODO(estade): remove DeepCopy. - scoped_ptr<ListValue> CreateDeepCopy() const; - - private: - ValueVector list_; - - DISALLOW_COPY_AND_ASSIGN(ListValue); -}; - -// This interface is implemented by classes that know how to serialize -// Value objects. -class BASE_EXPORT ValueSerializer { - public: - virtual ~ValueSerializer(); - - virtual bool Serialize(const Value& root) = 0; -}; - -// This interface is implemented by classes that know how to deserialize Value -// objects. -class BASE_EXPORT ValueDeserializer { - public: - virtual ~ValueDeserializer(); - - // This method deserializes the subclass-specific format into a Value object. - // If the return value is non-NULL, the caller takes ownership of returned - // Value. If the return value is NULL, and if error_code is non-NULL, - // error_code will be set with the underlying error. - // If |error_message| is non-null, it will be filled in with a formatted - // error message including the location of the error if appropriate. - virtual scoped_ptr<Value> Deserialize(int* error_code, - std::string* error_str) = 0; -}; - -// Stream operator so Values can be used in assertion statements. In order that -// gtest uses this operator to print readable output on test failures, we must -// override each specific type. Otherwise, the default template implementation -// is preferred over an upcast. -BASE_EXPORT std::ostream& operator<<(std::ostream& out, const Value& value); - -BASE_EXPORT inline std::ostream& operator<<(std::ostream& out, - const FundamentalValue& value) { - return out << static_cast<const Value&>(value); -} - -BASE_EXPORT inline std::ostream& operator<<(std::ostream& out, - const StringValue& value) { - return out << static_cast<const Value&>(value); -} - -BASE_EXPORT inline std::ostream& operator<<(std::ostream& out, - const DictionaryValue& value) { - return out << static_cast<const Value&>(value); -} - -BASE_EXPORT inline std::ostream& operator<<(std::ostream& out, - const ListValue& value) { - return out << static_cast<const Value&>(value); -} - -} // namespace base - -#endif // BASE_VALUES_H_ diff --git a/security/sandbox/chromium/base/version.h b/security/sandbox/chromium/base/version.h deleted file mode 100644 index 85c99a355..000000000 --- a/security/sandbox/chromium/base/version.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_VERSION_H_ -#define BASE_VERSION_H_ - -#include <stdint.h> -#include <string> -#include <vector> - -#include "base/base_export.h" - -namespace base { - -// Version represents a dotted version number, like "1.2.3.4", supporting -// parsing and comparison. -class BASE_EXPORT Version { - public: - // The only thing you can legally do to a default constructed - // Version object is assign to it. - Version(); - - ~Version(); - - // Initializes from a decimal dotted version number, like "0.1.1". - // Each component is limited to a uint16_t. Call IsValid() to learn - // the outcome. - explicit Version(const std::string& version_str); - - // Returns true if the object contains a valid version number. - bool IsValid() const; - - // Returns true if the version wildcard string is valid. The version wildcard - // string may end with ".*" (e.g. 1.2.*, 1.*). Any other arrangement with "*" - // is invalid (e.g. 1.*.3 or 1.2.3*). This functions defaults to standard - // Version behavior (IsValid) if no wildcard is present. - static bool IsValidWildcardString(const std::string& wildcard_string); - - // Commonly used pattern. Given a valid version object, compare if a - // |version_str| results in a newer version. Returns true if the - // string represents valid version and if the version is greater than - // than the version of this object. - bool IsOlderThan(const std::string& version_str) const; - - bool Equals(const Version& other) const; - - // Returns -1, 0, 1 for <, ==, >. - int CompareTo(const Version& other) const; - - // Given a valid version object, compare if a |wildcard_string| results in a - // newer version. This function will default to CompareTo if the string does - // not end in wildcard sequence ".*". IsValidWildcard(wildcard_string) must be - // true before using this function. - int CompareToWildcardString(const std::string& wildcard_string) const; - - // Return the string representation of this version. - const std::string GetString() const; - - const std::vector<uint32_t>& components() const { return components_; } - - private: - std::vector<uint32_t> components_; -}; - -} // namespace base - -// TODO(xhwang) remove this when all users are updated to explicitly use the -// namespace -using base::Version; - -#endif // BASE_VERSION_H_ diff --git a/security/sandbox/chromium/base/win/pe_image.cc b/security/sandbox/chromium/base/win/pe_image.cc deleted file mode 100644 index 4b5d62099..000000000 --- a/security/sandbox/chromium/base/win/pe_image.cc +++ /dev/null @@ -1,580 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file implements PEImage, a generic class to manipulate PE files. -// This file was adapted from GreenBorder's Code. - -#include <stddef.h> - -#include "base/win/pe_image.h" - -namespace base { -namespace win { - -// Structure to perform imports enumerations. -struct EnumAllImportsStorage { - PEImage::EnumImportsFunction callback; - PVOID cookie; -}; - -namespace { - -// PdbInfo Signature -const DWORD kPdbInfoSignature = 'SDSR'; - -// Compare two strings byte by byte on an unsigned basis. -// if s1 == s2, return 0 -// if s1 < s2, return negative -// if s1 > s2, return positive -// Exception if inputs are invalid. -int StrCmpByByte(LPCSTR s1, LPCSTR s2) { - while (*s1 != '\0' && *s1 == *s2) { - ++s1; - ++s2; - } - - return (*reinterpret_cast<const unsigned char*>(s1) - - *reinterpret_cast<const unsigned char*>(s2)); -} - -struct PdbInfo { - DWORD Signature; - GUID Guid; - DWORD Age; - char PdbFileName[1]; -}; - -} // namespace - -// Callback used to enumerate imports. See EnumImportChunksFunction. -bool ProcessImportChunk(const PEImage &image, LPCSTR module, - PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, PVOID cookie) { - EnumAllImportsStorage& storage = - *reinterpret_cast<EnumAllImportsStorage*>(cookie); - - return image.EnumOneImportChunk(storage.callback, module, name_table, iat, - storage.cookie); -} - -// Callback used to enumerate delay imports. See EnumDelayImportChunksFunction. -bool ProcessDelayImportChunk(const PEImage& image, - PImgDelayDescr delay_descriptor, - LPCSTR module, - PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, - PVOID cookie) { - EnumAllImportsStorage& storage = - *reinterpret_cast<EnumAllImportsStorage*>(cookie); - - return image.EnumOneDelayImportChunk(storage.callback, delay_descriptor, - module, name_table, iat, storage.cookie); -} - -void PEImage::set_module(HMODULE module) { - module_ = module; -} - -PIMAGE_DOS_HEADER PEImage::GetDosHeader() const { - return reinterpret_cast<PIMAGE_DOS_HEADER>(module_); -} - -PIMAGE_NT_HEADERS PEImage::GetNTHeaders() const { - PIMAGE_DOS_HEADER dos_header = GetDosHeader(); - - return reinterpret_cast<PIMAGE_NT_HEADERS>( - reinterpret_cast<char*>(dos_header) + dos_header->e_lfanew); -} - -PIMAGE_SECTION_HEADER PEImage::GetSectionHeader(UINT section) const { - PIMAGE_NT_HEADERS nt_headers = GetNTHeaders(); - PIMAGE_SECTION_HEADER first_section = IMAGE_FIRST_SECTION(nt_headers); - - if (section < nt_headers->FileHeader.NumberOfSections) - return first_section + section; - else - return NULL; -} - -WORD PEImage::GetNumSections() const { - return GetNTHeaders()->FileHeader.NumberOfSections; -} - -DWORD PEImage::GetImageDirectoryEntrySize(UINT directory) const { - PIMAGE_NT_HEADERS nt_headers = GetNTHeaders(); - - return nt_headers->OptionalHeader.DataDirectory[directory].Size; -} - -PVOID PEImage::GetImageDirectoryEntryAddr(UINT directory) const { - PIMAGE_NT_HEADERS nt_headers = GetNTHeaders(); - - return RVAToAddr( - nt_headers->OptionalHeader.DataDirectory[directory].VirtualAddress); -} - -PIMAGE_SECTION_HEADER PEImage::GetImageSectionFromAddr(PVOID address) const { - PBYTE target = reinterpret_cast<PBYTE>(address); - PIMAGE_SECTION_HEADER section; - - for (UINT i = 0; NULL != (section = GetSectionHeader(i)); i++) { - // Don't use the virtual RVAToAddr. - PBYTE start = reinterpret_cast<PBYTE>( - PEImage::RVAToAddr(section->VirtualAddress)); - - DWORD size = section->Misc.VirtualSize; - - if ((start <= target) && (start + size > target)) - return section; - } - - return NULL; -} - -PIMAGE_SECTION_HEADER PEImage::GetImageSectionHeaderByName( - LPCSTR section_name) const { - if (NULL == section_name) - return NULL; - - PIMAGE_SECTION_HEADER ret = NULL; - int num_sections = GetNumSections(); - - for (int i = 0; i < num_sections; i++) { - PIMAGE_SECTION_HEADER section = GetSectionHeader(i); - if (0 == _strnicmp(reinterpret_cast<LPCSTR>(section->Name), section_name, - sizeof(section->Name))) { - ret = section; - break; - } - } - - return ret; -} - -bool PEImage::GetDebugId(LPGUID guid, LPDWORD age) const { - if (NULL == guid || NULL == age) { - return false; - } - - DWORD debug_directory_size = - GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_DEBUG); - PIMAGE_DEBUG_DIRECTORY debug_directory = - reinterpret_cast<PIMAGE_DEBUG_DIRECTORY>( - GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_DEBUG)); - - size_t directory_count = - debug_directory_size / sizeof(IMAGE_DEBUG_DIRECTORY); - - for (size_t index = 0; index < directory_count; ++index) { - if (debug_directory[index].Type == IMAGE_DEBUG_TYPE_CODEVIEW) { - PdbInfo* pdb_info = reinterpret_cast<PdbInfo*>( - RVAToAddr(debug_directory[index].AddressOfRawData)); - if (pdb_info->Signature != kPdbInfoSignature) { - // Unsupported PdbInfo signature - return false; - } - *guid = pdb_info->Guid; - *age = pdb_info->Age; - return true; - } - } - return false; -} - -PDWORD PEImage::GetExportEntry(LPCSTR name) const { - PIMAGE_EXPORT_DIRECTORY exports = GetExportDirectory(); - - if (NULL == exports) - return NULL; - - WORD ordinal = 0; - if (!GetProcOrdinal(name, &ordinal)) - return NULL; - - PDWORD functions = reinterpret_cast<PDWORD>( - RVAToAddr(exports->AddressOfFunctions)); - - return functions + ordinal - exports->Base; -} - -FARPROC PEImage::GetProcAddress(LPCSTR function_name) const { - PDWORD export_entry = GetExportEntry(function_name); - if (NULL == export_entry) - return NULL; - - PBYTE function = reinterpret_cast<PBYTE>(RVAToAddr(*export_entry)); - - PBYTE exports = reinterpret_cast<PBYTE>( - GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_EXPORT)); - DWORD size = GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_EXPORT); - - // Check for forwarded exports as a special case. - if (exports <= function && exports + size > function) - return reinterpret_cast<FARPROC>(-1); - - return reinterpret_cast<FARPROC>(function); -} - -bool PEImage::GetProcOrdinal(LPCSTR function_name, WORD *ordinal) const { - if (NULL == ordinal) - return false; - - PIMAGE_EXPORT_DIRECTORY exports = GetExportDirectory(); - - if (NULL == exports) - return false; - - if (IsOrdinal(function_name)) { - *ordinal = ToOrdinal(function_name); - } else { - PDWORD names = reinterpret_cast<PDWORD>(RVAToAddr(exports->AddressOfNames)); - PDWORD lower = names; - PDWORD upper = names + exports->NumberOfNames; - int cmp = -1; - - // Binary Search for the name. - while (lower != upper) { - PDWORD middle = lower + (upper - lower) / 2; - LPCSTR name = reinterpret_cast<LPCSTR>(RVAToAddr(*middle)); - - // This may be called by sandbox before MSVCRT dll loads, so can't use - // CRT function here. - cmp = StrCmpByByte(function_name, name); - - if (cmp == 0) { - lower = middle; - break; - } - - if (cmp > 0) - lower = middle + 1; - else - upper = middle; - } - - if (cmp != 0) - return false; - - - PWORD ordinals = reinterpret_cast<PWORD>( - RVAToAddr(exports->AddressOfNameOrdinals)); - - *ordinal = ordinals[lower - names] + static_cast<WORD>(exports->Base); - } - - return true; -} - -bool PEImage::EnumSections(EnumSectionsFunction callback, PVOID cookie) const { - PIMAGE_NT_HEADERS nt_headers = GetNTHeaders(); - UINT num_sections = nt_headers->FileHeader.NumberOfSections; - PIMAGE_SECTION_HEADER section = GetSectionHeader(0); - - for (UINT i = 0; i < num_sections; i++, section++) { - PVOID section_start = RVAToAddr(section->VirtualAddress); - DWORD size = section->Misc.VirtualSize; - - if (!callback(*this, section, section_start, size, cookie)) - return false; - } - - return true; -} - -bool PEImage::EnumExports(EnumExportsFunction callback, PVOID cookie) const { - PVOID directory = GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_EXPORT); - DWORD size = GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_EXPORT); - - // Check if there are any exports at all. - if (NULL == directory || 0 == size) - return true; - - PIMAGE_EXPORT_DIRECTORY exports = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>( - directory); - UINT ordinal_base = exports->Base; - UINT num_funcs = exports->NumberOfFunctions; - UINT num_names = exports->NumberOfNames; - PDWORD functions = reinterpret_cast<PDWORD>(RVAToAddr( - exports->AddressOfFunctions)); - PDWORD names = reinterpret_cast<PDWORD>(RVAToAddr(exports->AddressOfNames)); - PWORD ordinals = reinterpret_cast<PWORD>(RVAToAddr( - exports->AddressOfNameOrdinals)); - - for (UINT count = 0; count < num_funcs; count++) { - PVOID func = RVAToAddr(functions[count]); - if (NULL == func) - continue; - - // Check for a name. - LPCSTR name = NULL; - UINT hint; - for (hint = 0; hint < num_names; hint++) { - if (ordinals[hint] == count) { - name = reinterpret_cast<LPCSTR>(RVAToAddr(names[hint])); - break; - } - } - - if (name == NULL) - hint = 0; - - // Check for forwarded exports. - LPCSTR forward = NULL; - if (reinterpret_cast<char*>(func) >= reinterpret_cast<char*>(directory) && - reinterpret_cast<char*>(func) <= reinterpret_cast<char*>(directory) + - size) { - forward = reinterpret_cast<LPCSTR>(func); - func = 0; - } - - if (!callback(*this, ordinal_base + count, hint, name, func, forward, - cookie)) - return false; - } - - return true; -} - -bool PEImage::EnumRelocs(EnumRelocsFunction callback, PVOID cookie) const { - PVOID directory = GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_BASERELOC); - DWORD size = GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_BASERELOC); - PIMAGE_BASE_RELOCATION base = reinterpret_cast<PIMAGE_BASE_RELOCATION>( - directory); - - if (!directory) - return true; - - while (size >= sizeof(IMAGE_BASE_RELOCATION) && base->SizeOfBlock && - size >= base->SizeOfBlock) { - PWORD reloc = reinterpret_cast<PWORD>(base + 1); - UINT num_relocs = (base->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / - sizeof(WORD); - - for (UINT i = 0; i < num_relocs; i++, reloc++) { - WORD type = *reloc >> 12; - PVOID address = RVAToAddr(base->VirtualAddress + (*reloc & 0x0FFF)); - - if (!callback(*this, type, address, cookie)) - return false; - } - - size -= base->SizeOfBlock; - base = reinterpret_cast<PIMAGE_BASE_RELOCATION>( - reinterpret_cast<char*>(base) + base->SizeOfBlock); - } - - return true; -} - -bool PEImage::EnumImportChunks(EnumImportChunksFunction callback, - PVOID cookie) const { - DWORD size = GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_IMPORT); - PIMAGE_IMPORT_DESCRIPTOR import = GetFirstImportChunk(); - - if (import == NULL || size < sizeof(IMAGE_IMPORT_DESCRIPTOR)) - return true; - - for (; import->FirstThunk; import++) { - LPCSTR module_name = reinterpret_cast<LPCSTR>(RVAToAddr(import->Name)); - PIMAGE_THUNK_DATA name_table = reinterpret_cast<PIMAGE_THUNK_DATA>( - RVAToAddr(import->OriginalFirstThunk)); - PIMAGE_THUNK_DATA iat = reinterpret_cast<PIMAGE_THUNK_DATA>( - RVAToAddr(import->FirstThunk)); - - if (!callback(*this, module_name, name_table, iat, cookie)) - return false; - } - - return true; -} - -bool PEImage::EnumOneImportChunk(EnumImportsFunction callback, - LPCSTR module_name, - PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, PVOID cookie) const { - if (NULL == name_table) - return false; - - for (; name_table && name_table->u1.Ordinal; name_table++, iat++) { - LPCSTR name = NULL; - WORD ordinal = 0; - WORD hint = 0; - - if (IMAGE_SNAP_BY_ORDINAL(name_table->u1.Ordinal)) { - ordinal = static_cast<WORD>(IMAGE_ORDINAL32(name_table->u1.Ordinal)); - } else { - PIMAGE_IMPORT_BY_NAME import = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>( - RVAToAddr(name_table->u1.ForwarderString)); - - hint = import->Hint; - name = reinterpret_cast<LPCSTR>(&import->Name); - } - - if (!callback(*this, module_name, ordinal, name, hint, iat, cookie)) - return false; - } - - return true; -} - -bool PEImage::EnumAllImports(EnumImportsFunction callback, PVOID cookie) const { - EnumAllImportsStorage temp = { callback, cookie }; - return EnumImportChunks(ProcessImportChunk, &temp); -} - -bool PEImage::EnumDelayImportChunks(EnumDelayImportChunksFunction callback, - PVOID cookie) const { - PVOID directory = GetImageDirectoryEntryAddr( - IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT); - DWORD size = GetImageDirectoryEntrySize(IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT); - PImgDelayDescr delay_descriptor = reinterpret_cast<PImgDelayDescr>(directory); - - if (directory == NULL || size == 0) - return true; - - for (; delay_descriptor->rvaHmod; delay_descriptor++) { - PIMAGE_THUNK_DATA name_table; - PIMAGE_THUNK_DATA iat; - LPCSTR module_name; - - // check if VC7-style imports, using RVAs instead of - // VC6-style addresses. - bool rvas = (delay_descriptor->grAttrs & dlattrRva) != 0; - - if (rvas) { - module_name = - reinterpret_cast<LPCSTR>(RVAToAddr(delay_descriptor->rvaDLLName)); - name_table = reinterpret_cast<PIMAGE_THUNK_DATA>( - RVAToAddr(delay_descriptor->rvaINT)); - iat = reinterpret_cast<PIMAGE_THUNK_DATA>( - RVAToAddr(delay_descriptor->rvaIAT)); - } else { - // Values in IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT are 32-bit, even on 64-bit - // platforms. See section 4.8 of PECOFF image spec rev 8.3. - module_name = reinterpret_cast<LPCSTR>( - static_cast<uintptr_t>(delay_descriptor->rvaDLLName)); - name_table = reinterpret_cast<PIMAGE_THUNK_DATA>( - static_cast<uintptr_t>(delay_descriptor->rvaINT)); - iat = reinterpret_cast<PIMAGE_THUNK_DATA>( - static_cast<uintptr_t>(delay_descriptor->rvaIAT)); - } - - if (!callback(*this, delay_descriptor, module_name, name_table, iat, - cookie)) - return false; - } - - return true; -} - -bool PEImage::EnumOneDelayImportChunk(EnumImportsFunction callback, - PImgDelayDescr delay_descriptor, - LPCSTR module_name, - PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, - PVOID cookie) const { - for (; name_table->u1.Ordinal; name_table++, iat++) { - LPCSTR name = NULL; - WORD ordinal = 0; - WORD hint = 0; - - if (IMAGE_SNAP_BY_ORDINAL(name_table->u1.Ordinal)) { - ordinal = static_cast<WORD>(IMAGE_ORDINAL32(name_table->u1.Ordinal)); - } else { - PIMAGE_IMPORT_BY_NAME import; - bool rvas = (delay_descriptor->grAttrs & dlattrRva) != 0; - - if (rvas) { - import = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>( - RVAToAddr(name_table->u1.ForwarderString)); - } else { - import = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>( - name_table->u1.ForwarderString); - } - - hint = import->Hint; - name = reinterpret_cast<LPCSTR>(&import->Name); - } - - if (!callback(*this, module_name, ordinal, name, hint, iat, cookie)) - return false; - } - - return true; -} - -bool PEImage::EnumAllDelayImports(EnumImportsFunction callback, - PVOID cookie) const { - EnumAllImportsStorage temp = { callback, cookie }; - return EnumDelayImportChunks(ProcessDelayImportChunk, &temp); -} - -bool PEImage::VerifyMagic() const { - PIMAGE_DOS_HEADER dos_header = GetDosHeader(); - - if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) - return false; - - PIMAGE_NT_HEADERS nt_headers = GetNTHeaders(); - - if (nt_headers->Signature != IMAGE_NT_SIGNATURE) - return false; - - if (nt_headers->FileHeader.SizeOfOptionalHeader != - sizeof(IMAGE_OPTIONAL_HEADER)) - return false; - - if (nt_headers->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC) - return false; - - return true; -} - -bool PEImage::ImageRVAToOnDiskOffset(DWORD rva, DWORD* on_disk_offset) const { - LPVOID address = RVAToAddr(rva); - return ImageAddrToOnDiskOffset(address, on_disk_offset); -} - -bool PEImage::ImageAddrToOnDiskOffset(LPVOID address, - DWORD* on_disk_offset) const { - if (NULL == address) - return false; - - // Get the section that this address belongs to. - PIMAGE_SECTION_HEADER section_header = GetImageSectionFromAddr(address); - if (NULL == section_header) - return false; - - // Don't follow the virtual RVAToAddr, use the one on the base. - DWORD offset_within_section = - static_cast<DWORD>(reinterpret_cast<uintptr_t>(address)) - - static_cast<DWORD>(reinterpret_cast<uintptr_t>( - PEImage::RVAToAddr(section_header->VirtualAddress))); - - *on_disk_offset = section_header->PointerToRawData + offset_within_section; - return true; -} - -PVOID PEImage::RVAToAddr(DWORD rva) const { - if (rva == 0) - return NULL; - - return reinterpret_cast<char*>(module_) + rva; -} - -PVOID PEImageAsData::RVAToAddr(DWORD rva) const { - if (rva == 0) - return NULL; - - PVOID in_memory = PEImage::RVAToAddr(rva); - DWORD disk_offset; - - if (!ImageAddrToOnDiskOffset(in_memory, &disk_offset)) - return NULL; - - return PEImage::RVAToAddr(disk_offset); -} - -} // namespace win -} // namespace base diff --git a/security/sandbox/chromium/base/win/pe_image.h b/security/sandbox/chromium/base/win/pe_image.h deleted file mode 100644 index 4c36bcf85..000000000 --- a/security/sandbox/chromium/base/win/pe_image.h +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file was adapted from GreenBorder's Code. -// To understand what this class is about (for other than well known functions -// as GetProcAddress), a good starting point is "An In-Depth Look into the -// Win32 Portable Executable File Format" by Matt Pietrek: -// http://msdn.microsoft.com/msdnmag/issues/02/02/PE/default.aspx - -#ifndef BASE_WIN_PE_IMAGE_H_ -#define BASE_WIN_PE_IMAGE_H_ - -#include <windows.h> - -#if defined(_WIN32_WINNT_WIN8) -// The Windows 8 SDK defines FACILITY_VISUALCPP in winerror.h. -#undef FACILITY_VISUALCPP -#endif -#include <DelayIMP.h> - -namespace base { -namespace win { - -// This class is a wrapper for the Portable Executable File Format (PE). -// Its main purpose is to provide an easy way to work with imports and exports -// from a file, mapped in memory as image. -class PEImage { - public: - // Callback to enumerate sections. - // cookie is the value passed to the enumerate method. - // Returns true to continue the enumeration. - typedef bool (*EnumSectionsFunction)(const PEImage &image, - PIMAGE_SECTION_HEADER header, - PVOID section_start, DWORD section_size, - PVOID cookie); - - // Callback to enumerate exports. - // function is the actual address of the symbol. If forward is not null, it - // contains the dll and symbol to forward this export to. cookie is the value - // passed to the enumerate method. - // Returns true to continue the enumeration. - typedef bool (*EnumExportsFunction)(const PEImage &image, DWORD ordinal, - DWORD hint, LPCSTR name, PVOID function, - LPCSTR forward, PVOID cookie); - - // Callback to enumerate import blocks. - // name_table and iat point to the imports name table and address table for - // this block. cookie is the value passed to the enumerate method. - // Returns true to continue the enumeration. - typedef bool (*EnumImportChunksFunction)(const PEImage &image, LPCSTR module, - PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, PVOID cookie); - - // Callback to enumerate imports. - // module is the dll that exports this symbol. cookie is the value passed to - // the enumerate method. - // Returns true to continue the enumeration. - typedef bool (*EnumImportsFunction)(const PEImage &image, LPCSTR module, - DWORD ordinal, LPCSTR name, DWORD hint, - PIMAGE_THUNK_DATA iat, PVOID cookie); - - // Callback to enumerate dalayed import blocks. - // module is the dll that exports this block of symbols. cookie is the value - // passed to the enumerate method. - // Returns true to continue the enumeration. - typedef bool (*EnumDelayImportChunksFunction)(const PEImage &image, - PImgDelayDescr delay_descriptor, - LPCSTR module, - PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, - PVOID cookie); - - // Callback to enumerate relocations. - // cookie is the value passed to the enumerate method. - // Returns true to continue the enumeration. - typedef bool (*EnumRelocsFunction)(const PEImage &image, WORD type, - PVOID address, PVOID cookie); - - explicit PEImage(HMODULE module) : module_(module) {} - explicit PEImage(const void* module) { - module_ = reinterpret_cast<HMODULE>(const_cast<void*>(module)); - } - - virtual ~PEImage() {} - - // Gets the HMODULE for this object. - HMODULE module() const; - - // Sets this object's HMODULE. - void set_module(HMODULE module); - - // Checks if this symbol is actually an ordinal. - static bool IsOrdinal(LPCSTR name); - - // Converts a named symbol to the corresponding ordinal. - static WORD ToOrdinal(LPCSTR name); - - // Returns the DOS_HEADER for this PE. - PIMAGE_DOS_HEADER GetDosHeader() const; - - // Returns the NT_HEADER for this PE. - PIMAGE_NT_HEADERS GetNTHeaders() const; - - // Returns number of sections of this PE. - WORD GetNumSections() const; - - // Returns the header for a given section. - // returns NULL if there is no such section. - PIMAGE_SECTION_HEADER GetSectionHeader(UINT section) const; - - // Returns the size of a given directory entry. - DWORD GetImageDirectoryEntrySize(UINT directory) const; - - // Returns the address of a given directory entry. - PVOID GetImageDirectoryEntryAddr(UINT directory) const; - - // Returns the section header for a given address. - // Use: s = image.GetImageSectionFromAddr(a); - // Post: 's' is the section header of the section that contains 'a' - // or NULL if there is no such section. - PIMAGE_SECTION_HEADER GetImageSectionFromAddr(PVOID address) const; - - // Returns the section header for a given section. - PIMAGE_SECTION_HEADER GetImageSectionHeaderByName(LPCSTR section_name) const; - - // Returns the first block of imports. - PIMAGE_IMPORT_DESCRIPTOR GetFirstImportChunk() const; - - // Returns the exports directory. - PIMAGE_EXPORT_DIRECTORY GetExportDirectory() const; - - // Returns the debug id (guid+age). - bool GetDebugId(LPGUID guid, LPDWORD age) const; - - // Returns a given export entry. - // Use: e = image.GetExportEntry(f); - // Pre: 'f' is either a zero terminated string or ordinal - // Post: 'e' is a pointer to the export directory entry - // that contains 'f's export RVA, or NULL if 'f' - // is not exported from this image - PDWORD GetExportEntry(LPCSTR name) const; - - // Returns the address for a given exported symbol. - // Use: p = image.GetProcAddress(f); - // Pre: 'f' is either a zero terminated string or ordinal. - // Post: if 'f' is a non-forwarded export from image, 'p' is - // the exported function. If 'f' is a forwarded export - // then p is the special value -1. In this case - // RVAToAddr(*GetExportEntry) can be used to resolve - // the string that describes the forward. - FARPROC GetProcAddress(LPCSTR function_name) const; - - // Retrieves the ordinal for a given exported symbol. - // Returns true if the symbol was found. - bool GetProcOrdinal(LPCSTR function_name, WORD *ordinal) const; - - // Enumerates PE sections. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumSections(EnumSectionsFunction callback, PVOID cookie) const; - - // Enumerates PE exports. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumExports(EnumExportsFunction callback, PVOID cookie) const; - - // Enumerates PE imports. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumAllImports(EnumImportsFunction callback, PVOID cookie) const; - - // Enumerates PE import blocks. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumImportChunks(EnumImportChunksFunction callback, PVOID cookie) const; - - // Enumerates the imports from a single PE import block. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumOneImportChunk(EnumImportsFunction callback, LPCSTR module_name, - PIMAGE_THUNK_DATA name_table, PIMAGE_THUNK_DATA iat, - PVOID cookie) const; - - - // Enumerates PE delay imports. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumAllDelayImports(EnumImportsFunction callback, PVOID cookie) const; - - // Enumerates PE delay import blocks. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumDelayImportChunks(EnumDelayImportChunksFunction callback, - PVOID cookie) const; - - // Enumerates imports from a single PE delay import block. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumOneDelayImportChunk(EnumImportsFunction callback, - PImgDelayDescr delay_descriptor, - LPCSTR module_name, - PIMAGE_THUNK_DATA name_table, - PIMAGE_THUNK_DATA iat, - PVOID cookie) const; - - // Enumerates PE relocation entries. - // cookie is a generic cookie to pass to the callback. - // Returns true on success. - bool EnumRelocs(EnumRelocsFunction callback, PVOID cookie) const; - - // Verifies the magic values on the PE file. - // Returns true if all values are correct. - bool VerifyMagic() const; - - // Converts an rva value to the appropriate address. - virtual PVOID RVAToAddr(DWORD rva) const; - - // Converts an rva value to an offset on disk. - // Returns true on success. - bool ImageRVAToOnDiskOffset(DWORD rva, DWORD *on_disk_offset) const; - - // Converts an address to an offset on disk. - // Returns true on success. - bool ImageAddrToOnDiskOffset(LPVOID address, DWORD *on_disk_offset) const; - - private: - HMODULE module_; -}; - -// This class is an extension to the PEImage class that allows working with PE -// files mapped as data instead of as image file. -class PEImageAsData : public PEImage { - public: - explicit PEImageAsData(HMODULE hModule) : PEImage(hModule) {} - - PVOID RVAToAddr(DWORD rva) const override; -}; - -inline bool PEImage::IsOrdinal(LPCSTR name) { - return reinterpret_cast<uintptr_t>(name) <= 0xFFFF; -} - -inline WORD PEImage::ToOrdinal(LPCSTR name) { - return static_cast<WORD>(reinterpret_cast<intptr_t>(name)); -} - -inline HMODULE PEImage::module() const { - return module_; -} - -inline PIMAGE_IMPORT_DESCRIPTOR PEImage::GetFirstImportChunk() const { - return reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>( - GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_IMPORT)); -} - -inline PIMAGE_EXPORT_DIRECTORY PEImage::GetExportDirectory() const { - return reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>( - GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_EXPORT)); -} - -} // namespace win -} // namespace base - -#endif // BASE_WIN_PE_IMAGE_H_ diff --git a/security/sandbox/chromium/base/win/scoped_handle.cc b/security/sandbox/chromium/base/win/scoped_handle.cc deleted file mode 100644 index 9c21603a0..000000000 --- a/security/sandbox/chromium/base/win/scoped_handle.cc +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/win/scoped_handle.h" - -#include <stddef.h> - -#include <unordered_map> - -#include "base/debug/alias.h" -#include "base/hash.h" -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/synchronization/lock_impl.h" - -extern "C" { -__declspec(dllexport) void* GetHandleVerifier(); -typedef void* (*GetHandleVerifierFn)(); -} - -namespace { - -struct HandleHash { - size_t operator()(const HANDLE& handle) const { - char buffer[sizeof(handle)]; - memcpy(buffer, &handle, sizeof(handle)); - return base::Hash(buffer, sizeof(buffer)); - } -}; - -struct Info { - const void* owner; - const void* pc1; - const void* pc2; - DWORD thread_id; -}; -typedef std::unordered_map<HANDLE, Info, HandleHash> HandleMap; - -// g_lock protects the handle map and setting g_active_verifier. -typedef base::internal::LockImpl NativeLock; -base::LazyInstance<NativeLock>::Leaky g_lock = LAZY_INSTANCE_INITIALIZER; - -bool CloseHandleWrapper(HANDLE handle) { - if (!::CloseHandle(handle)) - CHECK(false); - return true; -} - -// Simple automatic locking using a native critical section so it supports -// recursive locking. -class AutoNativeLock { - public: - explicit AutoNativeLock(NativeLock& lock) : lock_(lock) { - lock_.Lock(); - } - - ~AutoNativeLock() { - lock_.Unlock(); - } - - private: - NativeLock& lock_; - DISALLOW_COPY_AND_ASSIGN(AutoNativeLock); -}; - -// Implements the actual object that is verifying handles for this process. -// The active instance is shared across the module boundary but there is no -// way to delete this object from the wrong side of it (or any side, actually). -class ActiveVerifier { - public: - explicit ActiveVerifier(bool enabled) - : enabled_(enabled), closing_(false), lock_(g_lock.Pointer()) { - } - - // Retrieves the current verifier. - static ActiveVerifier* Get(); - - // The methods required by HandleTraits. They are virtual because we need to - // forward the call execution to another module, instead of letting the - // compiler call the version that is linked in the current module. - virtual bool CloseHandle(HANDLE handle); - virtual void StartTracking(HANDLE handle, const void* owner, - const void* pc1, const void* pc2); - virtual void StopTracking(HANDLE handle, const void* owner, - const void* pc1, const void* pc2); - virtual void Disable(); - virtual void OnHandleBeingClosed(HANDLE handle); - - private: - ~ActiveVerifier(); // Not implemented. - - static void InstallVerifier(); - - bool enabled_; - bool closing_; - NativeLock* lock_; - HandleMap map_; - DISALLOW_COPY_AND_ASSIGN(ActiveVerifier); -}; -ActiveVerifier* g_active_verifier = NULL; - -// static -ActiveVerifier* ActiveVerifier::Get() { - if (!g_active_verifier) - ActiveVerifier::InstallVerifier(); - - return g_active_verifier; -} - -// static -void ActiveVerifier::InstallVerifier() { -#if defined(COMPONENT_BUILD) - AutoNativeLock lock(g_lock.Get()); - g_active_verifier = new ActiveVerifier(true); -#else - // If you are reading this, wondering why your process seems deadlocked, take - // a look at your DllMain code and remove things that should not be done - // there, like doing whatever gave you that nice windows handle you are trying - // to store in a ScopedHandle. - HMODULE main_module = ::GetModuleHandle(NULL); - GetHandleVerifierFn get_handle_verifier = - reinterpret_cast<GetHandleVerifierFn>(::GetProcAddress( - main_module, "GetHandleVerifier")); - - if (!get_handle_verifier) { - g_active_verifier = new ActiveVerifier(false); - return; - } - - ActiveVerifier* verifier = - reinterpret_cast<ActiveVerifier*>(get_handle_verifier()); - - // This lock only protects against races in this module, which is fine. - AutoNativeLock lock(g_lock.Get()); - g_active_verifier = verifier ? verifier : new ActiveVerifier(true); -#endif -} - -bool ActiveVerifier::CloseHandle(HANDLE handle) { - if (!enabled_) - return CloseHandleWrapper(handle); - - AutoNativeLock lock(*lock_); - closing_ = true; - CloseHandleWrapper(handle); - closing_ = false; - - return true; -} - -void ActiveVerifier::StartTracking(HANDLE handle, const void* owner, - const void* pc1, const void* pc2) { - if (!enabled_) - return; - - // Grab the thread id before the lock. - DWORD thread_id = GetCurrentThreadId(); - - AutoNativeLock lock(*lock_); - - Info handle_info = { owner, pc1, pc2, thread_id }; - std::pair<HANDLE, Info> item(handle, handle_info); - std::pair<HandleMap::iterator, bool> result = map_.insert(item); - if (!result.second) { - Info other = result.first->second; - base::debug::Alias(&other); - CHECK(false); - } -} - -void ActiveVerifier::StopTracking(HANDLE handle, const void* owner, - const void* pc1, const void* pc2) { - if (!enabled_) - return; - - AutoNativeLock lock(*lock_); - HandleMap::iterator i = map_.find(handle); - if (i == map_.end()) - CHECK(false); - - Info other = i->second; - if (other.owner != owner) { - base::debug::Alias(&other); - CHECK(false); - } - - map_.erase(i); -} - -void ActiveVerifier::Disable() { - enabled_ = false; -} - -void ActiveVerifier::OnHandleBeingClosed(HANDLE handle) { - if (!enabled_) - return; - - AutoNativeLock lock(*lock_); - if (closing_) - return; - - HandleMap::iterator i = map_.find(handle); - if (i == map_.end()) - return; - - Info other = i->second; - base::debug::Alias(&other); - CHECK(false); -} - -} // namespace - -void* GetHandleVerifier() { - return g_active_verifier; -} - -namespace base { -namespace win { - -// Static. -bool HandleTraits::CloseHandle(HANDLE handle) { - return ActiveVerifier::Get()->CloseHandle(handle); -} - -// Static. -void VerifierTraits::StartTracking(HANDLE handle, const void* owner, - const void* pc1, const void* pc2) { - return ActiveVerifier::Get()->StartTracking(handle, owner, pc1, pc2); -} - -// Static. -void VerifierTraits::StopTracking(HANDLE handle, const void* owner, - const void* pc1, const void* pc2) { - return ActiveVerifier::Get()->StopTracking(handle, owner, pc1, pc2); -} - -void DisableHandleVerifier() { - return ActiveVerifier::Get()->Disable(); -} - -void OnHandleBeingClosed(HANDLE handle) { - return ActiveVerifier::Get()->OnHandleBeingClosed(handle); -} - -} // namespace win -} // namespace base diff --git a/security/sandbox/chromium/base/win/scoped_handle.h b/security/sandbox/chromium/base/win/scoped_handle.h deleted file mode 100644 index 404ab6693..000000000 --- a/security/sandbox/chromium/base/win/scoped_handle.h +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_WIN_SCOPED_HANDLE_H_ -#define BASE_WIN_SCOPED_HANDLE_H_ - -#include <windows.h> - -#include "base/base_export.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/move.h" - -// TODO(rvargas): remove this with the rest of the verifier. -#if defined(COMPILER_MSVC) -#include <intrin.h> -#define BASE_WIN_GET_CALLER _ReturnAddress() -#elif defined(COMPILER_GCC) -#define BASE_WIN_GET_CALLER __builtin_extract_return_addr(\\ - __builtin_return_address(0)) -#endif - -namespace base { -namespace win { - -// Generic wrapper for raw handles that takes care of closing handles -// automatically. The class interface follows the style of -// the ScopedFILE class with two additions: -// - IsValid() method can tolerate multiple invalid handle values such as NULL -// and INVALID_HANDLE_VALUE (-1) for Win32 handles. -// - Set() (and the constructors and assignment operators that call it) -// preserve the Windows LastError code. This ensures that GetLastError() can -// be called after stashing a handle in a GenericScopedHandle object. Doing -// this explicitly is necessary because of bug 528394 and VC++ 2015. -template <class Traits, class Verifier> -class GenericScopedHandle { - MOVE_ONLY_TYPE_FOR_CPP_03(GenericScopedHandle) - - public: - typedef typename Traits::Handle Handle; - - GenericScopedHandle() : handle_(Traits::NullHandle()) {} - - explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) { - Set(handle); - } - - GenericScopedHandle(GenericScopedHandle&& other) - : handle_(Traits::NullHandle()) { - Set(other.Take()); - } - - ~GenericScopedHandle() { - Close(); - } - - bool IsValid() const { - return Traits::IsHandleValid(handle_); - } - - GenericScopedHandle& operator=(GenericScopedHandle&& other) { - DCHECK_NE(this, &other); - Set(other.Take()); - return *this; - } - - void Set(Handle handle) { - if (handle_ != handle) { - // Preserve old LastError to avoid bug 528394. - auto last_error = ::GetLastError(); - Close(); - - if (Traits::IsHandleValid(handle)) { - handle_ = handle; - Verifier::StartTracking(handle, this, BASE_WIN_GET_CALLER, - tracked_objects::GetProgramCounter()); - } - ::SetLastError(last_error); - } - } - - Handle Get() const { - return handle_; - } - - // Transfers ownership away from this object. - Handle Take() { - Handle temp = handle_; - handle_ = Traits::NullHandle(); - if (Traits::IsHandleValid(temp)) { - Verifier::StopTracking(temp, this, BASE_WIN_GET_CALLER, - tracked_objects::GetProgramCounter()); - } - return temp; - } - - // Explicitly closes the owned handle. - void Close() { - if (Traits::IsHandleValid(handle_)) { - Verifier::StopTracking(handle_, this, BASE_WIN_GET_CALLER, - tracked_objects::GetProgramCounter()); - - Traits::CloseHandle(handle_); - handle_ = Traits::NullHandle(); - } - } - - private: - Handle handle_; -}; - -#undef BASE_WIN_GET_CALLER - -// The traits class for Win32 handles that can be closed via CloseHandle() API. -class HandleTraits { - public: - typedef HANDLE Handle; - - // Closes the handle. - static bool BASE_EXPORT CloseHandle(HANDLE handle); - - // Returns true if the handle value is valid. - static bool IsHandleValid(HANDLE handle) { - return handle != NULL && handle != INVALID_HANDLE_VALUE; - } - - // Returns NULL handle value. - static HANDLE NullHandle() { - return NULL; - } - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits); -}; - -// Do-nothing verifier. -class DummyVerifierTraits { - public: - typedef HANDLE Handle; - - static void StartTracking(HANDLE handle, const void* owner, - const void* pc1, const void* pc2) {} - static void StopTracking(HANDLE handle, const void* owner, - const void* pc1, const void* pc2) {} - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(DummyVerifierTraits); -}; - -// Performs actual run-time tracking. -class BASE_EXPORT VerifierTraits { - public: - typedef HANDLE Handle; - - static void StartTracking(HANDLE handle, const void* owner, - const void* pc1, const void* pc2); - static void StopTracking(HANDLE handle, const void* owner, - const void* pc1, const void* pc2); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits); -}; - -typedef GenericScopedHandle<HandleTraits, VerifierTraits> ScopedHandle; - -// This function may be called by the embedder to disable the use of -// VerifierTraits at runtime. It has no effect if DummyVerifierTraits is used -// for ScopedHandle. -void BASE_EXPORT DisableHandleVerifier(); - -// This should be called whenever the OS is closing a handle, if extended -// verification of improper handle closing is desired. If |handle| is being -// tracked by the handle verifier and ScopedHandle is not the one closing it, -// a CHECK is generated. -void BASE_EXPORT OnHandleBeingClosed(HANDLE handle); - -} // namespace win -} // namespace base - -#endif // BASE_WIN_SCOPED_HANDLE_H_ diff --git a/security/sandbox/chromium/base/win/scoped_process_information.cc b/security/sandbox/chromium/base/win/scoped_process_information.cc deleted file mode 100644 index 634a538ee..000000000 --- a/security/sandbox/chromium/base/win/scoped_process_information.cc +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/win/scoped_process_information.h" - -#include "base/logging.h" -#include "base/win/scoped_handle.h" -#include "base/win/windows_version.h" - -namespace base { -namespace win { - -namespace { - -// Duplicates source into target, returning true upon success. |target| is -// guaranteed to be untouched in case of failure. Succeeds with no side-effects -// if source is NULL. -bool CheckAndDuplicateHandle(HANDLE source, ScopedHandle* target) { - if (!source) - return true; - - HANDLE temp = NULL; - - // TODO(shrikant): Remove following code as soon as we gather some - // information regarding AppContainer related DuplicateHandle failures that - // only seem to happen on certain machine and only random launches (normally - // renderer launches seem to succeed even on those machines.) - if (base::win::GetVersion() == base::win::VERSION_WIN8 || - base::win::GetVersion() == base::win::VERSION_WIN8_1) { - typedef LONG (WINAPI *NtDuplicateObject)( - IN HANDLE SourceProcess, - IN HANDLE SourceHandle, - IN HANDLE TargetProcess, - OUT PHANDLE TargetHandle, - IN ACCESS_MASK DesiredAccess, - IN ULONG Attributes, - IN ULONG Options); - - typedef ULONG (WINAPI *RtlNtStatusToDosError)(IN LONG Status); - - NtDuplicateObject nt_duplicate_object = - reinterpret_cast<NtDuplicateObject>(::GetProcAddress( - GetModuleHandle(L"ntdll.dll"), "NtDuplicateObject")); - if (nt_duplicate_object != NULL) { - LONG status = nt_duplicate_object(::GetCurrentProcess(), source, - ::GetCurrentProcess(), &temp, - 0, FALSE, DUPLICATE_SAME_ACCESS); - if (status < 0) { - DPLOG(ERROR) << "Failed to duplicate a handle."; - RtlNtStatusToDosError ntstatus_to_doserror = - reinterpret_cast<RtlNtStatusToDosError>(::GetProcAddress( - GetModuleHandle(L"ntdll.dll"), "RtlNtStatusToDosError")); - if (ntstatus_to_doserror != NULL) { - ::SetLastError(ntstatus_to_doserror(status)); - } - return false; - } - } - } else { - if (!::DuplicateHandle(::GetCurrentProcess(), source, - ::GetCurrentProcess(), &temp, 0, FALSE, - DUPLICATE_SAME_ACCESS)) { - DPLOG(ERROR) << "Failed to duplicate a handle."; - return false; - } - } - target->Set(temp); - return true; -} - -} // namespace - -ScopedProcessInformation::ScopedProcessInformation() - : process_id_(0), thread_id_(0) { -} - -ScopedProcessInformation::ScopedProcessInformation( - const PROCESS_INFORMATION& process_info) : process_id_(0), thread_id_(0) { - Set(process_info); -} - -ScopedProcessInformation::~ScopedProcessInformation() { - Close(); -} - -bool ScopedProcessInformation::IsValid() const { - return process_id_ || process_handle_.Get() || - thread_id_ || thread_handle_.Get(); -} - -void ScopedProcessInformation::Close() { - process_handle_.Close(); - thread_handle_.Close(); - process_id_ = 0; - thread_id_ = 0; -} - -void ScopedProcessInformation::Set(const PROCESS_INFORMATION& process_info) { - if (IsValid()) - Close(); - - process_handle_.Set(process_info.hProcess); - thread_handle_.Set(process_info.hThread); - process_id_ = process_info.dwProcessId; - thread_id_ = process_info.dwThreadId; -} - -bool ScopedProcessInformation::DuplicateFrom( - const ScopedProcessInformation& other) { - DCHECK(!IsValid()) << "target ScopedProcessInformation must be NULL"; - DCHECK(other.IsValid()) << "source ScopedProcessInformation must be valid"; - - if (CheckAndDuplicateHandle(other.process_handle(), &process_handle_) && - CheckAndDuplicateHandle(other.thread_handle(), &thread_handle_)) { - process_id_ = other.process_id(); - thread_id_ = other.thread_id(); - return true; - } - - return false; -} - -PROCESS_INFORMATION ScopedProcessInformation::Take() { - PROCESS_INFORMATION process_information = {}; - process_information.hProcess = process_handle_.Take(); - process_information.hThread = thread_handle_.Take(); - process_information.dwProcessId = process_id(); - process_information.dwThreadId = thread_id(); - process_id_ = 0; - thread_id_ = 0; - - return process_information; -} - -HANDLE ScopedProcessInformation::TakeProcessHandle() { - process_id_ = 0; - return process_handle_.Take(); -} - -HANDLE ScopedProcessInformation::TakeThreadHandle() { - thread_id_ = 0; - return thread_handle_.Take(); -} - -} // namespace win -} // namespace base diff --git a/security/sandbox/chromium/base/win/scoped_process_information.h b/security/sandbox/chromium/base/win/scoped_process_information.h deleted file mode 100644 index 01df861f0..000000000 --- a/security/sandbox/chromium/base/win/scoped_process_information.h +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_WIN_SCOPED_PROCESS_INFORMATION_H_ -#define BASE_WIN_SCOPED_PROCESS_INFORMATION_H_ - -#include <windows.h> - -#include "base/base_export.h" -#include "base/macros.h" -#include "base/win/scoped_handle.h" - -namespace base { -namespace win { - -// Manages the closing of process and thread handles from PROCESS_INFORMATION -// structures. Allows clients to take ownership of either handle independently. -class BASE_EXPORT ScopedProcessInformation { - public: - ScopedProcessInformation(); - explicit ScopedProcessInformation(const PROCESS_INFORMATION& process_info); - ~ScopedProcessInformation(); - - // Returns true iff this instance is holding a thread and/or process handle. - bool IsValid() const; - - // Closes the held thread and process handles, if any. - void Close(); - - // Populates this instance with the provided |process_info|. - void Set(const PROCESS_INFORMATION& process_info); - - // Populates this instance with duplicate handles and the thread/process IDs - // from |other|. Returns false in case of failure, in which case this instance - // will be completely unpopulated. - bool DuplicateFrom(const ScopedProcessInformation& other); - - // Transfers ownership of the held PROCESS_INFORMATION, if any, away from this - // instance. - PROCESS_INFORMATION Take(); - - // Transfers ownership of the held process handle, if any, away from this - // instance. Note that the related process_id will also be cleared. - HANDLE TakeProcessHandle(); - - // Transfers ownership of the held thread handle, if any, away from this - // instance. Note that the related thread_id will also be cleared. - HANDLE TakeThreadHandle(); - - // Returns the held process handle, if any, while retaining ownership. - HANDLE process_handle() const { - return process_handle_.Get(); - } - - // Returns the held thread handle, if any, while retaining ownership. - HANDLE thread_handle() const { - return thread_handle_.Get(); - } - - // Returns the held process id, if any. - DWORD process_id() const { - return process_id_; - } - - // Returns the held thread id, if any. - DWORD thread_id() const { - return thread_id_; - } - - private: - ScopedHandle process_handle_; - ScopedHandle thread_handle_; - DWORD process_id_; - DWORD thread_id_; - - DISALLOW_COPY_AND_ASSIGN(ScopedProcessInformation); -}; - -} // namespace win -} // namespace base - -#endif // BASE_WIN_SCOPED_PROCESS_INFORMATION_H_ diff --git a/security/sandbox/chromium/base/win/startup_information.cc b/security/sandbox/chromium/base/win/startup_information.cc deleted file mode 100644 index aff52eb79..000000000 --- a/security/sandbox/chromium/base/win/startup_information.cc +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/win/startup_information.h" - -#include "base/logging.h" -#include "base/win/windows_version.h" - -namespace { - -typedef BOOL (WINAPI *InitializeProcThreadAttributeListFunction)( - LPPROC_THREAD_ATTRIBUTE_LIST attribute_list, - DWORD attribute_count, - DWORD flags, - PSIZE_T size); -static InitializeProcThreadAttributeListFunction - initialize_proc_thread_attribute_list; - -typedef BOOL (WINAPI *UpdateProcThreadAttributeFunction)( - LPPROC_THREAD_ATTRIBUTE_LIST attribute_list, - DWORD flags, - DWORD_PTR attribute, - PVOID value, - SIZE_T size, - PVOID previous_value, - PSIZE_T return_size); -static UpdateProcThreadAttributeFunction update_proc_thread_attribute_list; - -typedef VOID (WINAPI *DeleteProcThreadAttributeListFunction)( - LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList); -static DeleteProcThreadAttributeListFunction delete_proc_thread_attribute_list; - -} // namespace - -namespace base { -namespace win { - -StartupInformation::StartupInformation() { - memset(&startup_info_, 0, sizeof(startup_info_)); - - // Pre Windows Vista doesn't support STARTUPINFOEX. - if (base::win::GetVersion() < base::win::VERSION_VISTA) { - startup_info_.StartupInfo.cb = sizeof(STARTUPINFO); - return; - } - - startup_info_.StartupInfo.cb = sizeof(startup_info_); - - // Load the attribute API functions. - if (!initialize_proc_thread_attribute_list || - !update_proc_thread_attribute_list || - !delete_proc_thread_attribute_list) { - HMODULE module = ::GetModuleHandleW(L"kernel32.dll"); - initialize_proc_thread_attribute_list = - reinterpret_cast<InitializeProcThreadAttributeListFunction>( - ::GetProcAddress(module, "InitializeProcThreadAttributeList")); - update_proc_thread_attribute_list = - reinterpret_cast<UpdateProcThreadAttributeFunction>( - ::GetProcAddress(module, "UpdateProcThreadAttribute")); - delete_proc_thread_attribute_list = - reinterpret_cast<DeleteProcThreadAttributeListFunction>( - ::GetProcAddress(module, "DeleteProcThreadAttributeList")); - } -} - -StartupInformation::~StartupInformation() { - if (startup_info_.lpAttributeList) { - delete_proc_thread_attribute_list(startup_info_.lpAttributeList); - delete [] reinterpret_cast<BYTE*>(startup_info_.lpAttributeList); - } -} - -bool StartupInformation::InitializeProcThreadAttributeList( - DWORD attribute_count) { - if (startup_info_.StartupInfo.cb != sizeof(startup_info_) || - startup_info_.lpAttributeList) - return false; - - SIZE_T size = 0; - initialize_proc_thread_attribute_list(NULL, attribute_count, 0, &size); - if (size == 0) - return false; - - startup_info_.lpAttributeList = - reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(new BYTE[size]); - if (!initialize_proc_thread_attribute_list(startup_info_.lpAttributeList, - attribute_count, 0, &size)) { - delete [] reinterpret_cast<BYTE*>(startup_info_.lpAttributeList); - startup_info_.lpAttributeList = NULL; - return false; - } - - return true; -} - -bool StartupInformation::UpdateProcThreadAttribute( - DWORD_PTR attribute, - void* value, - size_t size) { - if (!startup_info_.lpAttributeList) - return false; - return !!update_proc_thread_attribute_list(startup_info_.lpAttributeList, 0, - attribute, value, size, NULL, NULL); -} - -} // namespace win -} // namespace base - diff --git a/security/sandbox/chromium/base/win/startup_information.h b/security/sandbox/chromium/base/win/startup_information.h deleted file mode 100644 index 5b777baef..000000000 --- a/security/sandbox/chromium/base/win/startup_information.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_WIN_STARTUP_INFORMATION_H_ -#define BASE_WIN_STARTUP_INFORMATION_H_ - -#include <windows.h> -#include <stddef.h> - -#include "base/base_export.h" -#include "base/macros.h" - -namespace base { -namespace win { - -// Manages the lifetime of additional attributes in STARTUPINFOEX. -class BASE_EXPORT StartupInformation { - public: - StartupInformation(); - - ~StartupInformation(); - - // Initialize the attribute list for the specified number of entries. - bool InitializeProcThreadAttributeList(DWORD attribute_count); - - // Sets one entry in the initialized attribute list. - // |value| needs to live at least as long as the StartupInformation object - // this is called on. - bool UpdateProcThreadAttribute(DWORD_PTR attribute, - void* value, - size_t size); - - LPSTARTUPINFOW startup_info() { return &startup_info_.StartupInfo; } - LPSTARTUPINFOW startup_info() const { - return const_cast<const LPSTARTUPINFOW>(&startup_info_.StartupInfo); - } - - bool has_extended_startup_info() const { - return !!startup_info_.lpAttributeList; - } - - private: - STARTUPINFOEXW startup_info_; - DISALLOW_COPY_AND_ASSIGN(StartupInformation); -}; - -} // namespace win -} // namespace base - -#endif // BASE_WIN_STARTUP_INFORMATION_H_ diff --git a/security/sandbox/chromium/base/win/windows_version.cc b/security/sandbox/chromium/base/win/windows_version.cc deleted file mode 100644 index eb3f4993d..000000000 --- a/security/sandbox/chromium/base/win/windows_version.cc +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/win/windows_version.h" - -#include <windows.h> - -#include "base/file_version_info_win.h" -#include "base/files/file_path.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/strings/utf_string_conversions.h" -#include "base/win/registry.h" - -namespace { -typedef BOOL (WINAPI *GetProductInfoPtr)(DWORD, DWORD, DWORD, DWORD, PDWORD); -} // namespace - -namespace base { -namespace win { - -namespace { - -// Helper to map a major.minor.x.build version (e.g. 6.1) to a Windows release. -Version MajorMinorBuildToVersion(int major, int minor, int build) { - if ((major == 5) && (minor > 0)) { - // Treat XP Pro x64, Home Server, and Server 2003 R2 as Server 2003. - return (minor == 1) ? VERSION_XP : VERSION_SERVER_2003; - } else if (major == 6) { - switch (minor) { - case 0: - // Treat Windows Server 2008 the same as Windows Vista. - return VERSION_VISTA; - case 1: - // Treat Windows Server 2008 R2 the same as Windows 7. - return VERSION_WIN7; - case 2: - // Treat Windows Server 2012 the same as Windows 8. - return VERSION_WIN8; - default: - DCHECK_EQ(minor, 3); - return VERSION_WIN8_1; - } - } else if (major == 10) { - if (build < 10586) { - return VERSION_WIN10; - } else { - return VERSION_WIN10_TH2; - } - } else if (major > 6) { - NOTREACHED(); - return VERSION_WIN_LAST; - } - - return VERSION_PRE_XP; -} - -// Retrieve a version from kernel32. This is useful because when running in -// compatibility mode for a down-level version of the OS, the file version of -// kernel32 will still be the "real" version. -Version GetVersionFromKernel32() { - scoped_ptr<FileVersionInfoWin> file_version_info( - static_cast<FileVersionInfoWin*>( - FileVersionInfoWin::CreateFileVersionInfo( - base::FilePath(FILE_PATH_LITERAL("kernel32.dll"))))); - if (file_version_info) { - const int major = - HIWORD(file_version_info->fixed_file_info()->dwFileVersionMS); - const int minor = - LOWORD(file_version_info->fixed_file_info()->dwFileVersionMS); - const int build = - HIWORD(file_version_info->fixed_file_info()->dwFileVersionLS); - return MajorMinorBuildToVersion(major, minor, build); - } - - NOTREACHED(); - return VERSION_WIN_LAST; -} - -} // namespace - -// static -OSInfo* OSInfo::GetInstance() { - // Note: we don't use the Singleton class because it depends on AtExitManager, - // and it's convenient for other modules to use this classs without it. This - // pattern is copied from gurl.cc. - static OSInfo* info; - if (!info) { - OSInfo* new_info = new OSInfo(); - if (InterlockedCompareExchangePointer( - reinterpret_cast<PVOID*>(&info), new_info, NULL)) { - delete new_info; - } - } - return info; -} - -OSInfo::OSInfo() - : version_(VERSION_PRE_XP), - kernel32_version_(VERSION_PRE_XP), - got_kernel32_version_(false), - architecture_(OTHER_ARCHITECTURE), - wow64_status_(GetWOW64StatusForProcess(GetCurrentProcess())) { - OSVERSIONINFOEX version_info = { sizeof version_info }; - ::GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info)); - version_number_.major = version_info.dwMajorVersion; - version_number_.minor = version_info.dwMinorVersion; - version_number_.build = version_info.dwBuildNumber; - version_ = MajorMinorBuildToVersion( - version_number_.major, version_number_.minor, version_number_.build); - service_pack_.major = version_info.wServicePackMajor; - service_pack_.minor = version_info.wServicePackMinor; - - SYSTEM_INFO system_info = {}; - ::GetNativeSystemInfo(&system_info); - switch (system_info.wProcessorArchitecture) { - case PROCESSOR_ARCHITECTURE_INTEL: architecture_ = X86_ARCHITECTURE; break; - case PROCESSOR_ARCHITECTURE_AMD64: architecture_ = X64_ARCHITECTURE; break; - case PROCESSOR_ARCHITECTURE_IA64: architecture_ = IA64_ARCHITECTURE; break; - } - processors_ = system_info.dwNumberOfProcessors; - allocation_granularity_ = system_info.dwAllocationGranularity; - - GetProductInfoPtr get_product_info; - DWORD os_type; - - if (version_info.dwMajorVersion == 6 || version_info.dwMajorVersion == 10) { - // Only present on Vista+. - get_product_info = reinterpret_cast<GetProductInfoPtr>( - ::GetProcAddress(::GetModuleHandle(L"kernel32.dll"), "GetProductInfo")); - - get_product_info(version_info.dwMajorVersion, version_info.dwMinorVersion, - 0, 0, &os_type); - switch (os_type) { - case PRODUCT_CLUSTER_SERVER: - case PRODUCT_DATACENTER_SERVER: - case PRODUCT_DATACENTER_SERVER_CORE: - case PRODUCT_ENTERPRISE_SERVER: - case PRODUCT_ENTERPRISE_SERVER_CORE: - case PRODUCT_ENTERPRISE_SERVER_IA64: - case PRODUCT_SMALLBUSINESS_SERVER: - case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM: - case PRODUCT_STANDARD_SERVER: - case PRODUCT_STANDARD_SERVER_CORE: - case PRODUCT_WEB_SERVER: - version_type_ = SUITE_SERVER; - break; - case PRODUCT_PROFESSIONAL: - case PRODUCT_ULTIMATE: - case PRODUCT_ENTERPRISE: - case PRODUCT_BUSINESS: - version_type_ = SUITE_PROFESSIONAL; - break; - case PRODUCT_HOME_BASIC: - case PRODUCT_HOME_PREMIUM: - case PRODUCT_STARTER: - default: - version_type_ = SUITE_HOME; - break; - } - } else if (version_info.dwMajorVersion == 5 && - version_info.dwMinorVersion == 2) { - if (version_info.wProductType == VER_NT_WORKSTATION && - system_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { - version_type_ = SUITE_PROFESSIONAL; - } else if (version_info.wSuiteMask & VER_SUITE_WH_SERVER ) { - version_type_ = SUITE_HOME; - } else { - version_type_ = SUITE_SERVER; - } - } else if (version_info.dwMajorVersion == 5 && - version_info.dwMinorVersion == 1) { - if(version_info.wSuiteMask & VER_SUITE_PERSONAL) - version_type_ = SUITE_HOME; - else - version_type_ = SUITE_PROFESSIONAL; - } else { - // Windows is pre XP so we don't care but pick a safe default. - version_type_ = SUITE_HOME; - } -} - -OSInfo::~OSInfo() { -} - -Version OSInfo::Kernel32Version() const { - if (!got_kernel32_version_) { - kernel32_version_ = GetVersionFromKernel32(); - got_kernel32_version_ = true; - } - return kernel32_version_; -} - -std::string OSInfo::processor_model_name() { - if (processor_model_name_.empty()) { - const wchar_t kProcessorNameString[] = - L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"; - base::win::RegKey key(HKEY_LOCAL_MACHINE, kProcessorNameString, KEY_READ); - string16 value; - key.ReadValue(L"ProcessorNameString", &value); - processor_model_name_ = UTF16ToUTF8(value); - } - return processor_model_name_; -} - -// static -OSInfo::WOW64Status OSInfo::GetWOW64StatusForProcess(HANDLE process_handle) { - typedef BOOL (WINAPI* IsWow64ProcessFunc)(HANDLE, PBOOL); - IsWow64ProcessFunc is_wow64_process = reinterpret_cast<IsWow64ProcessFunc>( - GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process")); - if (!is_wow64_process) - return WOW64_DISABLED; - BOOL is_wow64 = FALSE; - if (!(*is_wow64_process)(process_handle, &is_wow64)) - return WOW64_UNKNOWN; - return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED; -} - -Version GetVersion() { - return OSInfo::GetInstance()->version(); -} - -} // namespace win -} // namespace base diff --git a/security/sandbox/chromium/base/win/windows_version.h b/security/sandbox/chromium/base/win/windows_version.h deleted file mode 100644 index 7bc8b6fe5..000000000 --- a/security/sandbox/chromium/base/win/windows_version.h +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_WIN_WINDOWS_VERSION_H_ -#define BASE_WIN_WINDOWS_VERSION_H_ - -#include <stddef.h> - -#include <string> - -#include "base/base_export.h" -#include "base/macros.h" - -typedef void* HANDLE; - -namespace base { -namespace win { - -// The running version of Windows. This is declared outside OSInfo for -// syntactic sugar reasons; see the declaration of GetVersion() below. -// NOTE: Keep these in order so callers can do things like -// "if (base::win::GetVersion() >= base::win::VERSION_VISTA) ...". -// -// This enum is used in metrics histograms, so they shouldn't be reordered or -// removed. New values can be added before VERSION_WIN_LAST. -enum Version { - VERSION_PRE_XP = 0, // Not supported. - VERSION_XP = 1, - VERSION_SERVER_2003 = 2, // Also includes XP Pro x64 and Server 2003 R2. - VERSION_VISTA = 3, // Also includes Windows Server 2008. - VERSION_WIN7 = 4, // Also includes Windows Server 2008 R2. - VERSION_WIN8 = 5, // Also includes Windows Server 2012. - VERSION_WIN8_1 = 6, // Also includes Windows Server 2012 R2. - VERSION_WIN10 = 7, // Also includes Windows 10 Server. - VERSION_WIN10_TH2 = 8, // Threshold 2: Version 1511, Build 10586. - VERSION_WIN_LAST, // Indicates error condition. -}; - -// A rough bucketing of the available types of versions of Windows. This is used -// to distinguish enterprise enabled versions from home versions and potentially -// server versions. -enum VersionType { - SUITE_HOME, - SUITE_PROFESSIONAL, - SUITE_SERVER, - SUITE_LAST, -}; - -// A singleton that can be used to query various pieces of information about the -// OS and process state. Note that this doesn't use the base Singleton class, so -// it can be used without an AtExitManager. -class BASE_EXPORT OSInfo { - public: - struct VersionNumber { - int major; - int minor; - int build; - }; - - struct ServicePack { - int major; - int minor; - }; - - // The processor architecture this copy of Windows natively uses. For - // example, given an x64-capable processor, we have three possibilities: - // 32-bit Chrome running on 32-bit Windows: X86_ARCHITECTURE - // 32-bit Chrome running on 64-bit Windows via WOW64: X64_ARCHITECTURE - // 64-bit Chrome running on 64-bit Windows: X64_ARCHITECTURE - enum WindowsArchitecture { - X86_ARCHITECTURE, - X64_ARCHITECTURE, - IA64_ARCHITECTURE, - OTHER_ARCHITECTURE, - }; - - // Whether a process is running under WOW64 (the wrapper that allows 32-bit - // processes to run on 64-bit versions of Windows). This will return - // WOW64_DISABLED for both "32-bit Chrome on 32-bit Windows" and "64-bit - // Chrome on 64-bit Windows". WOW64_UNKNOWN means "an error occurred", e.g. - // the process does not have sufficient access rights to determine this. - enum WOW64Status { - WOW64_DISABLED, - WOW64_ENABLED, - WOW64_UNKNOWN, - }; - - static OSInfo* GetInstance(); - - Version version() const { return version_; } - Version Kernel32Version() const; - // The next two functions return arrays of values, [major, minor(, build)]. - VersionNumber version_number() const { return version_number_; } - VersionType version_type() const { return version_type_; } - ServicePack service_pack() const { return service_pack_; } - WindowsArchitecture architecture() const { return architecture_; } - int processors() const { return processors_; } - size_t allocation_granularity() const { return allocation_granularity_; } - WOW64Status wow64_status() const { return wow64_status_; } - std::string processor_model_name(); - - // Like wow64_status(), but for the supplied handle instead of the current - // process. This doesn't touch member state, so you can bypass the singleton. - static WOW64Status GetWOW64StatusForProcess(HANDLE process_handle); - - private: - OSInfo(); - ~OSInfo(); - - Version version_; - mutable Version kernel32_version_; - mutable bool got_kernel32_version_; - VersionNumber version_number_; - VersionType version_type_; - ServicePack service_pack_; - WindowsArchitecture architecture_; - int processors_; - size_t allocation_granularity_; - WOW64Status wow64_status_; - std::string processor_model_name_; - - DISALLOW_COPY_AND_ASSIGN(OSInfo); -}; - -// Because this is by far the most commonly-requested value from the above -// singleton, we add a global-scope accessor here as syntactic sugar. -BASE_EXPORT Version GetVersion(); - -} // namespace win -} // namespace base - -#endif // BASE_WIN_WINDOWS_VERSION_H_ |