int main(int argc, char* argv[]) { if (argc <= 1) { fprintf(stdout, "Usage:\n" " leb128 <big-big-number>\n"); return -1; } if (argv[1][0] == '-') { sleb128(); } else { uleb128(argv[1]); } return 0; }
void BindState::readBindOp(const uint8_t* bindsStart, const uint8_t*& p) { uintptr_t offset; uint8_t op = *p & BIND_OPCODE_MASK; uint8_t imm = *p & BIND_IMMEDIATE_MASK; if (!last_start) last_start = bindsStart; offset = last_start - bindsStart; LOG << "bind: op=" << std::hex << int(op) << " imm=" << int(imm) << std::dec << " @" << (void*)p << ", bindsStart at " << (void*)bindsStart << std::endl; p++; switch (op) { case BIND_OPCODE_DONE: last_start = p; break; case BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: ordinal = imm; break; case BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: ordinal = uleb128(p); break; case BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: if (imm == 0) ordinal = 0; else ordinal = BIND_OPCODE_MASK | imm; break; case BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: sym_name = reinterpret_cast<const char*>(p); p += strlen(sym_name) + 1; LOGF("sym_name=%s\n", sym_name); break; case BIND_OPCODE_SET_TYPE_IMM: type = imm; break; case BIND_OPCODE_SET_ADDEND_SLEB: addend = sleb128(p); break; case BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: seg_index = imm; seg_offset = uleb128(p); break; case BIND_OPCODE_ADD_ADDR_ULEB: seg_offset += uleb128(p); break; case BIND_OPCODE_DO_BIND: addBind(offset); break; case BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: LOGF("BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB\n"); addBind(offset); seg_offset += uleb128(p); break; case BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: LOGF("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED %d\n", (int)imm); addBind(offset); seg_offset += imm * mach->m_ptrsize; break; case BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: { uint64_t count = uleb128(p); uint64_t skip = uleb128(p); LOGF("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB %u %u\n", (unsigned)count, (unsigned)skip); for (uint64_t i = 0; i < count; i++) { addBind(offset); seg_offset += skip; } break; } default: fprintf(stderr, "unknown op: %x\n", op); } }
static uintptr_t readEncodedPointer(const eh_frame_hdr* hdr) { uint8_t format = hdr->eh_frame_ptr_enc & 0xf; uint8_t rel = hdr->eh_frame_ptr_enc & 0xf0; uintptr_t val; bool isSigned = false; if (hdr->eh_frame_ptr_enc == 0xff) return 0; switch (format) { case 1: // unsigned LEB { const uint8_t* ptr = reinterpret_cast<const uint8_t*>(hdr->eh_frame_ptr); val = uleb128(ptr); break; } case 2: // 2 bytes val = *reinterpret_cast<const uint16_t*>(hdr->eh_frame_ptr); break; case 3: val = *reinterpret_cast<const uint32_t*>(hdr->eh_frame_ptr); break; case 4: val = *reinterpret_cast<const uint64_t*>(hdr->eh_frame_ptr); break; case 9: // signed LEB { const uint8_t* ptr = reinterpret_cast<const uint8_t*>(hdr->eh_frame_ptr); val = sleb128(ptr); break; } // FIXME: add 'dlpi_addr' (base address) to these? case 0xa: val = *reinterpret_cast<const int16_t*>(hdr->eh_frame_ptr); break; case 0xb: val = *reinterpret_cast<const int32_t*>(hdr->eh_frame_ptr); break; case 0xc: val = *reinterpret_cast<const int64_t*>(hdr->eh_frame_ptr); break; default: return 0; } switch (rel) { case 0: // no change break; case 0x10: // pcrel val += reinterpret_cast<uintptr_t>(hdr) + 4; break; case 0x30: // eh_frame_hdr rel val += reinterpret_cast<uintptr_t>(hdr); break; default: return 0; } return val; }