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__);
 | |
| }
 |