| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #include "linux/threads.h" | 
|  | 2 | #include "linux/stddef.h"  // for NULL | 
|  | 3 | #include "linux/elf.h"  // for AT_NULL | 
|  | 4 |  | 
|  | 5 | /* The following function nicked from arch/ppc/kernel/process.c and | 
|  | 6 | * adapted slightly */ | 
|  | 7 | /* | 
|  | 8 | * XXX ld.so expects the auxiliary table to start on | 
|  | 9 | * a 16-byte boundary, so we have to find it and | 
|  | 10 | * move it up. :-( | 
|  | 11 | */ | 
|  | 12 | void shove_aux_table(unsigned long sp) | 
|  | 13 | { | 
|  | 14 | int argc; | 
|  | 15 | char *p; | 
|  | 16 | unsigned long e; | 
|  | 17 | unsigned long aux_start, offset; | 
|  | 18 |  | 
|  | 19 | argc = *(int *)sp; | 
|  | 20 | sp += sizeof(int) + (argc + 1) * sizeof(char *); | 
|  | 21 | /* skip over the environment pointers */ | 
|  | 22 | do { | 
|  | 23 | p = *(char **)sp; | 
|  | 24 | sp += sizeof(char *); | 
|  | 25 | } while (p != NULL); | 
|  | 26 | aux_start = sp; | 
|  | 27 | /* skip to the end of the auxiliary table */ | 
|  | 28 | do { | 
|  | 29 | e = *(unsigned long *)sp; | 
|  | 30 | sp += 2 * sizeof(unsigned long); | 
|  | 31 | } while (e != AT_NULL); | 
|  | 32 | offset = ((aux_start + 15) & ~15) - aux_start; | 
|  | 33 | if (offset != 0) { | 
|  | 34 | do { | 
|  | 35 | sp -= sizeof(unsigned long); | 
|  | 36 | e = *(unsigned long *)sp; | 
|  | 37 | *(unsigned long *)(sp + offset) = e; | 
|  | 38 | } while (sp > aux_start); | 
|  | 39 | } | 
|  | 40 | } | 
|  | 41 | /* END stuff taken from arch/ppc/kernel/process.c */ | 
|  | 42 |  |