program.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. package x86_64
  2. import (
  3. `fmt`
  4. `math`
  5. `math/bits`
  6. `github.com/chenzhuoyu/iasm/expr`
  7. )
  8. type (
  9. _PseudoType int
  10. _InstructionEncoder func(*Program, ...interface{}) *Instruction
  11. )
  12. const (
  13. _PseudoNop _PseudoType = iota + 1
  14. _PseudoByte
  15. _PseudoWord
  16. _PseudoLong
  17. _PseudoQuad
  18. _PseudoData
  19. _PseudoAlign
  20. )
  21. func (self _PseudoType) String() string {
  22. switch self {
  23. case _PseudoNop : return ".nop"
  24. case _PseudoByte : return ".byte"
  25. case _PseudoWord : return ".word"
  26. case _PseudoLong : return ".long"
  27. case _PseudoQuad : return ".quad"
  28. case _PseudoData : return ".data"
  29. case _PseudoAlign : return ".align"
  30. default : panic("unreachable")
  31. }
  32. }
  33. type _Pseudo struct {
  34. kind _PseudoType
  35. data []byte
  36. uint uint64
  37. expr *expr.Expr
  38. }
  39. func (self *_Pseudo) free() {
  40. if self.expr != nil {
  41. self.expr.Free()
  42. }
  43. }
  44. func (self *_Pseudo) encode(m *[]byte, pc uintptr) int {
  45. switch self.kind {
  46. case _PseudoNop : return 0
  47. case _PseudoByte : self.encodeByte(m) ; return 1
  48. case _PseudoWord : self.encodeWord(m) ; return 2
  49. case _PseudoLong : self.encodeLong(m) ; return 4
  50. case _PseudoQuad : self.encodeQuad(m) ; return 8
  51. case _PseudoData : self.encodeData(m) ; return len(self.data)
  52. case _PseudoAlign : self.encodeAlign(m, pc) ; return self.alignSize(pc)
  53. default : panic("invalid pseudo instruction")
  54. }
  55. }
  56. func (self *_Pseudo) evalExpr(low int64, high int64) int64 {
  57. if v, err := self.expr.Evaluate(); err != nil {
  58. panic(err)
  59. } else if v < low || v > high {
  60. panic(fmt.Sprintf("expression out of range [%d, %d]: %d", low, high, v))
  61. } else {
  62. return v
  63. }
  64. }
  65. func (self *_Pseudo) alignSize(pc uintptr) int {
  66. if !ispow2(self.uint) {
  67. panic(fmt.Sprintf("aligment should be a power of 2, not %d", self.uint))
  68. } else {
  69. return align(int(pc), bits.TrailingZeros64(self.uint)) - int(pc)
  70. }
  71. }
  72. func (self *_Pseudo) encodeData(m *[]byte) {
  73. if m != nil {
  74. *m = append(*m, self.data...)
  75. }
  76. }
  77. func (self *_Pseudo) encodeByte(m *[]byte) {
  78. if m != nil {
  79. append8(m, byte(self.evalExpr(math.MinInt8, math.MaxUint8)))
  80. }
  81. }
  82. func (self *_Pseudo) encodeWord(m *[]byte) {
  83. if m != nil {
  84. append16(m, uint16(self.evalExpr(math.MinInt16, math.MaxUint16)))
  85. }
  86. }
  87. func (self *_Pseudo) encodeLong(m *[]byte) {
  88. if m != nil {
  89. append32(m, uint32(self.evalExpr(math.MinInt32, math.MaxUint32)))
  90. }
  91. }
  92. func (self *_Pseudo) encodeQuad(m *[]byte) {
  93. if m != nil {
  94. if v, err := self.expr.Evaluate(); err != nil {
  95. panic(err)
  96. } else {
  97. append64(m, uint64(v))
  98. }
  99. }
  100. }
  101. func (self *_Pseudo) encodeAlign(m *[]byte, pc uintptr) {
  102. if m != nil {
  103. if self.expr == nil {
  104. expandmm(m, self.alignSize(pc), 0)
  105. } else {
  106. expandmm(m, self.alignSize(pc), byte(self.evalExpr(math.MinInt8, math.MaxUint8)))
  107. }
  108. }
  109. }
  110. // Operands represents a sequence of operand required by an instruction.
  111. type Operands [_N_args]interface{}
  112. // InstructionDomain represents the domain of an instruction.
  113. type InstructionDomain uint8
  114. const (
  115. DomainGeneric InstructionDomain = iota
  116. DomainMMXSSE
  117. DomainAVX
  118. DomainFMA
  119. DomainCrypto
  120. DomainMask
  121. DomainAMDSpecific
  122. DomainMisc
  123. DomainPseudo
  124. )
  125. type (
  126. _BranchType uint8
  127. )
  128. const (
  129. _B_none _BranchType = iota
  130. _B_conditional
  131. _B_unconditional
  132. )
  133. // Instruction represents an unencoded instruction.
  134. type Instruction struct {
  135. next *Instruction
  136. pc uintptr
  137. nb int
  138. len int
  139. argc int
  140. name string
  141. argv Operands
  142. forms [_N_forms]_Encoding
  143. pseudo _Pseudo
  144. branch _BranchType
  145. domain InstructionDomain
  146. prefix []byte
  147. }
  148. func (self *Instruction) add(flags int, encoder func(m *_Encoding, v []interface{})) {
  149. self.forms[self.len].flags = flags
  150. self.forms[self.len].encoder = encoder
  151. self.len++
  152. }
  153. func (self *Instruction) free() {
  154. self.clear()
  155. self.pseudo.free()
  156. freeInstruction(self)
  157. }
  158. func (self *Instruction) clear() {
  159. for i := 0; i < self.argc; i++ {
  160. if v, ok := self.argv[i].(Disposable); ok {
  161. v.Free()
  162. }
  163. }
  164. }
  165. func (self *Instruction) check(e *_Encoding) bool {
  166. if (e.flags & _F_rel1) != 0 {
  167. return isRel8(self.argv[0])
  168. } else if (e.flags & _F_rel4) != 0 {
  169. return isRel32(self.argv[0]) || isLabel(self.argv[0])
  170. } else {
  171. return true
  172. }
  173. }
  174. func (self *Instruction) encode(m *[]byte) int {
  175. n := math.MaxInt64
  176. p := (*_Encoding)(nil)
  177. /* encode prefixes if any */
  178. if self.nb = len(self.prefix); m != nil {
  179. *m = append(*m, self.prefix...)
  180. }
  181. /* check for pseudo-instructions */
  182. if self.pseudo.kind != 0 {
  183. self.nb += self.pseudo.encode(m, self.pc)
  184. return self.nb
  185. }
  186. /* find the shortest encoding */
  187. for i := 0; i < self.len; i++ {
  188. if e := &self.forms[i]; self.check(e) {
  189. if v := e.encode(self.argv[:self.argc]); v < n {
  190. n = v
  191. p = e
  192. }
  193. }
  194. }
  195. /* add to buffer if needed */
  196. if m != nil {
  197. *m = append(*m, p.bytes[:n]...)
  198. }
  199. /* update the instruction length */
  200. self.nb += n
  201. return self.nb
  202. }
  203. /** Instruction Prefixes **/
  204. const (
  205. _P_cs = 0x2e
  206. _P_ds = 0x3e
  207. _P_es = 0x26
  208. _P_fs = 0x64
  209. _P_gs = 0x65
  210. _P_ss = 0x36
  211. _P_lock = 0xf0
  212. )
  213. // CS overrides the memory operation of this instruction to CS.
  214. func (self *Instruction) CS() *Instruction {
  215. self.prefix = append(self.prefix, _P_cs)
  216. return self
  217. }
  218. // DS overrides the memory operation of this instruction to DS,
  219. // this is the default section for most instructions if not specified.
  220. func (self *Instruction) DS() *Instruction {
  221. self.prefix = append(self.prefix, _P_ds)
  222. return self
  223. }
  224. // ES overrides the memory operation of this instruction to ES.
  225. func (self *Instruction) ES() *Instruction {
  226. self.prefix = append(self.prefix, _P_es)
  227. return self
  228. }
  229. // FS overrides the memory operation of this instruction to FS.
  230. func (self *Instruction) FS() *Instruction {
  231. self.prefix = append(self.prefix, _P_fs)
  232. return self
  233. }
  234. // GS overrides the memory operation of this instruction to GS.
  235. func (self *Instruction) GS() *Instruction {
  236. self.prefix = append(self.prefix, _P_gs)
  237. return self
  238. }
  239. // SS overrides the memory operation of this instruction to SS.
  240. func (self *Instruction) SS() *Instruction {
  241. self.prefix = append(self.prefix, _P_ss)
  242. return self
  243. }
  244. // LOCK causes the processor's LOCK# signal to be asserted during execution of
  245. // the accompanying instruction (turns the instruction into an atomic instruction).
  246. // In a multiprocessor environment, the LOCK# signal insures that the processor
  247. // has exclusive use of any shared memory while the signal is asserted.
  248. func (self *Instruction) LOCK() *Instruction {
  249. self.prefix = append(self.prefix, _P_lock)
  250. return self
  251. }
  252. /** Basic Instruction Properties **/
  253. // Name returns the instruction name.
  254. func (self *Instruction) Name() string {
  255. return self.name
  256. }
  257. // Domain returns the domain of this instruction.
  258. func (self *Instruction) Domain() InstructionDomain {
  259. return self.domain
  260. }
  261. // Operands returns the operands of this instruction.
  262. func (self *Instruction) Operands() []interface{} {
  263. return self.argv[:self.argc]
  264. }
  265. // Program represents a sequence of instructions.
  266. type Program struct {
  267. arch *Arch
  268. head *Instruction
  269. tail *Instruction
  270. }
  271. const (
  272. _N_near = 2 // near-branch (-128 ~ +127) takes 2 bytes to encode
  273. _N_far_cond = 6 // conditional far-branch takes 6 bytes to encode
  274. _N_far_uncond = 5 // unconditional far-branch takes 5 bytes to encode
  275. )
  276. func (self *Program) clear() {
  277. for p, q := self.head, self.head; p != nil; p = q {
  278. q = p.next
  279. p.free()
  280. }
  281. }
  282. func (self *Program) alloc(name string, argc int, argv Operands) *Instruction {
  283. p := self.tail
  284. q := newInstruction(name, argc, argv)
  285. /* attach to tail if any */
  286. if p != nil {
  287. p.next = q
  288. } else {
  289. self.head = q
  290. }
  291. /* set the new tail */
  292. self.tail = q
  293. return q
  294. }
  295. func (self *Program) pseudo(kind _PseudoType) (p *Instruction) {
  296. p = self.alloc(kind.String(), 0, Operands{})
  297. p.domain = DomainPseudo
  298. p.pseudo.kind = kind
  299. return
  300. }
  301. func (self *Program) require(isa ISA) {
  302. if !self.arch.HasISA(isa) {
  303. panic("ISA '" + isa.String() + "' was not enabled")
  304. }
  305. }
  306. func (self *Program) branchSize(p *Instruction) int {
  307. switch p.branch {
  308. case _B_none : panic("p is not a branch")
  309. case _B_conditional : return _N_far_cond
  310. case _B_unconditional : return _N_far_uncond
  311. default : panic("invalid instruction")
  312. }
  313. }
  314. /** Pseudo-Instructions **/
  315. // Byte is a pseudo-instruction to add raw byte to the assembled code.
  316. func (self *Program) Byte(v *expr.Expr) (p *Instruction) {
  317. p = self.pseudo(_PseudoByte)
  318. p.pseudo.expr = v
  319. return
  320. }
  321. // Word is a pseudo-instruction to add raw uint16 as little-endian to the assembled code.
  322. func (self *Program) Word(v *expr.Expr) (p *Instruction) {
  323. p = self.pseudo(_PseudoWord)
  324. p.pseudo.expr = v
  325. return
  326. }
  327. // Long is a pseudo-instruction to add raw uint32 as little-endian to the assembled code.
  328. func (self *Program) Long(v *expr.Expr) (p *Instruction) {
  329. p = self.pseudo(_PseudoLong)
  330. p.pseudo.expr = v
  331. return
  332. }
  333. // Quad is a pseudo-instruction to add raw uint64 as little-endian to the assembled code.
  334. func (self *Program) Quad(v *expr.Expr) (p *Instruction) {
  335. p = self.pseudo(_PseudoQuad)
  336. p.pseudo.expr = v
  337. return
  338. }
  339. // Data is a pseudo-instruction to add raw bytes to the assembled code.
  340. func (self *Program) Data(v []byte) (p *Instruction) {
  341. p = self.pseudo(_PseudoData)
  342. p.pseudo.data = v
  343. return
  344. }
  345. // Align is a pseudo-instruction to ensure the PC is aligned to a certain value.
  346. func (self *Program) Align(align uint64, padding *expr.Expr) (p *Instruction) {
  347. p = self.pseudo(_PseudoAlign)
  348. p.pseudo.uint = align
  349. p.pseudo.expr = padding
  350. return
  351. }
  352. /** Program Assembler **/
  353. // Free returns the Program object into pool.
  354. // Any operation performed after Free is undefined behavior.
  355. //
  356. // NOTE: This also frees all the instructions, labels, memory
  357. // operands and expressions associated with this program.
  358. //
  359. func (self *Program) Free() {
  360. self.clear()
  361. freeProgram(self)
  362. }
  363. // Link pins a label at the current position.
  364. func (self *Program) Link(p *Label) {
  365. if p.Dest != nil {
  366. panic("lable was alreay linked")
  367. } else {
  368. p.Dest = self.pseudo(_PseudoNop)
  369. }
  370. }
  371. // Assemble assembles and links the entire program into machine code.
  372. func (self *Program) Assemble(pc uintptr) (ret []byte) {
  373. orig := pc
  374. next := true
  375. offs := uintptr(0)
  376. /* Pass 0: PC-precompute, assume all labeled branches are far-branches. */
  377. for p := self.head; p != nil; p = p.next {
  378. if p.pc = pc; !isLabel(p.argv[0]) || p.branch == _B_none {
  379. pc += uintptr(p.encode(nil))
  380. } else {
  381. pc += uintptr(self.branchSize(p))
  382. }
  383. }
  384. /* allocate space for the machine code */
  385. nb := int(pc - orig)
  386. ret = make([]byte, 0, nb)
  387. /* Pass 1: adjust all the jumps */
  388. for next {
  389. next = false
  390. offs = uintptr(0)
  391. /* scan all the branches */
  392. for p := self.head; p != nil; p = p.next {
  393. var ok bool
  394. var lb *Label
  395. /* re-calculate the alignment here */
  396. if nb = p.nb; p.pseudo.kind == _PseudoAlign {
  397. p.pc -= offs
  398. offs += uintptr(nb - p.encode(nil))
  399. continue
  400. }
  401. /* adjust the program counter */
  402. p.pc -= offs
  403. lb, ok = p.argv[0].(*Label)
  404. /* only care about labeled far-branches */
  405. if !ok || p.nb == _N_near || p.branch == _B_none {
  406. continue
  407. }
  408. /* calculate the jump offset */
  409. size := self.branchSize(p)
  410. diff := lb.offset(p.pc, size)
  411. /* too far to be a near jump */
  412. if diff > 127 || diff < -128 {
  413. p.nb = size
  414. continue
  415. }
  416. /* a far jump becomes a near jump, calculate
  417. * the PC adjustment value and assemble again */
  418. next = true
  419. p.nb = _N_near
  420. offs += uintptr(size - _N_near)
  421. }
  422. }
  423. /* Pass 3: link all the cross-references */
  424. for p := self.head; p != nil; p = p.next {
  425. for i := 0; i < p.argc; i++ {
  426. var ok bool
  427. var lb *Label
  428. var op *MemoryOperand
  429. /* resolve labels */
  430. if lb, ok = p.argv[i].(*Label); ok {
  431. p.argv[i] = lb.offset(p.pc, p.nb)
  432. continue
  433. }
  434. /* check for memory operands */
  435. if op, ok = p.argv[i].(*MemoryOperand); !ok {
  436. continue
  437. }
  438. /* check for label references */
  439. if op.Addr.Type != Reference {
  440. continue
  441. }
  442. /* replace the label with the real offset */
  443. op.Addr.Type = Offset
  444. op.Addr.Offset = op.Addr.Reference.offset(p.pc, p.nb)
  445. }
  446. }
  447. /* Pass 4: actually encode all the instructions */
  448. for p := self.head; p != nil; p = p.next {
  449. p.encode(&ret)
  450. }
  451. /* all done */
  452. return ret
  453. }
  454. // AssembleAndFree is like Assemble, but it frees the Program after assembling.
  455. func (self *Program) AssembleAndFree(pc uintptr) (ret []byte) {
  456. ret = self.Assemble(pc)
  457. self.Free()
  458. return
  459. }