8000 Rename stuff and protect readable memory · python/cpython@27a50cf · GitHub
[go: up one dir, main page]

Skip to content

Commit 27a50cf

Browse files
committed
Rename stuff and protect readable memory
1 parent 6490a71 commit 27a50cf

File tree

2 files changed

+164
-149
lines changed

2 files changed

+164
-149
lines changed

Python/jit.c

Lines changed: 84 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -74,27 +74,57 @@ mark_executable(unsigned char *memory, size_t pages)
7474
return 0;
7575
}
7676
#ifdef MS_WINDOWS
77+
if (!FlushInstructionCache(GetCurrentProcess(), memory, size)) {
78+
const char *w = "JIT unable to flush instruction cache (%d)";
79+
PyErr_WarnFormat(PyExc_RuntimeWarning, 0, w, GetLastError());
80+
return -1;
81+
}
7782
DWORD old;
78-
if (!FlushInstructionCache(GetCurrentProcess(), memory, size) ||
79-
!VirtualProtect(memory, size, PAGE_EXECUTE_READ, &old))
80-
{
81-
int code = GetLastError();
83+
if (!VirtualProtect(memory, size, PAGE_EXECUTE, &old)) {
84+
const char *w = "JIT unable to protect executable memory (%d)";
85+
PyErr_WarnFormat(PyExc_RuntimeWarning, 0, w, GetLastError());
86+
return -1;
87+
}
8288
#else
8389
__builtin___clear_cache((char *)memory, (char *)memory + size);
84-
if (mprotect(memory, size, PROT_EXEC | PROT_READ)) {
85-
int code = errno;
90+
if (mprotect(memory, size, PROT_EXEC)) {
91+
const char *w = "JIT unable to protect executable memory (%d)";
92+
PyErr_WarnFormat(PyExc_RuntimeWarning, 0, w, errno);
93+
return -1;
94+
}
8695
#endif
87-
const char *w = "JIT unable to map executable memory (%d)";
88-
PyErr_WarnFormat(PyExc_RuntimeWarning, 0, w, code);
96+
return 0;
97+
}
98+
99+
static int
100+
mark_readable(unsigned char *memory, size_t pages)
101+
{
102+
assert(is_page_aligned(memory));
103+
size_t size = pages * page_size;
104+
if (size == 0) {
105+
return 0;
106+
}
107+
#ifdef MS_WINDOWS
108+
DWORD old;
109+
if (!VirtualProtect(memory, size, PAGE_READONLY, &old)) {
110+
const char *w = "JIT unable to protect readable memory (%d)";
111+
PyErr_WarnFormat(PyExc_RuntimeWarning, 0, w, GetLastError());
112+
return -1;
113+
}
114+
#else
115+
if (mprotect(memory, size, PROT_READ)) {
116+
const char *w = "JIT unable to protect readable memory (%d)";
117+
PyErr_WarnFormat(PyExc_RuntimeWarning, 0, w, errno);
89118
return -1;
90119
}
120+
#endif
91121
return 0;
92122
}
93123

94124
static size_t
95-
bytes_to_pages(size_t nbytes)
125+
size_to_pages(size_t size)
96126
{
97-
return (nbytes + page_size - 1) / page_size;
127+
return (size + page_size - 1) / page_size;
98128
}
99129

100130
static void
@@ -177,8 +207,8 @@ patch(unsigned char *base, const Hole *hole, uint64_t *patches)
177207
static void
178208
copy_and_patch(unsigned char *base, const Stencil *stencil, uint64_t *patches)
179209
{
180-
memcpy(base, stencil->bytes, stencil->nbytes);
181-
for (size_t i = 0; i < stencil->nholes; i++) {
210+
memcpy(base, stencil->body, stencil->body_size);
211+
for (size_t i = 0; i < stencil->holes_size; i++) {
182212
patch(base, &stencil->holes[i], patches);
183213
}
184214
}
@@ -188,8 +218,8 @@ emit(const StencilGroup *stencil_group, uint64_t patches[])
188218
{
189219
unsigned char *data = (unsigned char *)(uintptr_t)patches[_JIT_DATA];
190220
copy_and_patch(data, &stencil_group->data, patches);
191-
unsigned char *body = (unsigned char *)(uintptr_t)patches[_JIT_BODY];
192-
copy_and_patch(body, &stencil_group->body, patches);
221+
unsigned char *text = (unsigned char *)(uintptr_t)patches[_JIT_BODY];
222+
copy_and_patch(text, &stencil_group->text, patches);
193223
}
194224

195225
static int
@@ -229,46 +259,48 @@ initialize_jit(void)
229259
// Write our deopt stub:
230260
{
231261
const StencilGroup *stencil_group = &deoptimize_stencil_group;
232-
size_t pages_body = bytes_to_pages(stencil_group->body.nbytes);
233-
deoptimize_stub = alloc(pages_body);
234-
if (deoptimize_stub == NULL) {
262+
size_t text_pages = size_to_pages(stencil_group->text.body_size);
263+
unsigned char *text = alloc(text_pages);
264+
if (text == NULL) {
235265
return needs_initializing;
236266
}
237-
size_t pages_data = bytes_to_pages(stencil_group->data.nbytes);
238-
unsigned char *data = alloc(pages_data);
267+
size_t data_pages = size_to_pages(stencil_group->data.body_size);
268+
unsigned char *data = alloc(data_pages);
239269
if (data == NULL) {
240270
return needs_initializing;
241271
}
242272
uint64_t patches[] = GET_PATCHES();
243-
patches[_JIT_BODY] = (uintptr_t)deoptimize_stub;
273+
patches[_JIT_BODY] = (uintptr_t)text;
244274
patches[_JIT_DATA] = (uintptr_t)data;
245275
patches[_JIT_ZERO] = 0;
246276
emit(stencil_group, patches);
247-
if (mark_executable(deoptimize_stub, pages_body)) {
277+
if (mark_executable(text, text_pages) || mark_readable(data, data_pages)) {
248278
return needs_initializing;
249279
}
280+
deoptimize_stub = text;
250281
}
251282
// Write our error stub:
252283
{
253284
const StencilGroup *stencil_group = &error_stencil_group;
254-
size_t pages_body = bytes_to_pages(stencil_group->body.nbytes);
255-
error_stub = alloc(pages_body);
256-
if (error_stub == NULL) {
285+
size_t text_pages = size_to_pages(stencil_group->text.body_size);
286+
unsigned char *text = alloc(text_pages);
287+
if (text == NULL) {
257288
return needs_initializing;
258289
}
259-
size_t pages_data = bytes_to_pages(stencil_group->data.nbytes);
260-
unsigned char *data = alloc(pages_data);
290+
size_t data_pages = size_to_pages(stencil_group->data.body_size);
291+
unsigned char *data = alloc(data_pages);
261292
if (data == NULL) {
262293
return needs_initializing;
263294
}
264295
uint64_t patches[] = GET_PATCHES();
265-
patches[_JIT_BODY] = (uintptr_t)error_stub;
296+
patches[_JIT_BODY] = (uintptr_t)text;
266297
patches[_JIT_DATA] = (uintptr_t)data;
267298
patches[_JIT_ZERO] = 0;
268299
emit(stencil_group, patches);
269-
if (mark_executable(error_stub, pages_body)) {
300+
if (mark_executable(text, text_pages) || mark_readable(data, data_pages)) {
270301
return needs_initializing;
271302
}
303+
error_stub = text;
272304
}
273305
// Done:
274306
needs_initializing = 0;
@@ -283,62 +315,62 @@ _PyJIT_CompileTrace(_PyUOpExecutorObject *executor, _PyUOpInstruction *trace, in
283315
return NULL;
284316
}
285317
// First, loop over everything once to find the total compiled size:
286-
size_t nbytes_body = trampoline_stencil_group.body.nbytes;
287-
size_t nbytes_data = trampoline_stencil_group.data.nbytes;
318+
size_t text_size = trampoline_stencil_group.text.body_size;
319+
size_t data_size = trampoline_stencil_group.data.body_size;
288320
for (int i = 0; i < size; i++) {
289321
_PyUOpInstruction *instruction = &trace[i];
290322
const StencilGroup *stencil_group = &stencil_groups[instruction->opcode];
291-
nbytes_body += stencil_group->body.nbytes;
292-
nbytes_data += stencil_group->data.nbytes;
293-
assert(stencil_group->body.nbytes);
323+
text_size += stencil_group->text.body_size;
324+
data_size += stencil_group->data.body_size;
325+
assert(stencil_group->text.body_size);
294326
};
295-
size_t pages_body = bytes_to_pages(nbytes_body);
296-
unsigned char *body = alloc(pages_body);
297-
if (body == NULL) {
327+
size_t text_pages = size_to_pages(text_size);
328+
unsigned char *text = alloc(text_pages);
329+
if (text == NULL) {
298330
return NULL;
299331
}
300-
size_t pages_data = bytes_to_pages(nbytes_data);
301-
unsigned char *data = alloc(pages_data);
332+
size_t data_pages = size_to_pages(data_size);
333+
unsigned char *data = alloc(data_pages);
302334
if (data == NULL) {
303335
return NULL;
304336
}
305-
unsigned char *head_body = body;
337+
unsigned char *head_text = text;
306338
unsigned char *head_data = data;
307339
// First, the trampoline:
308340
const StencilGroup *stencil_group = &trampoline_stencil_group;
309341
uint64_t patches[] = GET_PATCHES();
310-
patches[_JIT_BODY] = (uintptr_t)head_body;
342+
patches[_JIT_BODY] = (uintptr_t)head_text;
311343
patches[_JIT_DATA] = (uintptr_t)head_data;
312-
patches[_JIT_CONTINUE] = (uintptr_t)head_body + F42D stencil_group->body.nbytes;
344+
patches[_JIT_CONTINUE] = (uintptr_t)head_text + stencil_group->text.body_size;
313345
patches[_JIT_ZERO] = 0;
314346
emit(stencil_group, patches);
315-
head_body += stencil_group->body.nbytes;
316-
head_data += stencil_group->data.nbytes;
347+
head_text += stencil_group->text.body_size;
348+
head_data += stencil_group->data.body_size;
317349
// Then, all of the stencils:
318350
for (int i = 0; i < size; i++) {
319351
_PyUOpInstruction *instruction = &trace[i];
320352
const StencilGroup *stencil_group = &stencil_groups[instruction->opcode];
321353
uint64_t patches[] = GET_PATCHES();
322-
patches[_JIT_BODY] = (uintptr_t)head_body;
354+
patches[_JIT_BODY] = (uintptr_t)head_text;
323355
patches[_JIT_DATA] = (uintptr_t)head_data;
324-
patches[_JIT_CONTINUE] = (uintptr_t)head_body + stencil_group->body.nbytes;
356+
patches[_JIT_CONTINUE] = (uintptr_t)head_text + stencil_group->text.body_size;
325357
patches[_JIT_CURRENT_EXECUTOR] = (uintptr_t)executor;
326358
patches[_JIT_DEOPTIMIZE] = (uintptr_t)deoptimize_stub;
327359
patches[_JIT_ERROR] = (uintptr_t)error_stub;
328360
patches[_JIT_OPARG] = instruction->oparg;
329361
patches[_JIT_OPERAND] = instruction->operand;
330362
patches[_JIT_TARGET] = instruction->target;
331-
patches[_JIT_TOP] = (uintptr_t)body + trampoline_stencil_group.body.nbytes;
363+
patches[_JIT_TOP] = (uintptr_t)text + trampoline_stencil_group.text.body_size;
332364
patches[_JIT_ZERO] = 0;
333365
emit(stencil_group, patches);
334-
head_body += stencil_group->body.nbytes;
335-
head_data += stencil_group->data.nbytes;
366+
head_text += stencil_group->text.body_size;
367+
head_data += stencil_group->data.body_size;
336368
};
337-
if (mark_executable(body, pages_body)) {
369+
if (mark_executable(text, text_pages) || mark_readable(data, data_pages)) {
338370
return NULL;
339371
}
340372
// Wow, done already?
341-
assert(head_body == body + nbytes_body);
342-
assert(head_data == data + nbytes_data);
343-
return (_PyJITFunction)body;
373+
assert(head_text == text + text_size);
374+
assert(head_data == data + data_size);
375+
return (_PyJITFunction)text;
344376
}

0 commit comments

Comments
 (0)
0