Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Find table-line-number from an array of bytes.
private static int byteArrayToLineNumber(byte[] bytesSeek, CtMethod ctMethod, int byteArraySize)
throws BadBytecode, RuntimeException {
// Using bytesSeek iterate through the ctMethod's bytecode looking for a matching byte array sized to byteArraySize
int bytecodeIndex = -1;
CodeIterator codeIterator = ctMethod.getMethodInfo().getCodeAttribute().iterator();
codeIterator.begin();
long find = byteArrayToLong(bytesSeek);
while (codeIterator.hasNext() && codeIterator.lookAhead() + byteArraySize < codeIterator.getCodeLength()) {
int index = codeIterator.next();
byte[] bytesFound = new byte[byteArraySize];
for(int i=0;i<byteArraySize;i++){
bytesFound[i] = (byte)codeIterator.byteAt(index + i);
}
long found = byteArrayToLong(bytesFound);
if (found == find) {
bytecodeIndex = index;
}
}
if (bytecodeIndex == -1)
throw new RuntimeException("no bytecode match found.");
// Get the line number table entry for the bytecodeIndex.
LineNumberAttribute lineNumberAttribute = (LineNumberAttribute) ctMethod.getMethodInfo().getCodeAttribute()
.getAttribute(LineNumberAttribute.tag);
int lineNumber = lineNumberAttribute.toLineNumber(bytecodeIndex);
int lineNumberTableOrdinal = IntStream.range(0, lineNumberAttribute.tableLength())
.filter(value -> Objects.equals(lineNumberAttribute.lineNumber(value), lineNumber))
.findFirst()
.orElseThrow(RuntimeException::new);
return lineNumberAttribute.lineNumber(lineNumberTableOrdinal);
}
private static long byteArrayToLong(byte[] bytesOriginal) {
if (bytesOriginal.length < 8) {
byte[] bytesLongPadded = new byte[8];
System.arraycopy(bytesOriginal, 0, bytesLongPadded, 8 - bytesOriginal.length,
bytesOriginal.length);
return ByteBuffer.wrap(bytesLongPadded).getLong();
}
else
return ByteBuffer.wrap(bytesOriginal).getLong();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.