JesusFreke / smali

smali/baksmali
6.29k stars 1.07k forks source link

[Question] Is it possible to differentiate between attached Labels? #808

Closed auermich93 closed 3 years ago

auermich93 commented 3 years ago

Hi @JesusFreke,

is it possible to tell whether the labels attached to some instruction (primarily BuilderInstruction) are referring to a branch, being a goto or try/catch-block label? I couldn't find any subclass of Label yet or anything else that would suit. I know that I could compute it on my own by tracking the opcode of the instruction and checking whether an instruction falls at the beginning of a try/catch-block, but this is what I want to avoid basically.

Thanks in advance!

JesusFreke commented 3 years ago

The MethodAnalyzer class is able to build the control flow graph, and allow you to see the predecessors for any instruction.

auermich93 commented 3 years ago

That's what I use for building my graphs, but here my use-case is different. I basically want to go over the instructions in one pass and tell for each instruction instantly whether any assigned labels are referring to a branch, a try or catch block, e.g. à la

Set<Label> labels = instruction.getLabels();
for (Label label : labels) {
    if (label.getType() == LabelType.BRANCH_LABEL) {
       // ....
     }
}

In my special use case, I need to create immutable objects wrapping an instruction and a type when they match a certain criterion, but it can happen that actually several immutable objects are created for the same instruction, because they fullfill multiple criteria at once. In this case I need to prioritize based on the type attribute (which is derived from the label) and keep the one with the highest priority (it is a set). Right now, I simply remove and add a new immutable object with an updated type, but I want to avoid this. I know what you mean, I could use the AnalyzedInstructions and check whether the predecessor is a goto, if statement, etc. However, such instruction can't tell you by inspecting the predecessor whether it is hosted at the beginning of a branch or a catch block. Never mind, I stick to the current solution.