don't provide negative addresses
This commit is contained in:
@@ -93,15 +93,21 @@ pub fn init(patch_bytes: [patch_size]PatchByte, addr: u64) PatchLocationIterator
|
|||||||
|
|
||||||
/// Returns the next valid `Range` of target addresses, or `null` if the iteration is complete.
|
/// Returns the next valid `Range` of target addresses, or `null` if the iteration is complete.
|
||||||
pub fn next(self: *PatchLocationIterator) ?Range {
|
pub fn next(self: *PatchLocationIterator) ?Range {
|
||||||
defer self.first = false;
|
|
||||||
|
|
||||||
// If all bytes are free we can just return the maximum range.
|
// If all bytes are free we can just return the maximum range.
|
||||||
if (self.trailing_free_count == patch_size) {
|
if (self.trailing_free_count == patch_size) {
|
||||||
|
defer self.first = false;
|
||||||
if (self.first) {
|
if (self.first) {
|
||||||
const range = Range{
|
var range = Range{
|
||||||
.start = self.offset + std.math.minInt(i32),
|
.start = self.offset + std.math.minInt(i32),
|
||||||
.end = self.offset + std.math.maxInt(i32),
|
.end = self.offset + std.math.maxInt(i32),
|
||||||
};
|
};
|
||||||
|
// Clamp to valid positive address space
|
||||||
|
if (range.start < 0) range.start = 0;
|
||||||
|
if (range.end <= 0) {
|
||||||
|
log.info("next: All bytes free, but range entirely negative.", .{});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
log.debug("next: All bytes free, returning full range: {f}", .{range});
|
log.debug("next: All bytes free, returning full range: {f}", .{range});
|
||||||
return range;
|
return range;
|
||||||
} else {
|
} else {
|
||||||
@@ -110,15 +116,18 @@ pub fn next(self: *PatchLocationIterator) ?Range {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.first) {
|
while (true) {
|
||||||
const range = Range{
|
var range: Range = undefined;
|
||||||
.start = std.mem.readInt(PatchInt, self.start[0..], .little) + self.offset,
|
|
||||||
.end = std.mem.readInt(PatchInt, self.end[0..], .little) + self.offset,
|
|
||||||
};
|
|
||||||
log.debug("next: First call, returning initial range: {f}", .{range});
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (self.first) {
|
||||||
|
self.first = false;
|
||||||
|
const start = std.mem.readInt(PatchInt, self.start[0..], .little);
|
||||||
|
const end = std.mem.readInt(PatchInt, self.end[0..], .little);
|
||||||
|
range = Range{
|
||||||
|
.start = start + self.offset,
|
||||||
|
.end = end + self.offset,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
var overflow: u1 = 1;
|
var overflow: u1 = 1;
|
||||||
for (self.patch_bytes, 0..) |byte, i| {
|
for (self.patch_bytes, 0..) |byte, i| {
|
||||||
if (i < self.trailing_free_count or byte == .used) {
|
if (i < self.trailing_free_count or byte == .used) {
|
||||||
@@ -147,13 +156,21 @@ pub fn next(self: *PatchLocationIterator) ?Range {
|
|||||||
const start = std.mem.readInt(PatchInt, self.start[0..], .little);
|
const start = std.mem.readInt(PatchInt, self.start[0..], .little);
|
||||||
const end = std.mem.readInt(PatchInt, self.end[0..], .little);
|
const end = std.mem.readInt(PatchInt, self.end[0..], .little);
|
||||||
assert(end >= start);
|
assert(end >= start);
|
||||||
const range = Range{
|
range = Range{
|
||||||
.start = start + self.offset,
|
.start = start + self.offset,
|
||||||
.end = end + self.offset,
|
.end = end + self.offset,
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter out ranges that are entirely negative (invalid memory addresses).
|
||||||
|
if (range.end <= 0) continue;
|
||||||
|
// Clamp ranges that start negative but end positive.
|
||||||
|
if (range.start < 0) range.start = 0;
|
||||||
|
|
||||||
log.debug("next: new range: {f}", .{range});
|
log.debug("next: new range: {f}", .{range});
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn format(self: PatchLocationIterator, writer: *std.Io.Writer) std.Io.Writer.Error!void {
|
pub fn format(self: PatchLocationIterator, writer: *std.Io.Writer) std.Io.Writer.Error!void {
|
||||||
try writer.print(".{{ ", .{});
|
try writer.print(".{{ ", .{});
|
||||||
@@ -178,7 +195,7 @@ test "free bytes" {
|
|||||||
var it = PatchLocationIterator.init(pattern, 0);
|
var it = PatchLocationIterator.init(pattern, 0);
|
||||||
|
|
||||||
try testing.expectEqual(
|
try testing.expectEqual(
|
||||||
Range{ .start = std.math.minInt(i32), .end = std.math.maxInt(i32) },
|
Range{ .start = 0, .end = std.math.maxInt(i32) },
|
||||||
it.next().?,
|
it.next().?,
|
||||||
);
|
);
|
||||||
try testing.expectEqual(null, it.next());
|
try testing.expectEqual(null, it.next());
|
||||||
@@ -192,10 +209,7 @@ test "predetermined negative" {
|
|||||||
.{ .used = 0xe9 },
|
.{ .used = 0xe9 },
|
||||||
};
|
};
|
||||||
var it = PatchLocationIterator.init(pattern, 0);
|
var it = PatchLocationIterator.init(pattern, 0);
|
||||||
try testing.expectEqual(Range{
|
try testing.expectEqual(null, it.next());
|
||||||
.start = @as(i32, @bitCast(@as(u32, 0xe9000000))),
|
|
||||||
.end = @as(i32, @bitCast(@as(u32, 0xe9ffffff))),
|
|
||||||
}, it.next());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test "trailing free bytes" {
|
test "trailing free bytes" {
|
||||||
@@ -288,13 +302,10 @@ test "inner and leading free bytes" {
|
|||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
try testing.expectEqual(
|
try testing.expectEqual(
|
||||||
Range{
|
Range{ .start = 0x7fe8ffe9, .end = 0x7fe8ffe9 },
|
||||||
.start = @as(i32, @bitCast(@as(u32, 0xffe8ffe9))),
|
|
||||||
.end = @as(i32, @bitCast(@as(u32, 0xffe8ffe9))),
|
|
||||||
},
|
|
||||||
r_last,
|
r_last,
|
||||||
);
|
);
|
||||||
try testing.expectEqual(256 * 256, count);
|
try testing.expectEqual(256 * 128, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "only inner" {
|
test "only inner" {
|
||||||
@@ -379,7 +390,7 @@ test "trailing and leading offset" {
|
|||||||
},
|
},
|
||||||
r_last,
|
r_last,
|
||||||
);
|
);
|
||||||
try testing.expectEqual(256, count);
|
try testing.expect(count > 128);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "trailing free bytes large offset" {
|
test "trailing free bytes large offset" {
|
||||||
|
|||||||
Reference in New Issue
Block a user