1#
2# Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
3# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4#
5# This code is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 2 only, as
7# published by the Free Software Foundation.  Oracle designates this
8# particular file as subject to the "Classpath" exception as provided
9# by Oracle in the LICENSE file that accompanied this code.
10#
11# This code is distributed in the hope that it will be useful, but WITHOUT
12# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14# version 2 for more details (a copy is included in the LICENSE file that
15# accompanied this code).
16#
17# You should have received a copy of the GNU General Public License version
18# 2 along with this work; if not, write to the Free Software Foundation,
19# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20#
21# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22# or visit www.oracle.com if you need additional information or have any
23# questions.
24#
25
26################################################################################
27# Support for dtrace integration with libjvm, and stand-alone dtrace library
28# compilation.
29
30ifeq ($(call check-jvm-feature, dtrace), true)
31  ##############################################################################
32
33  ifeq ($(OPENJDK_TARGET_OS), solaris)
34    ############################################################################
35    # Integrate with libjvm. Here we generate three object files which are
36    # linked with libjvm.so. This step is complicated from a dependency
37    # perspective, since it needs the rest of the compiled object files from the
38    # libjvm compilation, but the output is object files that are to be included
39    # when linking libjvm.so. So this generation must happen as a part of the
40    # libjvm compilation.
41
42    # First we need to generate the dtraceGenOffsets tool. When run, this will
43    # produce more header files and a C++ file.
44
45    # Note that generateJvmOffsets.cpp must be compiled as if it were a file
46    # in the libjvm.so, using JVM_CFLAGS as setup in CompileJvm.gmk. Otherwise
47    # this would preferrably have been done as a part of GensrcDtrace.gmk.
48    $(eval $(call SetupNativeCompilation, BUILD_DTRACE_GEN_OFFSETS, \
49        SRC := $(HOTSPOT_TOPDIR)/src/os/$(OPENJDK_TARGET_OS)/dtrace, \
50        INCLUDE_FILES := generateJvmOffsets.cpp generateJvmOffsetsMain.c, \
51        CC := $(BUILD_CXX), \
52        CXX := $(BUILD_CXX), \
53        LDEXE := $(BUILD_CXX), \
54        generateJvmOffsets.cpp_CXXFLAGS := $(JVM_CFLAGS) -mt -xnolib -norunpath, \
55        generateJvmOffsetsMain.c_CFLAGS := -mt -m64 -norunpath -z nodefs, \
56        LDFLAGS := -m64, \
57        LIBS := -lc, \
58        OBJECT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets/objs, \
59        OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets, \
60        PROGRAM := dtraceGenOffsets, \
61    ))
62
63    DTRACE_GEN_OFFSETS_TOOL := $(BUILD_DTRACE_GEN_OFFSETS_TARGET)
64
65    # Argument 1: Output filename
66    # Argument 2: dtrace-gen-offset tool command line option
67    define SetupDtraceOffsetsGeneration
68      $1: $$(BUILD_DTRACE_GEN_OFFSETS)
69	$$(call LogInfo, Generating dtrace $2 file $$(@F))
70	$$(call MakeDir, $$(@D))
71	$$(call ExecuteWithLog, $$@, ( $$(DTRACE_GEN_OFFSETS_TOOL) -$$(strip $2) > $$@ ) )
72
73      TARGETS += $1
74    endef
75
76    JVM_OFFSETS_H := $(DTRACE_SUPPORT_DIR)/JvmOffsets.h
77    JVM_OFFSETS_CPP := $(DTRACE_SUPPORT_DIR)/JvmOffsets.cpp
78    JVM_OFFSETS_INDEX_H := $(DTRACE_SUPPORT_DIR)/JvmOffsetsIndex.h
79
80    # Run the dtrace-gen-offset tool to generate these three files.
81    $(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_H), header))
82    $(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_INDEX_H), index))
83    $(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_CPP), table))
84
85    ############################################################################
86    # Compile JVM_OFFSETS_OBJ which is linked with libjvm.so.
87
88    # JvmOffsets.cpp is compiled without the common JVM_CFLAGS. Otherwise, the
89    # natural way would have been to included this source code in BUILD_LIBJVM.
90    JVM_OFFSETS_CFLAGS := -m64
91    ifeq ($(OPENJDK_TARGET_CPU), sparcv9)
92      JVM_OFFSETS_CFLAGS += -xarch=sparc
93    endif
94
95    $(JVM_OFFSETS_OBJ): $(JVM_OFFSETS_CPP) $(JVM_OFFSETS_H)
96	$(call LogInfo, Compiling dtrace file JvmOffsets.cpp (for libjvm.so))
97	$(call ExecuteWithLog, $@, $(CXX) -c -I$(<D) -o $@ $(JVM_OFFSETS_CFLAGS) $<)
98
99    ############################################################################
100    # Generate DTRACE_OBJ which is linked with libjvm.so.
101
102    # Concatenate all *.d files into a single file
103    DTRACE_SOURCE_FILES := $(addprefix $(HOTSPOT_TOPDIR)/src/os/posix/dtrace/, \
104        hotspot_jni.d \
105        hotspot.d \
106        hs_private.d \
107    )
108
109    $(JVM_OUTPUTDIR)/objs/dtrace.d: $(DTRACE_SOURCE_FILES)
110	$(call LogInfo, Generating $(@F))
111	$(call MakeDir, $(@D))
112	$(CAT) $^ > $@
113
114    DTRACE_INSTRUMENTED_OBJS := $(addprefix $(JVM_OUTPUTDIR)/objs/, \
115        ciEnv.o \
116        classLoadingService.o \
117        compileBroker.o \
118        hashtable.o \
119        instanceKlass.o \
120        java.o \
121        jni.o \
122        jvm.o \
123        memoryManager.o \
124        nmethod.o \
125        objectMonitor.o \
126        runtimeService.o \
127        sharedRuntime.o \
128        synchronizer.o \
129        thread.o \
130        unsafe.o \
131        vmThread.o \
132        vmGCOperations.o \
133    )
134
135    ifeq ($(call check-jvm-feature, all-gcs), true)
136      DTRACE_INSTRUMENTED_OBJS += $(addprefix $(JVM_OUTPUTDIR)/objs/, \
137          vmCMSOperations.o \
138          vmPSOperations.o \
139      )
140    endif
141
142    DTRACE_FLAGS := -64 -G
143    DTRACE_CPP_FLAGS := -D_LP64
144
145    # Make sure we run our selected compiler for preprocessing instead of letting
146    # the dtrace tool pick it on it's own.
147    $(DTRACE_OBJ): $(JVM_OUTPUTDIR)/objs/dtrace.d $(DTRACE_INSTRUMENTED_OBJS)
148	$(call LogInfo, Generating $(@F) from $(<F) and object files)
149	$(call MakeDir, $(DTRACE_SUPPORT_DIR))
150	$(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, $(CC) -E \
151	    $(DTRACE_CPP_FLAGS) $< > $(DTRACE_SUPPORT_DIR)/$(@F).d)
152	$(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -xlazyload -o $@ \
153	    -s $(DTRACE_SUPPORT_DIR)/$(@F).d $(sort $(DTRACE_INSTRUMENTED_OBJS)))
154
155    ############################################################################
156    # Generate DTRACE_JHELPER_OBJ which is linked with libjvm.so.
157
158    # Unfortunately dtrace generates incorrect types for some symbols in
159    # dtrace_jhelper.o, resulting in "warning: symbol X has differing types"
160    # This is tracked in JDK-6890703.
161    $(DTRACE_JHELPER_OBJ): $(HOTSPOT_TOPDIR)/src/os/solaris/dtrace/jhelper.d \
162        $(JVM_OFFSETS_INDEX_H)
163	$(call LogInfo, Running dtrace for $(<F))
164	$(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) $(DTRACE_CPP_FLAGS) -C \
165	    -I$(DTRACE_SUPPORT_DIR) -o $@ -s $<)
166
167    # NOTE: We should really do something like this, but unfortunately this
168    # results in a compilation error. :-(
169    # $(call MakeDir, $(DTRACE_SUPPORT_DIR))
170    # $(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, $(CC) -E \
171    #     $(DTRACE_CPP_FLAGS) -I$(DTRACE_SUPPORT_DIR) $^ \
172    #     > $(DTRACE_SUPPORT_DIR)/$(@F).d)
173    # $(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -o $@ \
174    #     -s $(DTRACE_SUPPORT_DIR)/$(@F).d)
175
176    ############################################################################
177    # Build the stand-alone dtrace libraries
178
179    LIBJVM_DTRACE_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_dtrace
180
181    $(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DTRACE, \
182        LIBRARY := jvm_dtrace, \
183        OUTPUT_DIR := $(JVM_LIB_OUTPUTDIR), \
184        SRC := $(HOTSPOT_TOPDIR)/src/os/solaris/dtrace, \
185        INCLUDE_FILES := jvm_dtrace.c, \
186        CFLAGS := -m64 -G -mt -KPIC, \
187        LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \
188        LIBS := $(LIBDL) -lc -lthread -ldoor, \
189        MAPFILE := $(HOTSPOT_TOPDIR)/make/mapfiles/libjvm_dtrace/mapfile-vers, \
190        OBJECT_DIR := $(LIBJVM_DTRACE_OUTPUTDIR)/objs, \
191    ))
192
193    LIBJVM_DB_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_db
194
195    # Note that libjvm_db.c has tests for COMPILER2, but this was never set by
196    # the old build.
197    $(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DB, \
198        LIBRARY := jvm_db, \
199        OUTPUT_DIR := $(JVM_LIB_OUTPUTDIR), \
200        SRC := $(HOTSPOT_TOPDIR)/src/os/solaris/dtrace, \
201        INCLUDE_FILES := libjvm_db.c, \
202        CFLAGS := -I$(JVM_VARIANT_OUTPUTDIR)/gensrc -I$(DTRACE_SUPPORT_DIR) \
203            -m64 -G -mt -KPIC, \
204        LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \
205        LIBS := -lc, \
206        MAPFILE := $(HOTSPOT_TOPDIR)/make/mapfiles/libjvm_db/mapfile-vers, \
207        OBJECT_DIR := $(LIBJVM_DB_OUTPUTDIR)/objs, \
208    ))
209
210    # We need the generated JvmOffsets.h before we can compile the libjvm_db source code.
211    $(BUILD_LIBJVM_DB_ALL_OBJS): $(JVM_OFFSETS_H)
212
213    TARGETS += $(BUILD_LIBJVM_DTRACE) $(BUILD_LIBJVM_DB)
214  endif
215endif
216