forked from microsoft/llvm-mctoll
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathExternalFunctions.cpp
84 lines (76 loc) · 3.5 KB
/
ExternalFunctions.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//===-- ExternalFunctions.cpp -----------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the table of known external functions.
//
//===----------------------------------------------------------------------===//
#include "ExternalFunctions.h"
const std::map<StringRef, ExternalFunctions::RetAndArgs>
ExternalFunctions::GlibcFunctions = {
{"printf", {"i32", {"i8*"}, true}},
{"__printf_chk", {"i32", {"i8*"}, true}},
{"malloc", {"i8*", {"i64"}, false}},
{"memcpy", {"i8*", {"i8*", "i8*", "i64"}, false}},
{"memset", {"i8*", {"i8*", "i32", "i64"}, false}},
{"strcpy", {"i8*", {"i8*", "i8*"}, false}},
{"strncpy", {"i8*", {"i8*", "i8*", "i64"}, false}},
{"__isoc99_scanf", {"i32", {"i8*"}, true}},
{"clock_gettime", {"i32", {"i64", "i64*"}, false}},
{"time", {"i64", {"i64*"}, false}},
{"sleep", {"i32", {"i32"}, false}},
{"putchar", {"i32", {"i32"}, false}},
{"puts", {"i32", {"i8*"}, false}},
{"free", {"void", {"i8*"}, false}},
{"atoi", {"i32", {"i8*"}, false}},
{"calloc", {"i8*", {"i64", "i64"}, false}},
{"__assert_fail", {"void", {"i8*", "i8*", "i32", "i8*"}, false}},
{"fopen", {"%struct._IO_FILE*", {"i8*", "i8*"}, false}},
{"exp", {"float", {"float"}, false}},
{"realloc", {"i8*", {"i8*", "i64"}, false}},
{"tanh", {"float", {"float"}, false}},
{"lgamma", {"float", {"float"}, false}},
{"floor", {"float", {"float"}, false}},
{"strtol", {"i64", {"i8*", "i8**", "i32"}, false}},
{"strlen", {"i64", {"i8*"}, false}},
{"round", {"float", {"float"}, false}},
{"feof", {"i32", {"%struct._IO_FILE*"}, false}},
{"pow", {"float", {"float", "float"}, false}},
{"exit", {"void", {"i32"}, false}}};
// Construct and return a Function* corresponding to a known external function
Function *ExternalFunctions::Create(StringRef &CFuncName, ModuleRaiser &MR) {
Module *M = MR.getModule();
assert(M != nullptr && "Uninitialized ModuleRaiser!");
Function *Func = M->getFunction(CFuncName);
if (Func != nullptr)
return Func;
auto iter = ExternalFunctions::GlibcFunctions.find(CFuncName);
if (iter == ExternalFunctions::GlibcFunctions.end()) {
errs() << CFuncName.data() << "\n";
llvm_unreachable("Unsupported undefined function");
}
const ExternalFunctions::RetAndArgs &retAndArgs = iter->second;
Type *RetType =
MR.getFunctionFilter()->getPrimitiveDataType(retAndArgs.ReturnType);
std::vector<Type *> ArgVec;
for (StringRef arg : retAndArgs.Arguments) {
Type *argType = MR.getFunctionFilter()->getPrimitiveDataType(arg);
ArgVec.push_back(argType);
}
ArrayRef<Type *> Args(ArgVec);
if (FunctionType *FuncType =
FunctionType::get(RetType, Args, retAndArgs.isVariadic)) {
FunctionCallee FunCallee = M->getOrInsertFunction(CFuncName, FuncType);
assert(isa<Function>(FunCallee.getCallee()) && "Expect Function");
Func = reinterpret_cast<Function *>(FunCallee.getCallee());
Func->setCallingConv(CallingConv::C);
Func->setDSOLocal(true);
return Func;
}
errs() << CFuncName.data() << "\n";
llvm_unreachable("Failed to construct external function's type");
}