Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions include/phasar/Utils/LibrarySummary.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/******************************************************************************
* Copyright (c) 2025 Fabian Schiebel.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Fabian Schiebel and others
*****************************************************************************/

#ifndef PHASAR_UTILS_LIBRARY_SUMMARY_H
#define PHASAR_UTILS_LIBRARY_SUMMARY_H

#include "llvm/ADT/StringRef.h"

namespace psr {

/// Checks, whether a function with the given (mangled) name is known to be a
/// heap-allocating function, similar to malloc.
[[nodiscard]] bool isHeapAllocatingFunction(llvm::StringRef FName) noexcept;

/// Checks whether a function with the given (mangled) name is known to always
/// return the same pointer
[[nodiscard]] bool isSingletonReturningFunction(llvm::StringRef FName) noexcept;

} // namespace psr

#endif // PHASAR_UTILS_LIBRARY_SUMMARY_H
13 changes: 9 additions & 4 deletions lib/PhasarLLVM/Utils/LLVMShorthands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h"

#include "phasar/Config/Configuration.h"
#include "phasar/Utils/LibrarySummary.h"
#include "phasar/Utils/Utilities.h"

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/IR/Constants.h"
Expand Down Expand Up @@ -67,9 +67,14 @@ bool psr::isAllocaInstOrHeapAllocaFunction(const llvm::Value *V) noexcept {
}

bool psr::isHeapAllocatingFunction(const llvm::Function *Fun) noexcept {
return llvm::StringSwitch<bool>(Fun->getName())
.Cases("_Znwm", "_Znam", "_ZnwPv", "malloc", "calloc", "realloc", true)
.Default(false);
auto FunName = Fun->getName();

if (FunName == "realloc") {
// For backwards compatibility. We should treat realloc specially.
return true;
}

return isHeapAllocatingFunction(FunName);
}

// For C-style polymorphism we need to check whether a callee candidate would
Expand Down
160 changes: 160 additions & 0 deletions lib/Utils/LibrarySummary.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#include "phasar/Utils/LibrarySummary.h"

#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringRef.h"

static constexpr llvm::StringLiteral HeapAllocatingFunNames[] = {
// Also see SVF's extapi.c

// C functions:
"malloc",
"calloc",
"fopen",
"fopen64",
"fdopen",
"readdir64",
"tmpvoid64",
"zmalloc",
"gzdopen",
"iconv_open",
"lalloc",
"lalloc_clear",
"nhalloc",
"oballoc",
"popen",
"pthread_getspecific",
"readdir",
"safe_calloc",
"safe_malloc",
"safecalloc",
"safemalloc",
"setmntent",
"shmat",
"__sysv_signal",
"signal",
"tempnam",
"tmpvoid",
"xcalloc",
"xmalloc",
"xnmalloc",
"xcharalloc",
"xinmalloc",
"xizalloc",
"xzalloc",
"xpalloc",
"xicalloc",
"icalloc",
"imalloc",
"_gl_alloc_nomem",
"aligned_alloc",
"memalign",
"valloc",
"mmap64",
"XSetLocaleModifiers",
"__strdup",
"xmemdup",
"crypt",
"ctime",
"dlerror",
"dlopen",
"gai_strerror",
"gcry_cipher_algo_name",
"svfgcry_md_algo_name_",
"getenv",
"getlogin",
"getpass",
"gnutls_strerror",
"gpg_strerror",
"gzerror",
"inet_ntoa",
"initscr",
"llvm_stacksave",
"mmap",
"newwin",
"nl_langinfo",
"opendir",
"sbrk",
"strdup",
"xstrdup",
"strerror",
"strsignal",
"textdomain",
"tgetstr",
"tigetstr",
"tmpnam",
"ttyname",
"tzalloc",

// C++ functions:
"_Znwm",
"_Znam",
"_Znwj",
"_Znaj",
"_ZnwmRKSt9nothrow_t",
"_ZnamRKSt9nothrow_t",
"_ZnwmSt11align_val_t",
"_ZnamSt11align_val_t",
"_ZnwmSt11align_val_tRKSt9nothrow_t",
"_ZnamSt11align_val_tRKSt9nothrow_t",
"__cxa_allocate_exception",
};

static constexpr llvm::StringLiteral SingletonReturningFunctions[] = {
"__ctype_b_loc",
"__ctype_tolower_loc",
"__ctype_toupper_loc",
"__errno_location",
"__h_errno_location",
"__res_state",
"asctime",
"bindtextdomain",
"bind_textdomain_codeset",
"dcgettext",
"dgettext",
"dngettext",
"getgrgid",
"getgrnam",
"gethostbyaddr",
"gethostbyname",
"gethostbyname2",
"getmntent",
"getprotobyname",
"getprotobynumber",
"getpwent",
"getpwnam",
"getpwuid",
"getservbyname",
"getservbyport",
"getspnam",
"gettext",
"gmtime",
"gnu_get_libc_version",
"gnutls_check_version",
"localeconv",
"localtime",
"ngettext",
"pango_cairo_font_map_get_default",
"re_comp",
"setlocale",
"tgoto",
"tparm",
"zError",
};

bool psr::isHeapAllocatingFunction(llvm::StringRef FName) noexcept {
// Note: For a performance comparison of different search strategies, see
// https://quick-bench.com/q/lNjDT6z-M-L08h372fbCfYjwM64

static const llvm::DenseSet<llvm::StringRef> HAFs(
std::begin(HeapAllocatingFunNames), std::end(HeapAllocatingFunNames));

return HAFs.count(FName);
}

bool psr::isSingletonReturningFunction(llvm::StringRef FName) noexcept {
static const llvm::DenseSet<llvm::StringRef> SRFs(
std::begin(SingletonReturningFunctions),
std::end(SingletonReturningFunctions));

return SRFs.count(FName);
}
Loading