[Tizen] Add a library to retrieve memory regions for a coredump
[platform/upstream/coreclr.git] / src / debug / createdump / dnetmemoryenumlib.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdarg.h>
18 #include <iostream>
19 #include <vector>
20 #include "createdump.h"
21 #include "dnetmemoryenumlib.h"
22
23 bool g_diagnostics = false;
24
25 std::vector<SimpleMemoryRegion> sm_regions;
26
27 static std::vector<SimpleMemoryRegion>
28 get_regions(CrashInfo *crashInfo)
29 {
30     std::vector<SimpleMemoryRegion> reg_vec;
31     for (const MemoryRegion& memoryRegion : crashInfo->MemoryRegions()) {
32         if (memoryRegion.IsBackedByMemory()) {
33             reg_vec.push_back({memoryRegion.StartAddress(), memoryRegion.Size()});
34         }
35     }
36     return reg_vec;
37 }
38
39
40 extern "C" int
41 DotNetMemoryEnumInit()
42 {
43     int exitCode = PAL_InitializeDLL();
44     return exitCode;
45 }
46
47 extern "C" void
48 DotNetMemoryEnumFinish()
49 {
50     PAL_TerminateEx(0);
51 }
52
53 extern "C" int
54 DotNetMemoryEnumRegions(pid_t pid, elf_prstatus **statuses, int statuses_count,
55                         DUMP_TYPE minidump_type, SimpleMemoryRegion **regions)
56 {
57     g_diagnostics = true;
58
59     std::vector<elf_prstatus*> stats;
60     for (int i = 0; i < statuses_count; i++) {
61         stats.push_back(statuses[i]);
62     }
63
64     MINIDUMP_TYPE minidumpType;
65
66     switch (minidump_type) {
67     case DT_NORMAL:
68     default:
69         minidumpType = MiniDumpNormal;
70         break;
71     case DT_WITH_PRIV_AND_SHARED_MEM:
72         minidumpType = MiniDumpWithPrivateReadWriteMemory;
73         break;
74     case DT_FULL:
75         minidumpType = MiniDumpWithFullMemory;
76         break;
77     }
78
79     int exitCode = REGERR_OK;
80
81     if (pid != 0)
82     {
83         ReleaseHolder<DumpDataTarget> dataTarget = new DumpDataTarget(pid);
84         ReleaseHolder<CrashInfo> crashInfo = new CrashInfo(pid, dataTarget, true);
85
86         if (dataTarget->Initialize(crashInfo))
87         {
88             if (!crashInfo->EnumerateAndSuspendThreads(false))
89             {
90                 return REGERR_ENUMERATION_ERROR;
91             }
92             crashInfo->SetThreadsRegisters(stats);
93             crashInfo->GatherCrashInfo(minidumpType, false);
94             sm_regions = get_regions(crashInfo);
95             *regions = sm_regions.data();
96             exitCode = sm_regions.size();
97         }
98         else
99         {
100             exitCode = REGERR_INITIALIZATION_ERROR;
101         }
102     }
103     else
104     {
105         exitCode = REGERR_WRONG_PID;
106     }
107     return exitCode;
108 }