ios-kernel-patch/data/mach-o/read_dyld_info.h
2021-02-18 10:42:34 +07:00

57 lines
1.6 KiB
C

#pragma once
#include <stdint.h>
// ld64
static addr_t read_xleb128(void **ptr, void *end, bool is_signed) {
addr_t result = 0;
uint8_t *p = *ptr;
uint8_t bit;
unsigned int shift = 0;
do {
if(p >= (uint8_t *) end) die("uleb128 overrun");
bit = *p++;
addr_t k = bit & 0x7f;
// 0x0051 BIND_OPCODE_ADD_ADDR_ULEB(0xFFFFFFF8)
// the argument is a lie, it's actually 64 bits of fff, which overflows here
// it should just be sleb, but ...
//if(shift >= 8*sizeof(addr_t) || ((k << shift) >> shift) != k) die("uleb128 too big");
if(shift < sizeof(addr_t) * 8) {
result |= k << shift;
}
shift += 7;
} while(bit & 0x80);
if(is_signed && (bit & 0x40)) {
result |= ~(((addr_t) 0) << shift);
}
*ptr = p;
return result;
}
static addr_t read_uleb128(void **ptr, void *end) {
return read_xleb128(ptr, end, false);
}
__attribute__((unused)) static addr_t read_sleb128(void **ptr, void *end) {
return read_xleb128(ptr, end, true);
}
static inline void *read_bytes(void **ptr, void *end, size_t size) {
char *p = *ptr;
if((size_t) ((char *) end - p) < size) die("too big");
*ptr = p + size;
return p;
}
#define read_int(ptr, end, typ) *((typ *) read_bytes(ptr, end, sizeof(typ)))
static inline char *read_cstring(void **ptr, void *end) {
// could use strnlen...
char *start = *ptr, *strend = start;
while(strend != end) {
if(!*strend++) {
*ptr = strend;
return start;
}
}
die("c string overflow");
}