// balst_resolverimpl_windows.h                                       -*-C++-*-
#ifndef INCLUDED_BALST_RESOLVERIMPL_WINDOWS
#define INCLUDED_BALST_RESOLVERIMPL_WINDOWS

#include <bsls_ident.h>
BSLS_IDENT("$Id: $")

//@PURPOSE: Provide resolution of symbols in stack trace for Windows objects.
//
//@CLASSES:
//   balst::ResolverImpl<Windows>: symbol resolution for Windows objs
//
//@SEE_ALSO:
//
//@DESCRIPTION: This class provides a class this able to take a vector of
// `balst::StackTraceFrame`s that have only their `address` fields set, and
// sets as many of the other fields in the stack trace frames as possible.  Elf
// objects are used on Solaris and Linux platforms.
//
///Usage
///-----
// This component is an implementation detail of `balst` and is *not* intended
// for direct client use.  It is subject to change without notice.  As such, a
// usage example is not provided.

#include <balscm_version.h>

#include <balst_objectfileformat.h>
#include <balst_stacktrace.h>
#include <balst_stacktraceframe.h>

#include <bsl_vector.h>

#include <bslma_allocator.h>

namespace BloombergLP {

#if defined(BALST_OBJECTFILEFORMAT_RESOLVER_WINDOWS)

namespace balst {

template <typename RESOLVER_POLICY>
class ResolverImpl;

              // =============================================
              // class ResolverImpl<ObjectFileFormat::Windows>
              // =============================================

template <>
class ResolverImpl<ObjectFileFormat::Windows> {
    // This type is for resolving symbols in Windows executables.  Resolving
    // symbols on Windows is straightforward using the dbghelp.dll library,
    // described at
    // http://msdn.microsoft.com/en-us/library/ms681412(v=VS.85).aspx

  private:
    // NOT IMPLEMENTED
    ResolverImpl();
    ResolverImpl(const ResolverImpl&);
    ResolverImpl& operator=(const ResolverImpl&);
    ~ResolverImpl();

  public:
    // CLASS METHODS
    static int resolve(StackTrace *stackTrace,
                       bool              demangle);
        // Given a specified stack trace object 'stackTrace' of stack trace
        // frames with only their 'address' fields valid, set as many other
        // fields of the frames as possible.  The 'demangle' argument is
        // ignored, demangling always happens on Windows.  Return 0 if
        // successful and a non-zero value otherwise.

    static inline
    int testFunc();
        // For testing only.  Do some random garbage and return a line number
        // from within the routine.
};

                        // ----------------------------
                        // class ResolverImpl
                        // ----------------------------

inline
int ResolverImpl<ObjectFileFormat::Windows>::testFunc()
{
    // Do some random garbage to generate some code, then return a line number
    // within this routine

    int line = 0, lineCopy = 0;

    for (int ii = 0; true; ++ii) {
        BSLS_ASSERT_OPT(line == lineCopy);

        const int loopGuard = 0x8edf0000;    // garbage with a lot of trailing
                                             // 0's.
        const int mask      = 0xa72c3dca;    // pure garbage

        // k_LINE is not declared as enum as __LINE__ in some windows
        // compilation modes cannot be evaluated as compile time constant.
        // See DRQS 169040262 for details.
        const int k_LINE = __LINE__;

        for (int jj = 0; !(jj & loopGuard); ++jj) {
            line ^= (jj & mask);
        }

        // The above loop will leave the value of 'line' unchanged.

        BSLS_ASSERT_OPT(line == lineCopy);

        if (line != 0) {
            break;
        }

        line = k_LINE;
        lineCopy = line;
    }

    return line;
}

}  // close package namespace

#endif

}  // close enterprise namespace

#endif

// ----------------------------------------------------------------------------
// Copyright 2015 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
