Skip to content

Commit b56205d

Browse files
authored
More Heap-Allocating Functions (#772)
* Add more known heap-allocating functions + add singleton-returning functions * Add two more heap allocating functions
1 parent 64412c5 commit b56205d

File tree

3 files changed

+196
-4
lines changed

3 files changed

+196
-4
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/******************************************************************************
2+
* Copyright (c) 2025 Fabian Schiebel.
3+
* All rights reserved. This program and the accompanying materials are made
4+
* available under the terms of LICENSE.txt.
5+
*
6+
* Contributors:
7+
* Fabian Schiebel and others
8+
*****************************************************************************/
9+
10+
#ifndef PHASAR_UTILS_LIBRARY_SUMMARY_H
11+
#define PHASAR_UTILS_LIBRARY_SUMMARY_H
12+
13+
#include "llvm/ADT/StringRef.h"
14+
15+
namespace psr {
16+
17+
/// Checks, whether a function with the given (mangled) name is known to be a
18+
/// heap-allocating function, similar to malloc.
19+
[[nodiscard]] bool isHeapAllocatingFunction(llvm::StringRef FName) noexcept;
20+
21+
/// Checks whether a function with the given (mangled) name is known to always
22+
/// return the same pointer
23+
[[nodiscard]] bool isSingletonReturningFunction(llvm::StringRef FName) noexcept;
24+
25+
} // namespace psr
26+
27+
#endif // PHASAR_UTILS_LIBRARY_SUMMARY_H

lib/PhasarLLVM/Utils/LLVMShorthands.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h"
1818

1919
#include "phasar/Config/Configuration.h"
20+
#include "phasar/Utils/LibrarySummary.h"
2021
#include "phasar/Utils/Utilities.h"
2122

2223
#include "llvm/ADT/DenseMap.h"
2324
#include "llvm/ADT/StringRef.h"
24-
#include "llvm/ADT/StringSwitch.h"
2525
#include "llvm/Bitcode/BitcodeReader.h"
2626
#include "llvm/Bitcode/BitcodeWriter.h"
2727
#include "llvm/IR/Constants.h"
@@ -67,9 +67,14 @@ bool psr::isAllocaInstOrHeapAllocaFunction(const llvm::Value *V) noexcept {
6767
}
6868

6969
bool psr::isHeapAllocatingFunction(const llvm::Function *Fun) noexcept {
70-
return llvm::StringSwitch<bool>(Fun->getName())
71-
.Cases("_Znwm", "_Znam", "_ZnwPv", "malloc", "calloc", "realloc", true)
72-
.Default(false);
70+
auto FunName = Fun->getName();
71+
72+
if (FunName == "realloc") {
73+
// For backwards compatibility. We should treat realloc specially.
74+
return true;
75+
}
76+
77+
return isHeapAllocatingFunction(FunName);
7378
}
7479

7580
// For C-style polymorphism we need to check whether a callee candidate would

lib/Utils/LibrarySummary.cpp

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
#include "phasar/Utils/LibrarySummary.h"
2+
3+
#include "llvm/ADT/DenseSet.h"
4+
#include "llvm/ADT/StringRef.h"
5+
6+
static constexpr llvm::StringLiteral HeapAllocatingFunNames[] = {
7+
// Also see SVF's extapi.c
8+
9+
// C functions:
10+
"malloc",
11+
"calloc",
12+
"fopen",
13+
"fopen64",
14+
"fdopen",
15+
"readdir64",
16+
"tmpvoid64",
17+
"zmalloc",
18+
"gzdopen",
19+
"iconv_open",
20+
"lalloc",
21+
"lalloc_clear",
22+
"nhalloc",
23+
"oballoc",
24+
"popen",
25+
"pthread_getspecific",
26+
"readdir",
27+
"safe_calloc",
28+
"safe_malloc",
29+
"safecalloc",
30+
"safemalloc",
31+
"setmntent",
32+
"shmat",
33+
"__sysv_signal",
34+
"signal",
35+
"tempnam",
36+
"tmpvoid",
37+
"xcalloc",
38+
"xmalloc",
39+
"xnmalloc",
40+
"xcharalloc",
41+
"xinmalloc",
42+
"xizalloc",
43+
"xzalloc",
44+
"xpalloc",
45+
"xicalloc",
46+
"icalloc",
47+
"imalloc",
48+
"_gl_alloc_nomem",
49+
"aligned_alloc",
50+
"memalign",
51+
"valloc",
52+
"mmap64",
53+
"XSetLocaleModifiers",
54+
"__strdup",
55+
"xmemdup",
56+
"crypt",
57+
"ctime",
58+
"dlerror",
59+
"dlopen",
60+
"gai_strerror",
61+
"gcry_cipher_algo_name",
62+
"svfgcry_md_algo_name_",
63+
"getenv",
64+
"getlogin",
65+
"getpass",
66+
"gnutls_strerror",
67+
"gpg_strerror",
68+
"gzerror",
69+
"inet_ntoa",
70+
"initscr",
71+
"llvm_stacksave",
72+
"mmap",
73+
"newwin",
74+
"nl_langinfo",
75+
"opendir",
76+
"sbrk",
77+
"strdup",
78+
"xstrdup",
79+
"strerror",
80+
"strsignal",
81+
"textdomain",
82+
"tgetstr",
83+
"tigetstr",
84+
"tmpnam",
85+
"ttyname",
86+
"tzalloc",
87+
88+
// C++ functions:
89+
"_Znwm",
90+
"_Znam",
91+
"_Znwj",
92+
"_Znaj",
93+
"_ZnwmRKSt9nothrow_t",
94+
"_ZnamRKSt9nothrow_t",
95+
"_ZnwmSt11align_val_t",
96+
"_ZnamSt11align_val_t",
97+
"_ZnwmSt11align_val_tRKSt9nothrow_t",
98+
"_ZnamSt11align_val_tRKSt9nothrow_t",
99+
"__cxa_allocate_exception",
100+
};
101+
102+
static constexpr llvm::StringLiteral SingletonReturningFunctions[] = {
103+
"__ctype_b_loc",
104+
"__ctype_tolower_loc",
105+
"__ctype_toupper_loc",
106+
"__errno_location",
107+
"__h_errno_location",
108+
"__res_state",
109+
"asctime",
110+
"bindtextdomain",
111+
"bind_textdomain_codeset",
112+
"dcgettext",
113+
"dgettext",
114+
"dngettext",
115+
"getgrgid",
116+
"getgrnam",
117+
"gethostbyaddr",
118+
"gethostbyname",
119+
"gethostbyname2",
120+
"getmntent",
121+
"getprotobyname",
122+
"getprotobynumber",
123+
"getpwent",
124+
"getpwnam",
125+
"getpwuid",
126+
"getservbyname",
127+
"getservbyport",
128+
"getspnam",
129+
"gettext",
130+
"gmtime",
131+
"gnu_get_libc_version",
132+
"gnutls_check_version",
133+
"localeconv",
134+
"localtime",
135+
"ngettext",
136+
"pango_cairo_font_map_get_default",
137+
"re_comp",
138+
"setlocale",
139+
"tgoto",
140+
"tparm",
141+
"zError",
142+
};
143+
144+
bool psr::isHeapAllocatingFunction(llvm::StringRef FName) noexcept {
145+
// Note: For a performance comparison of different search strategies, see
146+
// https://quick-bench.com/q/lNjDT6z-M-L08h372fbCfYjwM64
147+
148+
static const llvm::DenseSet<llvm::StringRef> HAFs(
149+
std::begin(HeapAllocatingFunNames), std::end(HeapAllocatingFunNames));
150+
151+
return HAFs.count(FName);
152+
}
153+
154+
bool psr::isSingletonReturningFunction(llvm::StringRef FName) noexcept {
155+
static const llvm::DenseSet<llvm::StringRef> SRFs(
156+
std::begin(SingletonReturningFunctions),
157+
std::end(SingletonReturningFunctions));
158+
159+
return SRFs.count(FName);
160+
}

0 commit comments

Comments
 (0)