Skip to documentation
SLOP

tiny.tldr.formats.elf

Reference tiny.tldr formats elf

Defined in formats.

API (30)

Actions

Public operations.

Namespaces

Public namespaces.

No direct callersNo direct callsformatself
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Source: lib/tldr/src/formats/elf/link.zig:59

zig
pub fn linkExecutable(    allocator: Allocator,    inputs: []const model.Input,    options: model.LinkOptions,) model.Error!root.LinkedImage {    const link_phase = trace.scope("link.elf");    defer link_phase.end();    if (options.diagnostics) |diagnostics| diagnostics.clear();    if (options.requiresDynamicLinking()) return error.UnsupportedDynamicLinking;    if (options.output_kind != .executable) return error.UnsupportedOutputKind;    if (options.target.architecture != .x86_64 or options.target.endianness != .little) {        return error.UnsupportedArchitecture;    }    if (inputs.len == 0) return error.NoAllocSections;    var selection_state = std.heap.ArenaAllocator.init(allocator);    defer selection_state.deinit();    var selection_lock = allocators.LockedAllocator.init(selection_state.allocator());    const selection = selection_lock.allocator();    var scratch_state = std.heap.ArenaAllocator.init(allocator);    defer scratch_state.deinit();    const scratch = scratch_state.allocator();    var manifest_builder = build_manifest: {        const manifest_phase = trace.product(.manifest_recording);        defer manifest_phase.end();        var builder = try incremental.Builder.init(allocator, options);        errdefer builder.deinit();        for (inputs) |input| try builder.addInput(input);        break :build_manifest builder;    };    errdefer manifest_builder.deinit();    var objects = std.ArrayListUnmanaged(ObjectFile).empty;    defer objects.deinit(scratch);    try objects.ensureTotalCapacity(scratch, inputs.len);    var archive_state: archive_selection.ExtractionState = .{};    defer archive_state.deinit(scratch);    var prefetcher = archive_selection.Prefetcher.init(selection, inputs, options);    defer prefetcher.deinit();    prefetcher.advance(0);    for (inputs, 0..) |input, input_index| {        if (archive.isArchive(input.bytes)) {            const archive_phase = trace.product(.archive_member_selection);            defer archive_phase.end();            try archive_state.observeNewObjects(scratch, objects.items);            try archive_selection.addCandidates(scratch, selection, input, input_index, &archive_state, options, &prefetcher);            prefetcher.advance(input_index + 1);        } else {            var object = try parseInputObject(scratch, input, options);            object.input_index = input_index;            try objects.append(scratch, object);        }        if (archive_state.hasCandidates()) {            const archive_phase = trace.product(.archive_member_selection);            defer archive_phase.end();            try archive_state.observeNewObjects(scratch, objects.items);            try archive_selection.extractCandidates(                scratch,                selection,                &objects,                &archive_state,                options,            );        }    }    if (manifest_builder.recordsContributions()) {        const manifest_phase = trace.product(.manifest_recording);        defer manifest_phase.end();        try relink.recordInputLinkEvidence(&manifest_builder, scratch, inputs, objects.items, &archive_state);    }    var globals: std.StringHashMapUnmanaged(GlobalSymbol) = .{};    defer globals.deinit(scratch);    var global_symbol_refs = std.ArrayListUnmanaged(SymbolRef).empty;    defer global_symbol_refs.deinit(scratch);    {        const symbol_phase = trace.product(.symbol_database);        defer symbol_phase.end();        {            const duplicate_phase = trace.product(.duplicate_policy);            defer duplicate_phase.end();            try group.discardDuplicates(scratch, objects.items);        }        try collectGlobalSymbols(scratch, objects.items, &globals, &global_symbol_refs, options.max_link_jobs);        if (options.gc_sections) {            try liveness.discardUnreachable(scratch, objects.items, &globals, options);        }        if (options.icf == .all) {            const duplicate_phase = trace.product(.duplicate_policy);            defer duplicate_phase.end();            try icf.fold(scratch, objects.items);        }        try requireResolvedRelocationSymbols(scratch, objects.items, &globals, options);        try requireSupportedRelocations(scratch, objects.items, options);        try requireEntrySymbol(&globals, options);    }    if (options.commit_observer) |observer| observer.notify();    var output_sections = [output_section_count]OutputSection{        .{ .kind = .build_id_note, .alignment = 4 },        .{ .kind = .init, .alignment = 4 },        .{ .kind = .text, .alignment = 16 },        .{ .kind = .fini, .alignment = 4 },        .{ .kind = .iplt, .alignment = 16 },        .{ .kind = .eh_frame_hdr, .alignment = 4 },        .{ .kind = .eh_frame, .alignment = 8 },        .{ .kind = .rodata, .alignment = 1 },        .{ .kind = .rela_iplt, .alignment = 8 },        .{ .kind = .preinit_array, .alignment = 8 },        .{ .kind = .init_array, .alignment = 8 },        .{ .kind = .fini_array, .alignment = 8 },        .{ .kind = .data, .alignment = 8 },        .{ .kind = .got, .alignment = 8 },        .{ .kind = .igot, .alignment = 8 },        .{ .kind = .tdata, .alignment = 1 },        .{ .kind = .tbss, .alignment = 1 },        .{ .kind = .bss, .alignment = 1 },        .{ .kind = .debug_abbrev, .alignment = 1 },        .{ .kind = .debug_addr, .alignment = 1 },        .{ .kind = .debug_aranges, .alignment = 1 },        .{ .kind = .debug_cu_index, .alignment = 1 },        .{ .kind = .debug_frame, .alignment = 1 },        .{ .kind = .debug_info, .alignment = 1 },        .{ .kind = .debug_line, .alignment = 1 },        .{ .kind = .debug_line_str, .alignment = 1 },        .{ .kind = .debug_loc, .alignment = 1 },        .{ .kind = .debug_loclists, .alignment = 1 },        .{ .kind = .debug_macinfo, .alignment = 1 },        .{ .kind = .debug_macro, .alignment = 1 },        .{ .kind = .debug_names, .alignment = 1 },        .{ .kind = .debug_pubnames, .alignment = 1 },        .{ .kind = .debug_pubtypes, .alignment = 1 },        .{ .kind = .debug_ranges, .alignment = 1 },        .{ .kind = .debug_rnglists, .alignment = 1 },        .{ .kind = .debug_str, .alignment = 1 },        .{ .kind = .debug_str_offsets, .alignment = 1 },        .{ .kind = .debug_tu_index, .alignment = 1 },        .{ .kind = .debug_types, .alignment = 1 },    };    var layouts = try scratch.alloc(ObjectLayout, objects.items.len);    var layout_count: usize = 0;    var section_contributions: []SectionContribution = &.{};    defer {        for (layouts[0..layout_count]) |*object_layout| object_layout.deinit(scratch);        scratch.free(section_contributions);        scratch.free(layouts);    }    {        const layout_phase = trace.product(.section_contribution_graph);        defer layout_phase.end();        const section_contribution_count = try layout.collect.countObjectSections(objects.items);        section_contributions = try scratch.alloc(SectionContribution, section_contribution_count);        try layout.collect.sections(scratch, objects.items, &output_sections, layouts, section_contributions, &layout_count, &globals, options);        reserveBuildIdNote(&output_sections, options);        try ehframe.reserveHeader(&output_sections, objects.items, layouts[0..layout_count], options);    }    var ifunc_collector: elf.ifunc.Collector = undefined;    var got_layout: layout.GotLayout = undefined;    var ifunc_layout: elf.ifunc.IfuncLayout = undefined;    {        const layout_phase = trace.product(.layout_groups);        defer layout_phase.end();        ifunc_collector = try elf.ifunc.Collector.init(scratch, objects.items, &globals, options.max_link_jobs);        errdefer ifunc_collector.deinit(scratch);        const collect_ifunc = ifunc_collector.enabled();        got_layout = if (collect_ifunc)            try got_table.collectEntriesWithIfunc(scratch, objects.items, &output_sections, &globals, &ifunc_collector)        else            try collectGotEntries(scratch, objects.items, &output_sections, &globals);        errdefer got_layout.deinit(scratch);        ifunc_layout = if (collect_ifunc)            try ifunc_collector.finish(scratch, &output_sections)        else            elf.ifunc.IfuncLayout{};        errdefer ifunc_layout.deinit(scratch);    }    defer ifunc_collector.deinit(scratch);    defer got_layout.deinit(scratch);    defer ifunc_layout.deinit(scratch);    const live_output_count = layout.output.countLive(&output_sections);    if (live_output_count == 0) return error.NoAllocSections;    const program_header_count = try countProgramHeaders(&output_sections);    {        const layout_phase = trace.product(.address_assignment);        defer layout_phase.end();        try layout.output.assign(&output_sections, options, program_header_count);    }    {        const manifest_phase = trace.product(.manifest_recording);        defer manifest_phase.end();        for (output_sections) |section| {            if (section.logicalSize() == 0) continue;            try manifest_builder.addSection(                section.kind.name(),                section.address,                section.file_offset,                section.logicalSize(),                section.reserved_size,                section.alignment,            );        }        if (manifest_builder.recordsContributions()) {            try addContributionRecords(&manifest_builder, objects.items, layouts[0..layout_count], &output_sections);        }    }    var symbol_addresses = try SymbolAddressCache.init(scratch, objects.items, layouts[0..layout_count], &output_sections);    defer symbol_addresses.deinit(scratch);    try elf.ifunc.finalize(objects.items, layouts[0..layout_count], &output_sections, &globals, &symbol_addresses, ifunc_layout);    const entry_address = resolve_entry: {        const symbol_phase = trace.product(.symbol_database);        defer symbol_phase.end();        break :resolve_entry try resolveEntry(objects.items, layouts, &output_sections, &globals, &symbol_addresses, options.entry_symbol);    };    var linked_image = write_image: {        const write_phase = trace.product(.output_writing);        defer write_phase.end();        break :write_image try image.write(            scratch,            allocator,            objects.items,            layouts,            &output_sections,            &globals,            global_symbol_refs.items,            &symbol_addresses,            got_layout,            options,            entry_address,            live_output_count,            program_header_count,        );    };    errdefer linked_image.deinit(allocator);    const linked_bytes = linked_image.bytes;    try elf.ifunc.write(linked_bytes, &output_sections, ifunc_layout);    {        const materialize_phase = trace.product(.payload_materialization);        defer materialize_phase.end();        try relocation_namespace.materialize(scratch, objects.items, layouts, &output_sections, &globals, &symbol_addresses, got_layout, linked_bytes, options);    }    if (@import("builtin").mode == .debug) elf.payload.verifyMergePieceBytes(linked_bytes, objects.items, layouts, &output_sections);    try finishBuildIdNote(linked_bytes, &output_sections, options);    var manifest = finish_manifest: {        const manifest_phase = trace.product(.manifest_recording);        defer manifest_phase.end();        if (manifest_builder.recordsContributions()) {            try addExternalTargetRecords(                &manifest_builder,                scratch,                objects.items,                layouts[0..layout_count],                &output_sections,                &globals,                global_symbol_refs.items,                &symbol_addresses,            );            try addGotEntryRecords(&manifest_builder, objects.items, &output_sections, &globals, got_layout);            try addMergePieceRecords(&manifest_builder, objects.items, layouts[0..layout_count], &output_sections);        }        break :finish_manifest try manifest_builder.finish();    };    errdefer manifest.deinit(allocator);    return .{        .bytes = linked_bytes,        .storage = linked_image.storage,        .manifest = manifest,    };}
Called byCallsNo direct callersarchiveisArchiveprivate; no linklib.tldr.src.formats.elf.icffoldformats.elf.ifunc.Collectordeinitformats.elf.ifunc.Collectorenabledformats.elf.ifunc.Collectorfinish+21 moreformats.elflinkExecutable
Static calls · unresolved targets: 10 · external targets: 46.

