You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

187 regels
4.4 KiB

  1. // Copyright 2018 Google Inc. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Package arch contains architecture-specific definitions.
  15. package arch
  16. import (
  17. "encoding/binary"
  18. "math"
  19. )
  20. const MaxBreakpointSize = 4 // TODO
  21. // Architecture defines the architecture-specific details for a given machine.
  22. type Architecture struct {
  23. // BreakpointSize is the size of a breakpoint instruction, in bytes.
  24. BreakpointSize int
  25. // IntSize is the size of the int type, in bytes.
  26. IntSize int
  27. // PointerSize is the size of a pointer, in bytes.
  28. PointerSize int
  29. // ByteOrder is the byte order for ints and pointers.
  30. ByteOrder binary.ByteOrder
  31. // FloatByteOrder is the byte order for floats.
  32. FloatByteOrder binary.ByteOrder
  33. BreakpointInstr [MaxBreakpointSize]byte
  34. }
  35. func (a *Architecture) Int(buf []byte) int64 {
  36. return int64(a.Uint(buf))
  37. }
  38. func (a *Architecture) Uint(buf []byte) uint64 {
  39. if len(buf) != a.IntSize {
  40. panic("bad IntSize")
  41. }
  42. switch a.IntSize {
  43. case 4:
  44. return uint64(a.ByteOrder.Uint32(buf[:4]))
  45. case 8:
  46. return a.ByteOrder.Uint64(buf[:8])
  47. }
  48. panic("no IntSize")
  49. }
  50. func (a *Architecture) Int16(buf []byte) int16 {
  51. return int16(a.Uint16(buf))
  52. }
  53. func (a *Architecture) Int32(buf []byte) int32 {
  54. return int32(a.Uint32(buf))
  55. }
  56. func (a *Architecture) Int64(buf []byte) int64 {
  57. return int64(a.Uint64(buf))
  58. }
  59. func (a *Architecture) Uint16(buf []byte) uint16 {
  60. return a.ByteOrder.Uint16(buf)
  61. }
  62. func (a *Architecture) Uint32(buf []byte) uint32 {
  63. return a.ByteOrder.Uint32(buf)
  64. }
  65. func (a *Architecture) Uint64(buf []byte) uint64 {
  66. return a.ByteOrder.Uint64(buf)
  67. }
  68. func (a *Architecture) IntN(buf []byte) int64 {
  69. if len(buf) == 0 {
  70. return 0
  71. }
  72. x := int64(0)
  73. if a.ByteOrder == binary.LittleEndian {
  74. i := len(buf) - 1
  75. x = int64(int8(buf[i])) // sign-extended
  76. for i--; i >= 0; i-- {
  77. x <<= 8
  78. x |= int64(buf[i]) // not sign-extended
  79. }
  80. } else {
  81. x = int64(int8(buf[0])) // sign-extended
  82. for i := 1; i < len(buf); i++ {
  83. x <<= 8
  84. x |= int64(buf[i]) // not sign-extended
  85. }
  86. }
  87. return x
  88. }
  89. func (a *Architecture) UintN(buf []byte) uint64 {
  90. u := uint64(0)
  91. if a.ByteOrder == binary.LittleEndian {
  92. shift := uint(0)
  93. for _, c := range buf {
  94. u |= uint64(c) << shift
  95. shift += 8
  96. }
  97. } else {
  98. for _, c := range buf {
  99. u <<= 8
  100. u |= uint64(c)
  101. }
  102. }
  103. return u
  104. }
  105. func (a *Architecture) Uintptr(buf []byte) uint64 {
  106. if len(buf) != a.PointerSize {
  107. panic("bad PointerSize")
  108. }
  109. switch a.PointerSize {
  110. case 4:
  111. return uint64(a.ByteOrder.Uint32(buf[:4]))
  112. case 8:
  113. return a.ByteOrder.Uint64(buf[:8])
  114. }
  115. panic("no PointerSize")
  116. }
  117. func (a *Architecture) Float32(buf []byte) float32 {
  118. if len(buf) != 4 {
  119. panic("bad float32 size")
  120. }
  121. return math.Float32frombits(a.FloatByteOrder.Uint32(buf))
  122. }
  123. func (a *Architecture) Float64(buf []byte) float64 {
  124. if len(buf) != 8 {
  125. panic("bad float64 size")
  126. }
  127. return math.Float64frombits(a.FloatByteOrder.Uint64(buf))
  128. }
  129. func (a *Architecture) Complex64(buf []byte) complex64 {
  130. if len(buf) != 8 {
  131. panic("bad complex64 size")
  132. }
  133. return complex(a.Float32(buf[0:4]), a.Float32(buf[4:8]))
  134. }
  135. func (a *Architecture) Complex128(buf []byte) complex128 {
  136. if len(buf) != 16 {
  137. panic("bad complex128 size")
  138. }
  139. return complex(a.Float64(buf[0:8]), a.Float64(buf[8:16]))
  140. }
  141. var AMD64 = Architecture{
  142. BreakpointSize: 1,
  143. IntSize: 8,
  144. PointerSize: 8,
  145. ByteOrder: binary.LittleEndian,
  146. FloatByteOrder: binary.LittleEndian,
  147. BreakpointInstr: [MaxBreakpointSize]byte{0xCC}, // INT 3
  148. }
  149. var X86 = Architecture{
  150. BreakpointSize: 1,
  151. IntSize: 4,
  152. PointerSize: 4,
  153. ByteOrder: binary.LittleEndian,
  154. FloatByteOrder: binary.LittleEndian,
  155. BreakpointInstr: [MaxBreakpointSize]byte{0xCC}, // INT 3
  156. }
  157. var ARM = Architecture{
  158. BreakpointSize: 4, // TODO
  159. IntSize: 4,
  160. PointerSize: 4,
  161. ByteOrder: binary.LittleEndian,
  162. FloatByteOrder: binary.LittleEndian, // TODO
  163. BreakpointInstr: [MaxBreakpointSize]byte{0x00, 0x00, 0x00, 0x00}, // TODO
  164. }