Browse code

Support building with external LLVM 2.9, and drop support for building with external 2.8

Internal version is an LLVM 2.8 with 2 patches backported from LLVM 2.9 to fix a
crash on AVX chips.
So drop support for building with external LLVM 2.8, and add support for
building with external LLVM 2.9 instead.

Caveat:
stack smashing protection is broken on LLVM 2.9 so it is disabled

Example on Debian:
apt-get install llvm-2.9-dev
./configure --enable-llvm --with-system-llvm=/usr/bin/llvm-config-2.9

Török Edvin authored on 2011/05/06 21:18:32
Showing 13 changed files
... ...
@@ -1,3 +1,7 @@
1
+Fri May  6 16:16:00 EEST 2011 (edwin)
2
+------------------------------------
3
+ * libclamav/c++: add support for building with external LLVM 2.9, and drop external 2.8 support
4
+
1 5
 Thu May  5 01:07:57 CEST 2011 (acab)
2 6
 ------------------------------------
3 7
  * clamd: log request ip address for instream scans #bb2592
... ...
@@ -30,8 +30,14 @@
30 30
 #include "llvm/Analysis/DebugInfo.h"
31 31
 #include "llvm/Analysis/Dominators.h"
32 32
 #include "llvm/Analysis/ConstantFolding.h"
33
-#include "llvm/Analysis/LiveValues.h"
33
+//#include "llvm/Analysis/LiveValues.h"
34
+//
35
+#ifdef LLVM29
36
+#include "llvm/Analysis/ValueTracking.h"
37
+#include "PointerTracking.h"
38
+#else
34 39
 #include "llvm/Analysis/PointerTracking.h"
40
+#endif
35 41
 #include "llvm/Analysis/ScalarEvolution.h"
36 42
 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
37 43
 #include "llvm/Analysis/ScalarEvolutionExpander.h"
... ...
@@ -54,13 +60,22 @@
54 54
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
55 55
 #include "llvm/Support/Debug.h"
56 56
 
57
+#ifndef LLVM28
57 58
 #define LLVM28
59
+#endif
58 60
 #ifdef LLVM28
59 61
 #define DEFINEPASS(passname) passname() : FunctionPass(ID)
60 62
 #else
61 63
 #define DEFINEPASS(passname) passname() : FunctionPass(&ID)
62 64
 #endif
65
+
63 66
 using namespace llvm;