Source: lib/tldr/src/formats/elf/metadata.zig:57

zig
pub fn buildIdNoteRange(image: []const u8) model.Error!?MetadataRange {    const note = linkedSectionByName(image, build_id_note.section_name) catch |err| switch (err) {        error.MissingSection => return null,        else => return err,    };    return .{        .offset = std.math.cast(usize, note.offset) orelse return error.InvalidRange,        .len = std.math.cast(usize, note.size) orelse return error.InvalidRange,    };}
Called byCallsNo direct callersprivate sourcelib.tldr.src.formats.elf.metadatalinkedSectionByNameformats.elfbuildIdNoteRange
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/tldr/src/formats/elf/metadata.zig:48

zig
pub fn finishIncrementalMetadata(image: []u8, options: model.LinkOptions) model.Error!void {    try finishGeneratedBuildIdNote(image, options.build_id);}
Called byCallsNo direct callersprivate sourcelib.tldr.src.formats.elf.metadatafinishGeneratedBuildIdNoteformats.elffinishIncrementalMetadata
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/tldr/src/formats/elf/metadata.zig:35

zig
pub fn patchIncrementalMetadata(image: []u8, candidate_image: []const u8) model.Error!void {    if (image.len != candidate_image.len) return error.InvalidRange;    const image_metadata = try metadataLayout(image);    const candidate_metadata = try metadataLayout(candidate_image);    if (image_metadata.start != candidate_metadata.start) return error.InvalidElfHeader;    if (image_metadata.section_header_offset != candidate_metadata.section_header_offset) return error.InvalidElfHeader;    if (image_metadata.section_count != candidate_metadata.section_count) return error.InvalidElfHeader;    if (image_metadata.string_section_index != candidate_metadata.string_section_index) return error.InvalidElfHeader;    const start: usize = @intCast(image_metadata.start);    @memcpy(image[start..], candidate_image[start..]);    try patchGeneratedBuildIdNote(image, candidate_image);}
Called byCallstest sourcelib.tldr.src.formats.elf.testtest: ELF incremental candidate relin...private sourcelib.tldr.src.formats.elf.metadatametadataLayoutprivate sourcelib.tldr.src.formats.elf.metadatapatchGeneratedBuildIdNoteformats.elfpatchIncrementalMetadata
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/tldr/src/formats/elf/metadata.zig:68

