Skip to content

Commit

Permalink
Add link-time detection of LLVM_ABI_BREAKING_CHECKS mismatch (microso…
Browse files Browse the repository at this point in the history
…ft#5380)

The macro LLVM_ENABLE_ABI_BREAKING_CHECKS is moved to a new header
abi-breaking.h, from llvm-config.h. Only headers that are using the
macro are including this new header.

LLVM will define a symbol, either EnableABIBreakingChecks or
DisableABIBreakingChecks depending on the configuration setting for
LLVM_ABI_BREAKING_CHECKS.

The abi-breaking.h header will add weak references to these symbols in
every clients that includes this header. This should ensure that a
mismatch triggers a link failure (or a load time failure for DSO).

On MSVC, the pragma "detect_mismatch" is used instead.

Differential Revision: https://reviews.llvm.org/D26876

llvm-svn: 288082

Co-authored-by: Mehdi Amini <[email protected]>
  • Loading branch information
bfavela and joker-eph authored Jun 30, 2023
1 parent bf2d6c0 commit 5f931c3
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 8 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,9 @@ configure_file(
configure_file(
${LLVM_MAIN_INCLUDE_DIR}/llvm/Config/llvm-config.h.cmake
${LLVM_INCLUDE_DIR}/llvm/Config/llvm-config.h)
configure_file(
${LLVM_MAIN_INCLUDE_DIR}/llvm/Config/abi-breaking.h.cmake
${LLVM_INCLUDE_DIR}/llvm/Config/abi-breaking.h)
configure_file(
${LLVM_MAIN_INCLUDE_DIR}/llvm/Support/DataTypes.h.cmake
${LLVM_INCLUDE_DIR}/llvm/Support/DataTypes.h)
Expand Down
1 change: 1 addition & 0 deletions include/llvm/ADT/EpochTracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#ifndef LLVM_ADT_EPOCH_TRACKER_H
#define LLVM_ADT_EPOCH_TRACKER_H

#include "llvm/Config/abi-breaking.h"
#include "llvm/Config/llvm-config.h"

#include <cstdint>
Expand Down
2 changes: 2 additions & 0 deletions include/llvm/ADT/ilist_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#ifndef LLVM_ADT_ILIST_NODE_H
#define LLVM_ADT_ILIST_NODE_H

#include "llvm/Config/abi-breaking.h"

namespace llvm {

template<typename NodeTy>
Expand Down
39 changes: 39 additions & 0 deletions include/llvm/Config/abi-breaking.h.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*===------- llvm/Config/abi-breaking.h - llvm configuration -------*- C -*-===*/
/* */
/* The LLVM Compiler Infrastructure */
/* */
/* This file is distributed under the University of Illinois Open Source */
/* License. See LICENSE.TXT for details. */
/* */
/*===----------------------------------------------------------------------===*/

/* This file controls the C++ ABI break introduced in LLVM public header. */

#ifndef LLVM_ABI_BREAKING_CHECKS_H
#define LLVM_ABI_BREAKING_CHECKS_H

/* Define to enable checks that alter the LLVM C++ ABI */
#cmakedefine01 LLVM_ENABLE_ABI_BREAKING_CHECKS

// ABI_BREAKING_CHECKS protection: provides link-time failure when clients build
// mismatch with LLVM
#if defined(_MSC_VER)
// Use pragma with MSVC
#define LLVM_XSTR(s) LLVM_STR(s)
#define LLVM_STR(s) #s
#pragma detect_mismatch("LLVM_ENABLE_ABI_BREAKING_CHECKS", LLVM_XSTR(LLVM_ENABLE_ABI_BREAKING_CHECKS))
#undef LLVM_XSTR
#undef LLVM_STR
#elif defined(__cplusplus)
namespace llvm {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
extern int EnableABIBreakingChecks;
__attribute__((weak, visibility ("hidden"))) int *VerifyEnableABIBreakingChecks = &EnableABIBreakingChecks;
#else
extern int DisableABIBreakingChecks;
__attribute__((weak, visibility ("hidden"))) int *VerifyDisableABIBreakingChecks = &DisableABIBreakingChecks;
#endif
}
#endif // _MSC_VER

#endif
4 changes: 0 additions & 4 deletions include/llvm/Config/config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -432,10 +432,6 @@
/* Installation directory for documentation */
#cmakedefine LLVM_DOCSDIR "${LLVM_DOCSDIR}"

/* Define if LLVM is built with asserts and checks that change the layout of
client-visible data structures. */
#cmakedefine LLVM_ENABLE_ABI_BREAKING_CHECKS

/* Define if threads enabled */
#cmakedefine01 LLVM_ENABLE_THREADS

Expand Down
4 changes: 0 additions & 4 deletions include/llvm/Config/llvm-config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@
/* Installation directory for documentation */
#cmakedefine LLVM_DOCSDIR "${LLVM_DOCSDIR}"

/* Define if LLVM is built with asserts and checks that change the layout of
client-visible data structures. */
#cmakedefine LLVM_ENABLE_ABI_BREAKING_CHECKS

/* Define if threads enabled */
#cmakedefine01 LLVM_ENABLE_THREADS

Expand Down
1 change: 1 addition & 0 deletions include/llvm/Support/ErrorHandling.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Config/abi-breaking.h"
#include <string>

namespace llvm {
Expand Down
15 changes: 15 additions & 0 deletions lib/Support/ErrorHandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,18 @@ std::error_code llvm::mapWindowsError(unsigned EV) {
}

#endif

#ifndef _MSC_VER
namespace llvm {

// One of these two variables will be referenced by a symbol defined in
// llvm-config.h. We provide a link-time (or load time for DSO) failure when
// there is a mismatch in the build configuration of the API client and LLVM.
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
int EnableABIBreakingChecks;
#else
int DisableABIBreakingChecks;
#endif

} // end namespace llvm
#endif

0 comments on commit 5f931c3

Please sign in to comment.