github.com/cloudwego/iasm@v0.2.0/repl/display.go (about)

     1  //
     2  // Copyright 2024 CloudWeGo Authors
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  //
    16  
    17  package repl
    18  
    19  import (
    20      `fmt`
    21      `strings`
    22      `unicode`
    23  )
    24  
    25  func vector(v []byte, indent int) string {
    26      n := len(v)
    27      m := make([]string, 0, len(v))
    28  
    29      /* convert each element */
    30      for i := 0; i < n; i++ {
    31          if i == 0 || (i & 15) != 0 {
    32              m = append(m, fmt.Sprintf("0x%02x", v[n - i - 1]))
    33          } else {
    34              m = append(m, fmt.Sprintf("\n%s0x%02x", strings.Repeat(" ", indent + 1), v[n - i - 1]))
    35          }
    36      }
    37  
    38      /* join them together */
    39      return fmt.Sprintf(
    40          "{%s}",
    41          strings.Join(m, ", "),
    42      )
    43  }
    44  
    45  func display(v byte) string {
    46      if !unicode.IsPrint(rune(v)) {
    47          return "."
    48      } else {
    49          return string(v)
    50      }
    51  }
    52  
    53  func vecdiff(v0 []byte, v1 []byte, indent int) string {
    54      return vector(v0, indent) + strings.Repeat(" ", indent - 2) + "->" + vector(v1, indent)
    55  }
    56  
    57  func asmdump(m []byte, pos uintptr, src string) string {
    58      row := -1
    59      ret := []string(nil)
    60  
    61      /* must have at least 1 byte */
    62      if len(m) == 0 {
    63          panic("empty instruction bytes")
    64      }
    65  
    66      /* convert all the bytes */
    67      for i, v := range m {
    68          if i % 7 != 0 {
    69              ret[row] = ret[row] + fmt.Sprintf(" %02x", v)
    70          } else {
    71              ret, row = append(ret, fmt.Sprintf("(%#06x) %02x", pos + uintptr(i), v)), row + 1
    72          }
    73      }
    74  
    75      /* pad the first line if needed */
    76      if n := len(m); n < 7 {
    77          ret[0] += strings.Repeat(" ", (7 - n) * 3)
    78      }
    79  
    80      /* add the source */
    81      ret[0] += "    " + src
    82      return strings.Join(ret, "\n")
    83  }
    84  
    85  func hexdump(buf []byte, start uintptr) string {
    86      off := 0
    87      nbs := len(buf)
    88      ret := []string(nil)
    89  
    90      /* dump the data, 16-byte loop */
    91      for nbs >= 16 {
    92          _ = buf[off + 15]
    93          ret = append(ret, fmt.Sprintf("%x:", start + uintptr(off)))
    94          ret = append(ret, fmt.Sprintf(" %02x %02x %02x %02x", buf[off +  0], buf[off +  1], buf[off +  2], buf[off +  3]))
    95          ret = append(ret, fmt.Sprintf(" %02x %02x %02x %02x", buf[off +  4], buf[off +  5], buf[off +  6], buf[off +  7]), " ")
    96          ret = append(ret, fmt.Sprintf(" %02x %02x %02x %02x", buf[off +  8], buf[off +  9], buf[off + 10], buf[off + 11]))
    97          ret = append(ret, fmt.Sprintf(" %02x %02x %02x %02x", buf[off + 12], buf[off + 13], buf[off + 14], buf[off + 15]), "  ")
    98  
    99          /* print the 16 characters */
   100          for i := 0; i < 16; i++ {
   101              ret = append(ret, display(buf[off + i]))
   102          }
   103  
   104          /* move to the next line */
   105          off = off + 16
   106          nbs = nbs - 16
   107          ret = append(ret, "\n")
   108      }
   109  
   110      /* still have more bytes */
   111      if nbs > 0 {
   112          ret = append(ret, fmt.Sprintf("%x:", start + uintptr(off)))
   113      }
   114  
   115      /* print the remaining bytes */
   116      for i := 0; i < nbs; i++ {
   117          if i != 7 {
   118              ret = append(ret, fmt.Sprintf(" %02x", buf[off + i]))
   119          } else {
   120              ret = append(ret, fmt.Sprintf(" %02x ", buf[off + i]))
   121          }
   122      }
   123  
   124      /* pad the last line */
   125      if nbs > 0 {
   126          if nbs < 8 {
   127              ret = append(ret, strings.Repeat(" ", (17 - int(nbs)) * 3))
   128          } else {
   129              ret = append(ret, strings.Repeat(" ", (17 - int(nbs)) * 3 - 1))
   130          }
   131      }
   132  
   133      /* print the last characters */
   134      for i := 0; i < nbs; i++ {
   135          ret = append(ret, display(buf[off + i]))
   136      }
   137  
   138      /* check the final terminator */
   139      if nbs <= 0 {
   140          return strings.Join(ret, "")
   141      } else {
   142          return strings.Join(append(ret, "\n"), "")
   143      }
   144  }