aboutsummaryrefslogtreecommitdiff
path: root/lib/compiler/aro/backend/Object.zig
blob: 4f295a013500d65575f6eb4ea28eb698ee51f69e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
const std = @import("std");
const Allocator = std.mem.Allocator;
const Elf = @import("Object/Elf.zig");

const Object = @This();

format: std.Target.ObjectFormat,
target: std.Target,

pub fn create(gpa: Allocator, target: std.Target) !*Object {
    switch (target.ofmt) {
        .elf => return Elf.create(gpa, target),
        else => unreachable,
    }
}

pub fn deinit(obj: *Object) void {
    switch (obj.format) {
        .elf => @as(*Elf, @alignCast(@fieldParentPtr("obj", obj))).deinit(),
        else => unreachable,
    }
}

pub const Section = union(enum) {
    undefined,
    data,
    read_only_data,
    func,
    strings,
    custom: []const u8,
};

pub fn getSection(obj: *Object, section: Section) !*std.ArrayList(u8) {
    switch (obj.format) {
        .elf => return @as(*Elf, @alignCast(@fieldParentPtr("obj", obj))).getSection(section),
        else => unreachable,
    }
}

pub const SymbolType = enum {
    func,
    variable,
    external,
};

pub fn declareSymbol(
    obj: *Object,
    section: Section,
    name: ?[]const u8,
    linkage: std.builtin.GlobalLinkage,
    @"type": SymbolType,
    offset: u64,
    size: u64,
) ![]const u8 {
    switch (obj.format) {
        .elf => return @as(*Elf, @alignCast(@fieldParentPtr("obj", obj))).declareSymbol(section, name, linkage, @"type", offset, size),
        else => unreachable,
    }
}

pub fn addRelocation(obj: *Object, name: []const u8, section: Section, address: u64, addend: i64) !void {
    switch (obj.format) {
        .elf => return @as(*Elf, @alignCast(@fieldParentPtr("obj", obj))).addRelocation(name, section, address, addend),
        else => unreachable,
    }
}

pub fn finish(obj: *Object, w: *std.Io.Writer) !void {
    switch (obj.format) {
        .elf => return @as(*Elf, @alignCast(@fieldParentPtr("obj", obj))).finish(w),
        else => unreachable,
    }
}