This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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 , \



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]