[PATCH, SH] Do not treat plain binary as sh3.

Takashi Yoshii yoshii.takashi@renesas.com
Fri Jun 6 09:15:00 GMT 2008


With binutils-2.18.50.0.6,
building linux kernel for sh2a (a variant of SuperH) fails.
I found the issue comes from a behavior of binutils that treat plain
binary as sh3, and I would like to propose to change it.

I hope the patch at the very bottom describes everything.
Currently, EF_SH_UNKNOWN is mapped to bfd_mach_sh3.
I believe it should be the minimum one, practically bfd_mach_sh.

I guess this was produced as a kind of backward compatibility to the
time when elf32-sh-linux didn't carry any ISA information.
But this should be fixed now. It is no longer suitable choice.

I hope it will be fixed after discussion about backward compatibility,
and possible side effects.

---
Latter part is an explanation of the issue happened.
This is linux kernel specific case, not a general one.
But for understanding, I try to explain it.

* Detailed explanation
(A) Binutils/sh related.
- SH has many ISA(instruction set architecture) variants.
   Some combinations of ISAs are linkable, others are not.
   sh2+sh3 are linkable, sh2a+sh3 are not.
- elf32-sh carry ISA information on its flags field.
- If elf has no ISA information, binutils treat it as sh3.

(B) SH Linux related.
- Linux kernel image(zImage) is a kind of self-expanding program.
   It consist of inflate program and compressed kernel, linked by ld.
- For sh2a, inflate program is elf object which is marked as sh2a,
   compressed kernel is a data, so it has no ISA information.

As a result of (A) and (B), ld operate as linking sh2a+sh3, and fails
building linux kernel image.

* Simplified reproduction procedure
$ echo nop | sh-linux-as --isa=sh2a -o a -
$ echo plain binary > x
$ sh-linux-ld -r --format binary --oformat elf32-sh-linux -o b x
$ sh-linux-ld -o z a b
|
|sh-linux-ld: internal error: merge of architecture 'sh2a' with
|architecture 'sh3' produced unknown architecture
|
|sh-linux-ld: b: uses instructions which are incompatible with
|instructions |used in previous modules
|sh-linux-ld: failed to merge target specific data of file b

* Some confirmation
$ sh-linux-readelf -h a b | grep Flags
|  Flags:                             0xd, sh2a
|  Flags:                             0x0
$ sh-linux-objdump -f a b | grep arch
|architecture: sh2a, flags 0x00000010:
|architecture: sh3, flags 0x00000010:

The "sh3" on last line is unwanted one. Difference between readelf and
objdump is not a problem (as described readelf's source code).

Regards,
/yoshii

diff -ur binutils-2.18.50.0.6.org/include/elf/sh.h 
binutils-2.18.50.0.6/include/elf/sh.h
--- binutils-2.18.50.0.6.org/include/elf/sh.h	2005-05-11 
07:46:52.000000000 +0900
+++ binutils-2.18.50.0.6/include/elf/sh.h	2008-05-21 14:32:26.000000000 
+0900
@@ -54,7 +54,7 @@
     bfd_mach_* are defined in bfd_in2.h (generated from
     archures.c).  */
  #define EF_SH_BFD_TABLE \
-/* EF_SH_UNKNOWN	*/ bfd_mach_sh3		, \
+/* EF_SH_UNKNOWN	*/ bfd_mach_sh		, \
  /* EF_SH1		*/ bfd_mach_sh		, \
  /* EF_SH2		*/ bfd_mach_sh2		, \
  /* EF_SH3		*/ bfd_mach_sh3		, \



More information about the Binutils mailing list