-
Notifications
You must be signed in to change notification settings - Fork 11
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
x86 config #76
Comments
I've been hacking around but it's clearly not doing the right thing yet. My pc = "rip"
ifetch = "Read_ifetch"
read_exclusives = []
write_exclusives = []
[[toolchain]]
name = "default"
assembler = "as"
objdump = "objdump"
nm = "nm"
linker = "ld"
[mmu]
page_table_base = "0x300000"
page_size = "4096"
s2_page_table_base = "0x300000"
s2_page_size = "4096"
# This section contains the base address for loading the code for each
# thread in a litmus test, and the stride which is the distance
# between each thread in bytes. The overall range for thread memory is
# the half-open range [base,top)"
[threads]
base = "0x400000"
top = "0x500000"
stride = "0x10000"
[symbolic_addrs]
base = "0x600000"
top = "0x600000"
stride = "0x10"
[registers]
ignore = []
[registers.defaults]
# A map from register names in the litmus to Sail register specifiers
# (roughtly corresponding to l-expressions in Sail, i.e. subscripting
# R[n] and field accesses R.field are allowed.)
[registers.renames]
[reads]
[writes]
[cache_ops] I can run:
It appears to start doing something. But I'm guessing at a minimum I need a version of Any help appreciated! |
Yes, the |
Thanks! That would be much appreciated :) I wanted to encapsulate the build steps and required versions for generating #!/usr/bin/env bash
set -euxo pipefail
OCAML_COMPILER_VERSION="4.10.0"
ISLA_VERSION="4134411c0f463807edd788f67b3db34c1899d9b6"
SAIL_VERSION="eb8af69724828181bf0e91f1728399fe8a81e6f0"
SAIL_X86_VERSION="bfc016d354d902bf78f1e2e4a28cc82dd6d5cbfe"
# Working directory.
workdir=$(mktemp -d)
cd "${workdir}"
outputs="${workdir}/outputs"
mkdir -p "${outputs}"
# Download dependencies.
function github_download() {
local org="$1"
local repo="$2"
local version="$3"
archive="https://github.com/${org}/${repo}/archive/${version}.tar.gz"
mkdir -p "${repo}"
wget -O- "${archive}" | tar xzf - --strip-components 1 -C "${repo}"
}
github_download "rems-project" "isla" "${ISLA_VERSION}"
github_download "rems-project" "sail" "${SAIL_VERSION}"
github_download "rems-project" "sail-x86-from-acl2" "${SAIL_X86_VERSION}"
# Setup opam.
export OPAMROOT="${workdir}/opam"
mkdir -p "${OPAMROOT}"
opam init --yes --compiler="${OCAML_COMPILER_VERSION}"
eval $(opam env)
opam repo add rems 'https://github.com/rems-project/opam-repository.git'
# Pin and install sail.
opam pin --yes add sail
# Build isla-sail.
ISLA_SAIL_PATH=$(realpath isla/isla-sail)
make -C "${ISLA_SAIL_PATH}" all
export PATH="${ISLA_SAIL_PATH}:${PATH}"
# Build x86 IR.
make -C sail-x86-from-acl2/model x86.ir
cp sail-x86-from-acl2/model/x86.ir "${outputs}/"
# Show outputs.
tree "${outputs}" |
I've got one that I used for test generation, but it's on my home computer so it'll be this evening before I can look it out. I don't think there's a nice entry point for isla-footprint though, because it expects to call a single decode-and-execute function with the opcode, whereas the model interleaves fetch and decode. If you want to see the top-level structure of the model for yourself, |
I pushed the one I had here, but it's really barebones. |
Thanks for sharing. As you say the big remaining question is how to define the isla footprint entrypoint.
I am still getting up to speed with this project and trying to see if it will suit our use case, where x86 support is a critical. Are you able to give me a sense of how much of a problem the interleaved fetch and decode will be for using ISLA footprint? In particular, would that be a blocker for using the x86 model with islaris? Have you used x86 with islaris? Thanks for the quick responses to all my issues! |
I think a footprint function that just writes the instruction to memory before executing it would work fine in practice. The fetch and execute parts of the trace are delimited by an instruction announce event, so it might just be a case of having to filter out anything prior to the instruction announce. |
I've been looking into this a bit and just wanted to check I was on the right track. My first attempt (please don't laugh) was:
This fails with errors like:
It's not surprising to me that this didn't work. I imagine there's a bunch of memory setup required that I don't have here. I'm also not sure how the fetch step handles variable length instructions, and therefore if I need to write nop instruction bytes past the end of the 32-bit opcode here. Is there a version of this approach that would work? I'm now trying to make this work with an approach borrowed from
I don't have this finished but I'm feeling more comfortable with the APIs now, so I think I can see it through. But I wanted to make sure I'm not barking up the wrong tree. Please let me know how you would approach this. Thanks! |
Another attempt I've made at this was to setup a concrete memory range starting at
Any pointers appreciated. Thanks. |
I have something that produces a trace, though I'm still not sure it's the optimal approach. I'm using a limited version of the method in Beyond that, the following command-line was very helpful: Specifically it was critical to default the following registers:
In addition, it's also necessary to linearize some of the helper functions Even with simplification the trace for a simple register add ends up being quite bloated. Regardless, I'm hopeful I can get what I need from it. I'm glad to have got something apparently working, but I suspect there might be a cleaner way so I'm still interested to get your input. Happy Christmas! |
I think the reason that you're getting bloated traces is that the test generator doesn't attempt to simplify them at all, whereas footprint has several simplification options that help a lot. It probably wouldn't be too hard to add them. Another option would be to add a mode to isla-footprint where it sets up a small concrete region of memory with the opcode in it (or a symbolic code region, which is what the test generator does to allow the PC to vary). The definition of |
I'm running the following functions on the traces: simplify::remove_extra_register_fields(&mut events);
simplify::remove_repeated_register_reads(&mut events);
simplify::remove_unused_register_assumptions(&mut events);
simplify::remove_unused(&mut events);
simplify::propagate_forwards_used_once(&mut events);
simplify::commute_extract(&mut events);
simplify::eval(&mut events); Would you recommend any others? Or are you referring to something else?
I did try setting up a concrete region, but I got an error since the x86 decoder reads the opcode in multiple reads and the subsequent ones are symbolic. See my note above #76 (comment).
Right, yes I was aware of the variable-length x86 opcodes but I had hoped that just for a quick check I would be able to test with an opcode of at most 32 bits. I think your second problem there is the bigger issue. My code at the moment uses |
Do you have a link to any code that can reproduce the issue in that comment? I'm back from Christmas vacation, so I could look into it.
Means there is some symbolic thing that is affecting the address. I should probably make it so it prints the actual name rather than the id, but you can do |
No, you've already got them all.
Padding the opcode up to 32 bits should get rid of that initial error and there is an upper bound to x86 instructions, so it could work in general. For the memory callbacks you might need to fiddle with the |
Sorry I can't easily recover that version of the code. I was hacking and slashing a lot to get something to work for x86. The extremely messy code I have working right now is: https://gist.github.com/mmcloughlin/943d338e0126cdbb62f3d205f2b1c289 The config and example trace output are included in this gist too. The architecture IR file was derived from the script in #76 (comment). (Note I have hard-coded the opcode in this version of the code. In practice the opcode is coming from another Rust library I'm working with, but I removed that to make it simpler for you to work with the code if you'd like to.) If you have any suggestions for how to simplify or improve that code I'd be very interested. In particular, it would also be nice to have an approach that works for all architectures. Currently I have two different Rust programs for AArch64 and x86. So a unified approach might be either:
Thanks! |
I think I understand what the issue is now. There are a few ways I could go about addressing it so I'll have to think about which one is best. |
I am wondering if |
That should be handled by running |
I did add a commit that might help today. I think the issue is that
Then when the With the commit I added today, if we have a symbolic address with only has a single satisfiable value it will treat it as concrete which might solve this issue, assuming |
In #75 (comment) you suggested that you've had some success using ISLA with the x86 model.
I have used
isla-sail
to getx86.ir
fromsail-x86-from-acl2
.Do you have a
config/x86.toml
somewhere? Or can you advise on how I might create one?Thanks!
The text was updated successfully, but these errors were encountered: