lib/tldr/src/formats/elf/object/test.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 
 3 const tldr = @import("../../../root.zig");
 4 const elf = @import("../root.zig");
 5 const object = @import("root.zig");
 6 
 7 const Section = object.Section;
 8 const Symbol = object.Symbol;
 9 const Relocation = object.Relocation;
10 
11 test {
12     std.testing.refAllDecls(object);
13 }
14 
15 const text_bytes = "\x31\xc0\xc3\x90";
16 const data_bytes = "\x01\x02\x03\x04\x05\x06\x07\x08";
17 
18 test "ELF object round trips through the parser and the linker" {
19     const allocator = std.testing.allocator;
20     const bytes = try object.build(allocator, .{
21         .sections = &.{
22             Section.progbits(".text", text_bytes, std.elf.SHF_EXECINSTR, 16),
23             Section.progbits(".data", data_bytes, std.elf.SHF_WRITE, 8),
24             Section.nobits(".bss", 32, std.elf.SHF_WRITE, 8),
25         },
26         .symbols = &.{
27             Symbol.section(1),
28             Symbol.section(2),
29             Symbol.function("_start", 1, 0, 4),
30             Symbol.object("counter", 2, 0, 8),
31         },
32         .relocations = &.{Relocation.x86_64(2, 0, 3, .@"64", 0)},
33     });
34     defer allocator.free(bytes);
35 
36     var parsed = try tldr.parseObject(allocator, .{ .name = "object.o", .bytes = bytes });
37     defer parsed.deinit(allocator);
38     try std.testing.expectEqual(tldr.model.Architecture.x86_64, parsed.target.architecture);
39     try std.testing.expect(findSection(parsed, ".text") != null);
40     try std.testing.expect(findSection(parsed, ".bss") != null);
41     try std.testing.expect(findSymbol(parsed, "_start") != null);
42     try std.testing.expect(findSymbol(parsed, "counter") != null);
43 
44     const inputs = [_]tldr.Input{.{ .name = "object.o", .bytes = bytes }};
45     var linked = try elf.linkExecutable(allocator, &inputs, .{});
46     defer linked.deinit(allocator);
47 
48     const image = try elf.view.View.parse(linked.bytes);
49     try std.testing.expectEqual(std.elf.ET.EXEC, image.header.type);
50     try std.testing.expect(image.header.phnum != 0);
51     try std.testing.expect((try image.find(".text")) != null);
52 }
53 
54 fn findSection(parsed: tldr.Object, name: []const u8) ?tldr.ObjectSection {
55     for (parsed.sections) |section| {
56         if (std.mem.eql(u8, section.name, name)) return section;
57     }
58     return null;
59 }
60 
61 fn findSymbol(parsed: tldr.Object, name: []const u8) ?tldr.ObjectSymbol {
62     for (parsed.symbols) |symbol| {
63         if (std.mem.eql(u8, symbol.name, name)) return symbol;
64     }
65     return null;
66 }