diff --git a/CMakeLists.txt b/CMakeLists.txt index b9fca2a..4ce1b71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -454,7 +454,11 @@ set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LLVM_BINARY_DIR}/lib ) set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) if (APPLE) - set(CMAKE_INSTALL_NAME_DIR "@rpath") + if (LLVM_HOST_OSX_VERSION VERSION_LESS "10.5") + set(CMAKE_INSTALL_NAME_DIR "@loader_path/../lib") + else() + set(CMAKE_INSTALL_NAME_DIR "@rpath") + endif() set(CMAKE_INSTALL_RPATH "@executable_path/../lib") else(UNIX) if(NOT DEFINED CMAKE_INSTALL_RPATH) diff --git a/CREDITS.TXT b/CREDITS.TXT index 0447c40..dce3291 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -456,3 +456,9 @@ D: Bunches of stuff N: Bob Wilson E: bob.wilson@acm.org D: Advanced SIMD (NEON) support in the ARM backend. + +N: David Fang +D: PowerPC-Darwin port + +N: Iain Sandoe +D: PowerPC-Darwin port diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 34fadbe..3cc8e40 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -1781,11 +1781,11 @@ AC_LINK_IFELSE( ], [ AC_MSG_RESULT([yes]) - AC_DEFINE([LLVM_HAS_ATOMICS], [1], [Has gcc/MSVC atomic intrinsics]) + AC_DEFINE([LLVM_HAS_ATOMICS], [1], [Has gcc/MSVC/Apple atomic intrinsics]) ], [ AC_MSG_RESULT([no]) - AC_DEFINE([LLVM_HAS_ATOMICS], [0], [Has gcc/MSVC atomic intrinsics]) + AC_DEFINE([LLVM_HAS_ATOMICS], [0], [Has gcc/MSVC/Apple atomic intrinsics]) AC_MSG_WARN([LLVM will be built thread-unsafe because atomic builtins are missing]) ]) AC_LANG_POP([C++]) diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake index b862ceb..7b19772 100755 --- a/cmake/config-ix.cmake +++ b/cmake/config-ix.cmake @@ -326,6 +326,12 @@ get_host_triple(LLVM_INFERRED_HOST_TRIPLE) set(LLVM_HOST_TRIPLE "${LLVM_INFERRED_HOST_TRIPLE}" CACHE STRING "Host on which LLVM binaries will run") +if( APPLE ) +get_host_osx_version(LLVM_INFERRED_OSX_VERSION) +set(LLVM_HOST_OSX_VERSION "${LLVM_INFERRED_OSX_VERSION}" CACHE STRING + "Host version of Mac OS X") +endif( APPLE ) + # Determine the native architecture. string(TOLOWER "${LLVM_TARGET_ARCH}" LLVM_NATIVE_ARCH) if( LLVM_NATIVE_ARCH STREQUAL "host" ) diff --git a/cmake/modules/CheckAtomic.cmake b/cmake/modules/CheckAtomic.cmake index 0d63a82..213b57f 100644 --- a/cmake/modules/CheckAtomic.cmake +++ b/cmake/modules/CheckAtomic.cmake @@ -6,6 +6,10 @@ CHECK_CXX_SOURCE_COMPILES(" #ifdef _MSC_VER #include #endif +#define NEED_DARWIN_ATOMICS (defined(__APPLE__) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))) +#if NEED_DARWIN_ATOMICS +#include +#endif int main() { #ifdef _MSC_VER volatile LONG val = 1; @@ -13,6 +17,12 @@ int main() { InterlockedCompareExchange(&val, 0, 1); InterlockedIncrement(&val); InterlockedDecrement(&val); +#elif NEED_DARWIN_ATOMICS + int32_t val = 1; + OSMemoryBarrier(); + OSAtomicCompareAndSwap32Barrier(1, 0, &val); + OSAtomicIncrement32(&val); + OSAtomicDecrement32(&val); #else volatile unsigned long val = 1; __sync_synchronize(); diff --git a/cmake/modules/GetHostTriple.cmake b/cmake/modules/GetHostTriple.cmake index 671a8ce..37caa10 100644 --- a/cmake/modules/GetHostTriple.cmake +++ b/cmake/modules/GetHostTriple.cmake @@ -28,3 +28,15 @@ function( get_host_triple var ) set( ${var} ${value} PARENT_SCOPE ) message(STATUS "Target triple: ${value}") endfunction( get_host_triple var ) + +# Mac OS X only: get the host version +function( get_host_osx_version var ) + if( APPLE ) + execute_process(COMMAND sw_vers -productVersion COMMAND cut -d. -f1-2 + RESULT_VARIABLE TT_RV + OUTPUT_VARIABLE value + OUTPUT_STRIP_TRAILING_WHITESPACE) + set( ${var} ${value} PARENT_SCOPE ) + message(STATUS "Host OS X version: ${value}") + endif ( APPLE ) +endfunction( get_host_osx_version var ) diff --git a/cmake/modules/HandleLLVMOptions.cmake b/cmake/modules/HandleLLVMOptions.cmake index 8258512..3a1a9a4 100644 --- a/cmake/modules/HandleLLVMOptions.cmake +++ b/cmake/modules/HandleLLVMOptions.cmake @@ -319,7 +319,7 @@ elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE ) append("-std=c++11" CMAKE_CXX_FLAGS) endif() else() - message(FATAL_ERROR "LLVM requires C++11 support but the '-std=c++11' flag isn't supported.") + message(WARNING "LLVM requires C++11 support but the '-std=c++11' flag isn't supported.") endif() endif() endif( MSVC ) diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 1cb34c2..9e0f2f0 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -126,7 +126,7 @@ public: virtual void setBundlePadding(uint8_t N) { } - void dump(); + void dump() const; }; /// Interface implemented by fragments that contain encoded instructions and/or @@ -677,7 +677,7 @@ public: BundleGroupBeforeFirstInst = IsFirst; } - void dump(); + void dump() const; /// @} }; @@ -1243,7 +1243,7 @@ public: /// @} - void dump(); + void dump() const; }; } // end namespace llvm diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h index 12a7f0e..80e9d8e 100644 --- a/include/llvm/MC/MCMachObjectWriter.h +++ b/include/llvm/MC/MCMachObjectWriter.h @@ -16,6 +16,16 @@ #include "llvm/MC/MCObjectWriter.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/MachO.h" + +/** + Mach-O needs indirect symbols grouped by section. + Goal: 1 + */ +#define ORDER_INDIRECT_SYMBOLS_BY_SECTION 1 +#if ORDER_INDIRECT_SYMBOLS_BY_SECTION +#include "llvm/ADT/SetVector.h" +#endif + #include namespace llvm { @@ -113,6 +123,22 @@ class MachObjectWriter : public MCObjectWriter { MachSymbolData *findSymbolData(const MCSymbol &Sym); +#if ORDER_INDIRECT_SYMBOLS_BY_SECTION + /// @name Indirect Symbol Table Data + /// @{ + + typedef std::vector IndirectSymbol_list_type; + typedef DenseMap + IndirectSymbol_map_type; + // keep sections in order of appearance + typedef SetVector IndirectSymbolSection_set_type; + + IndirectSymbol_map_type IndirectSymbolMap; + IndirectSymbolSection_set_type IndirectSymbolSections; + + /// @} +#endif + public: MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS, bool _IsLittleEndian) diff --git a/include/llvm/MC/SectionKind.h b/include/llvm/MC/SectionKind.h index 85a91c6..fbb359a 100644 --- a/include/llvm/MC/SectionKind.h +++ b/include/llvm/MC/SectionKind.h @@ -133,6 +133,10 @@ class SectionKind { } K : 8; public: +#if 1 +// for debugging purposes only + Kind getKindEnum(void) const { return K; } +#endif bool isMetadata() const { return K == Metadata; } bool isText() const { return K == Text; } diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h index 5ca2450..edc82fa 100644 --- a/include/llvm/Object/RelocVisitor.h +++ b/include/llvm/Object/RelocVisitor.h @@ -166,7 +166,7 @@ public: return RelocToApply(); } - bool error() { return HasError; } + bool error() const { return HasError; } private: StringRef FileFormat; diff --git a/include/llvm/Support/Atomic.h b/include/llvm/Support/Atomic.h index 9ec23e8..f1a1fd9 100644 --- a/include/llvm/Support/Atomic.h +++ b/include/llvm/Support/Atomic.h @@ -14,14 +14,21 @@ #ifndef LLVM_SUPPORT_ATOMIC_H #define LLVM_SUPPORT_ATOMIC_H +#include "llvm/Support/Compiler.h" // for __GNUC_PREREQ #include "llvm/Support/DataTypes.h" +// convenience macro, to force use of darwin atomic functions +// stage 1 with gcc-4.0 needs this, but maybe not stage 2? +#define USE_DARWIN_ATOMICS (defined(__APPLE__) && !__GNUC_PREREQ(4, 2)) + namespace llvm { namespace sys { void MemoryFence(); #ifdef _MSC_VER typedef long cas_flag; +#elif USE_DARWIN_ATOMICS + typedef int32_t cas_flag; #else typedef uint32_t cas_flag; #endif diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index 25bf32a..211ebcc 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -141,7 +141,8 @@ #define LLVM_ATTRIBUTE_USED #endif -#if __has_attribute(warn_unused_result) || __GNUC_PREREQ(3, 4) +// gcc-4.0 spews tons of warning noise, so requiring 4.1 should silence them +#if __has_attribute(warn_unused_result) || __GNUC_PREREQ(4, 1) #define LLVM_ATTRIBUTE_UNUSED_RESULT __attribute__((__warn_unused_result__)) #else #define LLVM_ATTRIBUTE_UNUSED_RESULT @@ -178,7 +179,9 @@ #define LLVM_READNONE #endif -#if __has_attribute(pure) || defined(__GNUC__) +// this attribute may be buggy for older gcc-4.0.1 (apple) +// removing this fixes bug #14244 +#if __has_attribute(pure) || __GNUC_PREREQ(4, 2) // aka 'PURE' but following LLVM Conventions. #define LLVM_READONLY __attribute__((__pure__)) #else diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h index b713cc7..41ef5fa 100644 --- a/include/llvm/Support/Format.h +++ b/include/llvm/Support/Format.h @@ -225,6 +225,43 @@ format(const char *Fmt, const T1 &Val1, const T2 &Val2, const T3 &Val3, Val5, Val6); } +// provide some default format strings +template +struct default_format_string; + +// definitions in Support/Format.cpp +#define SPECIALIZE_DEFAULT_FORMAT_STRING(T) \ +template <> \ +struct default_format_string { \ + static const char hex[]; /* e.g. "%d" */ \ + static const char dec[]; /* e.g. "%x" */ \ +}; + +SPECIALIZE_DEFAULT_FORMAT_STRING(int) +SPECIALIZE_DEFAULT_FORMAT_STRING(long) +SPECIALIZE_DEFAULT_FORMAT_STRING(long long) +SPECIALIZE_DEFAULT_FORMAT_STRING(unsigned int) +SPECIALIZE_DEFAULT_FORMAT_STRING(unsigned long) +SPECIALIZE_DEFAULT_FORMAT_STRING(unsigned long long) + +#undef SPECIALIZE_DEFAULT_FORMAT_STRING + +// format manipulators +template +inline +format_object1 +hex(const T& v1) { + return format(default_format_string::hex, v1); +} + +// decimal is the default, so this isn't really needed +template +inline +format_object1 +dec(const T& v1) { + return format(default_format_string::dec, v1); +} + } // end namespace llvm #endif diff --git a/include/llvm/Support/cppcat.h b/include/llvm/Support/cppcat.h new file mode 100644 index 0000000..c46c576 --- /dev/null +++ b/include/llvm/Support/cppcat.h @@ -0,0 +1,48 @@ +/** + \file "util/cppcat.h" + Tricks for concatenating strings with the C-preprocessor. + I learned this trick from: + http://www.slack.net/~ant/cpp/unqiue_name.html + $Id: cppcat.h,v 1.1 2010/03/14 22:25:16 fang Exp $ + */ + +#ifndef __UTIL_CPPCAT_H__ +#define __UTIL_CPPCAT_H__ + +/** + Description also copied from the same web-site. + + Sometimes one needs to supply an identifier for something that will + never be referenced again. The most common occurrence is a local + object of some type whose construction and destruction side-effects + are wanted at the beginning and end of the scope it exists in, + respectively. Having to come up with a name is both tedious and + unclear, since the name will serve no purpose in the code. + If it were possible, providing no name would make the intent clearer. + + In the CONCAT macro, the seemingly-redundant helper macros + (CONCAT_2_ and CONCAT_3_) are needed due to particulars of the + preprocessor. + + Generally, this construct will only be needed in a source file + (and not a header). This makes it unlikely for it to clash with + anything else. If it's needed in a header file, care must be + taken that the name can't clash with any other identifier, + because a clash may not show up until the header is integrated + with another header file that happens to have an identical UNIQUE_NAME. + */ + +#define CONCAT_3_(x, y) x##y +#define CONCAT_2_(x, y) CONCAT_3_(x,y) +#define CONCAT(x, y) CONCAT_2_(x,y) +#define UNIQUIFY(str) CONCAT(str,__LINE__) + +/** + To try to protect macros with commas inside, without + requiring extra parentheses. + */ +#define CPPWRAP(x) x + + +#endif // __UTIL_CPPCAT_H__ + diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index 34fbe08..64159da 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -197,6 +197,11 @@ public: raw_ostream &operator<<(double N); + /// basic manipulator, unary function + raw_ostream& operator<<(raw_ostream& (*pf)(raw_ostream&)) { + return (*pf)(*this); + } + /// write_hex - Output \p N in hexadecimal, without any prefix or padding. raw_ostream &write_hex(unsigned long long N); @@ -422,6 +427,14 @@ raw_ostream &errs(); /// output. raw_ostream &nulls(); +/// manipulator functions +inline +raw_ostream& endl(raw_ostream& o) { + o << '\n'; + o.flush(); + return o; +} + //===----------------------------------------------------------------------===// // Output Stream Adaptors //===----------------------------------------------------------------------===// diff --git a/include/llvm/Support/raw_ostream_iterator.h b/include/llvm/Support/raw_ostream_iterator.h new file mode 100644 index 0000000..72d6065 --- /dev/null +++ b/include/llvm/Support/raw_ostream_iterator.h @@ -0,0 +1,79 @@ +//===--- raw_ostream.h - Raw output stream ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the raw_ostream_iterator class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_RAW_OSTREAM_ITERATOR_H +#define LLVM_SUPPORT_RAW_OSTREAM_ITERATOR_H + +#include "llvm/Support/raw_ostream.h" +#include + +namespace llvm { + +/// in the spirit of std::ostream_iterator +template +class ostream_iterator : + public std::iterator +{ +public: + //@{ + /// Public typedef + typedef T value_type; + typedef raw_ostream ostream_type; + //@} + +private: + ostream_type* _M_stream; + const char* _M_delim; + +public: + /// Construct from an ostream. + ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_delim(0) {} + + /** + * Construct from an ostream with optional delimiter. + * @param s Underlying ostream to write to. + * @param c CharT delimiter string to insert. + */ + ostream_iterator(ostream_type& __s, const char* __c) : + _M_stream(&__s), _M_delim(__c) { } + + /// Copy constructor. + ostream_iterator(const ostream_iterator& __obj) : + _M_stream(__obj._M_stream), _M_delim(__obj._M_delim) { } + + /// Writes @a value to underlying ostream using operator<<. If + /// constructed with delimiter string, writes delimiter to ostream. + ostream_iterator& + operator=(const T& __value) + { + *_M_stream << __value; + if (_M_delim) *_M_stream << _M_delim; + return *this; + } + + ostream_iterator& + operator*() + { return *this; } + + ostream_iterator& + operator++() + { return *this; } + + ostream_iterator& + operator++(int) + { return *this; } +}; // end class raw_ostream_iterator + +} // end llvm namespace + +#endif diff --git a/include/llvm/Support/stacktrace.h b/include/llvm/Support/stacktrace.h new file mode 100644 index 0000000..1c97647 --- /dev/null +++ b/include/llvm/Support/stacktrace.h @@ -0,0 +1,269 @@ +/** + \file "util/stacktrace.h" + Utility macros and header for convenient stack-trace debugging. + $Id: stacktrace.h,v 1.1 2010/03/14 22:25:18 fang Exp $ + */ + +#ifndef __UTIL_STACKTRACE_H__ +#define __UTIL_STACKTRACE_H__ + +// macros for enabling/disabling stacktrace code +/** + Strongly recommend using these macros to be able to + turn everything off at compile time. + Predefine this to 0 at compile time to turn-off. + */ +#ifndef ENABLE_STACKTRACE +#define ENABLE_STACKTRACE 0 // on (1) or off (0) by default +#endif + +#include + +/** + LLVM+friends only: + Define to 1 to use llvm::raw_ostream instead of std::ostream. + Rationale: be independent from system's libstdc++ iostream + */ +#define ST_USE_RAW_OSTREAM 1 +#if !ST_USE_RAW_OSTREAM +#include // needed for std::ostream forward declaration +#endif + +//============================================================================= +// This is the macro interface intended for the programmer. +#if ENABLE_STACKTRACE +#include "llvm/Support/cppcat.h" // for the UNIQUIFY macros +#include "llvm/Support/Compiler.h" // for LLVM_ATTRIBUTE_UNUSED + +#define __ATTRIBUTE_UNUSED__ LLVM_ATTRIBUTE_UNUSED + +/** + The macro that keeps track of scope and call stacks. + \param str the string to be printed. + */ +#define STACKTRACE(str) \ + const util::stacktrace UNIQUIFY(__stacktrace_) (str) +/** + No user-supplied string required, uses __PRETTY_FUNCTION__ + built-in internal string. Is this gcc-only? + There's always __func__ for brevity. + */ +#define STACKTRACE_BRIEF \ + const util::stacktrace UNIQUIFY(__stacktrace_) (__func__) +#define STACKTRACE_VERBOSE \ + const util::stacktrace UNIQUIFY(__stacktrace__) (__PRETTY_FUNCTION__) +/** + This enables echoing each time trace stack is updated, i.e., + upon entering and leaving function call stack + or lexical scopes. + */ +#define STACKTRACE_ECHO_ON \ + const util::stacktrace::echo UNIQUIFY(__echo_stacktrace__) (1) +#define STACKTRACE_ECHO_OFF \ + const util::stacktrace::echo UNIQUIFY(__echo_stacktrace__) (0) +#define STACKTRACE_STREAM \ + util::stacktrace::stream() +/** + Indents and returns the current stream used by stacktrace. + */ +#define STACKTRACE_INDENT \ + STACKTRACE_STREAM << util::stacktrace_auto_indent +/** + ostream << style printing. + This interface is preferable when compiler isn't smart enough + to optimize away no-ops with the null_stacktrace_stream. + \param x may be a set of <<-cascaded arguments. + */ +#define STACKTRACE_INDENT_PRINT(x) STACKTRACE_INDENT << x +#define REDIRECT_STACKTRACE(os) \ + const util::stacktrace::redirect UNIQUIFY(__redir_stacktrace__) (os) +#define ASSERT_STACKTRACE(expr) \ + if (!(expr)) { util::stacktrace::full_dump(); assert(expr); } + +#else // ENABLE_STACKTRACE -------------------------------------------------- + +#define STACKTRACE(str) +#define STACKTRACE_BRIEF +#define STACKTRACE_VERBOSE +#define STACKTRACE_ECHO_ON +#define STACKTRACE_ECHO_OFF +#define STACKTRACE_STREAM NULL_STACKTRACE_STREAM +#define STACKTRACE_INDENT NULL_STACKTRACE_STREAM +#define STACKTRACE_INDENT_PRINT(x) +#define REDIRECT_STACKTRACE(os) +#define ASSERT_STACKTRACE(expr) assert(expr) +#endif // ENABLE_STACKTRACE -------------------------------------------------- + +//============================================================================= +// additional macros for general purpose use +// we provide these macro layers for ease controlling +// certain subsets of debugging + +#ifndef STACKTRACE_DESTRUCTORS +#define STACKTRACE_DESTRUCTORS (0 && ENABLE_STACKTRACE) +#endif +#ifndef STACKTRACE_CONSTRUCTORS +#define STACKTRACE_CONSTRUCTORS (0 && ENABLE_STACKTRACE) +#endif + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +/** + STACKTRACE_DTOR is intended for use with destructors + */ +#ifndef STACKTRACE_DTOR +#if STACKTRACE_DESTRUCTORS + #define STACKTRACE_DTOR(x) STACKTRACE(x) + #define STACKTRACE_DTOR_BRIEF STACKTRACE_BRIEF + #define STACKTRACE_DTOR_VERBOSE STACKTRACE_VERBOSE + #define STACKTRACE_DTOR_PRINT(x) STACKTRACE_INDENT_PRINT(x) +#else + #define STACKTRACE_DTOR(x) + #define STACKTRACE_DTOR_BRIEF + #define STACKTRACE_DTOR_VERBOSE + #define STACKTRACE_DTOR_PRINT(x) +#endif // STACKTRACE_DESTRUCTORS +#endif // STACKTRACE_DTOR + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +/** + STACKTRACE_CTOR is intended for use with constructors + */ +#ifndef STACKTRACE_CTOR +#if STACKTRACE_CONSTRUCTORS + #define STACKTRACE_CTOR(x) STACKTRACE(x) + #define STACKTRACE_CTOR_BRIEF STACKTRACE_BRIEF + #define STACKTRACE_CTOR_VERBOSE STACKTRACE_VERBOSE + #define STACKTRACE_CTOR_PRINT(x) STACKTRACE_INDENT_PRINT(x) +#else + #define STACKTRACE_CTOR(x) + #define STACKTRACE_CTOR_BRIEF + #define STACKTRACE_CTOR_VERBOSE + #define STACKTRACE_CTOR_PRINT(x) +#endif // STACKTRACE_CONSTRUCTORS +#endif // STACKTRACE_CTOR + +//============================================================================= + +#if ENABLE_STACKTRACE + +#include +#include +#include +#include // needed + +#if ST_USE_RAW_OSTREAM +namespace llvm { +class raw_ostream; // from "Support/raw_ostream.h" +} +#endif + +namespace util { +using std::list; +using std::string; +using std::stack; +#if ST_USE_RAW_OSTREAM +typedef llvm::raw_ostream st_ostream_type; +#else +typedef std::ostream st_ostream_type; +#endif + +//============================================================================= +/** + Nothing is inlined because when you're debugging you shouldn't be + varing about performance. + Can use for function scopes or any conditional statement scopes. + Two mechanisms for controlling behavior, + compile-time macros and public static variables. + TODO: make one entry per thread, mapped by thread ID. + */ +class stacktrace { +public: + /// the type of stack used to hold feedback text + typedef list stack_text_type; + /// the type of stack used to track on/off mode + typedef stack stack_echo_type; + /// the type of stack used to track stream redirections + typedef stack stack_streams_type; + +public: + class manager; + struct echo; + struct redirect; + struct indent { }; + +public: +// stacktrace(const char*); + stacktrace(const string&); + ~stacktrace(); +public: + static + st_ostream_type& + stream(void); + + /** + Explicit request by user to dump the stack trace. + Useful in assertion failures. + */ + static + void + full_dump(void); + +private: + // and undefined + // non-copy-able + explicit + stacktrace(const stacktrace&); + + // non-assignable + stacktrace& + operator = (const stacktrace&); + + // non-heap allocatable + static void* operator new (size_t); + static void operator delete (void*); + static void* operator new (size_t, void*); + static void operator delete (void*, void*); + static void* operator new [] (size_t); + static void operator delete [] (void*); + static void* operator new [] (size_t, void*); + static void operator delete [] (void*, void*); + +} __ATTRIBUTE_UNUSED__ ; // end class stacktrace + +//----------------------------------------------------------------------------- +extern const stacktrace::indent stacktrace_auto_indent; + +st_ostream_type& +operator << (st_ostream_type&, const stacktrace::indent&); + +//----------------------------------------------------------------------------- +/** + Whether or not to print upon entering and exiting. + Pass in 0 to disable. + Enabling/disable lasts for the duration of the scope. + */ +struct stacktrace::echo { + echo(const int i = 1); + ~echo(); +} __ATTRIBUTE_UNUSED__ ; // end struct echo + +//----------------------------------------------------------------------------- +/** + Redirect all stack dumps to this ostream until changed otherwise. + Lasts for the duration of the scope where this is called. + */ +struct stacktrace::redirect { + redirect(st_ostream_type&); + ~redirect(); +} __ATTRIBUTE_UNUSED__ ; // end struct redirect + +//============================================================================= + +} // end namespace util + +#else // ENABLE_STACKTRACE + // don't even bother processing class declaration! +#endif // ENABLE_STACKTRACE + +#endif // __UTIL_STACKTRACE_H__ + diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 424e759..27b5cec 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include // for std::tie #include "llvm/CodeGen/AsmPrinter.h" #include "DwarfDebug.h" #include "DwarfException.h" @@ -187,10 +188,12 @@ bool AsmPrinter::doInitialization(Module &M) { // anyway. Triple TT(getTargetTriple()); if (TT.isOSDarwin()) { + static const unsigned MinMajor = 10, MinMinor = 9, MinUpdate = 0; unsigned Major, Minor, Update; TT.getOSVersion(Major, Minor, Update); // If there is a version specified, Major will be non-zero. - if (Major) + // Suppress this target directive for older toolchains (pre-darwin13). + if (Major && (std::tie(Major, Minor, Update) >= std::tie(MinMajor, MinMinor, MinUpdate))) OutStreamer.EmitVersionMin((TT.isMacOSX() ? MCVM_OSXVersionMin : MCVM_IOSVersionMin), Major, Minor, Update); diff --git a/lib/LineEditor/LineEditor.cpp b/lib/LineEditor/LineEditor.cpp index a50ccc3..5c1a784 100644 --- a/lib/LineEditor/LineEditor.cpp +++ b/lib/LineEditor/LineEditor.cpp @@ -14,7 +14,14 @@ #include "llvm/Support/raw_ostream.h" #include #ifdef HAVE_LIBEDIT +// darwin8 and darwin9's histedit.h missing extern "C", darwin10+'s OK +#ifdef __cplusplus +extern "C" { +#endif #include +#ifdef __cplusplus +} +#endif #endif using namespace llvm; diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index a8aad71..e108472 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -1119,7 +1119,7 @@ raw_ostream &operator<<(raw_ostream &OS, const MCFixup &AF) { } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -void MCFragment::dump() { +void MCFragment::dump() const { raw_ostream &OS = llvm::errs(); OS << "<"; @@ -1230,13 +1230,13 @@ void MCFragment::dump() { OS << ">"; } -void MCSectionData::dump() { +void MCSectionData::dump() const { raw_ostream &OS = llvm::errs(); OS << "dump(); } @@ -1259,19 +1259,19 @@ void MCSymbolData::dump() const { OS << ">"; } -void MCAssembler::dump() { +void MCAssembler::dump() const { raw_ostream &OS = llvm::errs(); OS << "dump(); } OS << "],\n"; OS << " Symbols:["; - for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) { + for (const_symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) { if (it != symbol_begin()) OS << ",\n "; it->dump(); } diff --git a/lib/MC/MCDisassembler/CMakeLists.txt b/lib/MC/MCDisassembler/CMakeLists.txt index 5195b9e..085b2ef 100644 --- a/lib/MC/MCDisassembler/CMakeLists.txt +++ b/lib/MC/MCDisassembler/CMakeLists.txt @@ -1,3 +1,28 @@ +set(BACKEND_LIBS "") +foreach(t ${LLVM_TARGETS_TO_BUILD}) + set(td ${LLVM_MAIN_SRC_DIR}/lib/Target/${t}) + if(EXISTS ${td}/TargetInfo/CMakeLists.txt) + append(BACKEND_LIBS "LLVM${t}Info") + endif() + if(EXISTS ${td}/MCTargetDesc/CMakeLists.txt) + append(BACKEND_LIBS "LLVM${t}Desc") + endif() + if(EXISTS ${td}/AsmParser/CMakeLists.txt) + append(BACKEND_LIBS "LLVM${t}AsmParser") + endif() + if(EXISTS ${td}/Disassembler/CMakeLists.txt) + append(BACKEND_LIBS "LLVM${t}Disassembler") + endif() +endforeach(t) + add_llvm_library(LLVMMCDisassembler Disassembler.cpp ) + +target_link_libraries(LLVMMCDisassembler + LLVMMC + LLVMMCParser + LLVMSupport + LLVMTarget + ${BACKEND_LIBS} + ) diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp index 5214398..03f5a88 100644 --- a/lib/MC/MachObjectWriter.cpp +++ b/lib/MC/MachObjectWriter.cpp @@ -484,6 +484,7 @@ void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) { } } +#if !ORDER_INDIRECT_SYMBOLS_BY_SECTION // Bind non-lazy symbol pointers first. unsigned IndirectIndex = 0; for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), @@ -522,6 +523,46 @@ void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) { if (Created) Entry.setFlags(Entry.getFlags() | 0x0001); } +#else // ORDER_INDIRECT_SYMBOLS_BY_SECTION + // sort indirect symbols by section + for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), + ie = Asm.indirect_symbol_end(); it != ie; ++it) { + // track their sections by order of appearance + IndirectSymbolSections.insert(it->SectionData); + IndirectSymbolMap[it->SectionData].push_back(it->Symbol); + } + // process indirect symbols by section + unsigned offset = 0; // running total of indirect symbol index offset + IndirectSymbolSection_set_type::const_iterator + i(IndirectSymbolSections.begin()), e(IndirectSymbolSections.end()); + for ( ; i!=e; ++i) { + const IndirectSymbol_list_type& b(IndirectSymbolMap.find(*i)->second); + IndirectSymbol_list_type::const_iterator bi(b.begin()), be(b.end()); + const MCSectionMachO& Section(cast((*i)->getSection())); + switch (Section.getType()) { + default: break; + case MachO::S_NON_LAZY_SYMBOL_POINTERS: { + for ( ; bi!=be; ++bi) + Asm.getOrCreateSymbolData(**bi); + break; + } + case MachO::S_LAZY_SYMBOL_POINTERS: // fall-through + case MachO::S_SYMBOL_STUBS: { + for ( ; bi!=be; ++bi) { + // Set the symbol type to undefined lazy, but only on construction. + // FIXME: Do not hardcode. + bool Created; + MCSymbolData &Entry(Asm.getOrCreateSymbolData(**bi, &Created)); + if (Created) + Entry.setFlags(Entry.getFlags() | 0x0001); + } // end for + break; + } + } // end switch(sectionType) + IndirectSymBase.insert(std::make_pair(*i, offset)); + offset += b.size(); + } +#endif // ORDER_INDIRECT_SYMBOLS_BY_SECTION } /// ComputeSymbolTable - Compute the symbol table data @@ -995,26 +1036,44 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm, // Write the symbol table data, if used. if (NumSymbols) { // Write the indirect symbol entries. +#if ORDER_INDIRECT_SYMBOLS_BY_SECTION + for (IndirectSymbolSection_set_type::const_iterator + si(IndirectSymbolSections.begin()), se(IndirectSymbolSections.end()); + si != se; ++si) { + const IndirectSymbol_list_type& l(IndirectSymbolMap.find(*si)->second); + for (IndirectSymbol_list_type::const_iterator + it(l.begin()), ie(l.end()); it != ie; ++it) +#else for (MCAssembler::const_indirect_symbol_iterator it = Asm.indirect_symbol_begin(), - ie = Asm.indirect_symbol_end(); it != ie; ++it) { + ie = Asm.indirect_symbol_end(); it != ie; ++it) +#endif + { // Indirect symbols in the non-lazy symbol pointer section have some // special handling. const MCSectionMachO &Section = +#if ORDER_INDIRECT_SYMBOLS_BY_SECTION + static_cast((*si)->getSection()); + const MCSymbol* Sym = *it; +#else static_cast(it->SectionData->getSection()); + const MCSymbol* Sym = it->Symbol; +#endif if (Section.getType() == MachO::S_NON_LAZY_SYMBOL_POINTERS) { // If this symbol is defined and internal, mark it as such. - if (it->Symbol->isDefined() && - !Asm.getSymbolData(*it->Symbol).isExternal()) { + if (Sym->isDefined() && + !Asm.getSymbolData(*Sym).isExternal()) { uint32_t Flags = MachO::INDIRECT_SYMBOL_LOCAL; - if (it->Symbol->isAbsolute()) + if (Sym->isAbsolute()) Flags |= MachO::INDIRECT_SYMBOL_ABS; Write32(Flags); continue; } } - - Write32(Asm.getSymbolData(*it->Symbol).getIndex()); + Write32(Asm.getSymbolData(*Sym).getIndex()); +#if ORDER_INDIRECT_SYMBOLS_BY_SECTION + } +#endif } // FIXME: Check that offsets match computed ones. diff --git a/lib/Support/Atomic.cpp b/lib/Support/Atomic.cpp index ac4ff3e..d820683 100644 --- a/lib/Support/Atomic.cpp +++ b/lib/Support/Atomic.cpp @@ -22,21 +22,68 @@ using namespace llvm; #undef MemoryFence #endif +// USE_DARWIN_ATOMICS conditionally defined in Atomics.h +#if USE_DARWIN_ATOMICS +#include +// __APPLE__ should take precedence over __GNUC__ +// sys::cas_flag is int32_t from Support/Atomic.h, so use '32' variants +// prototypes lack the 'volatile' qualifier, so we need to cast them away +template +static inline +T* vcast(volatile T* ptr) { return const_cast(ptr); } + +// note on weakly-ordered architectures (PPC): +/** +DESCRIPTION + These functions are thread and multiprocessor safe. For each function, + there is a version that does and another that does not incorporate a + memory barrier. Barriers strictly order memory access on a weakly- + ordered architecture such as PPC. All loads and stores executed in + sequential program order before the barrier will complete before any load + or store executed after the barrier. On a uniprocessor, the barrier + operation is typically a nop. On a multiprocessor, the barrier can be + quite expensive. + + Most code will want to use the barrier functions to insure that memory + shared between threads is properly synchronized. For example, if you + want to initialize a shared data structure and then atomically increment + a variable to indicate that the initialization is complete, then you MUST + use OSAtomicIncrement32Barrier() to ensure that the stores to your data + structure complete before the atomic add. Likewise, the consumer of that + data structure MUST use OSAtomicDecrement32Barrier(), in order to ensure + that their loads of the structure are not executed before the atomic + decrement. On the other hand, if you are simply incrementing a global + counter, then it is safe and potentially much faster to use OSAtomicIn- + crement32(). If you are unsure which version to use, prefer the barrier + variants as they are safer. + +RETURN VALUES + The arithmetic and logical operations return the new value, after the + operation has been performed. The compare-and-swap operations return + true if the comparison was equal, ie if the swap occured. The bit test + and set/clear operations return the original value of the bit. + + -- man 3 atomic (BSD Library Functions Manual) +**/ +#endif + #if defined(__GNUC__) || (defined(__IBMCPP__) && __IBMCPP__ >= 1210) +#if !USE_DARWIN_ATOMICS #define GNU_ATOMICS #endif +#endif void sys::MemoryFence() { #if LLVM_HAS_ATOMICS == 0 return; -#else -# if defined(GNU_ATOMICS) +#elif defined(GNU_ATOMICS) __sync_synchronize(); -# elif defined(_MSC_VER) +#elif USE_DARWIN_ATOMICS + OSMemoryBarrier(); +#elif defined(_MSC_VER) MemoryBarrier(); -# else +#else # error No memory fence implementation for your platform! -# endif #endif } @@ -50,6 +97,18 @@ sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr, return result; #elif defined(GNU_ATOMICS) return __sync_val_compare_and_swap(ptr, old_value, new_value); +/** +These builtins perform an atomic compare and swap. +That is, if the current value of *ptr is oldval, then write newval into *ptr. +The bool version returns true if the comparison is successful and newval +was written. The val version returns the contents of *ptr before the operation. + -- http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html +**/ +#elif USE_DARWIN_ATOMICS + const sys::cas_flag prev = *ptr; + // returns new value, but we don't want it + OSAtomicCompareAndSwap32Barrier(old_value, new_value, vcast(ptr)); + return prev; // return the previous value at *ptr #elif defined(_MSC_VER) return InterlockedCompareExchange(ptr, new_value, old_value); #else @@ -63,6 +122,8 @@ sys::cas_flag sys::AtomicIncrement(volatile sys::cas_flag* ptr) { return *ptr; #elif defined(GNU_ATOMICS) return __sync_add_and_fetch(ptr, 1); +#elif USE_DARWIN_ATOMICS + return OSAtomicIncrement32Barrier(vcast(ptr)); // return new value #elif defined(_MSC_VER) return InterlockedIncrement(ptr); #else @@ -76,6 +137,8 @@ sys::cas_flag sys::AtomicDecrement(volatile sys::cas_flag* ptr) { return *ptr; #elif defined(GNU_ATOMICS) return __sync_sub_and_fetch(ptr, 1); +#elif USE_DARWIN_ATOMICS + return OSAtomicDecrement32Barrier(vcast(ptr)); // return new value #elif defined(_MSC_VER) return InterlockedDecrement(ptr); #else @@ -89,6 +152,8 @@ sys::cas_flag sys::AtomicAdd(volatile sys::cas_flag* ptr, sys::cas_flag val) { return *ptr; #elif defined(GNU_ATOMICS) return __sync_add_and_fetch(ptr, val); +#elif USE_DARWIN_ATOMICS + return OSAtomicAdd32Barrier(val, vcast(ptr)); // return new value #elif defined(_MSC_VER) return InterlockedExchangeAdd(ptr, val) + val; #else diff --git a/lib/Support/CMakeLists.txt b/lib/Support/CMakeLists.txt index 80b6ab8..f62c981 100644 --- a/lib/Support/CMakeLists.txt +++ b/lib/Support/CMakeLists.txt @@ -23,6 +23,7 @@ add_llvm_library(LLVMSupport FileUtilities.cpp FileOutputBuffer.cpp FoldingSet.cpp + Format.cpp FormattedStream.cpp GraphWriter.cpp Hashing.cpp @@ -116,6 +117,8 @@ add_llvm_library(LLVMSupport Windows/ThreadLocal.inc Windows/TimeValue.inc Windows/Watchdog.inc +# fang's debugging tools + stacktrace.cc ) set(system_libs) if( NOT MSVC ) diff --git a/lib/Support/CrashRecoveryContext.cpp b/lib/Support/CrashRecoveryContext.cpp index 9b0e443..f4a1cf3 100644 --- a/lib/Support/CrashRecoveryContext.cpp +++ b/lib/Support/CrashRecoveryContext.cpp @@ -334,13 +334,13 @@ const std::string &CrashRecoveryContext::getBacktrace() const { // FIXME: Portability. static void setThreadBackgroundPriority() { -#ifdef __APPLE__ +#if defined(__APPLE__) && defined(PRIO_DARWIN_THREAD) && defined(PRIO_DARWIN_BG) setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG); #endif } static bool hasThreadBackgroundPriority() { -#ifdef __APPLE__ +#if defined(__APPLE__) && defined(PRIO_DARWIN_THREAD) return getpriority(PRIO_DARWIN_THREAD, 0) == 1; #else return false; diff --git a/lib/Support/Format.cpp b/lib/Support/Format.cpp new file mode 100644 index 0000000..ff378d4 --- /dev/null +++ b/lib/Support/Format.cpp @@ -0,0 +1,34 @@ +//===-- llvm/Support/FormattedStream.cpp - Formatted streams ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the implementation of default_format_string. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/Format.h" + +namespace llvm { + +#define FORMAT_DEC(T, fmt) const char default_format_string::dec[] = fmt; +#define FORMAT_HEX(T, fmt) const char default_format_string::hex[] = fmt; + +FORMAT_DEC(int, "%d") +FORMAT_HEX(int, "0x%x") +FORMAT_DEC(long, "%ld") +FORMAT_HEX(long, "0x%lx") +FORMAT_DEC(long long, "%lld") +FORMAT_HEX(long long, "0x%llx") +FORMAT_DEC(unsigned int, "%u") +FORMAT_HEX(unsigned int, "0x%x") +FORMAT_DEC(unsigned long, "%lu") +FORMAT_HEX(unsigned long, "0x%lx") +FORMAT_DEC(unsigned long long, "%llu") +FORMAT_HEX(unsigned long long, "0x%llx") + +} // end namespace llvm diff --git a/lib/Support/Unix/Memory.inc b/lib/Support/Unix/Memory.inc index c9d89a8..9c61876 100644 --- a/lib/Support/Unix/Memory.inc +++ b/lib/Support/Unix/Memory.inc @@ -55,7 +55,8 @@ int getPosixProtectionFlags(unsigned Flags) { llvm::sys::Memory::MF_EXEC: return PROT_READ | PROT_WRITE | PROT_EXEC; case llvm::sys::Memory::MF_EXEC: -#if defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(__APPLE__) + // patch from Roman Divacky, bug 14278 // On PowerPC, having an executable page that has no read permission // can have unintended consequences. The function InvalidateInstruction- // Cache uses instructions dcbf and icbi, both of which are treated by diff --git a/lib/Support/Unix/Signals.inc b/lib/Support/Unix/Signals.inc index 1841fea..725d858 100644 --- a/lib/Support/Unix/Signals.inc +++ b/lib/Support/Unix/Signals.inc @@ -333,7 +333,8 @@ static void PrintStackTraceSignalHandler(void *) { void llvm::sys::PrintStackTraceOnErrorSignal() { AddSignalHandler(PrintStackTraceSignalHandler, nullptr); -#if defined(__APPLE__) && defined(ENABLE_CRASH_OVERRIDES) +// some of these constants are not defined for darwin8 +#if defined(__APPLE__) && defined(ENABLE_CRASH_OVERRIDES) && defined(MACH_EXCEPTION_CODES) && defined(EXC_MASK_CRASH) // Environment variable to disable any kind of crash dialog. if (getenv("LLVM_DISABLE_CRASH_REPORT")) { mach_port_t self = mach_task_self(); diff --git a/lib/Support/stacktrace.cc b/lib/Support/stacktrace.cc new file mode 100644 index 0000000..40e91c4 --- /dev/null +++ b/lib/Support/stacktrace.cc @@ -0,0 +1,197 @@ +/** + \file "util/stacktrace.cc" + Implementation of stacktrace class. + $Id: stacktrace.cc,v 1.1 2010/03/14 22:25:17 fang Exp $ + */ + +// ENABLE_STACKTRACE is forced for this module, regardless of pre-definitions! +#define ENABLE_STACKTRACE 1 + +#include "llvm/Support/stacktrace.h" +#if ST_USE_RAW_OSTREAM +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/raw_ostream_iterator.h" +#else +#include +#include +#endif + +namespace util { +using std::list; +using std::stack; +#if ST_USE_RAW_OSTREAM +using llvm::ostream_iterator; +using llvm::endl; +static llvm::raw_ostream& cerr(llvm::errs()); // alias +#else +using std::ostream_iterator; +using std::cout; +using std::cerr; +using std::endl; +#endif + +#if !ST_USE_RAW_OSTREAM +/** + Guarantee that ios is initialized. + */ +static const std::ios_base::Init ios_init; +#endif + +//============================================================================= +/** + Private implementation class, not visible to other modules. + Only written as a class for convenient static initialization. + To be able to trace function calls that occur during static + initialization, we must guarantee that the manager's static + objects are initialized first! Global initialization ordering is + generally non-trivial, so resort to the techinique of + interfacing through reference functions which will guarantee + a one-time initialization upon first invocation. + (This technique is also used in util::persistent_object_manager.) + */ +class stacktrace::manager { +public: + typedef stacktrace::stack_text_type stack_text_type; + typedef stacktrace::stack_echo_type stack_echo_type; + typedef stacktrace::stack_streams_type stack_streams_type; + + static stack_text_type stack_text; + static stack_text_type stack_indent; + static stack_echo_type stack_echo; + static stack_streams_type stack_streams; + +private: + manager() { + // initialization moved to static initialization below. + } + + ~manager() { } + +public: + static + st_ostream_type& + print_auto_indent(st_ostream_type& o) { +#if !ST_USE_RAW_OSTREAM + // guarantee iostream initialized before first used. + static const std::ios_base::Init ios_init; +#endif + static const stack_text_type& si(manager::stack_indent); + // INVARIANT(o.good()); + ostream_iterator osi(o); + copy(si.begin(), si.end(), osi); + return o; + } + +}; // end class stacktrace::manager + +//----------------------------------------------------------------------------- +// static construction + +stacktrace::manager::stack_text_type +stacktrace::manager::stack_text; + +stacktrace::manager::stack_text_type +stacktrace::manager::stack_indent; + +stacktrace::manager::stack_echo_type +stacktrace::manager::stack_echo; + +stacktrace::manager::stack_streams_type +stacktrace::manager::stack_streams; + +static const int stack_echo_init = +(stacktrace::manager::stack_echo.push(1), 1); + +static const int stack_stream_init = +(stacktrace::manager::stack_streams.push(&cerr), 1); + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +/** + Stacktrace stream manipulator. + */ +const stacktrace::indent +stacktrace_auto_indent = stacktrace::indent(); + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +/** + Uses the stacktrace's position to automatically indent. + */ +st_ostream_type& +operator << (st_ostream_type& o, const stacktrace::indent&) { + // need static initializers? + return stacktrace::manager::print_auto_indent(o) << ": "; +} + +//============================================================================= +// class stacktrace method definitions + +stacktrace::stacktrace(const string& s) { + // cannot use string (without ref-count) because it may be destroyed + // prematurely during static destruction, char* is robust and permanent. + static const char* const + default_stack_indent_string = "| "; // permanent + // must be static or else, new ref_counts will be locally released + manager::stack_text.push_back(s); + if (manager::stack_echo.top()) { + st_ostream_type& os(*manager::stack_streams.top()); + manager::print_auto_indent(os) << "\\-{ " << + manager::stack_text.back() << endl; + } + manager::stack_indent.push_back(default_stack_indent_string); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +stacktrace::~stacktrace() { + manager::stack_indent.pop_back(); + if (manager::stack_echo.top()) { + st_ostream_type& os(*manager::stack_streams.top()); + manager::print_auto_indent(os) << "/-} " << + manager::stack_text.back() << endl; + } + manager::stack_text.pop_back(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +/** + Returns reference to the current stacktrace output stream. + */ +st_ostream_type& +stacktrace::stream(void) { + return *manager::stack_streams.top(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void +stacktrace::full_dump(void) { + st_ostream_type& current_stream(stream()); + ostream_iterator osi(current_stream, "\n"); + copy(manager::stack_text.begin(), manager::stack_text.end(), osi); + current_stream << endl; +} + +//============================================================================= +// struct stacktrace::echo method definitions + +stacktrace::echo::echo(const int i) { + manager::stack_echo.push(i); +} + +stacktrace::echo::~echo() { + manager::stack_echo.pop(); +} + +//============================================================================= +// struct redirect_stacktrace method definitions + +stacktrace::redirect::redirect(st_ostream_type& o) { + manager::stack_streams.push(&o); +} + +stacktrace::redirect::~redirect() { + manager::stack_streams.pop(); +} + +//============================================================================= +} // end namespace util + + diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp index c54d5e7..b967f86 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp @@ -22,6 +22,10 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MachO.h" #include "llvm/Support/TargetRegistry.h" + +#define ENABLE_STACKTRACE 0 +#include "llvm/Support/stacktrace.h" + using namespace llvm; static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) { @@ -209,6 +213,7 @@ namespace { DarwinPPCAsmBackend(const Target &T) : PPCAsmBackend(T, false) { } MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { + STACKTRACE_VERBOSE; bool is64 = getPointerSize() == 8; return createPPCMachObjectWriter( OS, @@ -236,6 +241,7 @@ namespace { MCAsmBackend *llvm::createPPCAsmBackend(const Target &T, const MCRegisterInfo &MRI, StringRef TT, StringRef CPU) { + STACKTRACE_VERBOSE; if (Triple(TT).isOSDarwin()) return new DarwinPPCAsmBackend(T); diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index 6f67c59..3a30441 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -59,6 +59,10 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetRegisterInfo.h" + +#define ENABLE_STACKTRACE 0 +#include "llvm/Support/stacktrace.h" + using namespace llvm; #define DEBUG_TYPE "asmprinter" @@ -1079,6 +1083,7 @@ static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) { return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr"); } +// 'L' needed to designate label as local static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) { // Add $tmp suffix to $stub, yielding $stub$tmp. return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp"); @@ -1086,6 +1091,7 @@ static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) { void PPCDarwinAsmPrinter:: EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { + STACKTRACE_VERBOSE; bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; bool isDarwin = Subtarget.isDarwin(); @@ -1096,7 +1102,9 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection(); // Output stubs for dynamically-linked functions + // see http://developer.apple.com/library/mac/#documentation/developertools/reference/assembler/050-PowerPC_Addressing_Modes_and_Assembler_Instructions/ppc_instructions.html if (TM.getRelocationModel() == Reloc::PIC_) { + STACKTRACE_INDENT_PRINT("Reloc::PIC_" << endl); const MCSection *StubSection = OutContext.getMachOSection("__TEXT", "__picsymbolstub1", MachO::S_SYMBOL_STUBS | @@ -1122,10 +1130,12 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { // mflr r0 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R0)); // bcl 20, 31, AnonSymbol + // unconditional, but doesn't push link register onto stack EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCLalways).addExpr(Anon)); OutStreamer.EmitLabel(AnonSymbol); // mflr r11 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R11)); + // load address one half at a time // addis r11, r11, ha16(LazyPtr - AnonSymbol) const MCExpr *SubHa16 = PPCMCExpr::CreateHa(Sub, isDarwin, OutContext); EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS) @@ -1165,6 +1175,7 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { return; } + STACKTRACE_INDENT_PRINT("not Reloc::PIC_" << endl); const MCSection *StubSection = OutContext.getMachOSection("__TEXT","__symbol_stub1", MachO::S_SYMBOL_STUBS | @@ -1222,6 +1233,7 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { bool PPCDarwinAsmPrinter::doFinalization(Module &M) { + STACKTRACE_VERBOSE; bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; // Darwin/PPC always uses mach-o. diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 708d36f..67e5202 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -3001,6 +3001,7 @@ PPCTargetLowering::LowerFormalArguments_Darwin( SmallVector MemOps; unsigned nAltivecParamsAtEnd = 0; + // for Darwin, reported as: http://llvm.org/bugs/show_bug.cgi?id=15821 Function::const_arg_iterator FuncArg = MF.getFunction()->arg_begin(); unsigned CurArgIdx = 0; for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) { diff --git a/lib/Target/PowerPC/PPCMCInstLower.cpp b/lib/Target/PowerPC/PPCMCInstLower.cpp index 6680413..d85bbaf 100644 --- a/lib/Target/PowerPC/PPCMCInstLower.cpp +++ b/lib/Target/PowerPC/PPCMCInstLower.cpp @@ -28,6 +28,11 @@ #include "llvm/MC/MCInst.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetLoweringObjectFile.h" + +#define ENABLE_STACKTRACE 0 +#include "llvm/Support/stacktrace.h" +#include "llvm/Support/raw_ostream.h" + using namespace llvm; static MachineModuleInfoMachO &getMachOMMI(AsmPrinter &AP) { @@ -36,6 +41,7 @@ static MachineModuleInfoMachO &getMachOMMI(AsmPrinter &AP) { static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){ + STACKTRACE_VERBOSE; const TargetMachine &TM = AP.TM; Mangler *Mang = AP.Mang; const DataLayout *DL = TM.getDataLayout(); @@ -56,12 +62,15 @@ static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){ unsigned PrefixLen = Name.size(); if (!MO.isGlobal()) { + STACKTRACE_INDENT_PRINT("!MO.isGlobal()" << endl); assert(MO.isSymbol() && "Isn't a symbol reference"); Mang->getNameWithPrefix(Name, MO.getSymbolName()); } else { + STACKTRACE_INDENT_PRINT("MO.isGlobal()" << endl); const GlobalValue *GV = MO.getGlobal(); TM.getNameWithPrefix(Name, GV, *Mang); } + STACKTRACE_INDENT_PRINT("base Name: " << Name << endl); unsigned OrigLen = Name.size() - PrefixLen; @@ -72,6 +81,7 @@ static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){ // If the target flags on the operand changes the name of the symbol, do that // before we return the symbol. if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB && isDarwin) { + STACKTRACE_INDENT_PRINT("is PPCII::MO_DARWIN_STUB" << endl); MachineModuleInfoImpl::StubValueTy &StubSym = getMachOMMI(AP).getFnStubEntry(Sym); if (StubSym.getPointer()) diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 9895ee6..4c55c2e 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -314,8 +314,8 @@ void PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II) const { unsigned Reg = MF.getRegInfo().createVirtualRegister(LP64 ? G8RC : GPRC); if (MaxAlign < TargetAlign && isInt<16>(FrameSize)) { - BuildMI(MBB, II, dl, TII.get(PPC::ADDI), Reg) - .addReg(PPC::R31) + BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::ADDI8 : PPC::ADDI), Reg) + .addReg(getFrameRegister(MF)) .addImm(FrameSize); } else if (LP64) { BuildMI(MBB, II, dl, TII.get(PPC::LD), Reg) diff --git a/lib/Transforms/Hello/CMakeLists.txt b/lib/Transforms/Hello/CMakeLists.txt index 3851b35..697ad03 100644 --- a/lib/Transforms/Hello/CMakeLists.txt +++ b/lib/Transforms/Hello/CMakeLists.txt @@ -1,3 +1,6 @@ +# patch: this should be built as a bundle/module/plug-in +set(MODULE TRUE) + # If we don't need RTTI or EH, there's no reason to export anything # from the hello plugin. if( NOT LLVM_REQUIRES_RTTI ) diff --git a/test/CodeGen/PowerPC/hello-reloc.ll b/test/CodeGen/PowerPC/hello-reloc.ll new file mode 100644 index 0000000..4af6f1c --- /dev/null +++ b/test/CodeGen/PowerPC/hello-reloc.ll @@ -0,0 +1,281 @@ +; This tests mach-O/PPC relocation entries. +; This test is paired with test/CodeGen/PowerPC/hello-reloc.s, +; which tests llvm-mc. + +; RUN: llc -filetype=asm -relocation-model=pic -mcpu=g4 -mtriple=powerpc-apple-darwin8 %s -o - | tee %t1 | FileCheck -check-prefix=DARWIN-G4-ASM %s +; RUN: llc -filetype=obj -relocation-model=pic -mcpu=g4 -mtriple=powerpc-apple-darwin8 %s -o - | tee %t2 | macho-dump | tee %t3 | FileCheck -check-prefix=DARWIN-G4-DUMP %s + +; FIXME: validating .s->.o requires darwin asm syntax support in PPCAsmParser +; RUN-XFAIL: llvm-mc -relocation-model=pic -mcpu=g4 -triple=powerpc-apple-darwin8 %t1 -o - | tee %t4 | macho-dump | tee %t5 | FileCheck -check-prefix=DARWIN-G4-DUMP %s +; RUN-XFAIL: diff -u %t2 %t4 || diff -u %t3 %t5 + +; ModuleID = 'hello-puts.c' +; compiled with clang (-fno-common -DPIC -femit-all-decls) from: +; extern int puts(const char*); +; int main(int argc, char* argv[]) { puts("Hello, world!"); return 0; } + +target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v128:128:128-n32" +target triple = "powerpc-apple-macosx10.4.0" + +@.str = private unnamed_addr constant [14 x i8] c"Hello, world!\00", align 1 + +; Function Attrs: nounwind +define i32 @main(i32 %argc, i8** %argv) #0 { +entry: + %retval = alloca i32, align 4 + %argc.addr = alloca i32, align 4 + %argv.addr = alloca i8**, align 4 + store i32 0, i32* %retval + store i32 %argc, i32* %argc.addr, align 4 + store i8** %argv, i8*** %argv.addr, align 4 + %call = call i32 @puts(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) + ret i32 0 +} + +declare i32 @puts(i8*) #1 + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "ssp-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "ssp-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +; DARWIN-G4-ASM: .machine ppc7400 +; DARWIN-G4-ASM: .section __TEXT,__textcoal_nt,coalesced,pure_instructions +; DARWIN-G4-ASM: .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 +; DARWIN-G4-ASM: .section __TEXT,__text,regular,pure_instructions +; DARWIN-G4-ASM: .globl _main +; DARWIN-G4-ASM: .align 4 +; DARWIN-G4-ASM:_main: ; @main +; DARWIN-G4-ASM:; BB#0: ; %entry +; DARWIN-G4-ASM: mflr r0 +; DARWIN-G4-ASM: stw r31, -4(r1) +; DARWIN-G4-ASM: stw r0, 8(r1) +; DARWIN-G4-ASM: stwu r1, -80(r1) +; DARWIN-G4-ASM: bl L0$pb +; DARWIN-G4-ASM:L0$pb: +; DARWIN-G4-ASM: mr r31, r1 +; DARWIN-G4-ASM: li [[REGA:r[0-9]+]], 0 +; DARWIN-G4-ASM: mflr [[REGC:r[0-9]+]] +; DARWIN-G4-ASM: stw [[REGB:r[0-9]+]], 68(r31) +; DARWIN-G4-ASM: stw [[REGA]], 72(r31) +; DARWIN-G4-ASM: stw r4, 64(r31) +; DARWIN-G4-ASM: addis [[REGC]], [[REGC]], ha16(L_.str-L0$pb) +; DARWIN-G4-ASM: la [[REGB]], lo16(L_.str-L0$pb)([[REGC]]) +; DARWIN-G4-ASM: bl L_puts$stub +; DARWIN-G4-ASM: li [[REGB]], 0 +; DARWIN-G4-ASM: addi r1, r1, 80 +; DARWIN-G4-ASM: lwz r0, 8(r1) +; DARWIN-G4-ASM: lwz r31, -4(r1) +; DARWIN-G4-ASM: mtlr r0 +; DARWIN-G4-ASM: blr +; DARWIN-G4-ASM: .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 +; DARWIN-G4-ASM: .align 4 +; DARWIN-G4-ASM:L_puts$stub: +; DARWIN-G4-ASM: .indirect_symbol _puts +; DARWIN-G4-ASM: mflr r0 +; DARWIN-G4-ASM: bcl 20, 31, L_puts$stub$tmp +; DARWIN-G4-ASM:L_puts$stub$tmp: +; DARWIN-G4-ASM: mflr [[REGD:r[0-9]+]] +; DARWIN-G4-ASM: addis [[REGD]], [[REGD]], ha16(L_puts$lazy_ptr-L_puts$stub$tmp) +; DARWIN-G4-ASM: mtlr r0 +; DARWIN-G4-ASM: lwzu [[REGE:r[0-9]+]], lo16(L_puts$lazy_ptr-L_puts$stub$tmp)([[REGD]]) +; DARWIN-G4-ASM: mtctr [[REGE]] +; DARWIN-G4-ASM: bctr +; DARWIN-G4-ASM: .section __DATA,__la_symbol_ptr,lazy_symbol_pointers +; DARWIN-G4-ASM:L_puts$lazy_ptr: +; DARWIN-G4-ASM: .indirect_symbol _puts +; DARWIN-G4-ASM: .long dyld_stub_binding_helper +; DARWIN-G4-ASM:.subsections_via_symbols +; DARWIN-G4-ASM: .section __TEXT,__cstring,cstring_literals +; DARWIN-G4-ASM:L_.str: ; @.str +; DARWIN-G4-ASM: .asciz "Hello, world!" + +; DARWIN-G4-DUMP: ('cputype', 18) +; DARWIN-G4-DUMP: ('cpusubtype', 0) +; DARWIN-G4-DUMP: ('filetype', 1) +; DARWIN-G4-DUMP: ('num_load_commands', 3) +; DARWIN-G4-DUMP: ('load_commands_size', 500) +; DARWIN-G4-DUMP: ('flag', 8192) +; DARWIN-G4-DUMP: ('load_commands', [ +; DARWIN-G4-DUMP: # Load Command 0 +; DARWIN-G4-DUMP: (('command', 1) +; DARWIN-G4-DUMP: ('size', 396) +; DARWIN-G4-DUMP: ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +; DARWIN-G4-DUMP: ('vm_addr', 0) +; DARWIN-G4-DUMP: ('vm_size', 130) +; DARWIN-G4-DUMP: ('file_offset', 528) +; DARWIN-G4-DUMP: ('file_size', 130) +; DARWIN-G4-DUMP: ('maxprot', 7) +; DARWIN-G4-DUMP: ('initprot', 7) +; DARWIN-G4-DUMP: ('num_sections', 5) +; DARWIN-G4-DUMP: ('flags', 0) +; DARWIN-G4-DUMP: ('sections', [ +; DARWIN-G4-DUMP: # Section 0 +; DARWIN-G4-DUMP: (('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +; DARWIN-G4-DUMP: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +; DARWIN-G4-DUMP: ('address', 0) +; DARWIN-G4-DUMP: ('size', 80) +; DARWIN-G4-DUMP: ('offset', 528) +; DARWIN-G4-DUMP: ('alignment', 4) +; DARWIN-G4-DUMP: ('reloc_offset', 660) +; DARWIN-G4-DUMP: ('num_reloc', 5) +; DARWIN-G4-DUMP: ('flags', 0x80000400) +; DARWIN-G4-DUMP: ('reserved1', 0) +; DARWIN-G4-DUMP: ('reserved2', 0) +; DARWIN-G4-DUMP: ), +; DARWIN-G4-DUMP: ('_relocations', [ +; DARWIN-G4-DUMP: # Relocation 0 +; DARWIN-G4-DUMP: (('word-0', 0x34), +; DARWIN-G4-DUMP: ('word-1', 0x3c3)), +; DARWIN-G4-DUMP: # Relocation 1 +; DARWIN-G4-DUMP: (('word-0', 0xab000030), +; DARWIN-G4-DUMP: ('word-1', 0x74)), +; DARWIN-G4-DUMP: # Relocation 2 +; DARWIN-G4-DUMP: (('word-0', 0xa1000000), +; DARWIN-G4-DUMP: ('word-1', 0x14)), +; DARWIN-G4-DUMP: # Relocation 3 +; DARWIN-G4-DUMP: (('word-0', 0xac00002c), +; DARWIN-G4-DUMP: ('word-1', 0x74)), +; DARWIN-G4-DUMP: # Relocation 4 +; DARWIN-G4-DUMP: (('word-0', 0xa1000060), +; DARWIN-G4-DUMP: ('word-1', 0x14)), +; DARWIN-G4-DUMP: ]) +; DARWIN-G4-DUMP: # Section 1 +; DARWIN-G4-DUMP: (('section_name', '__textcoal_nt\x00\x00\x00') +; DARWIN-G4-DUMP: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +; DARWIN-G4-DUMP: ('address', 80) +; DARWIN-G4-DUMP: ('size', 0) +; DARWIN-G4-DUMP: ('offset', 608) +; DARWIN-G4-DUMP: ('alignment', 0) +; DARWIN-G4-DUMP: ('reloc_offset', 0) +; DARWIN-G4-DUMP: ('num_reloc', 0) +; DARWIN-G4-DUMP: ('flags', 0x8000000b) +; DARWIN-G4-DUMP: ('reserved1', 0) +; DARWIN-G4-DUMP: ('reserved2', 0) +; DARWIN-G4-DUMP: ), +; DARWIN-G4-DUMP: ('_relocations', [ +; DARWIN-G4-DUMP: ]) +; DARWIN-G4-DUMP: # Section 2 +; DARWIN-G4-DUMP: (('section_name', '__picsymbolstub1') +; DARWIN-G4-DUMP: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +; DARWIN-G4-DUMP: ('address', 80) +; DARWIN-G4-DUMP: ('size', 32) +; DARWIN-G4-DUMP: ('offset', 608) +; DARWIN-G4-DUMP: ('alignment', 4) +; DARWIN-G4-DUMP: ('reloc_offset', 700) +; DARWIN-G4-DUMP: ('num_reloc', 4) +; DARWIN-G4-DUMP: ('flags', 0x80000408) +; DARWIN-G4-DUMP: ('reserved1', 0) +; DARWIN-G4-DUMP: ('reserved2', 32) +; DARWIN-G4-DUMP: ), +; DARWIN-G4-DUMP: ('_relocations', [ +; DARWIN-G4-DUMP: # Relocation 0 +; DARWIN-G4-DUMP: (('word-0', 0xab000014), +; DARWIN-G4-DUMP: ('word-1', 0x70)), +; DARWIN-G4-DUMP: # Relocation 1 +; DARWIN-G4-DUMP: (('word-0', 0xa1000000), +; DARWIN-G4-DUMP: ('word-1', 0x58)), +; DARWIN-G4-DUMP: # Relocation 2 +; DARWIN-G4-DUMP: (('word-0', 0xac00000c), +; DARWIN-G4-DUMP: ('word-1', 0x70)), +; DARWIN-G4-DUMP: # Relocation 3 +; DARWIN-G4-DUMP: (('word-0', 0xa1000018), +; DARWIN-G4-DUMP: ('word-1', 0x58)), +; DARWIN-G4-DUMP: ]) +; DARWIN-G4-DUMP: # Section 3 +; DARWIN-G4-DUMP: (('section_name', '__la_symbol_ptr\x00') +; DARWIN-G4-DUMP: ('segment_name', '__DATA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +; DARWIN-G4-DUMP: ('address', 112) +; DARWIN-G4-DUMP: ('size', 4) +; DARWIN-G4-DUMP: ('offset', 640) +; DARWIN-G4-DUMP: ('alignment', 0) +; DARWIN-G4-DUMP: ('reloc_offset', 732) +; DARWIN-G4-DUMP: ('num_reloc', 1) +; DARWIN-G4-DUMP: ('flags', 0x7) +; DARWIN-G4-DUMP: ('reserved1', 1) +; DARWIN-G4-DUMP: ('reserved2', 0) +; DARWIN-G4-DUMP: ), +; DARWIN-G4-DUMP: ('_relocations', [ +; DARWIN-G4-DUMP: # Relocation 0 +; DARWIN-G4-DUMP: (('word-0', 0x0), +; DARWIN-G4-DUMP: ('word-1', 0x250)), +; DARWIN-G4-DUMP: ]) +; DARWIN-G4-DUMP: # Section 4 +; DARWIN-G4-DUMP: (('section_name', '__cstring\x00\x00\x00\x00\x00\x00\x00') +; DARWIN-G4-DUMP: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +; DARWIN-G4-DUMP: ('address', 116) +; DARWIN-G4-DUMP: ('size', 14) +; DARWIN-G4-DUMP: ('offset', 644) +; DARWIN-G4-DUMP: ('alignment', 0) +; DARWIN-G4-DUMP: ('reloc_offset', 0) +; DARWIN-G4-DUMP: ('num_reloc', 0) +; DARWIN-G4-DUMP: ('flags', 0x2) +; DARWIN-G4-DUMP: ('reserved1', 0) +; DARWIN-G4-DUMP: ('reserved2', 0) +; DARWIN-G4-DUMP: ), +; DARWIN-G4-DUMP: ('_relocations', [ +; DARWIN-G4-DUMP: ]) +; DARWIN-G4-DUMP: ]) +; DARWIN-G4-DUMP: ), +; DARWIN-G4-DUMP: # Load Command 1 +; DARWIN-G4-DUMP: (('command', 2) +; DARWIN-G4-DUMP: ('size', 24) +; DARWIN-G4-DUMP: ('symoff', 748) +; DARWIN-G4-DUMP: ('nsyms', 3) +; DARWIN-G4-DUMP: ('stroff', 784) +; DARWIN-G4-DUMP: ('strsize', 40) +; DARWIN-G4-DUMP: ('_string_data', '\x00_main\x00dyld_stub_binding_helper\x00_puts\x00\x00\x00') +; DARWIN-G4-DUMP: ('_symbols', [ +; DARWIN-G4-DUMP: # Symbol 0 +; DARWIN-G4-DUMP: (('n_strx', 1) +; DARWIN-G4-DUMP: ('n_type', 0xf) +; DARWIN-G4-DUMP: ('n_sect', 1) +; DARWIN-G4-DUMP: ('n_desc', 0) +; DARWIN-G4-DUMP: ('n_value', 0) +; DARWIN-G4-DUMP: ('_string', '_main') +; DARWIN-G4-DUMP: ), +; DARWIN-G4-DUMP: # Symbol 1 +; DARWIN-G4-DUMP: (('n_strx', 32) +; DARWIN-G4-DUMP: ('n_type', 0x1) +; DARWIN-G4-DUMP: ('n_sect', 0) +; DARWIN-G4-DUMP: ('n_desc', 1) +; DARWIN-G4-DUMP: ('n_value', 0) +; DARWIN-G4-DUMP: ('_string', '_puts') +; DARWIN-G4-DUMP: ), +; DARWIN-G4-DUMP: # Symbol 2 +; DARWIN-G4-DUMP: (('n_strx', 7) +; DARWIN-G4-DUMP: ('n_type', 0x1) +; DARWIN-G4-DUMP: ('n_sect', 0) +; DARWIN-G4-DUMP: ('n_desc', 0) +; DARWIN-G4-DUMP: ('n_value', 0) +; DARWIN-G4-DUMP: ('_string', 'dyld_stub_binding_helper') +; DARWIN-G4-DUMP: ), +; DARWIN-G4-DUMP: ]) +; DARWIN-G4-DUMP: ), +; DARWIN-G4-DUMP: # Load Command 2 +; DARWIN-G4-DUMP: (('command', 11) +; DARWIN-G4-DUMP: ('size', 80) +; DARWIN-G4-DUMP: ('ilocalsym', 0) +; DARWIN-G4-DUMP: ('nlocalsym', 0) +; DARWIN-G4-DUMP: ('iextdefsym', 0) +; DARWIN-G4-DUMP: ('nextdefsym', 1) +; DARWIN-G4-DUMP: ('iundefsym', 1) +; DARWIN-G4-DUMP: ('nundefsym', 2) +; DARWIN-G4-DUMP: ('tocoff', 0) +; DARWIN-G4-DUMP: ('ntoc', 0) +; DARWIN-G4-DUMP: ('modtaboff', 0) +; DARWIN-G4-DUMP: ('nmodtab', 0) +; DARWIN-G4-DUMP: ('extrefsymoff', 0) +; DARWIN-G4-DUMP: ('nextrefsyms', 0) +; DARWIN-G4-DUMP: ('indirectsymoff', 740) +; DARWIN-G4-DUMP: ('nindirectsyms', 2) +; DARWIN-G4-DUMP: ('extreloff', 0) +; DARWIN-G4-DUMP: ('nextrel', 0) +; DARWIN-G4-DUMP: ('locreloff', 0) +; DARWIN-G4-DUMP: ('nlocrel', 0) +; DARWIN-G4-DUMP: ('_indirect_symbols', [ +; DARWIN-G4-DUMP: # Indirect Symbol 0 +; DARWIN-G4-DUMP: (('symbol_index', 0x1),), +; DARWIN-G4-DUMP: # Indirect Symbol 1 +; DARWIN-G4-DUMP: (('symbol_index', 0x1),), +; DARWIN-G4-DUMP: ]) +; DARWIN-G4-DUMP: ), +; DARWIN-G4-DUMP: ]) diff --git a/test/MC/MachO/indirect-symbols.s b/test/MC/MachO/indirect-symbols.s index 90fd231..deb9e7a 100644 --- a/test/MC/MachO/indirect-symbols.s +++ b/test/MC/MachO/indirect-symbols.s @@ -97,7 +97,7 @@ _e: // CHECK: ('nsyms', 6) // CHECK: ('stroff', 516) // CHECK: ('strsize', 20) -// CHECK: ('_string_data', '\x00_d\x00_a\x00_b\x00_c\x00_e\x00_f\x00\x00') +// CHECK: ('_string_data', '\x00_a\x00_d\x00_b\x00_c\x00_e\x00_f\x00\x00') // CHECK: ('_symbols', [ // CHECK: # Symbol 0 // CHECK: (('n_strx', 7) @@ -132,7 +132,7 @@ _e: // CHECK: ('_string', '_f') // CHECK: ), // CHECK: # Symbol 4 -// CHECK: (('n_strx', 4) +// CHECK: (('n_strx', 1) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) // CHECK: ('n_desc', 1) @@ -140,7 +140,7 @@ _e: // CHECK: ('_string', '_a') // CHECK: ), // CHECK: # Symbol 5 -// CHECK: (('n_strx', 1) +// CHECK: (('n_strx', 4) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) // CHECK: ('n_desc', 0) diff --git a/test/MC/MachO/symbol-indirect.s b/test/MC/MachO/symbol-indirect.s index 2412970..6f5c842 100644 --- a/test/MC/MachO/symbol-indirect.s +++ b/test/MC/MachO/symbol-indirect.s @@ -137,7 +137,7 @@ sym_nlp_G: // CHECK: ('nsyms', 10) // CHECK: ('stroff', 592) // CHECK: ('strsize', 104) -// CHECK: ('_string_data', '\x00sym_lsp_A\x00sym_lsp_G\x00sym_nlp_A\x00sym_nlp_G\x00sym_nlp_B\x00sym_nlp_E\x00sym_lsp_B\x00sym_lsp_E\x00sym_lsp_C\x00sym_nlp_C\x00\x00\x00\x00') +// CHECK: ('_string_data', '\x00sym_lsp_A\x00sym_lsp_G\x00sym_nlp_A\x00sym_nlp_G\x00sym_lsp_B\x00sym_lsp_E\x00sym_nlp_B\x00sym_nlp_E\x00sym_lsp_C\x00sym_nlp_C\x00\x00\x00\x00') // CHECK: ('_symbols', [ // CHECK: # Symbol 0 // CHECK: (('n_strx', 81) @@ -180,7 +180,7 @@ sym_nlp_G: // CHECK: ('_string', 'sym_lsp_A') // CHECK: ), // CHECK: # Symbol 5 -// CHECK: (('n_strx', 61) +// CHECK: (('n_strx', 41) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) // CHECK: ('n_desc', 1) @@ -188,7 +188,7 @@ sym_nlp_G: // CHECK: ('_string', 'sym_lsp_B') // CHECK: ), // CHECK: # Symbol 6 -// CHECK: (('n_strx', 71) +// CHECK: (('n_strx', 51) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) // CHECK: ('n_desc', 1) @@ -204,7 +204,7 @@ sym_nlp_G: // CHECK: ('_string', 'sym_nlp_A') // CHECK: ), // CHECK: # Symbol 8 -// CHECK: (('n_strx', 41) +// CHECK: (('n_strx', 61) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) // CHECK: ('n_desc', 0) @@ -212,7 +212,7 @@ sym_nlp_G: // CHECK: ('_string', 'sym_nlp_B') // CHECK: ), // CHECK: # Symbol 9 -// CHECK: (('n_strx', 51) +// CHECK: (('n_strx', 71) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) // CHECK: ('n_desc', 0) diff --git a/test/Transforms/GCOVProfiling/version.ll b/test/Transforms/GCOVProfiling/version.ll index 04f3f99..bc013b1 100644 --- a/test/Transforms/GCOVProfiling/version.ll +++ b/test/Transforms/GCOVProfiling/version.ll @@ -1,11 +1,11 @@ ; RUN: echo '!9 = metadata !{metadata !"%T/version.ll", metadata !0}' > %t1 ; RUN: cat %s %t1 > %t2 ; RUN: opt -insert-gcov-profiling -disable-output < %t2 -; RUN: head -c8 %T/version.gcno | grep '^oncg\*204' +; RUN: ghead -c8 %T/version.gcno | grep '^oncg\*204' ; RUN: rm %T/version.gcno ; RUN: not opt -insert-gcov-profiling -default-gcov-version=asdfasdf -disable-output < %t2 ; RUN: opt -insert-gcov-profiling -default-gcov-version=407* -disable-output < %t2 -; RUN: head -c8 %T/version.gcno | grep '^oncg\*704' +; RUN: ghead -c8 %T/version.gcno | grep '^oncg\*704' ; RUN: rm %T/version.gcno define void @test() { diff --git a/tools/bugpoint-passes/CMakeLists.txt b/tools/bugpoint-passes/CMakeLists.txt index de68bb5..06d439e 100644 --- a/tools/bugpoint-passes/CMakeLists.txt +++ b/tools/bugpoint-passes/CMakeLists.txt @@ -1,3 +1,6 @@ +# patch: this should be built as a bundle/module/plug-in +set(MODULE TRUE) + if( NOT LLVM_BUILD_TOOLS ) set(EXCLUDE_FROM_ALL ON) endif() diff --git a/utils/Target/PowerPC/darwin-to-linux-ppc-asm.sed b/utils/Target/PowerPC/darwin-to-linux-ppc-asm.sed new file mode 100755 index 0000000..ac01cda --- /dev/null +++ b/utils/Target/PowerPC/darwin-to-linux-ppc-asm.sed @@ -0,0 +1,7 @@ +#!env sed -f +# syntactically translates darwin-ppc assembly to GNU/linux assembly +# GNU sed required +s|\|\1|g +s|\\(([^(]*)\)|\1@ha|g +s|\\(([^(]*)\)|\1@l|g +# s|\|.&|g diff --git a/utils/lit/lit/LitConfig.py b/utils/lit/lit/LitConfig.py index b0dde5d..ecfd9a8 100644 --- a/utils/lit/lit/LitConfig.py +++ b/utils/lit/lit/LitConfig.py @@ -34,7 +34,8 @@ class LitConfig: self.debug = debug self.isWindows = bool(isWindows) self.params = dict(params) - self.bashPath = None + # local hack only, don't commit this patch + self.bashPath = '@FINK_PREFIX@/bin/bash' # Configuration files to look for when discovering test suites. self.config_prefix = config_prefix or 'lit' diff --git a/utils/lit/lit/TestRunner.py b/utils/lit/lit/TestRunner.py index 9752417..f71e95e 100644 --- a/utils/lit/lit/TestRunner.py +++ b/utils/lit/lit/TestRunner.py @@ -415,11 +415,16 @@ def parseIntegratedTestScript(test, normalize_slashes=False, return str(line_number - int(match.group(2))) ln = re.sub('%\(line *([\+-]) *(\d+)\)', replace_line_number, ln) + ln1 = ln.split(' ')[1]; # Collapse lines with trailing '\\'. if script and script[-1][-1] == '\\': script[-1] = script[-1][:-1] + ln - else: + # do not commit this patch + # exception: built-in shell commands and operators + elif ln[1] == '(' or ln[1] == '{' or ln[1] == '!' or ln[1] == '|' or ln1 == 'export' or ln1 == 'env' or ln1 == 'cd' or ln1 == 'pushd' or ln1 == 'set' or ln1 == 'test' or ln1 == 'umask': script.append(ln) + else: + script.append('gtimeout 1m ' +ln) elif command_type == 'XFAIL': test.xfails.extend([s.strip() for s in ln.split(',')]) elif command_type == 'REQUIRES':