1 : /*
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
4 : * found in the LICENSE file.
5 : */
6 :
7 : #if !NACL_ANDROID
8 : #include <link.h>
9 : #endif
10 : #include <stdlib.h>
11 :
12 : #include "native_client/src/trusted/service_runtime/linux/android_compat.h"
13 :
14 : /*
15 : * If we are started by the bootstrap program rather than in the
16 : * usual way, the debugger cannot figure out where our executable
17 : * or the dynamic linker or the shared libraries are in memory,
18 : * so it won't find any symbols. But we can fake it out to find us.
19 : *
20 : * The launcher passes --r_debug=0xXXXXXXXXXXXXXXXX.
21 : * nacl_helper_bootstrap replaces the Xs with the address of its _r_debug
22 : * structure. The debugger will look for that symbol by name to
23 : * discover the addresses of key dynamic linker data structures.
24 : * Since all it knows about is the original main executable, which
25 : * is the bootstrap program, it finds the symbol defined there. The
26 : * dynamic linker's structure is somewhere else, but it is filled in
27 : * after initialization. The parts that really matter to the
28 : * debugger never change. So we just copy the contents of the
29 : * dynamic linker's structure into the address provided by the option.
30 : * Hereafter, if someone attaches a debugger (or examines a core dump),
31 : * the debugger will find all the symbols in the normal way.
32 : */
33 :
34 290 : void NaClHandleRDebug(const char *switch_value, char *argv0) {
35 : #if NACL_ANDROID
36 : UNREFERENCED_PARAMETER(switch_value);
37 : UNREFERENCED_PARAMETER(argv0);
38 : #else
39 290 : char *endp = NULL;
40 290 : uintptr_t r_debug_addr = strtoul(switch_value, &endp, 0);
41 290 : if (r_debug_addr != 0 && *endp == '\0') {
42 : struct link_map *l;
43 290 : struct r_debug *bootstrap_r_debug = (struct r_debug *) r_debug_addr;
44 290 : *bootstrap_r_debug = _r_debug;
45 :
46 : /*
47 : * Since the main executable (the bootstrap program) does not
48 : * have a dynamic section, the debugger will not skip the
49 : * first element of the link_map list as it usually would for
50 : * an executable or PIE that was loaded normally. But the
51 : * dynamic linker has set l_name for the PIE to "" as is
52 : * normal for the main executable. So the debugger doesn't
53 : * know which file it is. Fill in the actual file name, which
54 : * came in as our argv[0].
55 : */
56 290 : l = _r_debug.r_map;
57 290 : if (l->l_name[0] == '\0')
58 290 : l->l_name = argv0;
59 : }
60 : #endif
61 290 : }
|