1 // binary_unittest.cc -- test Binary_to_elf 2 3 // Copyright (C) 2008-2014 Free Software Foundation, Inc. 4 // Written by Ian Lance Taylor <iant (at) google.com>. 5 6 // This file is part of gold. 7 8 // This program is free software; you can redistribute it and/or modify 9 // it under the terms of the GNU General Public License as published by 10 // the Free Software Foundation; either version 3 of the License, or 11 // (at your option) any later version. 12 13 // This program is distributed in the hope that it will be useful, 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 // GNU General Public License for more details. 17 18 // You should have received a copy of the GNU General Public License 19 // along with this program; if not, write to the Free Software 20 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21 // MA 02110-1301, USA. 22 23 #include "gold.h" 24 25 #include <unistd.h> 26 #include <sys/types.h> 27 #include <sys/stat.h> 28 #include <fcntl.h> 29 30 #include "elfcpp.h" 31 #include "parameters.h" 32 #include "errors.h" 33 #include "options.h" 34 #include "binary.h" 35 #include "object.h" 36 #include "descriptors.h" 37 38 #include "test.h" 39 #include "testfile.h" 40 41 namespace 42 { 43 44 ssize_t 45 read_all (int fd, unsigned char* buf, ssize_t size) 46 { 47 ssize_t total_read = 0; 48 while (size > 0) 49 { 50 ssize_t nread = ::read(fd, buf, size); 51 if (nread < 0) 52 return nread; 53 if (nread == 0) 54 break; 55 buf += nread; 56 size -= nread; 57 total_read += nread; 58 } 59 return total_read; 60 } 61 62 } // End anonymous namespace. 63 64 namespace gold_testsuite 65 { 66 67 using namespace gold; 68 69 template<int size, bool big_endian> 70 bool 71 Sized_binary_test() 72 { 73 parameters_clear_target(); 74 // We need a pretend Task. 75 const Task* task = reinterpret_cast<const Task*>(-1); 76 77 // Use the executable itself as the binary data. 78 struct stat st; 79 CHECK(::stat(gold::program_name, &st) == 0); 80 int o = open_descriptor(-1, gold::program_name, O_RDONLY); 81 CHECK(o >= 0); 82 unsigned char* filedata = new unsigned char[st.st_size]; 83 CHECK(read_all(o, filedata, st.st_size) == static_cast<ssize_t>(st.st_size)); 84 CHECK(::close(o) == 0); 85 86 Binary_to_elf binary(static_cast<elfcpp::EM>(0xffff), size, big_endian, 87 gold::program_name); 88 89 CHECK(binary.convert(task)); 90 91 Input_file input_file(task, "test.o", binary.converted_data(), 92 binary.converted_size()); 93 Object* object = make_elf_object("test.o", &input_file, 0, 94 binary.converted_data(), 95 binary.converted_size(), NULL); 96 CHECK(object != NULL); 97 if (object == NULL) 98 return false; 99 100 CHECK(!object->is_dynamic()); 101 CHECK(object->shnum() == 5); 102 CHECK(object->section_name(1) == ".data"); 103 CHECK(object->section_flags(1) == (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE)); 104 section_size_type len; 105 const unsigned char* contents = object->section_contents(1, &len, false); 106 CHECK(len == convert_to_section_size_type(st.st_size)); 107 CHECK(memcmp(filedata, contents, len) == 0); 108 109 // Force the symbols to be read internally, so that 110 // symbol_section_and_value will work. 111 Read_symbols_data sd; 112 object->read_symbols(&sd); 113 delete sd.section_headers; 114 sd.section_headers = NULL; 115 delete sd.section_names; 116 sd.section_names = NULL; 117 delete sd.symbols; 118 sd.symbols = NULL; 119 delete sd.symbol_names; 120 sd.symbol_names = NULL; 121 122 Sized_relobj_file<size, big_endian>* relobj = 123 static_cast<Sized_relobj_file<size, big_endian>*>(object); 124 typename Sized_relobj_file<size, big_endian>::Address value; 125 bool is_ordinary; 126 CHECK(relobj->symbol_section_and_value(0, &value, &is_ordinary) == 0); 127 CHECK(is_ordinary); 128 CHECK(value == 0); 129 CHECK(relobj->symbol_section_and_value(1, &value, &is_ordinary) == 1); 130 CHECK(is_ordinary); 131 CHECK(value == 0); 132 CHECK(relobj->symbol_section_and_value(2, &value, &is_ordinary) == 1); 133 CHECK(is_ordinary); 134 CHECK(static_cast<off_t>(value) == st.st_size); 135 CHECK(relobj->symbol_section_and_value(3, &value, &is_ordinary) 136 == elfcpp::SHN_ABS); 137 CHECK(!is_ordinary); 138 CHECK(static_cast<off_t>(value) == st.st_size); 139 140 object->unlock(task); 141 return true; 142 } 143 144 bool 145 Binary_test(Test_report*) 146 { 147 Errors errors(gold::program_name); 148 set_parameters_errors(&errors); 149 150 General_options options; 151 set_parameters_options(&options); 152 153 int fail = 0; 154 155 #ifdef HAVE_TARGET_32_LITTLE 156 if (!Sized_binary_test<32, false>()) 157 ++fail; 158 CHECK(¶meters->target() == target_test_pointer_32_little); 159 #endif 160 161 #ifdef HAVE_TARGET_32_BIG 162 if (!Sized_binary_test<32, true>()) 163 ++fail; 164 CHECK(¶meters->target() == target_test_pointer_32_big); 165 #endif 166 167 #ifdef HAVE_TARGET_64_LITTLE 168 if (!Sized_binary_test<64, false>()) 169 ++fail; 170 CHECK(¶meters->target() == target_test_pointer_64_little); 171 #endif 172 173 #ifdef HAVE_TARGET_64_BIG 174 if (!Sized_binary_test<64, true>()) 175 ++fail; 176 CHECK(¶meters->target() == target_test_pointer_64_big); 177 #endif 178 179 return fail == 0; 180 } 181 182 Register_test binary_register("Binary", Binary_test); 183 184 } // End namespace gold_testsuite. 185