Sign in

    moonlink

    Deterministic symbol resolution and link-map diagnostics for ELF64 relocatable objects.

    linker
    elf
    symbol-resolution
    link-map
    build-tools
    diagnostics
    Download zip
    Version
    0.2.0
    License
    MIT
    Last updated
    8 hours ago
    Downloads
    1

    #MoonLink

    MoonLink 是一个小型 MoonBit 工具,用来回答一个具体问题:一组 ELF64 可重定位对象能否按符号正确链接?

    它复用现有的 wuhaiting321/dwarfscope/src/elf 解码 ELF,不重复实现通用 ELF 解析器。MoonLink 自己负责跨目标文件的全局/弱/未定义符号解析、重复定义诊断和确定性链接报告。

    #当前功能

    • 读取一个或多个 ELF64 ET_REL 目标文件。
    • 识别强定义、弱定义、common、未定义符号和局部符号。
    • 强定义优先于弱定义;两个强定义会报告冲突。
    • 局部符号不会错误地满足其他目标文件的外部引用。
    • 输出稳定的文本链接映射,列出解析结果、重复定义和未解析符号。
    • 提供稳定 schema 的 JSON 报告,便于 CI 和构建工具读取。

    当前不做段布局、重定位应用或可执行文件写出;这不是一个替代系统 ld 的完整链接器。

    #快速开始

    moon add oilleelssq-wq/moonlink

    let input = @moonlink.parse_object("main.o", bytes)
    let report = @moonlink.resolve_objects([input])
    println(report.to_link_map())

    命令行:

    moon run cmd/moonlink --target wasm-gc -- resolve main.o helper.o

    如果存在未解析符号或重复强定义,命令会打印完整报告并以非零状态结束。

    CI 可以使用 JSON 输出:

    moon run cmd/moonlink --target wasm-gc -- resolve --json main.o helper.o

    报告 schema 为 moonlink-resolution-v1,包含 ok、解析结果、重复定义和未解析引用。

    #开发与验证

    moon fmt moon check --deny-warn moon test --deny-warn moon test --target wasm moon build cmd/moonlink --target wasm-gc

    测试覆盖强/弱/局部符号、重复定义、未解析引用和 ELF 适配层;测试数据由仓库内的自包含 fixture 构造。

    #项目状态

    • 版本:0.2.0
    • 许可:MIT
    • ELF 解码依赖:wuhaiting321/dwarfscope/src/elf(Apache-2.0)
    • 当前贡献边界:符号解析、冲突诊断、链接报告

    路线图见 docs/ROADMAP.md,申报材料见 PROPOSAL.md。

    LinkError

    pub(all) suberror LinkError {
    InvalidElf(String)
    UnsupportedObjectType(UInt)
    UnsupportedClass
    UnsupportedMachine
    MissingSymbolTable
    InvalidRelocation(String)
    }

    Errors raised while turning an ELF file into a link input.

    LinkError::message

    fn LinkError::message(self : LinkError) -> String

    A short, stable description of a link-input error.

    DuplicateDefinition

    pub(all) struct DuplicateDefinition {
    name : String
    objects : Array[String]
    }

    Two or more strong definitions of the same global symbol.

    LinkBinding

    pub(all) enum LinkBinding {
    Local
    Global
    Weak
    Other(UInt)
    }

    Symbol binding used during cross-object resolution.

    LinkBinding::name

    fn LinkBinding::name(self : LinkBinding) -> String

    Human-readable binding name.

    LinkInput

    pub(all) struct LinkInput {
    name : String
    machine : LinkMachine
    sections : Array[LinkSection]
    symbols : Array[LinkSymbol]
    relocations : Array[LinkRelocation]
    }

    A normalized, linker-facing view of one relocatable object.

    LinkInput::relocations_for

    fn LinkInput::relocations_for(self : LinkInput, target_section : UInt) -> Array[LinkRelocation]

    Return relocations that target a section.

    LinkInput::section

    fn LinkInput::section(self : LinkInput, index : UInt) -> LinkSection?

    Return a section by index.

    LinkInput::section_by_name

    fn LinkInput::section_by_name(self : LinkInput, name : String) -> LinkSection?

    Return the first section with the given name.

    LinkInput::summary

    fn LinkInput::summary(self : LinkInput) -> String

    A compact input description for logs and early diagnostics.

    LinkInput::symbol_by_name

    fn LinkInput::symbol_by_name(self : LinkInput, name : String) -> LinkSymbol?

    Return the first symbol with the given name.

    LinkMachine

    pub(all) enum LinkMachine {
    X86_64
    AArch64
    }

    Machine architectures understood by the first linking milestone.

    LinkMachine::name

    fn LinkMachine::name(self : LinkMachine) -> String

    Human-readable machine name.

    LinkRelocation

    pub(all) struct LinkRelocation {
    target_section : UInt
    offset : UInt64
    symbol_index : UInt
    kind : UInt
    addend : Int64
    has_addend : Bool
    }

    One relocation in a link input. symbol_index is the index in the flattened LinkInput.symbols array.

    LinkResolution

    pub(all) struct LinkResolution {
    symbols : Array[ResolvedSymbol]
    unresolved : Array[UnresolvedSymbol]
    duplicates : Array[DuplicateDefinition]
    object_count : Int
    input_symbol_count : Int
    }

    The result of resolving global and weak symbols across input objects.

    LinkResolution::is_ok

    fn LinkResolution::is_ok(self : LinkResolution) -> Bool

    Whether the resolution has no conflicts or missing definitions.

    LinkResolution::summary

    fn LinkResolution::summary(self : LinkResolution) -> String

    A deterministic one-line summary.

    LinkResolution::to_json

    fn LinkResolution::to_json(self : LinkResolution) -> String

    Render the resolution as a stable JSON document for CI and build tools.
    fn LinkResolution::to_link_map(self : LinkResolution) -> String

    Render a deterministic link map suitable for terminal output and CI logs.
    pub(all) struct LinkSection {
    index : UInt
    name : String
    kind : UInt
    flags : UInt64
    address : UInt64
    size : UInt64
    alignment : UInt64
    entry_size : UInt64
    }

    One section in a link input.

    LinkSection::is_alloc

    fn LinkSection::is_alloc(self : LinkSection) -> Bool

    Whether a section occupies memory at runtime.

    LinkSection::is_executable

    fn LinkSection::is_executable(self : LinkSection) -> Bool

    Whether a section contains executable code.

    LinkSymbol

    pub(all) struct LinkSymbol {
    index : UInt
    name : String
    binding : LinkBinding
    kind : LinkSymbolType
    visibility : UInt
    section_index : UInt
    value : UInt64
    size : UInt64
    }

    One symbol in a link input.

    LinkSymbol::binding_name

    fn LinkSymbol::binding_name(self : LinkSymbol) -> String

    Human-readable binding name.

    LinkSymbol::is_common

    fn LinkSymbol::is_common(self : LinkSymbol) -> Bool

    Whether this symbol is a tentative common definition.

    LinkSymbol::is_global_or_weak

    fn LinkSymbol::is_global_or_weak(self : LinkSymbol) -> Bool

    Whether this symbol participates in cross-object name resolution.

    LinkSymbol::is_undefined

    fn LinkSymbol::is_undefined(self : LinkSymbol) -> Bool

    Whether this symbol has no defining section.

    LinkSymbol::kind_name

    fn LinkSymbol::kind_name(self : LinkSymbol) -> String

    Human-readable symbol kind.

    LinkSymbolType

    pub(all) enum LinkSymbolType {
    NoType
    Object
    Func
    Section
    File
    Common
    Tls
    Other(UInt)
    }

    Symbol kind used in link maps and diagnostics.

    LinkSymbolType::name

    fn LinkSymbolType::name(self : LinkSymbolType) -> String

    Human-readable symbol kind.

    ResolvedSymbol

    pub(all) struct ResolvedSymbol {
    name : String
    binding : LinkBinding
    kind : LinkSymbolType
    object_index : UInt
    object_name : String
    symbol_index : UInt
    value : UInt64
    size : UInt64
    }

    One symbol selected for the link.

    ResolvedSymbol::binding_name

    fn ResolvedSymbol::binding_name(self : ResolvedSymbol) -> String

    Human-readable binding name for a resolved symbol.

    ResolvedSymbol::kind_name

    fn ResolvedSymbol::kind_name(self : ResolvedSymbol) -> String

    Human-readable symbol kind for a resolved symbol.

    SymbolReference

    pub(all) struct SymbolReference {
    object_index : UInt
    object_name : String
    symbol_index : UInt
    }

    One undefined reference to a symbol.

    UnresolvedSymbol

    pub(all) struct UnresolvedSymbol {
    name : String
    references : Array[SymbolReference]
    }

    A symbol referenced but not defined by any input object.

    parse_object

    fn parse_object(name : String, bytes : Bytes) -> LinkInput raise LinkError

    Parse one ELF64 relocatable object and normalize it for linking.

    ELF decoding is delegated to wuhaiting321/dwarfscope/src/elf; this package owns only the linker-facing validation and symbol/relocation model.

    resolve_objects

    fn resolve_objects(inputs : Array[LinkInput]) -> LinkResolution

    Resolve global and weak definitions across a set of input objects.

    Resolution order is caller order: inputs and symbols are visited in the order supplied. A strong definition wins over weak and common definitions; two strong definitions are reported as a duplicate instead of being silently chosen. Local symbols never participate in cross-object resolution.