question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

M68000 OperandTypes not being set properly

See original GitHub issue

Describe the bug For instructions where one of the operands is a register, the OperandTypes are not always set the same.

To Reproduce Steps to reproduce the behavior:

  1. In a Ghidra Script, iterate through instructions, and then through the the operands of each instruction.
  2. For each operand, print out the raw bitstring value of OperandType, in addition to Types that corresponds to.

Expected behavior Unless I am misunderstanding how these flags work, operands that are using the same addressing modes (e.g. offset from the address in a register) should have the same resulting operand types.

Screenshots

Here, the second operand is an address, but is not marked as one (output from my own script, attached)

instruction: move.b (0x070a079c).l,(0x4,A5)
    operand: [0x4, A5]
object type: <type 'ghidra.program.model.scalar.Scalar'>
object type: <type 'ghidra.program.model.lang.Register'>
  bitstring: 10000000000000000000000
operandtype: DYNAMIC

But here another operand is using the same addressing mode and is marked as an ADDRESS in addition to DYNAMIC

instruction: movea.l (-0x380,A6),A5
    operand: [-0x380, A6]
object type: <type 'ghidra.program.model.scalar.Scalar'>
object type: <type 'ghidra.program.model.lang.Register'>
  bitstring: 10000000010000000000000
operandtype: DYNAMIC, ADDRESS

Here is another example, where in one case a register is properly flagged as REGISTER,

instruction: move.l #0x288,D0
    operand: [D0]
object type: <type 'ghidra.program.model.lang.Register'>
  bitstring: 1000000000
operandtype: REGISTER

but here a register is not

instruction: mulu.l #0x406,D0
    operand: [D0]
object type: <type 'ghidra.program.model.lang.Register'>
  bitstring: 10000000000000000000000
operandtype: DYNAMIC

Attachments My (hacky) Ghidra script to print out this information:

# Print operand types for each operands
#
# @author balex
# @category M68K

from ghidra import *

# from https://ghidra.re/ghidra_docs/api/constant-values.html#ghidra.program.model.lang.OperandType
operand_type = {
  0: "READ",
  1: "WRITE",
  2: "INDIRECT",
  3: "IMMEDIATE",
  4: "RELATIVE",
  5: "IMPLICIT",
  6: "CODE",
  7: "DATA",
  8: "PORT",
  9: "REGISTER",
  10: "LIST",
  11: "FLAG",
  12: "TEXT",
  13: "ADDRESS",
  14: "SCALAR",
  15: "BIT",
  16: "BYTE",
  17: "WORD",
  18: "QUADWORD",
  19: "SIGNED",
  20: "FLOAT",
  21: "COP",
  22: "DYNAMIC"
}

def get_types(value):
    bitstr = "{0:b}".format(value)
    length = len(bitstr)
    print("  bitstring: " + bitstr)

    types = list()
    for i, bit in enumerate(bitstr):
        pos = length - i - 1
        if int(bit): types.append(operand_type[pos])

    return types

listing = currentProgram.getListing()

fm = currentProgram.getFunctionManager()
for func in fm.getFunctions(True):
    addr = func.getBody()
    instructs = listing.getInstructions(addr, True)

    for ins in instructs:
        for i in range(ins.getNumOperands()):
            oper = ins.getOpObjects(i)
            if len(oper):
                print("================")
                print('instruction: ' + str(ins))
                print('    operand: ' + str(list(oper)))
                for obj in oper:
                    print('object type: ' + str(type(obj)))
                print('operandtype: ' + ', '.join(get_types(ins.getOperandType(i))))

Environment (please complete the following information):

  • OS: Manjaro Linux 21.2.6
  • Java Version: 18.0.1.1
  • Ghidra Version: 10.1.3
  • Ghidra Origin: pacman

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
ghidra1commented, Jun 29, 2022

@alex-bellon API appears to be working as intended - albeit confusing at times. Closing ticket, but feel free to add comments/questions if you like.

0reactions
ghidra1commented, Jun 29, 2022

Case 1: For your movea.l (-0x380,A6),A5 case the presence of a memory/stack/external reference on the first operand will cause the addition of the ADDRESS type to what the instruction prototype generated (i.e., DYNAMIC). This reference is likely missing from the second. Analysis in some case is able to determine the resulting address associated with a computed operand and add such a reference.

Case 2: The move.l #0x288,D0 uses a simple register attach on the operand while the later one mulu.l #0x406,D0 uses submul which does not export a value for the operand. Without more investigation it is unclear to me why this mulu.l instruction has been implemented in such a complex manner.

:mul^mulsize e2l,submul		is opbig=0x4c & op67=0 & $(DAT_ALTER_ADDR_MODES); submul & mulsize; e2l [ savmod2=savmod1; regtsan=regtfan; ] { glbdenom=e2l; build submul; }

submul: regdq			is regdq & divsgn=0 & divsz=0				{ regdq = glbdenom * regdq; resflags(regdq); CF=0; }
submul: regdr-regdq		is regdq & divsgn=0 & divsz=1 & regdr			{ tmp1:8 = zext(glbdenom); tmp2:8 = zext(regdq); local res=tmp1*tmp2; regdq=res:4;

The DYNAMIC type is a default if no other specific type can be determined.

You can also look into the Instruction.getDefaultOperandRepresentationList(int operand) which will include objects such as Scalar, Address, Register which are specific to what you see rendered for an operand. This method avoids any extra markup which may occur when formatted for the listing display.

Read more comments on GitHub >

github_iconTop Results From Across the Web

M68000 Family Programmer's Reference Manual - NXP
This manual contains detailed information about software instructions used by the microprocessors and coprocessors in the M68000 family, including: MC68000.
Read more >
68000 TRICKS AND TRAPS - EASy68K
For no apparent reason, the CLR instruction always reads from an operand before clearing it. But unlike BCLR, CLR doesn't set the condition...
Read more >
Language processors for the Motorola M68000 microprocessor
The Motorola M68000 Microprocessor. 3. 2.1. Data Types. 3. 2.2. Registers. 3. 2.3. Addressing Modes. 4. 2.4. Operand Representation in ...
Read more >
GNU Compiler Collection (GCC) Internals
An immediate integer operand with a known numeric value is allowed. Many systems cannot support assembly-time constants for operands less than a word...
Read more >
Motorola 68000 - Wikipedia
The Motorola 68000 is a 16/32-bit complex instruction set computer (CISC) microprocessor, introduced in 1979 by Motorola Semiconductor Products Sector.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found