1 : /*
2 : * Copyright (c) 2008 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 :
8 : /* TODO: add comment why this is needed */
9 : #ifndef _GNU_SOURCE
10 : #define _GNU_SOURCE
11 : #endif
12 :
13 : #include <assert.h>
14 : #include <dlfcn.h>
15 : #include <libgen.h>
16 : #include <stdio.h>
17 : #include <stdint.h>
18 : #include <stdlib.h>
19 : #include <string.h>
20 : #include <unistd.h>
21 :
22 : #include "native_client/src/include/portability.h"
23 : #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h"
24 :
25 : namespace nacl {
26 :
27 : // First, try looking a symbol up in the dynamic loader's records.
28 0 : static void PathFromSymbol(char* buffer, size_t len, void* sym) {
29 : #if NACL_ANDROID
30 : UNREFERENCED_PARAMETER(sym);
31 : // We do not have dladdr() on Android.
32 : if (len > 0)
33 : buffer[0] = '\0';
34 : #else
35 : Dl_info info;
36 :
37 0 : if (0 != dladdr(sym, &info)) {
38 0 : strncpy(buffer, info.dli_fname, len - 1);
39 : } else {
40 0 : buffer[0] = '\0';
41 : }
42 : #endif
43 0 : }
44 :
45 : // Path of the current executable
46 0 : static void PathFromExe(char* buffer, size_t len) {
47 0 : int bin_dir_size = readlink("/proc/self/exe", buffer, len - 1);
48 0 : if (bin_dir_size < 0 || (size_t) bin_dir_size >= len) {
49 0 : buffer[0] = '\0';
50 : } else {
51 0 : buffer[len - 1] = '\0';
52 : }
53 0 : }
54 :
55 : // This code tries to determine the plugin directory which contains
56 : // the sel_ldr and possibly other libraries
57 0 : static void GetPluginDirectory(char* buffer, size_t len) {
58 : // C++ really does not like to convert function pointer to regular pointers.
59 : // This is apparently the only way to do it without compiler warnings
60 : void* sym_addr = reinterpret_cast<void*>(
61 0 : reinterpret_cast<uintptr_t>(GetPluginDirectory));
62 :
63 : // We try 2 heuristics before giving up
64 0 : PathFromSymbol(buffer, len, sym_addr);
65 :
66 0 : if (0 == strlen(buffer)) {
67 0 : PathFromExe(buffer, len);
68 : }
69 :
70 0 : if (0 == strlen(buffer)) {
71 : // TOOD(robertm): maybe emit error message - but these file seem to not
72 : // use NaClLog
73 0 : return;
74 : }
75 :
76 0 : char* path_end = strrchr(buffer, '/');
77 0 : if (NULL != path_end) {
78 0 : *path_end = '\0';
79 : }
80 : }
81 :
82 0 : void PluginSelLdrLocator::GetDirectory(char* buffer, size_t len) {
83 0 : GetPluginDirectory(buffer, len);
84 0 : }
85 :
86 :
87 : } // namespace nacl
|