Skip to content
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

Plan to make @Frame work/error on call chain involving inline assembly, extern fns, etc? #4387

Closed
he-la opened this issue Feb 4, 2020 · 1 comment
Labels
question No questions on the issue tracker, please.
Milestone

Comments

@he-la
Copy link
Contributor

he-la commented Feb 4, 2020

Currently @Frame is not able to detect frame requirements imposed by inline assembly:
test.zig:

const assert = @import("std").debug.assert;

export fn whatever(ptr: *const [0x4000]u8) callconv(.C) void {
    // do whatever
}

fn evil() void {
    asm volatile (
        \\ subq $0x4000, %%rsp
        \\ lea (%%rsp), %%rdi
        \\ call whatever
        \\ addq $0x4000, %%rsp
        :
        :
        : "rsp", "rdi"
    );
}

test "@sizeOf(@Frame(...)) works with inline assembly" {
    assert(@sizeOf(@Frame(evil)) >= 0x4000);
}

I'm not sure what a good solution would be here, perhaps once zig has its own assembler it could attempt parsing the assembly on some architectures and figuring out the required stack size, or else error out if that's not possible.

On a related note, the compiler will probably never be able to know the stack size of an external function. Currently this crashes the compiler:

// lets assume this requires 16KB (0x4000) bytes of stack
extern "c" fn some_external_fn() void;

test "@sizeOf(@Frame(...)) for extern functions" {
    // this should probably be a compiler error
    assert(@sizeOf(@Frame(some_external_fn)) >= 0x4000);
}

The expected result should probably be a compiler error.

@he-la he-la changed the title Plan to make @Frame work/error on call chain involving inline assembly, extern fns, etc Plan to make @Frame work/error on call chain involving inline assembly, extern fns, etc? Feb 4, 2020
@andrewrk andrewrk added the question No questions on the issue tracker, please. label Feb 10, 2020
@andrewrk
Copy link
Member

andrewrk commented Feb 10, 2020

When a program uses inline assembly, it drops beneath the async function abstraction and participates directly in machine code. @Frame is not a measurement of stack size; rather it is a struct that contains all the local variables. If inline assembly wants to cooperate with an async function frame then it should use memory of local variables to the function.

For the purposes of #157, it's the same deal. Inline assembly is not taken into account when calculating stack size. If it wants to affect the stack size measurement, then it will need to reference a local variable of an appropriate size, to annotate the possibility of stack space used.

It's planned for external functions and function pointers to have a "required stack size" annotation. External functions will default to something like 8 MiB.

@andrewrk andrewrk added this to the 0.6.0 milestone Feb 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question No questions on the issue tracker, please.
Projects
None yet
Development

No branches or pull requests

2 participants