67
+#ifndef LLVM29
68
+static Value *GetUnderlyingObject(Value *P, TargetData *TD)
69
+{
70
+    return P->getUnderlyingObject();
71
+}
72
+#endif
64 73
 namespace {
65 74
 
66 75
   class PtrVerifier : public FunctionPass {
... ...
@@ -275,7 +290,7 @@ namespace {
275 275
       if (BaseMap.count(P)) {
276 276
         return BaseMap[Ptr] = BaseMap[P];
277 277
       }
278
-      Value *P2 = P->getUnderlyingObject();
278
+      Value *P2 = GetUnderlyingObject(P, TD);
279 279
       if (P2 != P) {
280 280
         Value *V = getPointerBase(P2);
281 281
         return BaseMap[Ptr] = V;
... ...
@@ -334,7 +349,7 @@ namespace {
334 334
 	  }
335 335
       }
336 336
       if (LoadInst *LI = dyn_cast<LoadInst>(Base)) {
337
-	  Value *V = LI->getPointerOperand()->stripPointerCasts()->getUnderlyingObject();
337
+	  Value *V = GetUnderlyingObject(LI->getPointerOperand()->stripPointerCasts(), TD);
338 338
 	  if (Argument *A = dyn_cast<Argument>(V)) {
339 339
 	      if (A->getArgNo() == 0) {
340 340
 		  // pointers from hidden ctx are trusted to be at least the
... ...
@@ -33,10 +33,11 @@ if BUILD_EXTERNAL_LLVM
33 33
 # we know this will be built with GNU make, so its safe to use GNU make specific
34 34
 # $(shell ...)
35 35
 #LLVM_DEPS=$(shell $(LLVM_CONFIG) --libfiles jit nativecodegen)
36
-libclamavcxx_la_CXXFLAGS = $(AM_CPPFLAGS) @LLVMCONFIG_CXXFLAGS@ -fexceptions -DLLVM28
36
+libclamavcxx_la_CXXFLAGS = $(AM_CPPFLAGS) @LLVMCONFIG_CXXFLAGS@ -fexceptions -DLLVM28 -DLLVM29
37 37
 libclamavcxx_la_LDFLAGS = @LLVMCONFIG_LDFLAGS@ @LLVMCONFIG_LIBS@
38 38
 libclamavcxx_la_DEPENDENCIES = @LLVMCONFIG_LIBFILES@
39 39
 noinst_LTLIBRARIES = libclamavcxx.la
40
+libclamavcxx_la_SOURCES += PointerTracking.cpp
40 41
 
41 42
 else
42 43
 AM_CPPFLAGS += $(LLVM_INCLUDES) $(LLVM_DEFS)
... ...
@@ -51,14 +51,15 @@ POST_UNINSTALL = :
51 51
 build_triplet = @build@
52 52
 host_triplet = @host@
53 53
 target_triplet = @target@
54
-@BUILD_EXTERNAL_LLVM_FALSE@am__append_1 = $(LLVM_INCLUDES) $(LLVM_DEFS)
55
-@BUILD_EXTERNAL_LLVM_FALSE@@BUILD_X86_TRUE@am__append_2 = libllvmx86codegen.la
54
+@BUILD_EXTERNAL_LLVM_TRUE@am__append_1 = PointerTracking.cpp
55
+@BUILD_EXTERNAL_LLVM_FALSE@am__append_2 = $(LLVM_INCLUDES) $(LLVM_DEFS)
56 56
 @BUILD_EXTERNAL_LLVM_FALSE@@BUILD_X86_TRUE@am__append_3 = libllvmx86codegen.la
57 57
 @BUILD_EXTERNAL_LLVM_FALSE@@BUILD_X86_TRUE@am__append_4 = libllvmx86codegen.la
58
-@BUILD_EXTERNAL_LLVM_FALSE@@BUILD_PPC_TRUE@am__append_5 = libllvmpowerpccodegen.la
58
+@BUILD_EXTERNAL_LLVM_FALSE@@BUILD_X86_TRUE@am__append_5 = libllvmx86codegen.la
59 59
 @BUILD_EXTERNAL_LLVM_FALSE@@BUILD_PPC_TRUE@am__append_6 = libllvmpowerpccodegen.la
60 60
 @BUILD_EXTERNAL_LLVM_FALSE@@BUILD_PPC_TRUE@am__append_7 = libllvmpowerpccodegen.la
61
-@BUILD_EXTERNAL_LLVM_FALSE@@MAINTAINER_MODE_TRUE@am__append_8 = $(TBLGENFILES)
61
+@BUILD_EXTERNAL_LLVM_FALSE@@BUILD_PPC_TRUE@am__append_8 = libllvmpowerpccodegen.la
62
+@BUILD_EXTERNAL_LLVM_FALSE@@MAINTAINER_MODE_TRUE@am__append_9 = $(TBLGENFILES)
62 63
 @BUILD_EXTERNAL_LLVM_FALSE@@MAINTAINER_MODE_TRUE@noinst_PROGRAMS = tblgen$(EXEEXT)
63 64
 subdir = .
64 65
 DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \
... ...
@@ -81,8 +82,14 @@ CONFIG_HEADER = clamavcxx-config.h
81 81
 CONFIG_CLEAN_FILES =
82 82
 CONFIG_CLEAN_VPATH_FILES =
83 83
 LTLIBRARIES = $(noinst_LTLIBRARIES)
84
+am__libclamavcxx_la_SOURCES_DIST = bytecode2llvm.cpp \
85
+	ClamBCRTChecks.cpp ClamBCModule.h ClamBCDiagnostics.h \
86
+	detect.cpp PointerTracking.cpp
87
+@BUILD_EXTERNAL_LLVM_TRUE@am__objects_1 =  \
88
+@BUILD_EXTERNAL_LLVM_TRUE@	libclamavcxx_la-PointerTracking.lo
84 89
 am_libclamavcxx_la_OBJECTS = libclamavcxx_la-bytecode2llvm.lo \
85
-	libclamavcxx_la-ClamBCRTChecks.lo libclamavcxx_la-detect.lo
90
+	libclamavcxx_la-ClamBCRTChecks.lo libclamavcxx_la-detect.lo \
91
+	$(am__objects_1)
86 92
 libclamavcxx_la_OBJECTS = $(am_libclamavcxx_la_OBJECTS)
87 93
 AM_V_lt = $(am__v_lt_$(V))
88 94
 am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
... ...
@@ -798,7 +805,7 @@ SOURCES = $(libclamavcxx_la_SOURCES) $(libllvmcodegen_la_SOURCES) \
798 798
 	$(libllvmjit_la_SOURCES) $(libllvmpowerpccodegen_la_SOURCES) \
799 799
 	$(libllvmsystem_la_SOURCES) $(libllvmx86codegen_la_SOURCES) \
800 800
 	$(tblgen_SOURCES)
801
-DIST_SOURCES = $(libclamavcxx_la_SOURCES) \
801
+DIST_SOURCES = $(am__libclamavcxx_la_SOURCES_DIST) \
802 802
 	$(am__libllvmcodegen_la_SOURCES_DIST) \
803 803
 	$(am__libllvmjit_la_SOURCES_DIST) \
804 804
 	$(am__libllvmpowerpccodegen_la_SOURCES_DIST) \
... ...
@@ -958,38 +965,34 @@ LLVM_INCLUDES = -I$(top_srcdir)/llvm/include -I$(top_builddir)/llvm/include
958 958
 # TODO: HP-UX should have -D_REENTRANT -D_HPUX_SOURCE
959 959
 LLVM_DEFS = -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_DEBUG -D_GNU_SOURCE
960 960
 AM_CPPFLAGS = -I$(top_srcdir)/../.. -I$(top_srcdir)/.. \
961
-	-I$(top_builddir)/../../ $(am__append_1)
961
+	-I$(top_builddir)/../../ $(am__append_2)
962 962
 AM_CXXFLAGS = $(LLVM_CXXFLAGS) -fno-exceptions
963 963
 ACLOCAL_AMFLAGS = -I m4
964
-libclamavcxx_la_SOURCES = bytecode2llvm.cpp\
965
-			  ClamBCRTChecks.cpp\
966
-			  ClamBCModule.h\
967
-			  ClamBCDiagnostics.h\
968
-			  detect.cpp
969
-
964
+libclamavcxx_la_SOURCES = bytecode2llvm.cpp ClamBCRTChecks.cpp \
965
+	ClamBCModule.h ClamBCDiagnostics.h detect.cpp $(am__append_1)
970 966
 @BUILD_EXTERNAL_LLVM_FALSE@libclamavcxx_la_CXXFLAGS = $(LLVM_CXXFLAGS)
971 967
 #$(LLVM_CONFIG): build-llvm
972 968
 # we know this will be built with GNU make, so its safe to use GNU make specific
973 969
 # $(shell ...)
974 970
 #LLVM_DEPS=$(shell $(LLVM_CONFIG) --libfiles jit nativecodegen)
975
-@BUILD_EXTERNAL_LLVM_TRUE@libclamavcxx_la_CXXFLAGS = $(AM_CPPFLAGS) @LLVMCONFIG_CXXFLAGS@ -fexceptions -DLLVM28
971
+@BUILD_EXTERNAL_LLVM_TRUE@libclamavcxx_la_CXXFLAGS = $(AM_CPPFLAGS) @LLVMCONFIG_CXXFLAGS@ -fexceptions -DLLVM28 -DLLVM29
976 972
 @BUILD_EXTERNAL_LLVM_FALSE@libclamavcxx_la_LDFLAGS = -no-undefined
977 973
 @BUILD_EXTERNAL_LLVM_TRUE@libclamavcxx_la_LDFLAGS = @LLVMCONFIG_LDFLAGS@ @LLVMCONFIG_LIBS@
978 974
 @BUILD_EXTERNAL_LLVM_FALSE@libclamavcxx_la_DEPENDENCIES =  \
979 975
 @BUILD_EXTERNAL_LLVM_FALSE@	libllvmjit.la libllvmcodegen.la \
980
-@BUILD_EXTERNAL_LLVM_FALSE@	libllvmsystem.la $(am__append_3) \
981
-@BUILD_EXTERNAL_LLVM_FALSE@	$(am__append_6)
976
+@BUILD_EXTERNAL_LLVM_FALSE@	libllvmsystem.la $(am__append_4) \
977
+@BUILD_EXTERNAL_LLVM_FALSE@	$(am__append_7)
982 978
 @BUILD_EXTERNAL_LLVM_TRUE@libclamavcxx_la_DEPENDENCIES =  \
983 979
 @BUILD_EXTERNAL_LLVM_TRUE@	@LLVMCONFIG_LIBFILES@ \
984
-@BUILD_EXTERNAL_LLVM_TRUE@	$(am__append_3) $(am__append_6)
980
+@BUILD_EXTERNAL_LLVM_TRUE@	$(am__append_4) $(am__append_7)
985 981
 @BUILD_EXTERNAL_LLVM_FALSE@noinst_LTLIBRARIES = libclamavcxx.la \
986 982
 @BUILD_EXTERNAL_LLVM_FALSE@	libllvmsystem.la libllvmcodegen.la \
987
-@BUILD_EXTERNAL_LLVM_FALSE@	libllvmjit.la $(am__append_4) \
988
-@BUILD_EXTERNAL_LLVM_FALSE@	$(am__append_7)
983
+@BUILD_EXTERNAL_LLVM_FALSE@	libllvmjit.la $(am__append_5) \
984
+@BUILD_EXTERNAL_LLVM_FALSE@	$(am__append_8)
989 985
 @BUILD_EXTERNAL_LLVM_TRUE@noinst_LTLIBRARIES = libclamavcxx.la \
990
-@BUILD_EXTERNAL_LLVM_TRUE@	$(am__append_4) $(am__append_7)
986
+@BUILD_EXTERNAL_LLVM_TRUE@	$(am__append_5) $(am__append_8)
991 987
 @BUILD_EXTERNAL_LLVM_FALSE@libclamavcxx_la_LIBADD = libllvmjit.la \
992
-@BUILD_EXTERNAL_LLVM_FALSE@	$(am__append_2) $(am__append_5) \
988
+@BUILD_EXTERNAL_LLVM_FALSE@	$(am__append_3) $(am__append_6) \
993 989
 @BUILD_EXTERNAL_LLVM_FALSE@	libllvmcodegen.la libllvmsystem.la
994 990
 @BUILD_EXTERNAL_LLVM_FALSE@LLVM_CXXFLAGS = -Woverloaded-virtual -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings
995 991
 @BUILD_EXTERNAL_LLVM_FALSE@unittest_CXXFLAGS = @NO_VARIADIC_MACROS@ @NO_MISSING_FIELD_INITIALIZERS@ -DGTEST_HAS_TR1_TUPLE=0
... ...
@@ -1001,7 +1004,7 @@ libclamavcxx_la_SOURCES = bytecode2llvm.cpp\
1001 1001
 
1002 1002
 # Rule to rerun LLVM's configure if it changed, before building anything else
1003 1003
 # LLVM
1004
-@BUILD_EXTERNAL_LLVM_FALSE@BUILT_SOURCES = $(am__append_8) \
1004
+@BUILD_EXTERNAL_LLVM_FALSE@BUILT_SOURCES = $(am__append_9) \
1005 1005
 @BUILD_EXTERNAL_LLVM_FALSE@	llvm/config.status
1006 1006
 @BUILD_EXTERNAL_LLVM_FALSE@EXTRA_DIST = $(top_srcdir)/llvm llvmcheck.sh $(TBLGENFILES)
1007 1007
 @BUILD_EXTERNAL_LLVM_FALSE@libllvmsystem_la_LDFLAGS = @THREAD_LIBS@
... ...
@@ -1776,6 +1779,7 @@ distclean-compile:
1776 1776
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VirtRegRewriter.Plo@am__quote@
1777 1777
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/circular_raw_ostream.Plo@am__quote@
1778 1778
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamavcxx_la-ClamBCRTChecks.Plo@am__quote@
1779
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamavcxx_la-PointerTracking.Plo@am__quote@
1779 1780
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamavcxx_la-bytecode2llvm.Plo@am__quote@
1780 1781
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamavcxx_la-detect.Plo@am__quote@
1781 1782
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libllvmpowerpccodegen_la-PPCBranchSelector.Plo@am__quote@
... ...
@@ -2070,6 +2074,14 @@ libclamavcxx_la-detect.lo: detect.cpp
2070 2070
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2071 2071
 @am__fastdepCXX_FALSE@	$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamavcxx_la_CXXFLAGS) $(CXXFLAGS) -c -o libclamavcxx_la-detect.lo `test -f 'detect.cpp' || echo '$(srcdir)/'`detect.cpp
2072 2072
 
2073
+libclamavcxx_la-PointerTracking.lo: PointerTracking.cpp
2074
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamavcxx_la_CXXFLAGS) $(CXXFLAGS) -MT libclamavcxx_la-PointerTracking.lo -MD -MP -MF $(DEPDIR)/libclamavcxx_la-PointerTracking.Tpo -c -o libclamavcxx_la-PointerTracking.lo `test -f 'PointerTracking.cpp' || echo '$(srcdir)/'`PointerTracking.cpp
2075
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libclamavcxx_la-PointerTracking.Tpo $(DEPDIR)/libclamavcxx_la-PointerTracking.Plo
2076
+@am__fastdepCXX_FALSE@	$(AM_V_CXX) @AM_BACKSLASH@
2077
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='PointerTracking.cpp' object='libclamavcxx_la-PointerTracking.lo' libtool=yes @AMDEPBACKSLASH@
2078
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2079
+@am__fastdepCXX_FALSE@	$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamavcxx_la_CXXFLAGS) $(CXXFLAGS) -c -o libclamavcxx_la-PointerTracking.lo `test -f 'PointerTracking.cpp' || echo '$(srcdir)/'`PointerTracking.cpp
2080
+
2073 2081
 ConstantFolding.lo: llvm/lib/Analysis/ConstantFolding.cpp
2074 2082
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ConstantFolding.lo -MD -MP -MF $(DEPDIR)/ConstantFolding.Tpo -c -o ConstantFolding.lo `test -f 'llvm/lib/Analysis/ConstantFolding.cpp' || echo '$(srcdir)/'`llvm/lib/Analysis/ConstantFolding.cpp
2075 2083
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/ConstantFolding.Tpo $(DEPDIR)/ConstantFolding.Plo
2076 2084
new file mode 100644
... ...
@@ -0,0 +1,321 @@
0
+//===- PointerTracking.cpp - Pointer Bounds Tracking ------------*- C++ -*-===//
1
+//
2
+//                     The LLVM Compiler Infrastructure
3
+//
4
+// This file is distributed under the University of Illinois Open Source
5
+// License. See LICENSE.TXT for details.
6
+//
7
+//===----------------------------------------------------------------------===//
8
+//
9
+// This file implements tracking of pointer bounds.
10
+//
11
+//===----------------------------------------------------------------------===//
12
+
13
+#include "llvm/Analysis/ConstantFolding.h"
14
+#include "llvm/Analysis/Dominators.h"
15
+#include "llvm/Analysis/LoopInfo.h"
16
+#include "llvm/Analysis/MemoryBuiltins.h"
17
+#include "llvm/Analysis/ValueTracking.h"
18
+#include "PointerTracking.h"
19
+#include "llvm/Analysis/ScalarEvolution.h"
20
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
21
+#include "llvm/Constants.h"
22
+#include "llvm/Module.h"
23
+#include "llvm/Value.h"
24
+#include "llvm/Support/CallSite.h"
25
+#include "llvm/Support/InstIterator.h"
26
+#include "llvm/Support/raw_ostream.h"
27
+#include "llvm/Target/TargetData.h"
28
+using namespace llvm;
29
+namespace llvm {
30
+    void initializePointerTrackingPass(llvm::PassRegistry&);
31
+};
32
+INITIALIZE_PASS(PointerTracking, "pointertracking",
33
+                "Track pointer bounds", false, true);
34
+char PointerTracking::ID = 0;
35
+PointerTracking::PointerTracking() : FunctionPass(ID) {
36
+    initializePointerTrackingPass(*PassRegistry::getPassRegistry());
37
+}
38
+
39
+bool PointerTracking::runOnFunction(Function &F) {
40
+  predCache.clear();
41
+  assert(analyzing.empty());
42
+  FF = &F;
43
+  TD = getAnalysisIfAvailable<TargetData>();
44
+  SE = &getAnalysis<ScalarEvolution>();
45
+  LI = &getAnalysis<LoopInfo>();
46
+  DT = &getAnalysis<DominatorTree>();
47
+  return false;
48
+}
49
+
50
+void PointerTracking::getAnalysisUsage(AnalysisUsage &AU) const {
51
+  AU.addRequiredTransitive<DominatorTree>();
52
+  AU.addRequiredTransitive<LoopInfo>();
53
+  AU.addRequiredTransitive<ScalarEvolution>();
54
+  AU.setPreservesAll();
55
+}
56
+
57
+bool PointerTracking::doInitialization(Module &M) {
58
+  const Type *PTy = Type::getInt8PtrTy(M.getContext());
59
+
60
+  // Find calloc(i64, i64) or calloc(i32, i32).
61
+  callocFunc = M.getFunction("calloc");
62
+  if (callocFunc) {
63
+    const FunctionType *Ty = callocFunc->getFunctionType();
64
+
65
+    std::vector<const Type*> args, args2;
66
+    args.push_back(Type::getInt64Ty(M.getContext()));
67
+    args.push_back(Type::getInt64Ty(M.getContext()));
68
+    args2.push_back(Type::getInt32Ty(M.getContext()));
69
+    args2.push_back(Type::getInt32Ty(M.getContext()));
70
+    const FunctionType *Calloc1Type =
71
+      FunctionType::get(PTy, args, false);
72
+    const FunctionType *Calloc2Type =
73
+      FunctionType::get(PTy, args2, false);
74
+    if (Ty != Calloc1Type && Ty != Calloc2Type)
75
+      callocFunc = 0; // Give up
76
+  }
77
+
78
+  // Find realloc(i8*, i64) or realloc(i8*, i32).
79
+  reallocFunc = M.getFunction("realloc");
80
+  if (reallocFunc) {
81
+    const FunctionType *Ty = reallocFunc->getFunctionType();
82
+    std::vector<const Type*> args, args2;
83
+    args.push_back(PTy);
84
+    args.push_back(Type::getInt64Ty(M.getContext()));
85
+    args2.push_back(PTy);
86
+    args2.push_back(Type::getInt32Ty(M.getContext()));
87
+
88
+    const FunctionType *Realloc1Type =
89
+      FunctionType::get(PTy, args, false);
90
+    const FunctionType *Realloc2Type =
91
+      FunctionType::get(PTy, args2, false);
92
+    if (Ty != Realloc1Type && Ty != Realloc2Type)
93
+      reallocFunc = 0; // Give up
94
+  }
95
+  return false;
96
+}
97
+
98
+// Calculates the number of elements allocated for pointer P,
99
+// the type of the element is stored in Ty.
100
+const SCEV *PointerTracking::computeAllocationCount(Value *P,
101
+                                                    const Type *&Ty) const {
102
+  Value *V = P->stripPointerCasts();
103
+  if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
104
+    Value *arraySize = AI->getArraySize();
105
+    Ty = AI->getAllocatedType();
106
+    // arraySize elements of type Ty.
107
+    return SE->getSCEV(arraySize);
108
+  }
109
+
110
+  if (CallInst *CI = extractMallocCall(V)) {
111
+    Value *arraySize = getMallocArraySize(CI, TD);
112
+    const Type* AllocTy = getMallocAllocatedType(CI);
113
+    if (!AllocTy || !arraySize) return SE->getCouldNotCompute();
114
+    Ty = AllocTy;
115
+    // arraySize elements of type Ty.
116
+    return SE->getSCEV(arraySize);
117
+  }
118
+
119
+  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
120
+    if (GV->hasDefinitiveInitializer()) {
121
+      Constant *C = GV->getInitializer();
122
+      if (const ArrayType *ATy = dyn_cast<ArrayType>(C->getType())) {
123
+        Ty = ATy->getElementType();
124
+        return SE->getConstant(Type::getInt32Ty(P->getContext()),
125
+                               ATy->getNumElements());
126
+      }
127
+    }
128
+    Ty = GV->getType();
129
+    return SE->getConstant(Type::getInt32Ty(P->getContext()), 1);
130
+    //TODO: implement more tracking for globals
131
+  }
132
+
133
+  if (CallInst *CI = dyn_cast<CallInst>(V)) {
134
+    CallSite CS(CI);
135
+    Function *F = dyn_cast<Function>(CS.getCalledValue()->stripPointerCasts());
136
+    const Loop *L = LI->getLoopFor(CI->getParent());
137
+    if (F == callocFunc) {
138
+      Ty = Type::getInt8Ty(P->getContext());
139
+      // calloc allocates arg0*arg1 bytes.
140
+      return SE->getSCEVAtScope(SE->getMulExpr(SE->getSCEV(CS.getArgument(0)),
141
+                                               SE->getSCEV(CS.getArgument(1))),
142
+                                L);
143
+    } else if (F == reallocFunc) {
144
+      Ty = Type::getInt8Ty(P->getContext());
145
+      // realloc allocates arg1 bytes.
146
+      return SE->getSCEVAtScope(CS.getArgument(1), L);
147
+    }
148
+  }
149
+
150
+  return SE->getCouldNotCompute();
151
+}
152
+
153
+Value *PointerTracking::computeAllocationCountValue(Value *P, const Type *&Ty) const 
154
+{
155
+  Value *V = P->stripPointerCasts();
156
+  if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
157
+    Ty = AI->getAllocatedType();
158
+    // arraySize elements of type Ty.
159
+    return AI->getArraySize();
160
+  }
161
+
162
+  if (CallInst *CI = extractMallocCall(V)) {
163
+    Ty = getMallocAllocatedType(CI);
164
+    if (!Ty)
165
+      return 0;
166
+    Value *arraySize = getMallocArraySize(CI, TD);
167
+    if (!arraySize) {
168
+      Ty = Type::getInt8Ty(P->getContext());
169
+      return CI->getArgOperand(0);
170
+    }
171
+    // arraySize elements of type Ty.
172
+    return arraySize;
173
+  }
174
+
175
+  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
176
+    if (GV->hasDefinitiveInitializer()) {
177
+      Constant *C = GV->getInitializer();
178
+      if (const ArrayType *ATy = dyn_cast<ArrayType>(C->getType())) {
179
+        Ty = ATy->getElementType();
180
+        return ConstantInt::get(Type::getInt32Ty(P->getContext()),
181
+                               ATy->getNumElements());
182
+      }
183
+    }
184
+    Ty = cast<PointerType>(GV->getType())->getElementType();
185
+    return ConstantInt::get(Type::getInt32Ty(P->getContext()), 1);
186
+    //TODO: implement more tracking for globals
187
+  }
188
+
189
+  if (CallInst *CI = dyn_cast<CallInst>(V)) {
190
+    CallSite CS(CI);
191
+    Function *F = dyn_cast<Function>(CS.getCalledValue()->stripPointerCasts());
192
+    if (F == reallocFunc) {
193
+      Ty = Type::getInt8Ty(P->getContext());
194
+      // realloc allocates arg1 bytes.
195
+      return CS.getArgument(1);
196
+    }
197
+  }
198
+
199
+  return 0;
200
+}
201
+
202
+// Calculates the number of elements of type Ty allocated for P.
203
+const SCEV *PointerTracking::computeAllocationCountForType(Value *P,
204
+                                                           const Type *Ty)
205
+  const {
206
+    const Type *elementTy;
207
+    const SCEV *Count = computeAllocationCount(P, elementTy);
208
+    if (isa<SCEVCouldNotCompute>(Count))
209
+      return Count;
210
+    if (elementTy == Ty)
211
+      return Count;
212
+
213
+    if (!TD) // need TargetData from this point forward
214
+      return SE->getCouldNotCompute();
215
+
216
+    uint64_t elementSize = TD->getTypeAllocSize(elementTy);
217
+    uint64_t wantSize = TD->getTypeAllocSize(Ty);
218
+    if (elementSize == wantSize)
219
+      return Count;
220
+    if (elementSize % wantSize) //fractional counts not possible
221
+      return SE->getCouldNotCompute();
222
+    return SE->getMulExpr(Count, SE->getConstant(Count->getType(),
223
+                                                 elementSize/wantSize));
224
+}
225
+
226
+const SCEV *PointerTracking::getAllocationElementCount(Value *V) const {
227
+  // We only deal with pointers.
228
+  const PointerType *PTy = cast<PointerType>(V->getType());
229
+  return computeAllocationCountForType(V, PTy->getElementType());
230
+}
231
+
232
+const SCEV *PointerTracking::getAllocationSizeInBytes(Value *V) const {
233
+  return computeAllocationCountForType(V, Type::getInt8Ty(V->getContext()));
234
+}
235
+
236
+// Helper for isLoopGuardedBy that checks the swapped and inverted predicate too
237
+enum SolverResult PointerTracking::isLoopGuardedBy(const Loop *L,
238
+                                                   Predicate Pred,
239
+                                                   const SCEV *A,
240
+                                                   const SCEV *B) const {
241
+  if (SE->isLoopEntryGuardedByCond(L, Pred, A, B))
242
+    return AlwaysTrue;
243
+  Pred = ICmpInst::getSwappedPredicate(Pred);
244
+  if (SE->isLoopEntryGuardedByCond(L, Pred, B, A))
245
+    return AlwaysTrue;
246
+
247
+  Pred = ICmpInst::getInversePredicate(Pred);
248
+  if (SE->isLoopEntryGuardedByCond(L, Pred, B, A))
249
+    return AlwaysFalse;
250
+  Pred = ICmpInst::getSwappedPredicate(Pred);
251
+  if (SE->isLoopEntryGuardedByCond(L, Pred, A, B))
252
+    return AlwaysTrue;
253
+  return Unknown;
254
+}
255
+
256
+enum SolverResult PointerTracking::checkLimits(const SCEV *Offset,
257
+                                               const SCEV *Limit,
258
+                                               BasicBlock *BB)
259
+{
260
+  //FIXME: merge implementation
261
+  return Unknown;
262
+}
263
+
264
+void PointerTracking::getPointerOffset(Value *Pointer, Value *&Base,
265
+                                       const SCEV *&Limit,
266
+                                       const SCEV *&Offset) const
267
+{
268
+    Pointer = Pointer->stripPointerCasts();
269
+    Base = GetUnderlyingObject(Pointer, TD);
270
+    Limit = getAllocationSizeInBytes(Base);
271
+    if (isa<SCEVCouldNotCompute>(Limit)) {
272
+      Base = 0;
273
+      Offset = Limit;
274
+      return;
275
+    }
276
+
277
+    Offset = SE->getMinusSCEV(SE->getSCEV(Pointer), SE->getSCEV(Base));
278
+    if (isa<SCEVCouldNotCompute>(Offset)) {
279
+      Base = 0;
280
+      Limit = Offset;
281
+    }
282
+}
283
+
284
+void PointerTracking::print(raw_ostream &OS, const Module* M) const {
285
+  // Calling some PT methods may cause caches to be updated, however
286
+  // this should be safe for the same reason its safe for SCEV.
287
+  PointerTracking &PT = *const_cast<PointerTracking*>(this);
288
+  for (inst_iterator I=inst_begin(*FF), E=inst_end(*FF); I != E; ++I) {
289
+    if (!I->getType()->isPointerTy())
290
+      continue;
291
+    Value *Base;
292
+    const SCEV *Limit, *Offset;
293
+    getPointerOffset(&*I, Base, Limit, Offset);
294
+    if (!Base)
295
+      continue;
296
+
297
+    if (Base == &*I) {
298
+      const SCEV *S = getAllocationElementCount(Base);
299
+      OS << *Base << " ==> " << *S << " elements, ";
300
+      OS << *Limit << " bytes allocated\n";
301
+      continue;
302
+    }
303
+    OS << &*I << " -- base: " << *Base;
304
+    OS << " offset: " << *Offset;
305
+
306
+    enum SolverResult res = PT.checkLimits(Offset, Limit, I->getParent());
307
+    switch (res) {
308
+    case AlwaysTrue:
309
+      OS << " always safe\n";
310
+      break;
311
+    case AlwaysFalse:
312
+      OS << " always unsafe\n";
313
+      break;
314
+    case Unknown:
315
+      OS << " <<unknown>>\n";
316
+      break;
317
+    }
318
+  }
319
+}
320
+
0 321
new file mode 100644
... ...
@@ -0,0 +1,132 @@
0
+//===- PointerTracking.h - Pointer Bounds Tracking --------------*- C++ -*-===//
1
+//
2
+//                     The LLVM Compiler Infrastructure
3
+//
4
+// This file is distributed under the University of Illinois Open Source
5
+// License. See LICENSE.TXT for details.
6
+//
7
+//===----------------------------------------------------------------------===//
8
+//
9
+// This file implements tracking of pointer bounds.
10
+// It knows that the libc functions "calloc" and "realloc" allocate memory, thus
11
+// you should avoid using this pass if they mean something else for your
12
+// language.
13
+//
14
+// All methods assume that the pointer is not NULL, if it is then the returned
15
+// allocation size is wrong, and the result from checkLimits is wrong too.
16
+// It also assumes that pointers are valid, and that it is not analyzing a
17
+// use-after-free scenario.
18
+// Due to these limitations the "size" returned by these methods should be
19
+// considered as either 0 or the returned size.
20
+//
21
+// Another analysis pass should be used to find use-after-free/NULL dereference
22
+// bugs.
23
+//
24
+//===----------------------------------------------------------------------===//
25
+
26
+#ifndef LLVM_ANALYSIS_POINTERTRACKING_H
27
+#define LLVM_ANALYSIS_POINTERTRACKING_H
28
+
29
+#include "llvm/ADT/SmallPtrSet.h"
30
+#include "llvm/Analysis/Dominators.h"
31
+#include "llvm/Instructions.h"
32
+#include "llvm/Pass.h"
33
+#include "llvm/Support/PredIteratorCache.h"
34
+
35
+namespace llvm {
36
+  class DominatorTree;
37
+  class ScalarEvolution;
38
+  class SCEV;
39
+  class Loop;
40
+  class LoopInfo;
41
+  class TargetData;
42
+
43
+  // Result from solver, assuming pointer is not NULL,
44
+  // and it is not a use-after-free situation.
45
+  enum SolverResult {
46
+    AlwaysFalse,// always false with above constraints
47
+    AlwaysTrue,// always true with above constraints
48
+    Unknown // it can sometimes be true, sometimes false, or it is undecided
49
+  };
50
+
51
+  class PointerTracking : public FunctionPass {
52
+  public:
53
+    typedef ICmpInst::Predicate Predicate;
54
+    static char ID;
55
+    PointerTracking();
56
+
57
+    virtual bool doInitialization(Module &M);
58
+
59
+    // If this pointer directly points to an allocation, return
60
+    // the number of elements of type Ty allocated.
61
+    // Otherwise return CouldNotCompute.
62
+    // Since allocations can fail by returning NULL, the real element count
63
+    // for every allocation is either 0 or the value returned by this function.
64
+    const SCEV *getAllocationElementCount(Value *P) const;
65
+
66
+    // Same as getAllocationSize() but returns size in bytes.
67
+    // We consider one byte as 8 bits.
68
+    const SCEV *getAllocationSizeInBytes(Value *V) const;
69
+
70
+    // Given a Pointer, determine a base pointer of known size, and an offset
71
+    // therefrom.
72
+    // When unable to determine, sets Base to NULL, and Limit/Offset to
73
+    // CouldNotCompute.
74
+    // BaseSize, and Offset are in bytes: Pointer == Base + Offset
75
+    void getPointerOffset(Value *Pointer, Value *&Base, const SCEV *& BaseSize,
76
+                          const SCEV *&Offset) const;
77
+
78
+    // Compares the 2 scalar evolution expressions according to predicate,
79
+    // and if it can prove that the result is always true or always false
80
+    // return AlwaysTrue/AlwaysFalse. Otherwise it returns Unknown.
81
+    enum SolverResult compareSCEV(const SCEV *A, Predicate Pred, const SCEV *B,
82
+                                  const Loop *L);
83
+
84
+    // Determines whether the condition LHS <Pred> RHS is sufficient
85
+    // for the condition A <Pred> B to hold.
86
+    // Currently only ULT/ULE is supported.
87
+    // This errs on the side of returning false.
88
+    bool conditionSufficient(const SCEV *LHS, Predicate Pred1, const SCEV *RHS,
89
+                             const SCEV *A, Predicate Pred2, const SCEV *B,
90
+                             const Loop *L);
91
+
92
+    // Determines whether Offset is known to be always in [0, Limit) bounds.
93
+    // This errs on the side of returning Unknown.
94
+    enum SolverResult checkLimits(const SCEV *Offset, const SCEV *Limit,
95
+                                  BasicBlock *BB);
96
+
97
+    virtual bool runOnFunction(Function &F);
98
+    virtual void getAnalysisUsage(AnalysisUsage &AU) const;
99
+    void print(raw_ostream &OS, const Module* = 0) const;
100
+    Value *computeAllocationCountValue(Value *P, const Type *&Ty) const;
101
+  private:
102
+    Function *FF;
103
+    TargetData *TD;
104
+    ScalarEvolution *SE;
105
+    LoopInfo *LI;
106
+    DominatorTree *DT;
107
+
108
+    Function *callocFunc;
109
+    Function *reallocFunc;
110
+    PredIteratorCache predCache;
111
+
112
+    SmallPtrSet<const SCEV*, 1> analyzing;
113
+
114
+    enum SolverResult isLoopGuardedBy(const Loop *L, Predicate Pred,
115
+                                      const SCEV *A, const SCEV *B) const;
116
+    static bool isMonotonic(const SCEV *S);
117
+    bool scevPositive(const SCEV *A, const Loop *L, bool strict=true) const;
118
+    bool conditionSufficient(Value *Cond, bool negated,
119
+                             const SCEV *A, Predicate Pred, const SCEV *B);
120
+    Value *getConditionToReach(BasicBlock *A,
121
+                               DomTreeNodeBase<BasicBlock> *B,
122
+                               bool &negated);
123
+    Value *getConditionToReach(BasicBlock *A,
124
+                               BasicBlock *B,
125
+                               bool &negated);
126
+    const SCEV *computeAllocationCount(Value *P, const Type *&Ty) const;
127
+    const SCEV *computeAllocationCountForType(Value *P, const Type *Ty) const;
128
+  };
129
+}
130
+#endif
131
+
... ...
@@ -59,13 +59,29 @@
59 59
 #include "llvm/Support/SourceMgr.h"
