Skip to content

runtime: Go should not mark os memory as executable on Windows #5494

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
alexbrainman opened this issue May 17, 2013 · 16 comments
Closed

runtime: Go should not mark os memory as executable on Windows #5494

alexbrainman opened this issue May 17, 2013 · 16 comments
Milestone

Comments

@alexbrainman
Copy link
Member

http://build.golang.org/log/7f8f2103bb8ca2fa919865751753930a8922450f
@rsc
Copy link
Contributor

rsc commented Jun 3, 2013

Comment 1:

I believe it doesn't except on Windows.

Labels changed: added priority-later, go1.2, removed priority-triage.

@minux
Copy link
Member

minux commented Jun 3, 2013

Comment 2:

Hi Russ, do you have plan to remove the use of runtime-generated callback
function on windows?

@rsc
Copy link
Contributor

rsc commented Jun 3, 2013

Comment 3:

No, I don't. I was just updating the summary.

@alexbrainman
Copy link
Member Author

Comment 4:

I would welcome any suggestion about implementing this.
I can think of 2 ways of doing that (just ideas, didn't think it through):
1) Change compiler to output a JMP instruction in front of every Go function that can
potentially be used as callback function (functions that take one or many uintptr size
parameters and returns single uintptr size parameter). Have this JMP point to a special
routine that does all parameter marshalling and continue to call Go function that
follows JMP instruction;
2) At this moment we allow for maximum of 2000 callbacks. So create a memory page of
2000 JMP instructions (this can be done at runtime or in the linker - I haven't decided
which yet). Change our existing runtime.Callbacks from linked list into array. Use
address of a JMP instruction as an index into this array to decide which Go function to
call.
I don't like my proposals much, so, please, suggest alternatives.
Thank you.
Alex

@rsc
Copy link
Contributor

rsc commented Jun 4, 2013

Comment 5:

(2) is basically what we did for NaCl long ago, if I am remembering correctly.
I think that's actually a fine approach, and it's likely the best we can do.
The assembly would look something like:
TEXT callback0(SB),7,$0
    MOVL $0, AX
    JMP callback_common(SB)
TEXT callback1(SB),7,$0
    MOVL $1, AX
    JMP callback_common(SB)
TEXT callback_common(SB),7,$0
    .. whatever needs to happen, using AX

@alexbrainman
Copy link
Member Author

Comment 6:

Do you mean to generate asm source file with 2000 callback? functions in it? But then I
need some logic to keep track of which of these are used and how. Perhaps a table of
pointers to these functions?
Alex

@rsc
Copy link
Contributor

rsc commented Jun 4, 2013

Comment 7:

Yes, I do.
To keep track of what's used and not, a simple free list will work.
Keep track of the maximum # ever used so far and keep a free list
for the ones that were used but are no longer. To get a new one,
check the free list first, or take a brand new one second.

@alexbrainman
Copy link
Member Author

Comment 8:

Sorry to waste your time again, but how can I get address of my functions. For example,
I would need to return address of my callback20. How would I find it from my C code?
Thank you.
Alex

@rsc
Copy link
Contributor

rsc commented Jun 10, 2013

Comment 9:

You will need a C file too, one that looks like:
extern void callback0(void);
extern void callback1(void);
...
void (*callbacks[])(void) = {
    callback0,
    callback1,
    ...
};

@minux
Copy link
Member

minux commented Jun 10, 2013

Comment 10:

to save memory, i propose this:
TEXT callbacks(SB),7,$0
    CALL callback_common(SB)
    CALL callback_common(SB)
// .... 1998 more calls
TEXT callback_common(SB),7,$0
    .. whatever needs to happen, using the top entry on stack - size of the call instruction - callbacks(SB).

@alexbrainman
Copy link
Member Author

Comment 11:

That is going to be one long (and stupid looking) file. I wonder what Rob will say about
that? :-) I will have a go.
Alex

@minux
Copy link
Member

minux commented Jun 10, 2013

Comment 12:

at least my proposal doesn't require another long C file.
an alternative would be that we synthesize the code for callbacks in a special allocated
(and reserved) memory region in an as needed basis (one page at a time), so that at least
we don't need to make the whole heap as executable and writable.
to be extra safe, once we synthesize a page of calls, we can mark that page only readable
and executable so we don't have writable and executable page at the same time.
yet another option is we use a precompiled .syso file.

@alexbrainman
Copy link
Member Author

Comment 13:

Thank you gents. I have plenty of ideas.
Alex

@alexbrainman
Copy link
Member Author

Comment 14:

https://golang.org/cl/10368043/ should get rid of callbacks issue, then we can
reapply https://code.google.com/p/go/source/detail?r=3c2cddfbdaec again.
Alex

@alexbrainman
Copy link
Member Author

Comment 15:

This issue was updated by revision 05a5de3.

R=golang-dev, minux.ma, rsc, iant
CC=golang-dev
https://golang.org/cl/10368043

@alexbrainman
Copy link
Member Author

Comment 16:

This issue was closed by revision 3d513fa.

Status changed to Fixed.

@rsc rsc added this to the Go1.2 milestone Apr 14, 2015
@rsc rsc removed the go1.2 label Apr 14, 2015
@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants