Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose division-by-zero error occurring during Primus interpretation #839

Closed
mjambon opened this issue May 31, 2018 · 8 comments
Closed

Comments

@mjambon
Copy link
Contributor

mjambon commented May 31, 2018

Would it be possible to get a dedicated Primus.Interpreter.Division_by_zero just like there is a Primus.Interpreter.Halt (https://github.com/BinaryAnalysisPlatform/bap/blob/master/lib/bap_primus/bap_primus_interpreter.ml#L233)? (or perhaps something in-between like exposing the existing Primus.Interpreter.Runtime_error "Division by zero" with that string being documented?)

Right now we're pattern-matching against the string "Bap_primus runtime error: Division by zero" that we produce with Primus.Exn.to_string, which is brittle.

@ivg
Copy link
Member

ivg commented May 31, 2018

Sounds reasonable, will do.

@mjambon
Copy link
Contributor Author

mjambon commented May 31, 2018

Cool, thank you!

@ethan42
Copy link
Contributor

ethan42 commented May 31, 2018

if you do that, please expose Segmentation faults as well (this may already be in dev, I'm just not aware of it)

@ivg
Copy link
Member

ivg commented May 31, 2018

OK, though I'm started to ask myself whether we should represent division-by-zero and segmentation faults as CPU exceptions. It sounds right, except that the numbering is abi specific

@ethan42
Copy link
Contributor

ethan42 commented May 31, 2018

I was wondering about something similar.

There is another strange issue here: if all IL issues are handled by the lifter, then everything should just be a CPU exception and division-by-zero should never happen.

For instance, if all divisions are protected by a if denominator is zero then cpu_exn <div_code>, then we should never really see that exception right? So, you could enforce that the lifters generate code that catches such issues. However, for segfault-like errors you get the issue where every memory access will need to be wrapped by a similar construct which will lead to ugly IL. The fact that the cpu exception number will be ABI specific is another complication.

Having specific exceptions for exceptional circumstances (like a segfault) sounds reasonable?

@ivg
Copy link
Member

ivg commented May 31, 2018

The problem that I face, is that we can't stop Interpreter from diverging, in case of the division by zero error. So, there's no problem in exposing it, but it has a very limited use, at least in my whole program execution case.

@ivg
Copy link
Member

ivg commented May 31, 2018

I think that I will thread errors via observations, and implement ABI specific handlers, that will raise corresponding exceptions.

ivg added a commit to ivg/bap that referenced this issue Jun 1, 2018
Division by zero as well as faulty memory operations may terminate the
Primus Machine. Previously we were just terminating it with a specific
exception. However, this exceptions should actually be represented by
an CPU/ABI-specific interrupt or trap. The proposed implementation
provides a mechanism that allows:

- trap the exception and translate it to a machine specific
  interrupt;

- ignore or fix it;

- catch it on a low-level.

The mechanism is based on the same idea as in the Linker that used the
primus_unresolved_handler to trap unresolved names. For each trap we
provide a corresponding observation, that could be used to install the
trap. The trap itself, is a special name, that could be linked (either
on a permanent basis, or from the observation). If the trap hanlder is
assigned, then it is invoked. Concrete behavior depends on a
particular trap, e.g.,

- for linker trap - the hanlder is invoked instead of the missing code;
- for the division by zero - if the handler returns
  then the result is undefined;
- for memory fault - the trap should fix the problem or terminate.

We also introduce the Pagefault exception, to represent memory
traps. We keep segfault as a non-maskable (non-preventable)
exception.

In addition, we have provided several new operations in the Linker
interface:
- unlink: for code unlinking, useful for removing traps
- lookup: useful for restoring other's traps

As a showcase, we also reimplemented some parts of the promiscuous
mode. Now we use the pagefault trap to prevent segmentation
faults. Also the fixing is more efficient as instead of mapping one
byte pages, we are mapping pages with size of up to 4k.

Besides others, this commit will also provide a fix for BinaryAnalysisPlatform#839.
ivg added a commit to ivg/bap that referenced this issue Jun 1, 2018
Division by zero as well as faulty memory operations may terminate the
Primus Machine. Previously we were just terminating it with a specific
exception. However, this exceptions should actually be represented by
an CPU/ABI-specific interrupt or trap. The proposed implementation
provides a mechanism that allows:

- trap the exception and translate it to a machine specific
  interrupt;

- ignore or fix it;

- catch it on a low-level.

The mechanism is based on the same idea as in the Linker that used the
primus_unresolved_handler to trap unresolved names. For each trap we
provide a corresponding observation, that could be used to install the
trap. The trap itself, is a special name, that could be linked (either
on a permanent basis, or from the observation). If the trap hanlder is
assigned, then it is invoked. Concrete behavior depends on a
particular trap, e.g.,

- for linker trap - the hanlder is invoked instead of the missing code;
- for the division by zero - if the handler returns
  then the result is undefined;
- for memory fault - the trap should fix the problem or terminate.

We also introduce the Pagefault exception, to represent memory
traps. We keep segfault as a non-maskable (non-preventable)
exception.

In addition, we have provided several new operations in the Linker
interface:
- unlink: for code unlinking, useful for removing traps
- lookup: useful for restoring other's traps

As a showcase, we also reimplemented some parts of the promiscuous
mode. Now we use the pagefault trap to prevent segmentation
faults. Also the fixing is more efficient as instead of mapping one
byte pages, we are mapping pages with size of up to 4k.

Besides others, this commit will also provide a fix for BinaryAnalysisPlatform#839.
@ivg
Copy link
Member

ivg commented Jun 4, 2018

fixed in #840

@ivg ivg closed this as completed Jun 4, 2018
ivg added a commit that referenced this issue Jun 8, 2018
* adds traps for memory and division operations

Division by zero as well as faulty memory operations may terminate the
Primus Machine. Previously we were just terminating it with a specific
exception. However, this exceptions should actually be represented by
an CPU/ABI-specific interrupt or trap. The proposed implementation
provides a mechanism that allows:

- trap the exception and translate it to a machine specific
  interrupt;

- ignore or fix it;

- catch it on a low-level.

The mechanism is based on the same idea as in the Linker that used the
primus_unresolved_handler to trap unresolved names. For each trap we
provide a corresponding observation, that could be used to install the
trap. The trap itself, is a special name, that could be linked (either
on a permanent basis, or from the observation). If the trap hanlder is
assigned, then it is invoked. Concrete behavior depends on a
particular trap, e.g.,

- for linker trap - the hanlder is invoked instead of the missing code;
- for the division by zero - if the handler returns
  then the result is undefined;
- for memory fault - the trap should fix the problem or terminate.

We also introduce the Pagefault exception, to represent memory
traps. We keep segfault as a non-maskable (non-preventable)
exception.

In addition, we have provided several new operations in the Linker
interface:
- unlink: for code unlinking, useful for removing traps
- lookup: useful for restoring other's traps

As a showcase, we also reimplemented some parts of the promiscuous
mode. Now we use the pagefault trap to prevent segmentation
faults. Also the fixing is more efficient as instead of mapping one
byte pages, we are mapping pages with size of up to 4k.

Besides others, this commit will also provide a fix for #839.

* fixes a typo in the pagefault handler function name

handler
handler
handler
![handler](http://www.addletters.com/pictures/bart-simpson-generator/bart-simpson-generator.php?line=hanlder)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants