This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Add support for ARM ELF EABI versions
- To: binutils at sourceware dot cygnus dot com
- Subject: Add support for ARM ELF EABI versions
- From: Nick Clifton <nickc at cygnus dot com>
- Date: Thu, 6 Apr 2000 16:07:52 -0700
Hi Guys,
I am about to apply the following patch to binutils. It adds
support for the EABI version numbering for arm-elf ports, defined in
releases A-07 and A-08 of the ARM ELF specification.
It turns out that there is a conflict between these specifications
and the current implementation. The value for EF_ARM_SYMSARESORTED
is the same as that used for EF_INTERWORK. Since the ARM ELF spec
does not define EF_INTERWORK (or any of the other EF_xxx values used
by the arm-elf port) I have taken the decision of only decoding
these values if the EABI version number is set to 0 (ie unknown).
This means that the default behaviour of the toolchain will not
change.
In the future, of course, we will need to get official versions of
the EF_xxx values into the ARM ELF spec.
Phil - do you want me to apply this patch to the binutils branch ?
Cheers
Nick
[ChangeLog for include/elf]
2000-04-06 Nick Clifton <nickc@cygnus.com>
* arm.h (EF_ARM_SYMSARESORTED): Define.
(EF_ARM_EABIMASK): Define.
(EF_ARM_EABI_VERSION): Define.
(EF_ARM_EABI_UNKNOWN): Define.
(EF_ARM_EABI_VER1): Define.
[ChangeLog for bfd]
2000-04-06 Nick Clifton <nickc@cygnus.com>
* elf32-arm.h (elf32_arm_set_private_flags): Only check for
EF_INTERWORK if this is an unknown EABI.
(elf32_arm_merge_private_bfd_data): Check EABI version
numbers. Only check EF_xxx flags if the EABI version number
is unknown.
(elf32_arm_print_private_bfd_data): Only decode EF_xxx flags
if the EABI version number is unknown.
[ChangeLog for binutils]
2000-04-06 Nick Clifton <nickc@cygnus.com>
* readelf.c (decode_ARM_machine_flags): New function.
(get_machine_flags): Call decode_ARM_machine_flags for ARM
targets.
Index: include/elf/arm.h
===================================================================
RCS file: /cvs/src//src/include/elf/arm.h,v
retrieving revision 1.3
diff -p -r1.3 arm.h
*** arm.h 2000/01/27 20:05:27 1.3
--- arm.h 2000/04/06 22:53:42
***************
*** 34,39 ****
--- 34,47 ----
#define EF_OLD_ABI 0x100
#define EF_SOFT_FLOAT 0x200
+ /* Other constants defined in the ARM ELF spec. version A-08. */
+ #define EF_ARM_SYMSARESORTED 0x04 /* NB conflicts with EF_INTERWORK */
+ #define EF_ARM_EABIMASK 0xFF000000
+
+ #define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
+ #define EF_ARM_EABI_UNKNOWN 0x00000000
+ #define EF_ARM_EABI_VER1 0x01000000
+
/* Local aliases for some flags to match names used by COFF port. */
#define F_INTERWORK EF_INTERWORK
#define F_APCS26 EF_APCS_26
***************
*** 51,56 ****
--- 59,66 ----
/* ARM-specific program header flags. */
#define PF_ARM_SB 0x10000000 /* Segment contains the location addressed by the static base. */
+ #define PF_ARM_PI 0x20000000 /* Segment is position-independent. */
+ #define PF_ARM_ABS 0x40000000 /* Segment must be loaded at its base address. */
/* Relocation types. */
START_RELOC_NUMBERS (elf_arm_reloc_type)
Index: bfd/elf32-arm.h
===================================================================
RCS file: /cvs/src//src/bfd/elf32-arm.h,v
retrieving revision 1.25
diff -p -r1.25 elf32-arm.h
*** elf32-arm.h 2000/03/01 19:40:53 1.25
--- elf32-arm.h 2000/04/06 22:53:42
*************** elf32_arm_set_private_flags (abfd, flags
*** 1887,1900 ****
if (elf_flags_init (abfd)
&& elf_elfheader (abfd)->e_flags != flags)
{
! if (flags & EF_INTERWORK)
! _bfd_error_handler (_ ("\
Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"),
! bfd_get_filename (abfd));
! else
! _bfd_error_handler (_ ("\
Warning: Clearing the interwork flag of %s due to outside request"),
! bfd_get_filename (abfd));
}
else
{
--- 1905,1921 ----
if (elf_flags_init (abfd)
&& elf_elfheader (abfd)->e_flags != flags)
{
! if (EF_ARM_EABI_VERSION (flags) == EF_ARM_EABI_UNKNOWN)
! {
! if (flags & EF_INTERWORK)
! _bfd_error_handler (_ ("\
Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"),
! bfd_get_filename (abfd));
! else
! _bfd_error_handler (_ ("\
Warning: Clearing the interwork flag of %s due to outside request"),
! bfd_get_filename (abfd));
! }
}
else
{
*************** elf32_arm_merge_private_bfd_data (ibfd,
*** 2018,2058 ****
return true;
/* Complain about various flag mismatches. */
!
! if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
! _bfd_error_handler (_ ("\
Error: %s compiled for APCS-%d, whereas %s is compiled for APCS-%d"),
! bfd_get_filename (ibfd),
! in_flags & EF_APCS_26 ? 26 : 32,
! bfd_get_filename (obfd),
! out_flags & EF_APCS_26 ? 26 : 32);
! if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
! _bfd_error_handler (_ ("\
Error: %s passes floats in %s registers, whereas %s passes them in %s registers"),
! bfd_get_filename (ibfd),
! in_flags & EF_APCS_FLOAT ? _ ("float") : _ ("integer"),
! bfd_get_filename (obfd),
! out_flags & EF_APCS_26 ? _ ("float") : _ ("integer"));
! if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
! _bfd_error_handler (_ ("\
Error: %s is compiled as position %s code, whereas %s is not"),
! bfd_get_filename (ibfd),
! in_flags & EF_PIC ? _ ("independent") : _ ("dependent"),
! bfd_get_filename (obfd));
/* Interworking mismatch is only a warning. */
! if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
! {
! _bfd_error_handler (_ ("\
Warning: %s %s interworking, whereas %s %s"),
! bfd_get_filename (ibfd),
! in_flags & EF_INTERWORK ? _ ("supports") : _ ("does not support"),
! bfd_get_filename (obfd),
! out_flags & EF_INTERWORK ? _ ("does not") : _ ("does"));
! return true;
}
return false;
}
--- 2039,2094 ----
return true;
/* Complain about various flag mismatches. */
! if (EF_ARM_EABI_VERSION (in_flags) != EF_ARM_EABI_VERSION (out_flags))
! {
! _bfd_error_handler (_("\
! Error: %s compiled for EABI version %d, whereas %s is compiled for version %d"),
! bfd_get_filename (ibfd),
! (in_flags & EF_ARM_EABIMASK) >> 24,
! bfd_get_filename (obfd),
! (out_flags & EF_ARM_EABIMASK) >> 24);
! }
! else if (EF_ARM_EABI_VERSION (in_flags) == EF_ARM_EABI_UNKNOWN)
! {
! if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
! _bfd_error_handler (_ ("\
Error: %s compiled for APCS-%d, whereas %s is compiled for APCS-%d"),
! bfd_get_filename (ibfd),
! in_flags & EF_APCS_26 ? 26 : 32,
! bfd_get_filename (obfd),
! out_flags & EF_APCS_26 ? 26 : 32);
! if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT))
! _bfd_error_handler (_ ("\
Error: %s passes floats in %s registers, whereas %s passes them in %s registers"),
! bfd_get_filename (ibfd),
! in_flags & EF_APCS_FLOAT ? _ ("float") : _ ("integer"),
! bfd_get_filename (obfd),
! out_flags & EF_APCS_26 ? _ ("float") : _ ("integer"));
! if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
! _bfd_error_handler (_ ("\
Error: %s is compiled as position %s code, whereas %s is not"),
! bfd_get_filename (ibfd),
! in_flags & EF_PIC ? _ ("independent") : _ ("dependent"),
! bfd_get_filename (obfd));
/* Interworking mismatch is only a warning. */
! if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK))
! {
! _bfd_error_handler (_ ("\
Warning: %s %s interworking, whereas %s %s"),
! bfd_get_filename (ibfd),
! in_flags & EF_INTERWORK
! ? _ ("supports") : _ ("does not support"),
! bfd_get_filename (obfd),
! out_flags & EF_INTERWORK ? _ ("does not") : _ ("does"));
! return true;
! }
}
+ else
+ /* Not sure what needs to be checked for EABI versions >= 1. */
+ return true;
return false;
}
*************** elf32_arm_print_private_bfd_data (abfd,
*** 2063,2100 ****
bfd *abfd;
PTR ptr;
{
! FILE *file = (FILE *) ptr;
!
BFD_ASSERT (abfd != NULL && ptr != NULL);
/* Print normal ELF private data. */
_bfd_elf_print_private_bfd_data (abfd, ptr);
/* Ignore init flag - it may not be set, despite the flags field containing valid data. */
/* xgettext:c-format */
! fprintf (file, _ ("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
! if (elf_elfheader (abfd)->e_flags & EF_INTERWORK)
! fprintf (file, _ (" [interworking enabled]"));
! else
! fprintf (file, _ (" [interworking not enabled]"));
! if (elf_elfheader (abfd)->e_flags & EF_APCS_26)
! fprintf (file, _ (" [APCS-26]"));
! else
! fprintf (file, _ (" [APCS-32]"));
! if (elf_elfheader (abfd)->e_flags & EF_APCS_FLOAT)
! fprintf (file, _ (" [floats passed in float registers]"));
! else
! fprintf (file, _ (" [floats passed in integer registers]"));
! if (elf_elfheader (abfd)->e_flags & EF_PIC)
! fprintf (file, _ (" [position independent]"));
! else
! fprintf (file, _ (" [absolute position]"));
fputc ('\n', file);
return true;
--- 2099,2180 ----
bfd *abfd;
PTR ptr;
{
! FILE * file = (FILE *) ptr;
! unsigned long flags;
!
BFD_ASSERT (abfd != NULL && ptr != NULL);
/* Print normal ELF private data. */
_bfd_elf_print_private_bfd_data (abfd, ptr);
+ flags = elf_elfheader (abfd)->e_flags;
/* Ignore init flag - it may not be set, despite the flags field containing valid data. */
/* xgettext:c-format */
! fprintf (file, _ ("private flags = %lx:"), flags);
! switch (EF_ARM_EABI_VERSION (flags))
! {
! case EF_ARM_EABI_UNKNOWN:
! /* The following flag bits are GNU extenstions and not part of the
! official ARM ELF extended ABI. Hence they are only decoded if
! the EABI version is not set. */
! if (flags & EF_INTERWORK)
! fprintf (file, _ (" [interworking enabled]"));
!
! if (flags & EF_APCS_26)
! fprintf (file, _ (" [APCS-26]"));
! else
! fprintf (file, _ (" [APCS-32]"));
!
! if (flags & EF_APCS_FLOAT)
! fprintf (file, _ (" [floats passed in float registers]"));
!
! if (flags & EF_PIC)
! fprintf (file, _ (" [position independent]"));
! if (flags & EF_NEW_ABI)
! fprintf (file, _ (" [new ABI]"));
!
! if (flags & EF_OLD_ABI)
! fprintf (file, _ (" [old ABI]"));
!
! if (flags & EF_SOFT_FLOAT)
! fprintf (file, _ (" [software FP]"));
!
! flags &= ~(EF_INTERWORK | EF_APCS_26 | EF_APCS_FLOAT | EF_PIC
! | EF_NEW_ABI | EF_OLD_ABI | EF_SOFT_FLOAT);
! break;
!
! case EF_ARM_EABI_VER1:
! fprintf (file, _ (" [Version1 EABI]"));
!
! if (flags & EF_ARM_SYMSARESORTED)
! fprintf (file, _ (" [sorted symbol table]"));
! else
! fprintf (file, _ (" [unsorted symbol table]"));
!
! flags &= ~ EF_ARM_SYMSARESORTED;
! break;
!
! default:
! fprintf (file, _ (" <EABI version unrecognised>"));
! break;
! }
! flags &= ~ EF_ARM_EABIMASK;
! if (flags & EF_ARM_RELEXEC)
! fprintf (file, _ (" [relocatable executable]"));
!
! if (flags & EF_ARM_HASENTRY)
! fprintf (file, _ (" [has entry point]"));
+ flags &= ~ (EF_ARM_RELEXEC | EF_ARM_HASENTRY);
+
+ if (flags)
+ fprintf (file, _ ("<Unrecognised flag bits set>"));
+
fputc ('\n', file);
return true;
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/src//src/binutils/readelf.c,v
retrieving revision 1.49
diff -p -r1.49 readelf.c
*** readelf.c 2000/04/04 23:05:32 1.49
--- readelf.c 2000/04/06 22:53:43
*************** static const char * get_dynamic_ty
*** 153,158 ****
--- 153,159 ----
static int dump_relocations PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, unsigned long, char *, int));
static char * get_file_type PARAMS ((unsigned));
static char * get_machine_name PARAMS ((unsigned));
+ static void decode_ARM_machine_flags PARAMS ((unsigned, char []));
static char * get_machine_flags PARAMS ((unsigned, unsigned));
static const char * get_mips_segment_type PARAMS ((unsigned long));
static const char * get_parisc_segment_type PARAMS ((unsigned long));
*************** get_machine_name (e_machine)
*** 1240,1251 ****
--- 1241,1363 ----
}
}
+ static void
+ decode_ARM_machine_flags (e_flags, buf)
+ unsigned e_flags;
+ char buf[];
+ {
+ unsigned eabi;
+ int unknown = 0;
+
+ eabi = EF_ARM_EABI_VERSION (e_flags);
+ e_flags &= ~ EF_ARM_EABIMASK;
+
+ /* Handle "generic" ARM flags. */
+ if (e_flags & EF_ARM_RELEXEC)
+ {
+ strcat (buf, ", relocatable executable");
+ e_flags &= ~ EF_ARM_RELEXEC;
+ }
+
+ if (e_flags & EF_ARM_HASENTRY)
+ {
+ strcat (buf, ", has entry point");
+ e_flags &= ~ EF_ARM_HASENTRY;
+ }
+
+ /* Now handle EABI specific flags. */
+ switch (eabi)
+ {
+ default:
+ strcat (buf, ", <unknown EABI>");
+ if (e_flags)
+ unknown = 1;
+ break;
+
+ case EF_ARM_EABI_VER1:
+ while (e_flags)
+ {
+ unsigned flag;
+
+ /* Process flags one bit at a time. */
+ flag = e_flags & - e_flags;
+ e_flags &= ~ flag;
+
+ switch (flag)
+ {
+ case EF_ARM_SYMSARESORTED: /* Conflicts with EF_INTERWORK. */
+ strcat (buf, ", sorted symbol tables");
+ break;
+
+ default:
+ unknown = 1;
+ break;
+ }
+ }
+ break;
+
+ case EF_ARM_EABI_UNKNOWN:
+ while (e_flags)
+ {
+ unsigned flag;
+
+ /* Process flags one bit at a time. */
+ flag = e_flags & - e_flags;
+ e_flags &= ~ flag;
+
+ switch (flag)
+ {
+ case EF_INTERWORK:
+ strcat (buf, ", interworking enabled");
+ break;
+
+ case EF_APCS_26:
+ strcat (buf, ", uses APCS/26");
+ break;
+
+ case EF_APCS_FLOAT:
+ strcat (buf, ", uses APCS/float");
+ break;
+
+ case EF_PIC:
+ strcat (buf, ", position independent");
+ break;
+
+ case EF_ALIGN8:
+ strcat (buf, ", 8 bit structure alignment");
+ break;
+
+ case EF_NEW_ABI:
+ strcat (buf, ", uses new ABI");
+ break;
+
+ case EF_OLD_ABI:
+ strcat (buf, ", uses old ABI");
+ break;
+
+ case EF_SOFT_FLOAT:
+ strcat (buf, ", software FP");
+ break;
+
+ default:
+ unknown = 1;
+ break;
+ }
+ }
+ }
+
+
+ if (unknown)
+ strcat (buf,", <unknown>");
+ }
+
static char *
get_machine_flags (e_flags, e_machine)
unsigned e_flags;
*************** get_machine_flags (e_flags, e_machine)
*** 1262,1267 ****
--- 1374,1383 ----
default:
break;
+ case EM_ARM:
+ decode_ARM_machine_flags (e_flags, buf);
+ break;
+
case EM_68K:
if (e_flags & EF_CPU32)
strcat (buf, ", cpu32");