15 #include "ittnotify.h"
19 #include "llvm/Config/config.h"
36 #define DEBUG_TYPE "amplifier-jit-event-listener"
40 class IntelIttnotifyInfo {
41 std::string ModuleName;
42 std::vector<std::string> SectionNamesVector;
43 std::vector<__itt_section_info> SectionInfoVector;
44 __itt_module_object *ModuleObject;
49 : ModuleObject(NULL), WrapperRef(
Wrapper){};
50 ~IntelIttnotifyInfo() {
delete ModuleObject; };
52 void setModuleName(
const char *
Name) { ModuleName = std::string(
Name); }
54 const char *getModuleName() {
return ModuleName.c_str(); }
56 void setModuleObject(__itt_module_object *ModuleObj) {
57 ModuleObject = ModuleObj;
60 __itt_module_object *getModuleObject() {
return ModuleObject; }
62 __itt_section_info *getSectionInfoVectorBegin() {
63 if (SectionInfoVector.size())
64 return &SectionInfoVector[0];
73 int fillSectionInformation(
const ObjectFile &Obj,
76 int SectionCounter = 0;
80 if (SectionLoadAddr) {
83 __itt_section_info SectionInfo;
84 memset(&SectionInfo, 0,
sizeof(SectionInfo));
85 SectionInfo.start_addr =
reinterpret_cast<void *
>(SectionLoadAddr);
86 SectionInfo.file_offset = ElfSection.
getOffset();
87 SectionInfo.flags = ElfSection.
getFlags();
90 auto SectionNameOrError = ElfSection.
getName();
91 if (SectionNameOrError)
95 SectionInfo.size = ElfSection.
getSize();
99 if (ElfSection.
isBSS()) {
100 SectionInfo.type = itt_section_type_bss;
101 }
else if (ElfSection.
isData()) {
102 SectionInfo.type = itt_section_type_data;
103 }
else if (ElfSection.
isText()) {
104 SectionInfo.type = itt_section_type_text;
106 SectionInfoVector.push_back(SectionInfo);
113 for (
int I = 0;
I < SectionCounter; ++
I) {
114 SectionInfoVector[
I].name = SectionNamesVector[
I].c_str();
116 return SectionCounter;
123 std::unique_ptr<IntelJITEventsWrapper>
Wrapper;
124 MethodIDMap MethodIDs;
129 ObjectMap LoadedObjectMap;
130 std::map<ObjectKey, OwningBinary<ObjectFile>> DebugObjects;
132 std::map<ObjectKey, std::unique_ptr<IntelIttnotifyInfo>> KeyToIttnotify;
139 ~IntelJITEventListener() {
142 void notifyObjectLoaded(ObjectKey
Key,
const ObjectFile &Obj,
145 void notifyFreeingObject(ObjectKey
Key)
override;
148 static LineNumberInfo DILineInfoToIntelJITFormat(uintptr_t StartAddress,
153 Result.Offset =
Address - StartAddress;
154 Result.LineNumber = Line.
Line;
167 Result.method_id =
Wrapper.iJIT_GetNewMethodID();
168 Result.method_name =
const_cast<char*
>(FnName);
169 Result.method_load_address =
reinterpret_cast<void*
>(FnStart);
170 Result.method_size = FnSize;
173 Result.class_file_name = NULL;
174 Result.user_data = NULL;
175 Result.user_data_size = 0;
181 int getBackwardCompatibilityMode() {
183 char *BackwardCompatibilityEnv = getenv(
"INTEL_JIT_BACKWARD_COMPATIBILITY");
184 int BackwardCompatibilityMode = 0;
185 if (BackwardCompatibilityEnv) {
189 return BackwardCompatibilityMode;
192 void IntelJITEventListener::notifyObjectLoaded(
196 int BackwardCompatibilityMode = getBackwardCompatibilityMode();
197 if (BackwardCompatibilityMode == 0) {
199 std::unique_ptr<IntelIttnotifyInfo> ModuleIttnotify =
200 std::make_unique<IntelIttnotifyInfo>(*
Wrapper);
201 ModuleIttnotify->setModuleName(
207 __itt_module_object *ModuleObject =
new __itt_module_object();
208 ModuleObject->module_name = ModuleIttnotify->getModuleName();
211 ModuleObject->module_name,
212 ModuleObject->module_size);
213 ModuleObject->module_type = __itt_module_type_elf;
214 ModuleObject->section_number =
215 ModuleIttnotify->fillSectionInformation(Obj, L);
216 ModuleObject->module_buffer =
218 ModuleObject->module_id =
219 __itt_id_make((
void *)&(*ModuleObject), ModuleObject->module_size);
220 ModuleObject->section_array =
221 ModuleIttnotify->getSectionInfoVectorBegin();
222 ModuleIttnotify->setModuleObject(ModuleObject);
224 __itt_module_load_with_sections(ModuleObject);
228 }
else if (BackwardCompatibilityMode == 1) {
238 MethodAddressVector Functions;
241 for (
const std::pair<SymbolRef, uint64_t> &
P :
244 std::vector<LineNumberInfo> LineInfo;
245 std::string SourceFileName;
270 uint64_t
Addr = *AddrOrErr;
271 uint64_t
Size =
P.second;
282 uint64_t
Index = Sec->getIndex();
285 Functions.push_back((
void *)
Addr);
296 DILineInfoToIntelJITFormat((uintptr_t)
Addr, It->first, It->second));
298 if (LineInfo.size() == 0) {
311 LineInfo.push_back(last);
312 for (
size_t i = LineInfo.size() - 2;
i > 0; --
i)
313 LineInfo[
i].LineNumber = LineInfo[
i - 1].LineNumber;
315 SourceFileName = Lines.front().second.FileName;
317 const_cast<char *
>(SourceFileName.c_str());
330 LoadedObjectMap[ObjData] = Functions;
335 void IntelJITEventListener::notifyFreeingObject(ObjectKey
Key) {
337 int BackwardCompatibilityMode = getBackwardCompatibilityMode();
338 if (BackwardCompatibilityMode == 0) {
339 if (KeyToIttnotify.find(
Key) == KeyToIttnotify.end())
341 __itt_module_unload_with_sections(KeyToIttnotify[
Key]->getModuleObject());
344 KeyToIttnotify[
Key]->getModuleObject()->module_name,
345 KeyToIttnotify[
Key]->getModuleObject()->module_size);
346 KeyToIttnotify.erase(
Key);
347 }
else if (BackwardCompatibilityMode == 1) {
350 if (DebugObjects.find(
Key) == DebugObjects.end())
358 ObjectMap::iterator OI = LoadedObjectMap.find(ObjData);
359 if (OI == LoadedObjectMap.end())
361 MethodAddressVector &Functions = OI->second;
364 for (MethodAddressVector::iterator FI = Functions.begin(),
365 FE = Functions.end();
367 void *FnStart =
const_cast<void *
>(*FI);
368 MethodIDMap::iterator
MI = MethodIDs.find(FnStart);
369 if (
MI != MethodIDs.end()) {
377 LoadedObjectMap.erase(OI);
378 DebugObjects.erase(
Key);
392 return new IntelJITEventListener(TestImpl);