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 }