60 60
 #include "llvm/Support/IRBuilder.h"
61 61
 #include "llvm/Support/PrettyStackTrace.h"
62
+
63
+#ifdef LLVM29
64
+#include "llvm/Support/DataTypes.h"
65
+#include "llvm/Support/FileSystem.h"
66
+#include "llvm/Support/Host.h"
67
+#include "llvm/Support/Memory.h"
68
+#include "llvm/Support/Mutex.h"
69
+#include "llvm/Support/Signals.h"
70
+#include "llvm/Support/Threading.h"
71
+#include "llvm/Support/ThreadLocal.h"
72
+#include "llvm/IntrinsicInst.h"
73
+#include "llvm/PassRegistry.h"
74
+#else
62 75
 #include "llvm/System/DataTypes.h"
63 76
 #include "llvm/System/Host.h"
64 77
 #include "llvm/System/Memory.h"
65 78
 #include "llvm/System/Mutex.h"
66 79
 #include "llvm/System/Signals.h"
67
-#include "llvm/Support/Timer.h"
68 80
 #include "llvm/System/Threading.h"
81
+#include "llvm/System/ThreadLocal.h"
82
+#endif
83
+
84
+#include "llvm/Support/Timer.h"
69 85
 
70 86
 extern "C" {
71 87
 void LLVMInitializeX86AsmPrinter();
... ...
@@ -78,7 +94,6 @@ void LLVMInitializePowerPCAsmPrinter();
78 78
 #include "llvm/Transforms/Scalar.h"
79 79
 #include "llvm/Transforms/IPO.h"
80 80
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
81
-#include "llvm/System/ThreadLocal.h"
82 81
 #include <cstdlib>
83 82
 #include <csetjmp>
84 83
 #include <new>
... ...
@@ -133,6 +148,11 @@ struct cli_bcengine {
133 133
 };
134 134
 
135 135
 extern "C" uint8_t cli_debug_flag;
136
+#ifdef LLVM29
137
+namespace llvm {
138
+    void initializeRuntimeLimitsPass(PassRegistry&);
139
+};
140
+#endif
136 141
 namespace {
137 142
 
138 143
 #ifndef LLVM28
... ...
@@ -149,6 +169,10 @@ namespace {
149 149
 #define DEFINEPASS(passname) passname() : FunctionPass(&ID)
150 150
 #endif
151 151
 
152
+#ifdef LLVM29
153
+#define NORETURN LLVM_ATTRIBUTE_NORETURN
154
+#endif
155
+
152 156
 static sys::ThreadLocal<const jmp_buf> ExceptionReturn;
153 157
 
154 158
 static void UpgradeCall(CallInst *&C, Function *Intr)
... ...
@@ -526,7 +550,12 @@ class RuntimeLimits : public FunctionPass {
526 526
 
527 527
 public:
528 528
     static char ID;
529
-    DEFINEPASS(RuntimeLimits) {}
529
+    DEFINEPASS(RuntimeLimits) {
530
+#ifdef LLVM29
531
+	PassRegistry &Registry = *PassRegistry::getPassRegistry();
532
+	initializeRuntimeLimitsPass(Registry);
533
+#endif
534
+    }
530 535
 
531 536
     virtual bool runOnFunction(Function &F) {
532 537
 	BBSetTy BackedgeTargets;
... ...
@@ -1043,12 +1072,18 @@ public:
1043 1043
 	    // Have an alloca -> some instruction uses its address otherwise
1044 1044
 	    // mem2reg would have converted it to an SSA register.
1045 1045
 	    // Enable stack protector for this function.
1046
+#ifndef LLVM29
1047
+	    // LLVM 2.9 has broken SSP, it does a 'mov 0x28, $rax', which tries
1048
+	    // to read from the address 0x28 and crashes
1046 1049
 	    F->addFnAttr(Attribute::StackProtectReq);
1050
+#endif
1047 1051
 	}
1048 1052
 	// always add stackprotect attribute (bb #2239), so we know this
1049 1053
 	// function was verified. If there is no alloca it won't actually add
1050 1054
 	// stack protector in emitted code so this won't slow down the app.
1055
+#ifndef LLVM29
1051 1056
 	F->addFnAttr(Attribute::StackProtect);
1057
+#endif
1052 1058
     }
1053 1059
 
1054 1060
     Value *GEPOperand(Value *V) {
... ...
@@ -1830,6 +1865,13 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
1830 1830
 }
1831 1831
 
1832 1832
 }
1833
+#ifdef LLVM29
1834
+INITIALIZE_PASS_BEGIN(RuntimeLimits, "rl", "Runtime Limits", false, false)
1835
+INITIALIZE_PASS_DEPENDENCY(LoopInfo)
1836
+INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
1837
+INITIALIZE_PASS_DEPENDENCY(DominatorTree)
1838
+INITIALIZE_PASS_END(RuntimeLimits, "rl" ,"Runtime Limits", false, false)
1839
+#endif
1833 1840
 
1834 1841
 static pthread_mutex_t watchdog_mutex = PTHREAD_MUTEX_INITIALIZER;
1835 1842
 static pthread_cond_t watchdog_cond = PTHREAD_COND_INITIALIZER;
... ...
@@ -2179,7 +2221,9 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
2179 2179
 	PM.add(createCFGSimplificationPass());
2180 2180
 	PM.add(createGlobalOptimizerPass());
2181 2181
 	PM.add(createConstantMergePass());
2182
-	PM.add(new RuntimeLimits());
2182
+
2183
+	RuntimeLimits *RL = new RuntimeLimits();
2184
+	PM.add(RL);
2183 2185
 	TimerWrapper pmTimer2("Transform passes");
2184 2186
 	pmTimer2.startTimer();
2185 2187
 	PM.run(*M);
... ...
@@ -2327,7 +2371,17 @@ void cli_bytecode_debug_printsrc(const struct cli_bc_ctx *ctx)
2327 2327
     if (I == LinePrinter.files.end()) {
2328 2328
 	lines = new linesTy;
2329 2329
 	std::string ErrorMessage;
2330
+#ifdef LLVM29
2331
+	OwningPtr<MemoryBuffer> File;
2332
+	error_code ec = MemoryBuffer::getFile(path, File);
2333
+	if (ec) {
2334
+	    ErrorMessage = ec.message();
2335
+	    lines->buffer = 0;
2336
+	} else
2337
+	    lines->buffer = File.take();
2338
+#else
2330 2339
 	lines->buffer = MemoryBuffer::getFile(path, &ErrorMessage);
2340
+#endif
2331 2341
 	if (!lines->buffer) {
2332 2342
 	    errs() << "Unable to open file '" << path << "'\n";
2333 2343
 	    return ;
... ...
@@ -2401,6 +2455,117 @@ void stop(const char *msg, llvm::Function* F, llvm::Instruction* I)
2401 2401
 }
2402 2402
 }
2403 2403
 
2404
+#ifdef LLVM29
2405
+static Value *findDbgGlobalDeclare(GlobalVariable *V) {
2406
+  const Module *M = V->getParent();
2407
+  NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv");
2408
+  if (!NMD)
2409
+    return 0;
2410
+
2411
+  for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
2412
+    DIDescriptor DIG(cast<MDNode>(NMD->getOperand(i)));
2413
+    if (!DIG.isGlobalVariable())
2414
+      continue;
2415
+    if (DIGlobalVariable(DIG).getGlobal() == V)
2416
+      return DIG;
2417
+  }
2418
+  return 0;
2419
+}
2420
+
2421
+/// Find the debug info descriptor corresponding to this function.
2422
+static Value *findDbgSubprogramDeclare(Function *V) {
2423
+  const Module *M = V->getParent();
2424
+  NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.sp");
2425
+  if (!NMD)
2426
+    return 0;
2427
+
2428
+  for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
2429
+    DIDescriptor DIG(cast<MDNode>(NMD->getOperand(i)));
2430
+    if (!DIG.isSubprogram())
2431
+      continue;
2432
+    if (DISubprogram(DIG).getFunction() == V)
2433
+      return DIG;
2434
+  }
2435
+  return 0;
2436
+}
2437
+
2438
+/// Finds the llvm.dbg.declare intrinsic corresponding to this value if any.
2439
+/// It looks through pointer casts too.
2440
+static const DbgDeclareInst *findDbgDeclare(const Value *V) {
2441
+  V = V->stripPointerCasts();
2442
+
2443
+  if (!isa<Instruction>(V) && !isa<Argument>(V))
2444
+    return 0;
2445
+
2446
+  const Function *F = NULL;
2447
+  if (const Instruction *I = dyn_cast<Instruction>(V))
2448
+    F = I->getParent()->getParent();
2449
+  else if (const Argument *A = dyn_cast<Argument>(V))
2450
+    F = A->getParent();
2451
+
2452
+  for (Function::const_iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
2453
+    for (BasicBlock::const_iterator BI = (*FI).begin(), BE = (*FI).end();
2454
+         BI != BE; ++BI)
2455
+      if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI))
2456
+        if (DDI->getAddress() == V)
2457
+          return DDI;
2458
+
2459
+  return 0;
2460
+}
2461
+static bool getLocationInfo(const Value *V, std::string &DisplayName,
2462
+                            std::string &Type, unsigned &LineNo,
2463
+                            std::string &File, std::string &Dir) {
2464
+  DICompileUnit Unit;
2465
+  DIType TypeD;
2466
+
2467
+  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(const_cast<Value*>(V))) {
2468
+    Value *DIGV = findDbgGlobalDeclare(GV);
2469
+    if (!DIGV) return false;
2470
+    DIGlobalVariable Var(cast<MDNode>(DIGV));
2471
+
2472
+    StringRef D = Var.getDisplayName();
2473
+    if (!D.empty())
2474
+      DisplayName = D;
2475
+    LineNo = Var.getLineNumber();
2476
+    Unit = Var.getCompileUnit();
2477
+    TypeD = Var.getType();
2478
+  } else if (Function *F = dyn_cast<Function>(const_cast<Value*>(V))){
2479
+    Value *DIF = findDbgSubprogramDeclare(F);
2480
+    if (!DIF) return false;
2481
+    DISubprogram Var(cast<MDNode>(DIF));
2482
+
2483
+    StringRef D = Var.getDisplayName();
2484
+    if (!D.empty())
2485
+      DisplayName = D;
2486
+    LineNo = Var.getLineNumber();
2487
+    Unit = Var.getCompileUnit();
2488
+    TypeD = Var.getType();
2489
+  } else {
2490
+    const DbgDeclareInst *DDI = findDbgDeclare(V);
2491
+    if (!DDI) return false;
2492
+    DIVariable Var(cast<MDNode>(DDI->getVariable()));
2493
+
2494
+    StringRef D = Var.getName();
2495
+    if (!D.empty())
2496
+      DisplayName = D;
2497
+    LineNo = Var.getLineNumber();
2498
+    Unit = Var.getCompileUnit();
2499
+    TypeD = Var.getType();
2500
+  }
2501
+
2502
+  StringRef T = TypeD.getName();
2503
+  if (!T.empty())
2504
+    Type = T;
2505
+  StringRef F = Unit.getFilename();
2506
+  if (!F.empty())
2507
+    File = F;
2508
+  StringRef D = Unit.getDirectory();
2509
+  if (!D.empty())
2510
+    Dir = D;
2511
+  return true;
2512
+}
2513
+#endif
2514
+
2404 2515
 void printValue(llvm::Value *V, bool a, bool b) {
2405 2516
     std::string DisplayName;
2406 2517
     std::string Type;
... ...
@@ -15370,8 +15370,8 @@ if test "${with_system_llvm+set}" = set; then :
15370 15370
   *)
