fix(asm): close the oracle parity gaps in frame addressing and calls
This commit is contained in:
+12
-4
@@ -515,6 +515,9 @@ func addSP(size int) []byte { // ADDQ $size, SP
|
||||
func instrSize(s *ast.Instr, fi frameInfo, long bool, link *linkInfo) (int, error) {
|
||||
mnem := strings.ToUpper(s.Mnemonic.Text)
|
||||
if isJumpMnemonic(mnem) {
|
||||
if (mnem == "CALL" || mnem == "JMP") && isSBCall(s) {
|
||||
return 5, nil // opcode + rel32, always the long form
|
||||
}
|
||||
return jumpSize(mnem, long), nil
|
||||
}
|
||||
code, _, err := encodeInstr(s, 0, nil, fi, false, nil, link)
|
||||
@@ -564,9 +567,10 @@ func encodeInstr(s *ast.Instr, pc int, offsets map[string]int, fi frameInfo, lon
|
||||
var ps []sbPatch
|
||||
var err error
|
||||
if isJumpMnemonic(mnem) {
|
||||
if mnem == "CALL" && isSBCall(s) {
|
||||
// CALL sym(SB): a rel32 call against a static or external
|
||||
// symbol, resolved by the file-level layout or the linker.
|
||||
if (mnem == "CALL" || mnem == "JMP") && isSBCall(s) {
|
||||
// CALL/JMP sym(SB): a rel32 call (or tail call) against a
|
||||
// static or external symbol, resolved by the file-level layout
|
||||
// or the linker.
|
||||
code, ps, err = encodeSBCall(s, link)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -678,8 +682,12 @@ func encodeSBCall(s *ast.Instr, link *linkInfo) ([]byte, []sbPatch, error) {
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("CALL: unsupported operand")
|
||||
}
|
||||
opcode := []byte{0xE8}
|
||||
if strings.ToUpper(s.Mnemonic.Text) == "JMP" {
|
||||
opcode = []byte{0xE9} // a tail call, no return address pushed
|
||||
}
|
||||
e := &enc{}
|
||||
if err := e.emit(&instr{opcode: []byte{0xE8}, modrm: -1, sib: -1, disp: le32(0), sb: &sbRef{name: m.name, addend: m.addend}}); err != nil {
|
||||
if err := e.emit(&instr{opcode: opcode, modrm: -1, sib: -1, disp: le32(0), sb: &sbRef{name: m.name, addend: m.addend}}); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
ps := make([]sbPatch, len(e.patches))
|
||||
|
||||
Reference in New Issue
Block a user