lib/tldr/src/formats/elf/address/target.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const root = @import("../../../root.zig");
3 const elf = @import("../root.zig");
4 const cache = @import("cache.zig");
5 const size = @import("size.zig");
6 const symbol = @import("symbol.zig");
7
8 const model = root.model;
9 const format = elf.format;
10 const layout = elf.layout;
11 const merge = elf.merge;
12
13 const Access = cache.Access;
14 const Cache = cache.Cache;
15 const GlobalSymbol = layout.GlobalSymbol;
16 const ObjectFile = elf.parser.ObjectFile;
17 const ObjectLayout = layout.ObjectLayout;
18 const OutputSection = layout.OutputSection;
19 const Rela = format.Rela;
20
21 pub const Target = struct {
22 address: i128,
23 addend: i64,
24 size: u64,
25 };
26
27 pub fn relocation(
28 comptime cache_access: Access,
29 objects: []const ObjectFile,
30 layouts: []const ObjectLayout,
31 output_sections: []const OutputSection,
32 globals: *const std.StringHashMapUnmanaged(GlobalSymbol),
33 symbol_addresses: *Cache,
34 object_index: usize,
35 symbol_index: usize,
36 relocation_record: Rela,
37 needs_size: bool,
38 ) model.Error!Target {
39 const object = objects[object_index];
40 if (symbol_index >= object.symbols.len) return error.UndefinedSymbol;
41
42 if (needs_size) {
43 return .{
44 .address = 0,
45 .addend = relocation_record.addend,
46 .size = try size.symbol(objects, globals, object_index, symbol_index),
47 };
48 }
49
50 const symbol_record = object.symbols[symbol_index];
51 if (symbol_record.isSection()) {
52 if (relocation_record.addend >= 0) {
53 const offset: u64 = @intCast(relocation_record.addend);
54 if (merge.address(layouts[object_index], object, output_sections, symbol_record.section_index, offset)) |resolved| {
55 return .{ .address = resolved, .addend = 0, .size = 0 };
56 }
57 }
58 return .{
59 .address = @intCast(try symbol.sectionSymbolAddress(cache_access, objects, layouts, output_sections, symbol_addresses, object_index, symbol_index, symbol_record)),
60 .addend = relocation_record.addend,
61 .size = 0,
62 };
63 }
64
65 return .{
66 .address = try symbol.relocation(cache_access, objects, layouts, output_sections, globals, symbol_addresses, object_index, symbol_index),
67 .addend = relocation_record.addend,
68 .size = 0,
69 };
70 }