ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
macos/system.c
Go to the documentation of this file.
1
7#include <ascii-chat/platform/abstraction.h>
8#include <ascii-chat/platform/internal.h>
9#include <ascii-chat/common.h>
10#include <mach-o/dyld.h>
11#include <mach-o/loader.h>
12#include <string.h>
13
20static uint64_t get_image_size_from_header(const struct mach_header_64 *header) {
21 if (!header || header->magic != MH_MAGIC_64) {
22 return 0;
23 }
24
25 uint64_t size = 0;
26 const struct load_command *cmd = (const struct load_command *)(header + 1);
27
28 for (uint32_t i = 0; i < header->ncmds; i++) {
29 if (cmd->cmd == LC_SEGMENT_64) {
30 const struct segment_command_64 *seg = (const struct segment_command_64 *)cmd;
31 uint64_t seg_end = seg->vmaddr + seg->vmsize;
32 if (seg_end > size) {
33 size = seg_end;
34 }
35 }
36 cmd = (const struct load_command *)((uintptr_t)cmd + cmd->cmdsize);
37 }
38
39 return size;
40}
41
54int get_binary_file_address_offsets(const void *addr, platform_binary_match_t *matches, int max_matches) {
55 int count = 0;
56 uintptr_t addr_int = (uintptr_t)addr;
57
58 uint32_t image_count = _dyld_image_count();
59 for (uint32_t i = 0; i < image_count && count < max_matches; i++) {
60 const char *image_name = _dyld_get_image_name(i);
61 const struct mach_header_64 *header = (const struct mach_header_64 *)_dyld_get_image_header(i);
62 intptr_t slide = _dyld_get_image_vmaddr_slide(i);
63
64 if (!header || !image_name) {
65 continue;
66 }
67
68 // Calculate image size from mach header
69 uint64_t image_size = get_image_size_from_header(header);
70 if (image_size == 0) {
71 continue;
72 }
73
74 // Base address is header address + slide
75 uintptr_t base = (uintptr_t)header + slide;
76 uintptr_t end = base + image_size;
77
78 // Check if address falls within this image
79 if (addr_int >= base && addr_int < end) {
80 strncpy(matches[count].path, image_name, PLATFORM_MAX_PATH_LENGTH - 1);
81 matches[count].path[PLATFORM_MAX_PATH_LENGTH - 1] = '\0';
82 matches[count].file_offset = addr_int - base;
83
84#ifndef NDEBUG
85 log_debug("[macOS dyld] addr=%p matches %s (offset=%lx, base=%p, slide=%ld)", addr, image_name,
86 matches[count].file_offset, (void *)base, slide);
87#endif
88 count++;
89 }
90 }
91
92 return count;
93}
int get_binary_file_address_offsets(const void *addr, platform_binary_match_t *matches, int max_matches)
Get binary that contains address on macOS via dyld.
#define PLATFORM_MAX_PATH_LENGTH
Definition system.c:64