This is the mail archive of the binutils@sourceware.cygnus.com 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]

Add support for ARM ELF EABI versions


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");

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