interp: make getelementptr offsets signed

getelementptr offsets are signed, not unsigned. Yet they were used as
unsigned integers in interp.
Somehow this worked most of the time, until finally there was some code
that did a getelementptr with a negative index.
This commit is contained in:
Ayke van Laethem
2024-02-27 14:18:47 +01:00
committed by Ron Evans
parent 9951eb9990
commit 1f6d34d995
3 changed files with 14 additions and 5 deletions
+5 -5
View File
@@ -644,11 +644,11 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
case llvm.GetElementPtr:
// GetElementPtr does pointer arithmetic, changing the offset of the
// pointer into the underlying object.
var offset uint64
var offset int64
for i := 1; i < len(operands); i += 2 {
index := operands[i].Uint()
elementSize := operands[i+1].Uint()
if int64(elementSize) < 0 {
index := operands[i].Int()
elementSize := operands[i+1].Int()
if elementSize < 0 {
// This is a struct field.
offset += index
} else {
@@ -662,7 +662,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
return nil, mem, r.errorAt(inst, err)
}
// GEP on fixed pointer value (for example, memory-mapped I/O).
ptrValue := operands[0].Uint() + offset
ptrValue := operands[0].Uint() + uint64(offset)
locals[inst.localIndex] = makeLiteralInt(ptrValue, int(operands[0].len(r)*8))
continue
}