55 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			55 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Code to byte-swap static constructor/destructor tables on
 | 
						|
   broken a.out little-endian targets. The startup code should call
 | 
						|
   __fix_ctors just before calling main.  It is safe to use on non-broken
 | 
						|
   or big-endian targets. */
 | 
						|
 | 
						|
extern long __CTOR_LIST__[];
 | 
						|
extern long __DTOR_LIST__[];
 | 
						|
 | 
						|
static void
 | 
						|
byte_swap (long *entry)
 | 
						|
{
 | 
						|
  unsigned char *p = (unsigned char *)entry;
 | 
						|
  unsigned char tmp;
 | 
						|
 | 
						|
  tmp = p[0];
 | 
						|
  p[0] = p[3];
 | 
						|
  p[3] = tmp;
 | 
						|
  tmp = p[1];
 | 
						|
  p[1] = p[2];
 | 
						|
  p[2] = tmp;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
fix_table (long *table)
 | 
						|
{
 | 
						|
  long len = table[0];
 | 
						|
 | 
						|
  /* The heuristic for deciding if a table is broken is to examine
 | 
						|
     the word at the start of the table, which contains the number
 | 
						|
     of function pointers immediately following.  If the low word
 | 
						|
     is zero, and the high word is non-zero, it's very likely that
 | 
						|
     it is byte-swapped.  This test will fail if the program has
 | 
						|
     an exact multiple of 64K static constructors or destructors, a very
 | 
						|
     unlikely situation. */
 | 
						|
  if ((len & 0xffff) == 0 && (len & 0xffff0000) != 0)
 | 
						|
    {
 | 
						|
 | 
						|
      /* The table looks broken.  Byte-swap all the words in the table, up
 | 
						|
         to a NULL entry, which marks the end of the table. */
 | 
						|
      do
 | 
						|
	{
 | 
						|
	  byte_swap (table);
 | 
						|
	  table++;
 | 
						|
	}
 | 
						|
      while (*table);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
__fix_ctors (void)
 | 
						|
{
 | 
						|
  fix_table (__CTOR_LIST__);
 | 
						|
  fix_table (__DTOR_LIST__);
 | 
						|
}
 |