/*
		 * This is used by the sliding function to read and execute
		 * the compressed reloc table.
		 */
		static void rebaseCompressed(struct dyld_info_command* dyldInfo,
									 macho_segment_command* linkEdit,
									 uintptr_t slide,
									 macho_segment_command** segments,
									 int segCount)
		{
			/*
			 * HARD MODE!!!
			 */

			const uint8_t* base = (uint8_t*)((linkEdit->vmaddr + slide) - linkEdit->fileoff);
			const uint8_t* start = addUintPtr2(dyldInfo->rebase_off, base);
			const uint8_t* end = addUintPtr3(dyldInfo->rebase_size, dyldInfo->rebase_off, base);
			const uint8_t* p = start;

			/*
			 * If you want a better documented version of this code, see 'MachObject.cpp'
			 */

			uint8_t type = 0;
			int segmentIndex = 0;
			uintptr_t address = (segments[0]->vmaddr + slide);
			uintptr_t segmentEndAddress = (segments[0]->vmaddr + slide + segments[0]->vmsize);
			uint32_t count;
			uint32_t skip;

			bool done = false;
			while ( !done && (p < end) ) {
				uint8_t immediate = *p & REBASE_IMMEDIATE_MASK;
				uint8_t opcode = *p & REBASE_OPCODE_MASK;

				++p;

				switch (opcode) {
					case REBASE_OPCODE_DONE:
						done = true;
						break;
					case REBASE_OPCODE_SET_TYPE_IMM:
						type = immediate;
						break;
					case REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
						segmentIndex = immediate;
						if (segmentIndex > segCount)
							lnk::ldbg::printText("LNK_RELOC_ERROR: baaaad whatever \n");

						address = (segments[segmentIndex]->vmaddr + slide) + read_uleb128(p, end);
						segmentEndAddress = (segments[segmentIndex]->vmaddr + segments[segmentIndex]->vmsize + slide);
						break;
					case REBASE_OPCODE_ADD_ADDR_ULEB:
						address += read_uleb128(p, end);
						break;
					case REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
						address += immediate*sizeof(uintptr_t);
						break;
					case REBASE_OPCODE_DO_REBASE_IMM_TIMES:
						for (int i=0; i < immediate; ++i) {
							if ( address >= segmentEndAddress )
								lnk::ldbg::printText("LNK_RELOC_ERROR: baaaad REBASE_OPCODE_DO_REBASE_IMM_TIMES \n");
							rebaseAt(address, slide, type);
							address += sizeof(uintptr_t);
						}
						break;
					case REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
						count = read_uleb128(p, end);
						for (uint32_t i=0; i < count; ++i) {
							if ( address >= segmentEndAddress )
								lnk::ldbg::printText("LNK_RELOC_ERROR: baaaad REBASE_OPCODE_DO_REBASE_ULEB_TIMES \n");
							rebaseAt(address, slide, type);
							address += sizeof(uintptr_t);
						}
						break;
					case REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
						if ( address >= segmentEndAddress )
							lnk::ldbg::printText("LNK_RELOC_ERROR: baaaad REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB \n");
						rebaseAt(address, slide, type);
						address += read_uleb128(p, end) + sizeof(uintptr_t);
						break;
					case REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
						count = read_uleb128(p, end);
						skip = read_uleb128(p, end);
						for (uint32_t i=0; i < count; ++i) {
							if ( address >= segmentEndAddress )
								lnk::ldbg::printText("LNK_RELOC_ERROR: baaaad REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB \n");
							rebaseAt(address, slide, type);
							address += skip + sizeof(uintptr_t);
						}
						break;
					default:
						_printAbrt();
				}
			}
		}
void MachObject::readRebase(const uint8_t* start, const uint8_t* end)
{
    /* aaaa!!!! */;

    uint8_t type = 0;
    int segmentIndex = 0;
    uintptr_t address = segActualLoadAddr(0);
    uintptr_t segmentEndAddress = segActualEndAddr(0);
    uint32_t count;
    uint32_t skip;
    const uint8_t* p = start;

    bool done = false;
    while ( !done && (p < end) ) {
        uint8_t immediate = *p & REBASE_IMMEDIATE_MASK;
        uint8_t opcode = *p & REBASE_OPCODE_MASK;

        ++p;

        switch (opcode) {
        case REBASE_OPCODE_DONE:
            done = true;
            break;
        case REBASE_OPCODE_SET_TYPE_IMM:
            type = immediate;
            break;
        case REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:
            segmentIndex = immediate;
            if (segmentIndex > fSegmentsCount)
                lnk::halt("baaaad seg count for rebase!");

            address = segActualLoadAddr(segmentIndex) + read_uleb128(p, end);
            segmentEndAddress = segActualEndAddr(segmentIndex);
            break;
        case REBASE_OPCODE_ADD_ADDR_ULEB:
            address += read_uleb128(p, end);
            break;
        case REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
            address += immediate*sizeof(uintptr_t);
            break;
        case REBASE_OPCODE_DO_REBASE_IMM_TIMES:
            for (int i=0; i < immediate; ++i) {
                if ( address >= segmentEndAddress )
                    throwBadBindingAddress(address, segmentEndAddress, segmentIndex, start, end, p);
                this->rebaseAt(address, fSlide, type);
                address += sizeof(uintptr_t);
            }
            break;
        case REBASE_OPCODE_DO_REBASE_ULEB_TIMES:
            count = read_uleb128(p, end);
            for (uint32_t i=0; i < count; ++i) {
                if ( address >= segmentEndAddress )
                    throwBadBindingAddress(address, segmentEndAddress, segmentIndex, start, end, p);
                this->rebaseAt(address, fSlide, type);
                address += sizeof(uintptr_t);
            }
            break;
        case REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:
            if ( address >= segmentEndAddress )
                throwBadBindingAddress(address, segmentEndAddress, segmentIndex, start, end, p);
            this->rebaseAt(address, fSlide, type);
            address += read_uleb128(p, end) + sizeof(uintptr_t);
            break;
        case REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:
            count = read_uleb128(p, end);
            skip = read_uleb128(p, end);
            for (uint32_t i=0; i < count; ++i) {
                if ( address >= segmentEndAddress )
                    throwBadBindingAddress(address, segmentEndAddress, segmentIndex, start, end, p);
                rebaseAt(address, fSlide, type);
                address += skip + sizeof(uintptr_t);
            }
            break;
        default:
            lnk::halt("invalid opcode %d for rebase", *p);
            break;
        }
    }

}