1// $ readelf -h ./elf
2// https://github.com/bminor/binutils-gdb/blob/master/binutils/readelf.c
3
4const std = @import("std");
5
6const Elf64ExecutionHeader = packed struct {
7 ident: u128,
8 type: u16,
9 machine: u16,
10 version: u32,
11 entry: u64,
12 phoff: u64,
13 shoff: u64,
14 flags: u32,
15 ehsize: u16,
16 phentsize: u16,
17 phnum: u16,
18 shentsize: u16,
19 shnum: u16,
20 shstrndx: u16,
21};
22
23pub fn main() !void {
24 var file = try std.fs.cwd().openFile("./elf", .{});
25 defer file.close();
26
27 var buffer: [64]u8 align(@alignOf(Elf64ExecutionHeader)) = undefined;
28 _ = try file.read(buffer[0..@sizeOf(Elf64ExecutionHeader)]);
29
30 const header: *Elf64ExecutionHeader = @ptrCast(&buffer);
31
32 std.debug.print("sizeOf(Elf64ExecutionHeader) = {}\n", .{@sizeOf(Elf64ExecutionHeader)});
33 std.debug.print("bitSizeOf(Elf64ExecutionHeader) = {} ({}/8={d})\n", .{
34 @bitSizeOf(Elf64ExecutionHeader),
35 @bitSizeOf(Elf64ExecutionHeader),
36 @bitSizeOf(Elf64ExecutionHeader) / 8,
37 });
38
39 std.debug.print("Object file type: {}\n", .{header.type});
40 std.debug.print("Architecture: {}\n", .{header.machine});
41 std.debug.print("Object file version: 0x{X:0>2}\n", .{header.version});
42 std.debug.print("Entry point virtual address: 0x{X:0>2}\n", .{header.entry});
43 std.debug.print("Program header table file offset: {}\n", .{header.phoff});
44 std.debug.print("Section header table file offset: {}\n", .{header.shoff});
45 std.debug.print("Processor-specific flags: 0x{X:0>2}\n", .{header.flags});
46 std.debug.print("ELF header size in bytes: {}\n", .{header.ehsize});
47 std.debug.print("Program header table entry size: {}\n", .{header.phentsize});
48 std.debug.print("Program header table entry count: {}\n", .{header.phnum});
49 std.debug.print("Section header table entry size: {}\n", .{header.shentsize});
50 std.debug.print("Section header table entry count: {}\n", .{header.shnum});
51 std.debug.print("Section header string table index: {}\n", .{header.shstrndx});
52}