ppc64/ppc64asm: fix objdump tests

In short, these tests create an object file from a list of opcodes,
and expect objdump to generate exactly as many decoded opcodes.

Unfortunately, objdump generates two opcode entries for each invalid
prefixed instruction, which causes the the testing code to deadlock
itself.

For example, objdump decodes an invalid form of paddi like:

    .long ...
    addi ...

instead of something like:

    .quadword ...

Work around this by examing the primary opcode of any entry which
objdump reports as ".long", and skip over the next word if the
primary opcode is "1" (the prefix opcode). The test skips over
".long" entries, so it will continue to work as expected.

Change-Id: I9dd0fda10683f666aace4140b63e81fc0fea2ad0
Reviewed-on: https://go-review.googlesource.com/c/arch/+/418857
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Paul Murphy <murp@ibm.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
Paul E. Murphy 2022-07-20 13:26:21 -05:00 коммит произвёл Paul Murphy
Родитель 00200b7164
Коммит 13eedde411
2 изменённых файлов: 23 добавлений и 14 удалений

Просмотреть файл

@ -40,7 +40,7 @@ var (
// from an external disassembler's output.
type ExtInst struct {
addr uint32
enc [4]byte
enc [8]byte
nenc int
text string
}
@ -200,20 +200,25 @@ func writeInst(generate func(func([]byte))) (file string, f *os.File, size int,
defer w.Flush()
size = 0
generate(func(x []byte) {
if len(x) > 4 {
x = x[:4]
if len(x) != 4 && len(x) != 8 {
panic(fmt.Sprintf("Unexpected instruction %v\n", x))
}
izeros := zeros
if len(x) == 4 {
// Only pad to 4 bytes for a 4 byte instruction word.
izeros = izeros[4:]
}
if debug {
fmt.Printf("%#x: %x%x\n", start+size, x, zeros[len(x):])
fmt.Printf("%#x: %x%x\n", start+size, x, izeros[len(x):])
}
w.Write(x)
w.Write(zeros[len(x):])
size += len(zeros)
w.Write(izeros[len(x):])
size += len(izeros)
})
return file, f, size, nil
}
var zeros = []byte{0, 0, 0, 0}
var zeros = []byte{0, 0, 0, 0, 0, 0, 0, 0}
// pad pads the code sequence with pops.
func pad(enc []byte) []byte {

Просмотреть файл

@ -64,7 +64,7 @@ func objdump(ext *ExtDis) error {
reading bool
next uint32 = start
addr uint32
encbuf [4]byte
encbuf [8]byte
enc []byte
text string
)
@ -88,15 +88,19 @@ func objdump(ext *ExtDis) error {
text = "error: unknown instruction"
enc = nil
}
if len(enc) == 4 {
// prints as word but we want to record bytes
enc[0], enc[3] = enc[3], enc[0]
enc[1], enc[2] = enc[2], enc[1]
// Prefixed instructions may not decode as expected if
// they are an invalid form. Some are tested in decode.txt.
// objdump treats these like two instructions.
//
// Look for primary opcode 1 and advance an exta 4 bytes if
// this failed to decode.
if strings.HasPrefix(text, ".long") && enc[0]>>2 == 1 {
next += 4
}
ext.Dec <- ExtInst{addr, encbuf, len(enc), text}
encbuf = [4]byte{}
encbuf = [8]byte{}
next += uint32(len(enc))
enc = nil
next += 4
}
}
var textangle = []byte("<.text>:")