Added reading of ELF binaries in Zig

Author Mitja Felicijan <mitja.felicijan@gmail.com> 2024-09-19 14:13:59 +0200
Committer Mitja Felicijan <mitja.felicijan@gmail.com> 2024-09-19 14:13:59 +0200
Commit 9eb604113b9a531331897e14fafe0bef7f62d236 (patch)
-rw-r--r-- README.md 1
-rw-r--r-- zig-elf/.clang-format 4
-rw-r--r-- zig-elf/Makefile 5
-rwxr-xr-x zig-elf/elf bin 0 B -> 15.7 KB
-rw-r--r-- zig-elf/elf-64-gen.pdf bin 0 B -> 168.4 KB
-rw-r--r-- zig-elf/elf.c 6
-rw-r--r-- zig-elf/elf.png bin 0 B -> 318.4 KB
-rw-r--r-- zig-elf/main.zig 51
8 files changed, 67 insertions, 0 deletions
diff --git a/README.md b/README.md
...
35
| [zig-tlv-encoding](./zig-tlv-encoding) | zig-0.13.0 | Naive implementation of TLV encoding in Zig.                   |
35
| [zig-tlv-encoding](./zig-tlv-encoding) | zig-0.13.0 | Naive implementation of TLV encoding in Zig.                   |
36
| [zig-embed](./zig-embed)               | zig-0.13.0 | Embedding external resources in compiled binary.               |
36
| [zig-embed](./zig-embed)               | zig-0.13.0 | Embedding external resources in compiled binary.               |
37
| [zig-struct-bin](./zig-struct-bin)     | zig-0.13.0 | Save a struct into binary file and then reading it back.       |
37
| [zig-struct-bin](./zig-struct-bin)     | zig-0.13.0 | Save a struct into binary file and then reading it back.       |
  
38
| [zig-elf](./zig-elf)                   | zig-0.14.0 | Read execution header of Elf64 format in Zig.                  |
38
  
39
  
39
## License
40
## License
40
  
41
  
...
diff --git a/zig-elf/.clang-format b/zig-elf/.clang-format
  
1
BasedOnStyle: LLVM
  
2
ColumnLimit: 120
  
3
IndentWidth: 4
  
4
  
diff --git a/zig-elf/Makefile b/zig-elf/Makefile
  
1
default:
  
2
	zig run main.zig
  
3
  
  
4
elf:
  
5
	clang -o elf elf.c
diff --git a/zig-elf/elf b/zig-elf/elf
diff --git a/zig-elf/elf-64-gen.pdf b/zig-elf/elf-64-gen.pdf
diff --git a/zig-elf/elf.c b/zig-elf/elf.c
  
1
#include <stdio.h>
  
2
  
  
3
int main(void) {
  
4
  printf("Oh, hi Mark!\n");
  
5
  return 0;
  
6
}
diff --git a/zig-elf/elf.png b/zig-elf/elf.png
diff --git a/zig-elf/main.zig b/zig-elf/main.zig
  
1
// $ readelf -h ./elf
  
2
// https://github.com/bminor/binutils-gdb/blob/master/binutils/readelf.c
  
3
  
  
4
// There is still a problem with packed structs and aligment padding
  
5
// better referenced in these two threads (sometime struct is not aligned
  
6
// properly or even has 1 byte more than its C alternative):
  
7
//  - https://ziggit.dev/t/mapping-64-u8-buffer-to-a-struct/6052/19
  
8
//  - https://ziggit.dev/t/wrong-sizes-of-extern-packed-structs/6053/6
  
9
  
  
10
const std = @import("std");
  
11
  
  
12
const Elf64ExecutionHeader = packed struct {
  
13
    ident: u128,
  
14
    type: u16,
  
15
    machine: u16,
  
16
    version: u32,
  
17
    entry: u64,
  
18
    phoff: u64,
  
19
    shoff: u64,
  
20
    flags: u32,
  
21
    ehsize: u16,
  
22
    phentsize: u16,
  
23
    phnum: u16,
  
24
    shentsize: u16,
  
25
    shnum: u16,
  
26
    shstrndx: u16,
  
27
};
  
28
  
  
29
pub fn main() !void {
  
30
    var file = try std.fs.cwd().openFile("./elf", .{});
  
31
    defer file.close();
  
32
  
  
33
    var buffer: [64]u8 = undefined;
  
34
    _ = try file.read(buffer[0..]);
  
35
  
  
36
    const header: *Elf64ExecutionHeader = @ptrCast(@alignCast(&buffer));
  
37
  
  
38
    std.debug.print("Object file type: {}\n", .{header.type});
  
39
    std.debug.print("Architecture: {}\n", .{header.machine});
  
40
    std.debug.print("Object file version: 0x{X:0>2}\n", .{header.version});
  
41
    std.debug.print("Entry point virtual address: 0x{X:0>2}\n", .{header.entry});
  
42
    std.debug.print("Program header table file offset: {}\n", .{header.phoff});
  
43
    std.debug.print("Section header table file offset: {}\n", .{header.shoff});
  
44
    std.debug.print("Processor-specific flags: 0x{X:0>2}\n", .{header.flags});
  
45
    std.debug.print("ELF header size in bytes: {}\n", .{header.ehsize});
  
46
    std.debug.print("Program header table entry size: {}\n", .{header.phentsize});
  
47
    // std.debug.print("Program header table entry count: {}\n", .{header.phnum});
  
48
    // std.debug.print("Section header table entry size: {}\n", .{header.shentsize});
  
49
    // std.debug.print("Section header table entry count: {}\n", .{header.shnum});
  
50
    // std.debug.print("Section header string table index: {}\n", .{header.shstrndx});
  
51
}