mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
6da21c0e33
That causes references to them to be weak references which can collapse to null if no definition is provided. We call these functions unconditionally, so a definition *must* be provided. Make the definitions provided in the .cpp file weak by re-declaring them as weak just prior to defining them. This should keep compilers which cannot attach the weak attribute to the definition happy while actually resolving the symbols correctly during the link. You might ask yourself upon reading this commit log: how did *any* of this work before? Well, fun story. It turns out we have some code in Support (BumpPtrAllocator) which both uses virtual dispatch and has out-of-line vtables used by that virtual dispatch. If you move the virtual dispatch into its header in *just* the right way, the optimizer gets to devirtualize, and remove all references to the vtable. Then the sad part: the references to this one vtable were the only strong symbol uses in the support library for llvm-tblgen AFAICT. At least, after doing something just like this, these symbols stopped getting their weak definition and random calls to them would segfault instead. Yay software. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205137 91177308-0d34-0410-b5e6-96231b3b80d8
76 lines
2.6 KiB
C++
76 lines
2.6 KiB
C++
//===-- Valgrind.cpp - Implement Valgrind communication ---------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Defines Valgrind communication methods, if HAVE_VALGRIND_VALGRIND_H is
|
|
// defined. If we have valgrind.h but valgrind isn't running, its macros are
|
|
// no-ops.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Support/Valgrind.h"
|
|
#include "llvm/Config/config.h"
|
|
|
|
#if HAVE_VALGRIND_VALGRIND_H
|
|
#include <valgrind/valgrind.h>
|
|
|
|
static bool InitNotUnderValgrind() {
|
|
return !RUNNING_ON_VALGRIND;
|
|
}
|
|
|
|
// This bool is negated from what we'd expect because code may run before it
|
|
// gets initialized. If that happens, it will appear to be 0 (false), and we
|
|
// want that to cause the rest of the code in this file to run the
|
|
// Valgrind-provided macros.
|
|
static const bool NotUnderValgrind = InitNotUnderValgrind();
|
|
|
|
bool llvm::sys::RunningOnValgrind() {
|
|
if (NotUnderValgrind)
|
|
return false;
|
|
return RUNNING_ON_VALGRIND;
|
|
}
|
|
|
|
void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
|
|
if (NotUnderValgrind)
|
|
return;
|
|
|
|
VALGRIND_DISCARD_TRANSLATIONS(Addr, Len);
|
|
}
|
|
|
|
#else // !HAVE_VALGRIND_VALGRIND_H
|
|
|
|
bool llvm::sys::RunningOnValgrind() {
|
|
return false;
|
|
}
|
|
|
|
void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
|
|
}
|
|
|
|
#endif // !HAVE_VALGRIND_VALGRIND_H
|
|
|
|
#if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG)
|
|
// These functions require no implementation, tsan just looks at the arguments
|
|
// they're called with. However, they are required to be weak as some other
|
|
// application or library may already be providing these definitions for the
|
|
// same reason we are.
|
|
extern "C" {
|
|
LLVM_ATTRIBUTE_WEAK void AnnotateHappensAfter(const char *file, int line,
|
|
const volatile void *cv);
|
|
void AnnotateHappensAfter(const char *file, int line, const volatile void *cv) {
|
|
}
|
|
LLVM_ATTRIBUTE_WEAK void AnnotateHappensBefore(const char *file, int line,
|
|
const volatile void *cv);
|
|
void AnnotateHappensBefore(const char *file, int line,
|
|
const volatile void *cv) {}
|
|
LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesBegin(const char *file, int line);
|
|
void AnnotateIgnoreWritesBegin(const char *file, int line) {}
|
|
LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesEnd(const char *file, int line);
|
|
void AnnotateIgnoreWritesEnd(const char *file, int line) {}
|
|
}
|
|
#endif
|