This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] S/390: Fix objdump output of larl operand
- From: "Andreas Krebbel" <krebbel at linux dot vnet dot ibm dot com>
- To: binutils at sourceware dot org
- Cc: schwidefsky at de dot ibm dot com
- Date: Tue, 8 Sep 2009 16:00:13 +0200
- Subject: [PATCH] S/390: Fix objdump output of larl operand
Hi,
on S/390 objdump prints out the larl instruction with a sometimes
corrupted address operand:
800003b0: c0 10 bf ff fe 28 larl %r1,100000000 <_end+0x7ff6b050>
The operand should be zero in that case. This is caused by trying to
calculate the value in a 32bit integer. The operand is already 32
bits wide and has to be multiplied by two in order to get the correct
value.
The attached patch fixes this by using a long instead.
Tested on s390x. No regressions.
Ok to apply?
Bye,
-Andreas-
2009-09-08 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* s390-dis.c (s390_extract_operand): Change the return type to
long and also work internally with a long type value.
(print_insn_s390): Adjusted to the changed return type of
s390_extract_operand.
Index: opcodes/s390-dis.c
===================================================================
--- opcodes/s390-dis.c.orig 2009-09-08 14:58:09.000000000 +0200
+++ opcodes/s390-dis.c 2009-09-08 15:48:53.000000000 +0200
@@ -82,10 +82,10 @@ init_disasm (struct disassemble_info *in
/* Extracts an operand value from an instruction. */
-static inline unsigned int
+static inline long
s390_extract_operand (unsigned char *insn, const struct s390_operand *operand)
{
- unsigned int val;
+ long val;
int bits;
/* Extract fragments of the operand byte for byte. */
@@ -100,7 +100,7 @@ s390_extract_operand (unsigned char *ins
}
while (bits > 0);
val >>= -bits;
- val &= ((1U << (operand->bits - 1)) << 1) - 1;
+ val &= ((1UL << (operand->bits - 1)) << 1) - 1;
/* Check for special long displacement case. */
if (operand->bits == 20 && operand->shift == 20)
@@ -108,8 +108,8 @@ s390_extract_operand (unsigned char *ins
/* Sign extend value if the operand is signed or pc relative. */
if ((operand->flags & (S390_OPERAND_SIGNED | S390_OPERAND_PCREL))
- && (val & (1U << (operand->bits - 1))))
- val |= (-1U << (operand->bits - 1)) << 1;
+ && (val & (1UL << (operand->bits - 1))))
+ val |= (-1UL << (operand->bits - 1)) << 1;
/* Double value if the operand is pc relative. */
if (operand->flags & S390_OPERAND_PCREL)
@@ -196,7 +196,7 @@ print_insn_s390 (bfd_vma memaddr, struct
separator = 0;
for (opindex = opcode->operands; *opindex != 0; opindex++)
{
- unsigned int value;
+ long value;
operand = s390_operands + *opindex;
value = s390_extract_operand (buffer, operand);
@@ -214,19 +214,19 @@ print_insn_s390 (bfd_vma memaddr, struct
(*info->fprintf_func) (info->stream, "%c", separator);
if (operand->flags & S390_OPERAND_GPR)
- (*info->fprintf_func) (info->stream, "%%r%i", value);
+ (*info->fprintf_func) (info->stream, "%%r%li", value);
else if (operand->flags & S390_OPERAND_FPR)
- (*info->fprintf_func) (info->stream, "%%f%i", value);
+ (*info->fprintf_func) (info->stream, "%%f%li", value);
else if (operand->flags & S390_OPERAND_AR)
- (*info->fprintf_func) (info->stream, "%%a%i", value);
+ (*info->fprintf_func) (info->stream, "%%a%li", value);
else if (operand->flags & S390_OPERAND_CR)
- (*info->fprintf_func) (info->stream, "%%c%i", value);
+ (*info->fprintf_func) (info->stream, "%%c%li", value);
else if (operand->flags & S390_OPERAND_PCREL)
- (*info->print_address_func) (memaddr + (int) value, info);
+ (*info->print_address_func) (memaddr + value, info);
else if (operand->flags & S390_OPERAND_SIGNED)
- (*info->fprintf_func) (info->stream, "%i", (int) value);
+ (*info->fprintf_func) (info->stream, "%li", value);
else
- (*info->fprintf_func) (info->stream, "%u", value);
+ (*info->fprintf_func) (info->stream, "%lu", value);
if (operand->flags & S390_OPERAND_DISP)
{