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:
Родитель
00200b7164
Коммит
13eedde411
|
@ -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>:")
|
||||
|
|
Загрузка…
Ссылка в новой задаче