예제 #1
0
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;
}
예제 #2
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);
	}
 }
예제 #3
0
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;
}