Index: src/pkg/runtime/os_linux_arm.c |
=================================================================== |
--- a/src/pkg/runtime/os_linux_arm.c |
+++ b/src/pkg/runtime/os_linux_arm.c |
@@ -34,13 +34,52 @@ |
} |
#pragma textflag NOSPLIT |
-void |
-runtime·setup_auxv(int32 argc, byte **argv) |
+static void |
+parse_auxv_entry(uint32 key, uint32 val) { |
+ byte *rnd; |
+ uint32 t; |
+ |
+ switch(key) { |
+ case AT_RANDOM: // kernel provided 16-byte worth of random data |
+ if(val) { |
+ rnd = (byte*)val; |
+ runtime·randomNumber = rnd[4] | rnd[5]<<8 | rnd[6]<<16 | rnd[7]<<24; |
+ } |
+ break; |
+ case AT_PLATFORM: // v5l, v6l, v7l |
+ if(val) { |
+ t = *(uint8*)(val+1); |
+ if(t >= '5' && t <= '7') |
+ runtime·armArch = t - '0'; |
+ } |
+ break; |
+ case AT_HWCAP: // CPU capability bit flags |
+ runtime·hwcap = val; |
+ break; |
+ } |
+} |
+ |
+#pragma textflag NOSPLIT |
+static void |
+setup_auxv_from_proc(void) |
+{ |
+ int32 auxv_fd; |
+ uint32 auxv_entry[2]; |
+ |
+ auxv_fd = runtime·open((int8*)"/proc/self/auxv", O_RDONLY, 0); |
+ if(auxv_fd < 0) |
+ return; |
+ while(runtime·read(auxv_fd, auxv_entry, sizeof auxv_entry) == sizeof auxv_entry) |
+ parse_auxv_entry(auxv_entry[0], auxv_entry[1]); |
+ runtime·close(auxv_fd); |
+} |
+ |
+#pragma textflag NOSPLIT |
+static void |
+setup_auxv_from_argv(int32 argc, byte **argv) |
{ |
byte **envp; |
- byte *rnd; |
uint32 *auxv; |
- uint32 t; |
// skip envp to get to ELF auxiliary vector. |
for(envp = &argv[argc+1]; *envp != nil; envp++) |
@@ -48,28 +87,21 @@ |
envp++; |
for(auxv=(uint32*)envp; auxv[0] != AT_NULL; auxv += 2) { |
- switch(auxv[0]) { |
- case AT_RANDOM: // kernel provided 16-byte worth of random data |
- if(auxv[1]) { |
- rnd = (byte*)auxv[1]; |
- runtime·randomNumber = rnd[4] | rnd[5]<<8 | rnd[6]<<16 | rnd[7]<<24; |
- } |
- break; |
- case AT_PLATFORM: // v5l, v6l, v7l |
- if(auxv[1]) { |
- t = *(uint8*)(auxv[1]+1); |
- if(t >= '5' && t <= '7') |
- runtime·armArch = t - '0'; |
- } |
- break; |
- case AT_HWCAP: // CPU capability bit flags |
- runtime·hwcap = auxv[1]; |
- break; |
- } |
+ parse_auxv_entry(auxv[0], auxv[1]); |
} |
} |
#pragma textflag NOSPLIT |
+void |
+runtime·setup_auxv(int32 argc, byte **argv) |
+{ |
+ if(argc > 0) |
+ setup_auxv_from_argv(argc, argv); |
+ else |
+ setup_auxv_from_proc(); |
+} |
+ |
+#pragma textflag NOSPLIT |
int64 |
runtime·cputicks(void) |
{ |