Skip to content

FEATURE REQUEST: add a compiler directive to keep otherwise unused globals #5603

Description

@grngxd

hey, i'm working on a bare-metal x86_64 kernel using tinygo and i'm currently implementing the limine boot protocol which needs requests to be placed in a specific section so that it can find them. i'm currently doing this with the //go:section directive:

//go:section .limine_requests
var FramebufferRequest = LimineFramebufferRequest{
    Id:       LIMINE_FRAMEBUFFER_REQUEST_ID,
    Revision: 0,
}

this works as expected before optimization. for example, with -opt=0, the LLVM IR contains:

@"fey/kernel/limine/framebuffer.FramebufferRequest" = internal global ..., section ".limine_requests"

however, with -opt=1, -opt=2, -opt=s, or -opt=z, the global gets completely removed because nothing in the Go program references it.

i can confirm that it's actually being removed rather than just moved to another section. searching the generated LLVM IR at -opt=1 only finds the DWARF debug information for the variable:

!DIGlobalVariable(name: "fey/kernel/limine/framebuffer.FramebufferRequest", ...)

there is no actual LLVM global and no .limine_requests section.

this is a problem for things like limine requests because the variable is intentionally not referenced by the program. its purpose is to exist in the final .elf so that something outside the Go program, in this case the bootloader, can find it.

i don't think //go:section should necessarily imply that a global is used, but it would be useful to have some way to explicitly tell TinyGo that a global must not be dead-stripped.

for example, something like:

//go:keep
var ...

which could cause tinygo to retain the global through LLVM's llvm.used / llvm.compiler.used mechanisms.
i couldn't find an existing tinygo directive for this, so is there currently an intended way to prevent a global from being stripped, or would adding a directive for this be something the maintainers would consider?
thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions