-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcriu_necromancer.h
226 lines (184 loc) · 7.12 KB
/
criu_necromancer.h
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#include "Images/core.pb-c.h"
#include "Images/pstree.pb-c.h"
#include "Images/mm.pb-c.h"
#include "Images/pagemap.pb-c.h"
#include "Images/fdinfo.pb-c.h"
#include <stdio.h>
#include "user.h"
#include "file.h"
#ifdef MODE32
#define Elf_Half Elf32_Half
#define Elf_Sword Elf32_Sword
#define Elf_Word Elf32_Word
#define Elf_Xword Elf32_Xword
#define Elf_Sxword Elf32_Sxword
#define Elf_Addr Elf32_Addr
#define Elf_Off Elf32_Off
#define Elf_Section Elf32_Section
#define Elf_Versym Elf32_Versym
#define Elf_Ehdr Elf32_Ehdr
#define Elf_Shdr Elf32_Shdr
#define Elf_Chdr Elf32_Chdr
#define Elf_Sym Elf32_Sym
#define Elf_Syminfo Elf32_Syminfo
#define Elf_Rel Elf32_Rel
#define Elf_Rela Elf32_Rela
#define Elf_Phdr Elf32_Phdr
#define Elf_Dyn Elf32_Dyn
#define Elf_Verdef Elf32_Verdef
#define Elf_Verdaux Elf32_Verdaux
#define Elf_Verneed Elf32_Verneed
#define Elf_Vernaux Elf32_Vernaux
#define Elf_auxv_t Elf32_auxv_t
#define Elf_Nhdr Elf32_Nhdr
#define Elf_Move Elf32_Move
#define Elf_Lib Elf32_Lib
#else
#define Elf_Half Elf64_Half
#define Elf_Sword Elf64_Sword
#define Elf_Word Elf64_Word
#define Elf_Xword Elf64_Xword
#define Elf_Sxword Elf64_Sxword
#define Elf_Addr Elf64_Addr
#define Elf_Off Elf64_Off
#define Elf_Section Elf64_Section
#define Elf_Versym Elf64_Versym
#define Elf_Ehdr Elf64_Ehdr
#define Elf_Shdr Elf64_Shdr
#define Elf_Chdr Elf64_Chdr
#define Elf_Sym Elf64_Sym
#define Elf_Syminfo Elf64_Syminfo
#define Elf_Rel Elf64_Rel
#define Elf_Rela Elf64_Rela
#define Elf_Phdr Elf64_Phdr
#define Elf_Dyn Elf64_Dyn
#define Elf_Verdef Elf64_Verdef
#define Elf_Verdaux Elf64_Verdaux
#define Elf_Verneed Elf64_Verneed
#define Elf_Vernaux Elf64_Vernaux
#define Elf_auxv_t Elf64_auxv_t
#define Elf_Nhdr Elf64_Nhdr
#define Elf_Move Elf64_Move
#define Elf_Lib Elf64_Lib
#endif
typedef struct
{
// Placed on argv
const char* elf;
const char* criu_dump_path;
// Given from pstree
int criu_dump_id;
} ArgInfo;
typedef struct
{
char* buf;
Elf_Ehdr* elf_hdr; // usually == buf
Elf_Phdr* phdr_table;
Elf_Half phnum;
} Elf;
/*
As I understand, in v1.1 always 2 magics, except: inventory.
From https://criu.org/Images:
Or, you can visualize it like
Type Size, bytes
Magic0 4
[Magic1] [4]
Size0 4
Message0 Size0
... ...
SizeN 4
MessageN SizeN
Such images can be one of
Array image files
In these files the amount of entries can be any.
You should read the image file up to the EOF to find out the exact number.
Single-entry image files
In these files exactly one entry is stored.
name type
pstree array
core single-entry
mm single-entry
Pagemap files. {...} The file is a set of protobuf messages.
// ToDo: pstree and pagemap work with array?
*/
typedef struct
{
PstreeEntry* pstree;
CoreEntry* core;
MmEntry* mm;
FILE *pagemap, *pages;
// PagemapEntry* pagemap; // pagemap[0] = pages_id; pages-id.img - raw data
// FileEntry* files;
// int reserved;
} Images;
// ToDo: I don't like this struct and working with it. It's look like big copypaste.
typedef ProtobufCMessage* MessageUnpacker (ProtobufCAllocator*, size_t, const uint8_t*); // ToDo: maybe void -> ProtobufCMessage?
typedef size_t MessagePacker (const void*, uint8_t*);
typedef struct
{
uint32_t magic0, magic1;
} CriuMagic;
// MY_ will useful after, when include criu/criu/include/magic.h
// All numbers are given from this header
static const CriuMagic MY_PSTREE_MAGIC = {0x54564319, 0x50273030};
static const CriuMagic MY_CORE_MAGIC = {0x54564319, 0x55053847};
static const CriuMagic MY_MM_MAGIC = {0x54564319, 0x57492820};
static const CriuMagic MY_PAGEMAP_MAGIC = {0x54564319, 0x56084025};
static const CriuMagic MY_FILES_MAGIC = {0x54564319, 0x56213732};
static inline int CompareMagic (CriuMagic a, CriuMagic b) {return a.magic0 == b.magic0 && a.magic1 == b.magic1;}
const size_t SIZEOF_P_IMAGE_HDR = sizeof (uint32_t) * 3; // not including pb_msg
const ArgInfo EMPTY_ARGINFO = {};
const Images EMPTY_IMAGES = {};
const size_t PAGESIZE = 4096;
#define PE_PRESENT (1 << 2) // copypasted from criu/include/pagemap.h
#define VMA_AREA_VSYSCALL (1 << 2) // copypasted from criu/include/image.h
#define VMA_AREA_HEAP (1 << 5) // copypasted from criu/include/image.h
#define MAX_PATH_LEN 1024
int ParseArguments (int argc, char** argv, ArgInfo* args);
// C-style overloading. Maybe write it the other way?
char* CreateImagePath (const char* path, const char* name);
char* CreateImagePathWithPid (const char* path, const char* name, int pid);
void ArgInfoFree (ArgInfo* args);
Images* ImagesConstructor (ArgInfo* args);
void ImagesDestructor (Images* imgs);
void ChangeImagePid (const char* path, const char* name, int old_pid, int new_pid);
void ImagesWrite (Images* imgs, ArgInfo* args);
Elf* ElfConstructor (const char* filename);
void ElfDestructor (Elf* elf);
Elf_Ehdr* CheckElfHdr (const char* buf);
Elf_Phdr* CheckPhdrs (Elf* elf);
void GoPhdrs (Elf* elf, Images* imgs);
void GoNhdrs (void* nhdrs, Elf_Xword p_filesz, Images* imgs);
// ToDo: Mini documentation
/*
ToDo: Maybe do this: many headers -> one image
Instead of: one header -> many images
???
*/
static inline size_t GetAligned (size_t value, size_t align)
{
return value + (align - value % align) % align;
}
#define GetAlignedSimple(value) GetAligned (value, sizeof (value))
size_t GoPrpsinfo (Elf_Nhdr* nhdr, Images* imgs);
size_t GoPrstatus (Elf_Nhdr* nhdr, Images* imgs);
size_t GoFpregset (Elf_Nhdr* nhdr, Images* imgs);
size_t GoX86_State (Elf_Nhdr* nhdr, Images* imgs);
size_t GoSiginfo (Elf_Nhdr* nhdr, Images* imgs);
size_t GoAuxv (Elf_Nhdr* nhdr, Images* imgs);
size_t GoFile (Elf_Nhdr* nhdr, Images* imgs);
char* GetFilenameByNumInNTFile (file_t* file, size_t file_num);
int GoLoadPhdr (Elf* elf, Elf_Phdr* phdr, Images* imgs, size_t vma_counter);
void MmChangeIfNeeded (MmEntry* mm, VmaEntry* vma, Elf_Phdr* phdr);
uint32_t GetVmaProtByPhdr (Elf_Word phdr_flags);
// type of unpacker's return value == type of *unpacked_image
// allocator for unpacker = default
FILE* StartImageReading (const char* filename, CriuMagic expected_magic);
int ReadMessage (MessageUnpacker unpacker, ProtobufCMessage** unpacked_image, FILE* file);
int ReadOnlyOneMessage (const char* path, const char* name, int pid,
MessageUnpacker unpacker, ProtobufCMessage** unpacked_image, CriuMagic expected_magic);
FILE* StartImageWriting (const char* filename, CriuMagic magic);
int WriteMessage (MessagePacker packer, const ProtobufCMessage* unpacked_image, size_t packed_image_size, FILE* file);
int WriteOnlyOneMessage (const char* path, const char* name, int pid,
MessagePacker packer, const void* unpacked_image, size_t packed_image_size, CriuMagic magic);
void PrintUsage (void);