| OLD | NEW |
| 1 // Copyright 2016 The Native Client Authors. All rights reserved. | 1 // Copyright 2016 The Native Client Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "native_client/src/include/nacl_assert.h" | 5 #include "native_client/src/include/nacl_assert.h" |
| 6 #include "native_client/src/untrusted/pll_loader/pll_loader.h" | 6 #include "native_client/src/untrusted/pll_loader/pll_loader.h" |
| 7 | 7 |
| 8 | 8 |
| 9 namespace { | 9 namespace { |
| 10 | 10 |
| 11 template <typename VarType> | 11 template <typename VarType> |
| 12 void CheckTlsVar(ModuleSet *modset, const char *name_of_getter, | 12 void CheckTlsVar(ModuleSet *modset, const char *name_of_getter, |
| 13 int alignment, VarType expected_value) { | 13 int alignment, VarType expected_value) { |
| 14 auto getter = (VarType *(*)()) (uintptr_t) modset->GetSym(name_of_getter); | 14 auto getter = (VarType *(*)()) (uintptr_t) modset->GetSym(name_of_getter); |
| 15 ASSERT_NE(getter, NULL); | 15 ASSERT_NE(getter, NULL); |
| 16 VarType *var_ptr = getter(); | 16 VarType *var_ptr = getter(); |
| 17 ASSERT_NE(var_ptr, NULL); | 17 ASSERT_NE(var_ptr, NULL); |
| 18 ASSERT_EQ((uintptr_t) var_ptr & (alignment - 1), 0); | 18 ASSERT_EQ((uintptr_t) var_ptr & (alignment - 1), 0); |
| 19 ASSERT_EQ(*var_ptr, expected_value); | 19 ASSERT_EQ(*var_ptr, expected_value); |
| 20 } | 20 } |
| 21 | 21 |
| 22 } // namespace | 22 } // namespace |
| 23 | 23 |
| 24 int main(int argc, char **argv) { | 24 int main(int argc, char **argv) { |
| 25 if (argc != 4) { | 25 if (argc != 5) { |
| 26 fprintf(stderr, "Usage: pll_loader_test <3 ELF files>\n"); | 26 fprintf(stderr, "Usage: pll_loader_test <Directory path> <3 ELF files>\n"); |
| 27 return 1; | 27 return 1; |
| 28 } | 28 } |
| 29 | 29 |
| 30 const char *module_a_filename = argv[1]; | 30 const char *module_directory = argv[1]; |
| 31 const char *module_b_filename = argv[2]; | 31 const char *module_a_soname = argv[2]; |
| 32 const char *module_tls_filename = argv[3]; | 32 const char *module_b_soname = argv[3]; |
| 33 const char *module_tls_soname = argv[4]; |
| 33 | 34 |
| 34 ModuleSet modset; | 35 ModuleSet modset; |
| 36 std::vector<std::string> search_paths; |
| 37 search_paths.push_back(module_directory); |
| 38 modset.SetSonameSearchPaths(search_paths); |
| 35 | 39 |
| 36 // "module_a_var" should only be resolvable after we load module A. | 40 // "module_a_var" should only be resolvable after we load module A. |
| 37 int *module_a_var = (int *) modset.GetSym("module_a_var"); | 41 int *module_a_var = (int *) modset.GetSym("module_a_var"); |
| 38 ASSERT_EQ(module_a_var, NULL); | 42 ASSERT_EQ(module_a_var, NULL); |
| 39 | 43 |
| 40 modset.AddByFilename(module_a_filename); | 44 modset.AddBySoname(module_a_soname); |
| 41 module_a_var = (int *) modset.GetSym("module_a_var"); | 45 module_a_var = (int *) modset.GetSym("module_a_var"); |
| 42 ASSERT_NE(module_a_var, NULL); | 46 ASSERT_NE(module_a_var, NULL); |
| 43 ASSERT_EQ(*module_a_var, 2345); | 47 ASSERT_EQ(*module_a_var, 2345); |
| 44 | 48 |
| 45 modset.AddByFilename(module_b_filename); | 49 modset.AddBySoname(module_b_soname); |
| 46 int *module_b_var = (int *) modset.GetSym("module_b_var"); | 50 int *module_b_var = (int *) modset.GetSym("module_b_var"); |
| 47 ASSERT_NE(module_b_var, NULL); | 51 ASSERT_NE(module_b_var, NULL); |
| 48 ASSERT_EQ(*module_b_var, 1234); | 52 ASSERT_EQ(*module_b_var, 1234); |
| 49 | 53 |
| 50 modset.AddByFilename(module_tls_filename); | 54 modset.AddBySoname(module_tls_soname); |
| 51 | 55 |
| 52 modset.ResolveRefs(); | 56 modset.ResolveRefs(); |
| 53 | 57 |
| 54 // Check that "addr_of_module_a_var" has been correctly relocated to | 58 // Check that "addr_of_module_a_var" has been correctly relocated to |
| 55 // point to the other module. | 59 // point to the other module. |
| 56 int **addr_of_module_a_var = (int **) modset.GetSym("addr_of_module_a_var"); | 60 int **addr_of_module_a_var = (int **) modset.GetSym("addr_of_module_a_var"); |
| 57 ASSERT_NE(addr_of_module_a_var, NULL); | 61 ASSERT_NE(addr_of_module_a_var, NULL); |
| 58 ASSERT_EQ(*addr_of_module_a_var, module_a_var); | 62 ASSERT_EQ(*addr_of_module_a_var, module_a_var); |
| 59 | 63 |
| 60 // Test that TLS variables are instantiated and aligned properly. | 64 // Test that TLS variables are instantiated and aligned properly. |
| 61 CheckTlsVar<int>(&modset, "get_tls_var1", sizeof(int), 123); | 65 CheckTlsVar<int>(&modset, "get_tls_var1", sizeof(int), 123); |
| 62 CheckTlsVar<int *>(&modset, "get_tls_var2", sizeof(int), module_a_var); | 66 CheckTlsVar<int *>(&modset, "get_tls_var2", sizeof(int), module_a_var); |
| 63 CheckTlsVar<int>(&modset, "get_tls_var_aligned", 256, 345); | 67 CheckTlsVar<int>(&modset, "get_tls_var_aligned", 256, 345); |
| 64 CheckTlsVar<int>(&modset, "get_tls_bss_var1", sizeof(int), 0); | 68 CheckTlsVar<int>(&modset, "get_tls_bss_var1", sizeof(int), 0); |
| 65 CheckTlsVar<int>(&modset, "get_tls_bss_var_aligned", 256, 0); | 69 CheckTlsVar<int>(&modset, "get_tls_bss_var_aligned", 256, 0); |
| 66 | 70 |
| 67 return 0; | 71 return 0; |
| 68 } | 72 } |
| OLD | NEW |