mirror of
https://github.com/rui314/mold.git
synced 2024-09-21 09:57:18 +03:00
[Mach-O] wip
This commit is contained in:
parent
c89448d17c
commit
0cb34615d9
@ -277,13 +277,14 @@ class RebaseEncoder {
|
||||
public:
|
||||
RebaseEncoder();
|
||||
void add(i64 seg_idx, i64 offset);
|
||||
void flush();
|
||||
void finish();
|
||||
|
||||
std::vector<u8> buf;
|
||||
|
||||
private:
|
||||
i64 last_seg = -1;
|
||||
i64 last_off = 0;
|
||||
i64 cur_seg = -1;
|
||||
i64 cur_off = 0;
|
||||
i64 times = 0;
|
||||
};
|
||||
|
||||
|
@ -422,12 +422,54 @@ RebaseEncoder::RebaseEncoder() {
|
||||
|
||||
void RebaseEncoder::add(i64 seg_idx, i64 offset) {
|
||||
assert(seg_idx < 16);
|
||||
buf.push_back(REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | seg_idx);
|
||||
encode_uleb(buf, offset);
|
||||
buf.push_back(REBASE_OPCODE_DO_REBASE_IMM_TIMES | 1);
|
||||
|
||||
// Accumulate consecutive base relocations
|
||||
if (seg_idx == cur_seg && offset == cur_off) {
|
||||
cur_off += 8;
|
||||
times++;
|
||||
return;
|
||||
}
|
||||
|
||||
// Flush the accumulated base relocations
|
||||
flush();
|
||||
|
||||
// Advance the cursor
|
||||
if (seg_idx != cur_seg) {
|
||||
buf.push_back(REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | seg_idx);
|
||||
encode_uleb(buf, offset);
|
||||
} else {
|
||||
i64 dist = offset - cur_off;
|
||||
assert(dist >= 0);
|
||||
|
||||
if (dist % 8 == 0 && dist < 128) {
|
||||
buf.push_back(REBASE_OPCODE_ADD_ADDR_IMM_SCALED | (dist >> 3));
|
||||
} else {
|
||||
buf.push_back(REBASE_OPCODE_ADD_ADDR_ULEB);
|
||||
encode_uleb(buf, dist);
|
||||
}
|
||||
}
|
||||
|
||||
cur_seg = seg_idx;
|
||||
cur_off = offset + 8;
|
||||
times = 1;
|
||||
}
|
||||
|
||||
void RebaseEncoder::flush() {
|
||||
if (times == 0)
|
||||
return;
|
||||
|
||||
if (times < 16) {
|
||||
buf.push_back(REBASE_OPCODE_DO_REBASE_IMM_TIMES | times);
|
||||
} else {
|
||||
buf.push_back(REBASE_OPCODE_DO_REBASE_ULEB_TIMES);
|
||||
encode_uleb(buf, times);
|
||||
}
|
||||
|
||||
times = 0;
|
||||
}
|
||||
|
||||
void RebaseEncoder::finish() {
|
||||
flush();
|
||||
buf.push_back(REBASE_OPCODE_DONE);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user