- Notifications
You must be signed in to change notification settings - Fork27
Add Disassembler#89
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Merged
Uh oh!
There was an error while loading.Please reload this page.
Merged
Changes fromall commits
Commits
Show all changes
17 commits Select commitHold shift + click to select a range
ce82cbb First crude version of a disassembler
wnienhaus4c834e3 Replace crude disassembly with lookup table
wnienhaus8325c2b Add command line handling, implementing help (-h)
wnienhause4b34e2 Tease apart decoding of instruction and printing. Add unit tests.
wnienhaus2ebaacc Allow choosing which unit tests to run
wnienhaus278bbf0 Add unit tests for field level output
wnienhaus6720584 Show empty "instructions" as <empty>
wnienhaus2a06a54 Add support for disassembling a provided file
wnienhausa4867e8 Add verbose option. Hide field level detail when not verbose.
wnienhausb51677d Improve/clean-up dissambled output format
wnienhaus40ea7e9 Add byte offset to output to make seeing offsets easier
wnienhaus08bb182 use text_offset from ULP header instead of hardcoded offset
wnienhaus15a631a Output header in verbose mode. Also validate ULP header.
wnienhaus59766fb Print .text and .data section separately
wnienhaus10a5051 Add hex representation for any field value > 9
wnienhauseff6f96 Add integration tests for disassembler
wnienhaus06b277e Add documentation for disassembler
wnienhausFile filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
7 changes: 7 additions & 0 deletions.github/workflows/run_tests.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletionsREADME.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
146 changes: 146 additions & 0 deletionsdocs/disassembler.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,146 @@ | ||
| ===================== | ||
| Disassembler | ||
| ===================== | ||
| micropython-esp32-ulp contains a disassembler for disassembling code for the | ||
| ESP32 ULP (Ultra Low-Power) Co-Processor. | ||
| The main purpose of this tool is to inspect what instructions our assembler | ||
| created, what value each field is set to, and to compare this with the output | ||
| created by the assembler from Espressif (part of their `binutils-gdb fork <https://github.com/espressif/binutils-gdb/tree/esp32ulp-elf-2.35>`_), | ||
| which we use as our reference implementation. | ||
| Usage | ||
| ------------------------ | ||
| To disassemble a ULP binary, simply run: | ||
| .. code-block:: bash | ||
| micropython -m tools.disassemble path/to/binary.ulp | ||
| You can also specify additional options to ``disassemble.py`` as follows: | ||
| +--------------------------+----------------------------------------------------------------+ | ||
| | Option | Description | | ||
| +==========================+================================================================+ | ||
| | ``-h`` | Show help text | | ||
| +--------------------------+----------------------------------------------------------------+ | ||
| || ``-m <bytes sequence>`` || Disassemble a provided sequence of hex bytes | | ||
| || || (in this case any filename specified is ignored) | | ||
| +--------------------------+----------------------------------------------------------------+ | ||
| | ``-v`` | Verbose mode (shows ULP header and fields of each instruction) | | ||
| +--------------------------+----------------------------------------------------------------+ | ||
| Disassembling a file | ||
| ------------------------ | ||
| The simplest and default mode of the disassembler is to disassemble the | ||
| specified file. | ||
| Note that the ULP header is validates and files with unknown magic bytes will be | ||
| rejected. The correct 4 magic bytes at the start of a ULP binary are ``ulp\x00``. | ||
| Example: | ||
| .. code-block:: shell | ||
| $ micropython -m tools.disassemble path/to/binary.ulp | ||
| .text | ||
| 0000 040000d0 LD r0, r1, 0 | ||
| 0004 0e0400d0 LD r2, r3, 1 | ||
| 0008 84010068 ST r0, r1, 0 | ||
| 000c 8b090068 ST r3, r2, 2 | ||
| .data | ||
| 0000 00000000 <empty> | ||
| Disassembling a byte sequence | ||
| ----------------------------- | ||
| The ``-m`` option allows disassembling a sequences hex letters representing | ||
| ULP instructions. | ||
| This option expects the actual instructions directly, without any ULP header. | ||
| The sequence must contain a number of hex letters exactly divisible by 8, i.e. | ||
| 8, 16, 24, etc, because each 32-bit word is made up of 8 hex letters. Spaces | ||
| can be included in the sequence and they are ignored. | ||
| The typical use case for this feature is to copy/paste some instructions from | ||
| a hexdump (e.g. xxd output) for analysis. | ||
| Example: | ||
| .. code-block:: shell | ||
| # hexdump binary.ulp | ||
| $ xxd path/to/binary.ulp | ||
| 00000000: 756c 7000 0c00 2400 0400 0000 9300 8074 ulp...$........t | ||
| 00000010: 2a80 0488 2004 8074 1c00 0084 0000 0040 *... ..t.......@ | ||
| (...) | ||
| # analyse the last 2 instructions | ||
| $ micropython -m tools.disassemble -m "1c00 0084 0000 0040" | ||
| 0000 1c000084 JUMPS 0, 28, LT | ||
| 0004 00000040 NOP | ||
| Verbose mode | ||
| ------------------------ | ||
| In verbose mode the following extra outputs are enabled: | ||
| * ULP header (except when using ``-m``) | ||
| * The fields of each instruction and their values | ||
| For example: | ||
| .. code-block:: | ||
| header | ||
| ULP magic : b'ulp\x00' (0x00706c75) | ||
| .text offset : 12 (0x0c) | ||
| .text size : 36 (0x24) | ||
| .data offset : 48 (0x30) | ||
| .data size : 4 (0x04) | ||
| .bss size : 0 (0x00) | ||
| ---------------------------------------- | ||
| .text | ||
| 0000 93008072 MOVE r3, 9 | ||
| dreg = 3 | ||
| imm = 9 | ||
| opcode = 7 | ||
| sel = 4 (MOV) | ||
| sreg = 0 | ||
| sub_opcode = 1 | ||
| unused = 0 | ||
| (...detail truncated...) | ||
| 0020 000000b0 HALT | ||
| opcode = 11 (0x0b) | ||
| unused = 0 | ||
| ---------------------------------------- | ||
| .data | ||
| 0000 00000000 <empty> | ||
| Disassembling on device | ||
| ----------------------------- | ||
| The disassembler also works when used on an ESP32. | ||
| To use the disassembler on a real device: | ||
| * ensure ``micropython-esp32-ulp`` is installed on the device (see `docs/index.rst </docs/index.rst>`_). | ||
| * upload ``tools/disassemble.py`` to the device (any directory will do) | ||
| * run the following: | ||
| .. code-block:: python | ||
| from disassemble import disassemble_file | ||
| # then either: | ||
| disassemble_file('path/to/file.ulp') # normal mode | ||
| # or: | ||
| disassemble_file('path/to/file.ulp', True) # verbose mode |
9 changes: 9 additions & 0 deletionsdocs/index.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
4 changes: 3 additions & 1 deletiontests/00_unit_tests.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletionstests/03_disassembler_tests.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| #!/bin/bash | ||
| set -e | ||
| test_disassembling_a_file() { | ||
| local verbose | ||
| if [ "$1" == verbose ]; then | ||
| verbose=-v | ||
| echo -e "Testing disassembling a file in VERBOSE mode" | ||
| else | ||
| echo -e "Testing disassembling a file in NORMAL mode" | ||
| fi | ||
| testname=all_opcodes | ||
| fixture=fixtures/${testname}.S | ||
| echo -e "\tBuilding $fixture using micropython-esp32-ulp" | ||
| log_file="${testname}.log" | ||
| ulp_file="fixtures/${testname}.ulp" | ||
| micropython -m esp32_ulp $fixture 1>$log_file # generates $ulp_file | ||
| lst_file="${testname}.lst" | ||
| lst_file_fixture=fixtures/${testname}${verbose}.lst | ||
| echo -e "\tDisassembling $ulp_file using micropython-esp32-ulp disassembler" | ||
| micropython tools/disassemble.py $verbose $ulp_file > $lst_file | ||
| if ! diff $lst_file_fixture $lst_file 1>/dev/null; then | ||
| echo -e "\tDisassembled output differs from expected output!" | ||
| echo "" | ||
| echo "Disassembly test failed for $fixture" | ||
| echo "micropython-esp32-ulp log:" | ||
| cat $log_file | ||
| echo "Diff of disassembly: expected vs actual" | ||
| diff -u $lst_file_fixture $lst_file | ||
| fi | ||
| } | ||
| test_disassembling_a_manual_sequence() { | ||
| local verbose | ||
| if [ "$1" == verbose ]; then | ||
| verbose=-v | ||
| echo -e "Testing disassembling a manual byte sequence in VERBOSE mode" | ||
| else | ||
| echo -e "Testing disassembling a manual byte sequence in NORMAL mode" | ||
| fi | ||
| sequence="e1af 8c72 0100 0068 2705 cc19 0005 681d 0000 00a0 0000 0074" | ||
| lst_file="manual_bytes.lst" | ||
| lst_file_fixture=fixtures/manual_bytes${verbose}.lst | ||
| echo -e "\tDisassembling manual byte sequence using micropython-esp32-ulp disassembler" | ||
| micropython tools/disassemble.py $verbose -m $sequence > $lst_file | ||
| if ! diff $lst_file_fixture $lst_file 1>/dev/null; then | ||
| echo -e "\tDisassembled output differs from expected output!" | ||
| echo "" | ||
| echo "Disassembly test failed for manual byte sequence" | ||
| echo "Diff of disassembly: expected vs actual" | ||
| diff -u $lst_file_fixture $lst_file | ||
| fi | ||
| } | ||
| test_disassembling_a_file | ||
| test_disassembling_a_file verbose | ||
| test_disassembling_a_manual_sequence | ||
| test_disassembling_a_manual_sequence verbose |
Oops, something went wrong.
Uh oh!
There was an error while loading.Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.