1#!@SHELL@ 2## A utility -*- sh -*- filter highlighting disassembled code with ANSI escapes 3## Copyright (C) 2017 Luca Saiu 4## Written by Luca Saiu 5 6## This file is part of Jitter. 7 8## Jitter is free software: you can redistribute it and/or modify 9## it under the terms of the GNU General Public License as published by 10## the Free Software Foundation, either version 3 of the License, or 11## (at your option) any later version. 12 13## Jitter is distributed in the hope that it will be useful, 14## but WITHOUT ANY WARRANTY; without even the implied warranty of 15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16## GNU General Public License for more details. 17 18## You should have received a copy of the GNU General Public License 19## along with Jitter. If not, see <http://www.gnu.org/licenses/>. 20 21 22# Warnings. 23# ################################################################ 24 25 26# This filter script is just provided as a convenience for debugging. It makes 27# no serious attempt at being portable, and may rely on the GNU utilities. It 28# accepts no arguments. 29 30# The intended way of using the script is as the last stage of a shell pipeline, 31# filtering the output of a Jitter VM program which is disassembling code. 32 33 34# Terminal escape sequence definitions. 35# ################################################################ 36 37ESC=$(echo -e '\033') 38 39BLACK=$ESC[0m$ESC[30m 40BLUE=$ESC[0m$ESC[34m 41GREEN=$ESC[0m$ESC[32m 42CYAN=$ESC[0m$ESC[36m 43RED=$ESC[0m$ESC[31m 44MAGENTA=$ESC[0m$ESC[35m 45BROWN=$ESC[0m$ESC[33m 46LIGHTGRAY=$ESC[0m$ESC[37m 47DARKGRAY=$ESC[1m$ESC[30m 48LIGHTBLUE=$ESC[1m$ESC[34m 49LIGHTGREEN=$ESC[1m$ESC[32m 50LIGHTCYAN=$ESC[1m$ESC[36m 51LIGHTRED=$ESC[1m$ESC[31m 52LIGHTMAGENTA=$ESC[1m$ESC[35m 53YELLOW=$ESC[1m$ESC[33m 54WHITE=$ESC[1m$ESC[37m 55 56NOATTR=$ESC[0m 57 58BOLD=$ESC[1m 59FAINT=$ESC[2m 60ITALIC=$ESC[3m 61CROSSOUT=$ESC[9m 62UNDERLINE=$ESC[4m 63 64export REVERSE=$ESC[7m 65# Depending on the terminal BLINK could brighten the background 66export SLOWBLINK=$ESC[5m 67 68# Unsupported on all the terminals I've tried: 69export FASTBLINK=$ESC[6m 70export FRAME=$ESC[51m 71export ENCIRCLE=$ESC[52m 72export OVERLINE=$ESC[53m 73 74export CLEAR=$ESC[2J 75export TOPLEFT=$ESC[1\;1H 76 77# This is for setting the title of an Xterm window: 78export BEGINTITLE=\\033]0; 79export ENDTITLE=\\007 80 81 82# Define which attributes are to be used for highlighting. 83# ################################################################ 84 85# Specialized instructions and threads. 86SPECIALIZED="$YELLOW" 87 88# Native instruction address. 89ADDRESS="$LIGHTMAGENTA" 90 91# Native instruction hexadecimal encoding. 92INSTRUCTION="$LIGHTGREEN" 93 94# Disassembled native instructions. 95DISASSEMBLY="$LIGHTCYAN" 96 97 98# Define sed commands. 99# ################################################################ 100 101# I can easily insert, display and edit tab characters in the source code with 102# Emacs, but inferior editors will have problem showing it. Let's define a 103# shell variable just for other people's sake. 104TAB=$(echo -e '\011') 105 106# Match entire lines starting with '#'; those contain specialized instructions, 107# with threads and arguments. 108COMMAND_SPECIALIZED="s/^\\(#.*\\)\$/${SPECIALIZED}\\1${NOATTR}/g" 109 110# Filter out space characters immediately preceding a tab character. This lets 111# me remove one redundant space at the end of the instruction encoding as 112# displayed by objdump. 113REMOVE_SPACES_BEFORE_TAB="s/ *${TAB}/${TAB}/g" 114 115# Match the more complex disassembly lines, in the format generated by objdump 116# --disassembly (and my own compatibile fallback hexadecimal dumper). 117# Each of these line starts indented with spaces (filtered out); then, in order: 118# * the native instruction address (the initial "0x" is filtered out); 119# * the instruction hexadecimal encoding, possibly with bytes separated by 120# spaces (on some architectures), and possibly with a final space; 121# * the instruction disassembly, preceded by a tab. 122COMMAND_NOT_SPECIALIZED="s/^\\( *\\)\\?\\(0x\\)\\?\\([0-9a-f]*\\):\\?\\( *\\)\\([^${TAB}]*\\)\\t\\(.*\\)\$/${ADDRESS}\\3${NOATTR}${TAB}${INSTRUCTION}\\5${NOATTR}${TAB}${DISASSEMBLY}\\6${NOATTR}/g" 123 124# Replace sequences of multiple whitespace characters containing a tab with a 125# single tab. Replace multiple consecutive spaces with a single space. 126NORMALIZE_WHITESPACE="s/ *${TAB} */${TAB}/g;s/ */ /g" 127 128# Replace the first two tabs in each line with a space (to keep the address and 129# instruction encoding visually close in each disassembly line) and an otherwise 130# unused character, respectively; then replace any remaining tab with a space 131# (this removes any tab in the disassembly part, making it narrower); replace 132# back any occurrence of the unused character with a tab, to restore the visual 133# separation between instruction encoding and disassembly. 134UNUSED=$(echo -e '\a') 135NORMALIZE_TABS="s/^\\([^${TAB}]*\\)${TAB}\\([^${TAB}]*\\)${TAB}\\(.*\\)\$/\\1 \\2${UNUSED}\\3/g;s/${TAB}/ /g;s/${UNUSED}/${TAB}/g" 136 137 138# Run a sed program obtained by concatenating commands. 139# ################################################################ 140 141# Read on stdin, write on stdout. 142@SED@ \ 143 "${REMOVE_SPACES_BEFORE_TAB}; 144 ${COMMAND_SPECIALIZED}; 145 ${COMMAND_NOT_SPECIALIZED}; 146 ${NORMALIZE_WHITESPACE}; 147 ${NORMALIZE_TABS}" 148