zig
pub fn patchIncrementalMetadataRange(image: []const u8) model.Error!MetadataRange {    const image_metadata = try metadataLayout(image);    const start = std.math.cast(usize, image_metadata.start) orelse return error.InvalidRange;    return .{ .offset = start, .len = image.len - start };}
Called byCallsNo direct callersprivate sourcelib.tldr.src.formats.elf.metadatametadataLayoutformats.elfpatchIncrementalMetadataRange
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/tldr/src/formats/elf/root.zig

zig
const link = @import("link.zig");const metadata = @import("metadata.zig");pub const addressing = @import("address/root.zig");pub const diagnostic = @import("diagnostic.zig");pub const ehframe = @import("ehframe/root.zig");pub const format = @import("format.zig");pub const got_table = @import("got.zig");pub const ifunc = @import("ifunc.zig");pub const group = @import("group/root.zig");pub const icf = @import("icf/root.zig");pub const image = @import("image/root.zig");pub const layout = @import("layout/root.zig");pub const liveness = @import("liveness/root.zig");pub const merge = @import("merge/root.zig");pub const note = @import("note.zig");pub const object = @import("object/root.zig");pub const payload = @import("payload.zig");pub const program = @import("program.zig");pub const parser = @import("parser.zig");pub const relink = @import("relink.zig");pub const output_section = @import("section.zig");pub const relocation = @import("relocation/root.zig");pub const section_state = @import("sections.zig");pub const string = @import("string.zig");pub const symbol_table = @import("symbol.zig");pub const view = @import("view.zig");pub const parseObjectMetadata = parser.parseObjectMetadata;pub const linkExecutable = link.linkExecutable;pub const patchIncrementalMetadata = metadata.patchIncrementalMetadata;pub const finishIncrementalMetadata = metadata.finishIncrementalMetadata;pub const buildIdNoteRange = metadata.buildIdNoteRange;pub const patchIncrementalMetadataRange = metadata.patchIncrementalMetadataRange;

Source: lib/tldr/src/formats/root.zig:3

zig
pub const elf = @import("elf/root.zig");

Complete call list for formats.elf.linkExecutable

26 direct calls.

Audit

Definitions6
Public names6
Members0
Version26.7.0
Revisiondaab053ee433