ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.87k stars 2.55k forks source link

linksection allowed on variables with comptime only types #11282

Open Hugne opened 2 years ago

Hugne commented 2 years ago

Zig Version

0.10.0-dev.1487+916a65cb7

Steps to Reproduce

main.zig

const s linksection(".bar")= @import("s.zig");
comptime {
    @export(entry, .{ .name = "foo", .linkage = .Strong, .section = ".bar"});
}

fn foo() callconv(.C) c_uint {
    return s.bork();
}

s.zig

pub fn bork()  u32  {
    var p:u32 = 94;
    return p;
}

zig.exe build-lib main.zig -target x86_64-windows -fno-stack-check -fPIC -fno-soname -fno-unwind-tables -dynamic -fsingle-threaded --entry foo

Expected Behavior

The s.zig import (code and data) should be placed in section .bar

Actual Behavior

Only the entrypoint 'foo' is placed in .bar. The linksection attribute is silently ignored for the @import statement

Vexu commented 2 years ago

@import returns a type, it makes no sense to give it a link section as it will never be emitted to binary. The bug here is stage1 not giving an error for this.

Related #11170

Hugne commented 2 years ago

I see. How can i control code placement for non-exported symbols then? (is it even possible?)

Vexu commented 2 years ago

If you want to set bork's linksection you need to add the linksection attribute directly to bork. That issue is related because it's another case of stage1 not handling global variables that well, not because you'd have to export symbols to control their placement.


// zig build-obj a.zig
fn bork() linksection(".foo") void {}
comptime { _ = bork(); }
// objdump a.o -t | grep bork
// 0000000000000000 l     F .foo   0000000000000006 bork
Hugne commented 2 years ago

Maybe it would be worth considering support for syntax like:

linksection(".foo") {
fn bork() void {}
...
}

Kind of like the msvc preprocessor

#pragma code_seg(push,1, ".foo")
void bork() {}
...
#pragma code_seg(pop)