| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 * | 5 * |
| 6 * This is a standalone program that loads and runs the dynamic linker. | 6 * This is a standalone program that loads and runs the dynamic linker. |
| 7 * This program itself must be linked statically. To keep it small, it's | 7 * This program itself must be linked statically. To keep it small, it's |
| 8 * written to avoid all dependencies on libc and standard startup code. | 8 * written to avoid all dependencies on libc and standard startup code. |
| 9 * Hence, this should be linked using -nostartfiles. It must be compiled | 9 * Hence, this should be linked using -nostartfiles. It must be compiled |
| 10 * with -fno-stack-protector to ensure the compiler won't emit code that | 10 * with -fno-stack-protector to ensure the compiler won't emit code that |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 | 37 |
| 38 typedef uintptr_t __attribute__((may_alias)) stack_val_t; | 38 typedef uintptr_t __attribute__((may_alias)) stack_val_t; |
| 39 | 39 |
| 40 /* | 40 /* |
| 41 * These exact magic argument strings are recognized in check_r_debug_arg | 41 * These exact magic argument strings are recognized in check_r_debug_arg |
| 42 * and check_reserved_at_zero_arg, below. Requiring the arguments to have | 42 * and check_reserved_at_zero_arg, below. Requiring the arguments to have |
| 43 * those Xs as a template both simplifies our argument matching code and saves | 43 * those Xs as a template both simplifies our argument matching code and saves |
| 44 * us from having to reformat the whole stack to find space for a string longer | 44 * us from having to reformat the whole stack to find space for a string longer |
| 45 * than the original argument. | 45 * than the original argument. |
| 46 */ | 46 */ |
| 47 #define TEMPLATE_DIGITS "XXXXXXXXXXXXXXXX" |
| 47 #define R_DEBUG_TEMPLATE_PREFIX "--r_debug=0x" | 48 #define R_DEBUG_TEMPLATE_PREFIX "--r_debug=0x" |
| 48 #define R_DEBUG_TEMPLATE_DIGITS "XXXXXXXXXXXXXXXX" | 49 static const char kRDebugTemplate[] = R_DEBUG_TEMPLATE_PREFIX TEMPLATE_DIGITS; |
| 49 static const char kRDebugTemplate[] = | |
| 50 R_DEBUG_TEMPLATE_PREFIX R_DEBUG_TEMPLATE_DIGITS; | |
| 51 static const size_t kRDebugPrefixLen = sizeof(R_DEBUG_TEMPLATE_PREFIX) - 1; | 50 static const size_t kRDebugPrefixLen = sizeof(R_DEBUG_TEMPLATE_PREFIX) - 1; |
| 52 | 51 |
| 53 #define RESERVED_AT_ZERO_TEMPLATE_PREFIX "--reserved_at_zero=0x" | 52 #define RESERVED_AT_ZERO_TEMPLATE_PREFIX "--reserved_at_zero=0x" |
| 54 #define RESERVED_AT_ZERO_TEMPLATE_DIGITS "XXXXXXXX" | |
| 55 static const char kReservedAtZeroTemplate[] = | 53 static const char kReservedAtZeroTemplate[] = |
| 56 RESERVED_AT_ZERO_TEMPLATE_PREFIX RESERVED_AT_ZERO_TEMPLATE_DIGITS; | 54 RESERVED_AT_ZERO_TEMPLATE_PREFIX TEMPLATE_DIGITS; |
| 57 static const size_t kReservedAtZeroPrefixLen = | 55 static const size_t kReservedAtZeroPrefixLen = |
| 58 sizeof(RESERVED_AT_ZERO_TEMPLATE_PREFIX) - 1; | 56 sizeof(RESERVED_AT_ZERO_TEMPLATE_PREFIX) - 1; |
| 59 extern size_t RESERVE_TOP; | 57 extern size_t RESERVE_TOP; |
| 60 | 58 |
| 61 /* | 59 /* |
| 62 * We're not using <string.h> functions here, to avoid dependencies. | 60 * We're not using <string.h> functions here, to avoid dependencies. |
| 63 * In the x86 libc, even "simple" functions like memset and strlen can | 61 * In the x86 libc, even "simple" functions like memset and strlen can |
| 64 * depend on complex startup code, because in newer libc | 62 * depend on complex startup code, because in newer libc |
| 65 * implementations they are defined using STT_GNU_IFUNC. | 63 * implementations they are defined using STT_GNU_IFUNC. |
| 66 */ | 64 */ |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 */ | 409 */ |
| 412 struct r_debug _r_debug __attribute__((nocommon, section(".r_debug"))); | 410 struct r_debug _r_debug __attribute__((nocommon, section(".r_debug"))); |
| 413 | 411 |
| 414 /* | 412 /* |
| 415 * If the argument matches the kRDebugTemplate string, then replace | 413 * If the argument matches the kRDebugTemplate string, then replace |
| 416 * the 16 Xs with the hexadecimal address of our _r_debug variable. | 414 * the 16 Xs with the hexadecimal address of our _r_debug variable. |
| 417 */ | 415 */ |
| 418 static int check_r_debug_arg(char *arg) { | 416 static int check_r_debug_arg(char *arg) { |
| 419 if (my_strcmp(arg, kRDebugTemplate) == 0) { | 417 if (my_strcmp(arg, kRDebugTemplate) == 0) { |
| 420 fill_in_template_digits(arg + kRDebugPrefixLen, | 418 fill_in_template_digits(arg + kRDebugPrefixLen, |
| 421 sizeof(R_DEBUG_TEMPLATE_DIGITS) - 1, | 419 sizeof(TEMPLATE_DIGITS) - 1, |
| 422 (uintptr_t) &_r_debug); | 420 (uintptr_t) &_r_debug); |
| 423 return 1; | 421 return 1; |
| 424 } | 422 } |
| 425 return 0; | 423 return 0; |
| 426 } | 424 } |
| 427 | 425 |
| 428 /* | 426 /* |
| 429 * If the argument matches the kReservedAtZeroTemplate string, then replace | 427 * If the argument matches the kReservedAtZeroTemplate string, then replace |
| 430 * the 8 Xs with the hexadecimal representation of the amount of | 428 * the 8 Xs with the hexadecimal representation of the amount of |
| 431 * prereserved memory. | 429 * prereserved memory. |
| 432 */ | 430 */ |
| 433 static int check_reserved_at_zero_arg(char *arg) { | 431 static int check_reserved_at_zero_arg(char *arg) { |
| 434 if (my_strcmp(arg, kReservedAtZeroTemplate) == 0) { | 432 if (my_strcmp(arg, kReservedAtZeroTemplate) == 0) { |
| 435 fill_in_template_digits(arg + kReservedAtZeroPrefixLen, | 433 fill_in_template_digits(arg + kReservedAtZeroPrefixLen, |
| 436 sizeof(RESERVED_AT_ZERO_TEMPLATE_DIGITS) - 1, | 434 sizeof(TEMPLATE_DIGITS) - 1, |
| 437 (uintptr_t) &RESERVE_TOP); | 435 (uintptr_t) &RESERVE_TOP); |
| 438 return 1; | 436 return 1; |
| 439 } | 437 } |
| 440 return 0; | 438 return 0; |
| 441 } | 439 } |
| 442 | 440 |
| 443 | 441 |
| 444 /* | 442 /* |
| 445 * This is the main loading code. It's called with the starting stack pointer. | 443 * This is the main loading code. It's called with the starting stack pointer. |
| 446 * This points to a sequence of pointer-size words: | 444 * This points to a sequence of pointer-size words: |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 | 622 |
| 625 #if defined(__arm__) | 623 #if defined(__arm__) |
| 626 /* | 624 /* |
| 627 * We may bring in __aeabi_* functions from libgcc that in turn | 625 * We may bring in __aeabi_* functions from libgcc that in turn |
| 628 * want to call raise. | 626 * want to call raise. |
| 629 */ | 627 */ |
| 630 int raise(int sig) { | 628 int raise(int sig) { |
| 631 return sys_kill(sys_getpid(), sig); | 629 return sys_kill(sys_getpid(), sig); |
| 632 } | 630 } |
| 633 #endif | 631 #endif |
| OLD | NEW |