15371 15371
     llvmconfig="$withval"
15372 15372
     llvmver=`$llvmconfig --version`
15373
-    if test "$llvmver" != "2.8" -a "$llvmver" != "2.8svn" -a "$llvmver" != "2.8rc"; then
15374
-	as_fn_error $? "LLVM 2.8 or 2.8svn required, but \"$llvmver\" found" "$LINENO" 5
15373
+    if test "$llvmver" != "2.9"; then
15374
+	as_fn_error $? "LLVM 2.9 required, but \"$llvmver\" found" "$LINENO" 5
15375 15375
     fi
15376 15376
     LLVMCONFIG_CXXFLAGS=`$llvmconfig --cxxflags`
15377 15377
 
... ...
@@ -59,8 +59,8 @@ AC_ARG_WITH([system-llvm], AC_HELP_STRING([-with-system-llvm],
59 59
   *)
60 60
     llvmconfig="$withval"
61 61
     llvmver=`$llvmconfig --version`
62
-    if test "$llvmver" != "2.8" -a "$llvmver" != "2.8svn" -a "$llvmver" != "2.8rc"; then
63
-	AC_MSG_ERROR([LLVM 2.8 or 2.8svn required, but "$llvmver" found])
62
+    if test "$llvmver" != "2.9"; then
63
+	AC_MSG_ERROR([LLVM 2.9 required, but "$llvmver" found])
64 64
     fi
65 65
     AC_SUBST(LLVMCONFIG_CXXFLAGS, [`$llvmconfig --cxxflags`])
66 66
     AC_SUBST(LLVMCONFIG_LDFLAGS, [`$llvmconfig --ldflags`])
... ...
@@ -22,9 +22,16 @@
22 22
 
23 23
 #include "llvm/ADT/Triple.h"
24 24
 #include "llvm/Support/raw_ostream.h"
25
+#ifdef LLVM29
26
+#include "llvm/Support/Host.h"
27
+#include "llvm/Support/DataTypes.h"
28
+#include "llvm/Support/Memory.h"
29
+#else
25 30
 #include "llvm/System/Host.h"
26 31
 #include "llvm/System/DataTypes.h"
27 32
 #include "llvm/System/Memory.h"
33
+#endif
34
+
28 35
 #include "llvm/Config/config.h"
29 36
 
30 37
 extern "C" {
... ...
@@ -137,7 +144,9 @@ void cli_detect_env_jit(struct cli_environment *env)
137 137
 	CASE_OS(Linux, os_linux);
138 138
 	CASE_OS(Lv2, os_unknown);
139 139
 	CASE_OS(MinGW32, os_win32);
140
+#ifndef LLVM29
140 141
 	CASE_OS(MinGW64, os_win64);
142
+#endif
141 143
 	CASE_OS(NetBSD,  os_bsd);
142 144
 	CASE_OS(OpenBSD, os_bsd);
143 145
 	CASE_OS(Psp, os_unknown);
... ...
@@ -508,7 +508,7 @@
508 508
 /* #undef USE_SYSLOG */
509 509
 
510 510
 /* Version number of package */
511
-#define VERSION "devel-clamav-0.97-110-g60ba0f8"
511
+#define VERSION "devel-clamav-0.97-129-g0e3c6e3"
512 512
 
513 513
 /* Version suffix for package */
514 514
 #define VERSION_SUFFIX ""
... ...
@@ -1,4 +1,5 @@
1 1
 <?xml version="1.0" encoding="utf-8"?>
2
+
2 3
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 4
   <ItemGroup Label="ProjectConfigurations">
4 5
     <ProjectConfiguration Include="Debug|Win32">
... ...
@@ -332,7 +333,7 @@
332 332
     <ClCompile Include="compat\net.c"/>
333 333
     <ClCompile Include="compat\random.c"/>
334 334
     <ClCompile Include="compat\snprintf.c"/>
335
-    <ClCompile Include="compat\utf8_util.c" />
335
+    <ClCompile Include="compat\utf8_util.c"/>
336 336
     <ClCompile Include="compat\w32_errno.c"/>
337 337
     <ClCompile Include="compat\w32_stat.c"/>
338 338
   </ItemGroup>
... ...
@@ -356,4 +357,4 @@
356 356
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
357 357
   <ImportGroup Label="ExtensionTargets">
358 358
   </ImportGroup>
359
-</Project>
360 359
\ No newline at end of file
360
+</Project>
... ...
@@ -20,6 +20,7 @@
20 20
     </ProjectConfiguration>
21 21
   </ItemGroup>
22 22
   <ItemGroup>
23
+    <ClCompile Include="..\libclamav\c++\PointerTracking.cpp"/>
23 24
     <ClCompile Include="..\libclamav\c++\detect.cpp"/>
24 25
     <ClCompile Include="..\libclamav\c++\bytecode2llvm.cpp"/>
25 26
     <ClCompile Include="..\libclamav\c++\ClamBCRTChecks.cpp"/>