1// binary_unittest.cc -- test Binary_to_elf 2 3// Copyright 2008 Free Software Foundation, Inc. 4// Written by Ian Lance Taylor <iant@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 37#include "test.h" 38#include "testfile.h" 39 40namespace gold_testsuite 41{ 42 43using namespace gold; 44 45template<int size, bool big_endian> 46bool 47Sized_binary_test() 48{ 49 parameters_clear_target(); 50 // We need a pretend Task. 51 const Task* task = reinterpret_cast<const Task*>(-1); 52 53 // Use the executable itself as the binary data. 54 struct stat st; 55 CHECK(::stat(gold::program_name, &st) == 0); 56 int o = ::open(gold::program_name, O_RDONLY); 57 CHECK(o >= 0); 58 unsigned char* filedata = new unsigned char[st.st_size]; 59 CHECK(::read(o, filedata, st.st_size) == st.st_size); 60 CHECK(::close(o) == 0); 61 62 Binary_to_elf binary(static_cast<elfcpp::EM>(0xffff), size, big_endian, 63 gold::program_name); 64 65 CHECK(binary.convert(task)); 66 67 Input_file input_file(task, "test.o", binary.converted_data(), 68 binary.converted_size()); 69 Object* object = make_elf_object("test.o", &input_file, 0, 70 binary.converted_data(), 71 binary.converted_size(), NULL); 72 CHECK(object != NULL); 73 if (object == NULL) 74 return false; 75 76 CHECK(!object->is_dynamic()); 77 CHECK(object->shnum() == 5); 78 CHECK(object->section_name(1) == ".data"); 79 CHECK(object->section_flags(1) == (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE)); 80 section_size_type len; 81 const unsigned char* contents = object->section_contents(1, &len, false); 82 CHECK(len == convert_to_section_size_type(st.st_size)); 83 CHECK(memcmp(filedata, contents, len) == 0); 84 85 // Force the symbols to be read internally, so that 86 // symbol_section_and_value will work. 87 Read_symbols_data sd; 88 object->read_symbols(&sd); 89 delete sd.section_headers; 90 sd.section_headers = NULL; 91 delete sd.section_names; 92 sd.section_names = NULL; 93 delete sd.symbols; 94 sd.symbols = NULL; 95 delete sd.symbol_names; 96 sd.symbol_names = NULL; 97 98 Sized_relobj<size, big_endian>* relobj = 99 static_cast<Sized_relobj<size, big_endian>*>(object); 100 typename Sized_relobj<size, big_endian>::Address value; 101 bool is_ordinary; 102 CHECK(relobj->symbol_section_and_value(0, &value, &is_ordinary) == 0); 103 CHECK(is_ordinary); 104 CHECK(value == 0); 105 CHECK(relobj->symbol_section_and_value(1, &value, &is_ordinary) == 1); 106 CHECK(is_ordinary); 107 CHECK(value == 0); 108 CHECK(relobj->symbol_section_and_value(2, &value, &is_ordinary) == 1); 109 CHECK(is_ordinary); 110 CHECK(static_cast<off_t>(value) == st.st_size); 111 CHECK(relobj->symbol_section_and_value(3, &value, &is_ordinary) 112 == elfcpp::SHN_ABS); 113 CHECK(!is_ordinary); 114 CHECK(static_cast<off_t>(value) == st.st_size); 115 116 object->unlock(task); 117 return true; 118} 119 120bool 121Binary_test(Test_report*) 122{ 123 Errors errors(gold::program_name); 124 set_parameters_errors(&errors); 125 126 General_options options; 127 set_parameters_options(&options); 128 129 int fail = 0; 130 131#ifdef HAVE_TARGET_32_LITTLE 132 if (!Sized_binary_test<32, false>()) 133 ++fail; 134 CHECK(¶meters->target() == target_test_pointer_32_little); 135#endif 136 137#ifdef HAVE_TARGET_32_BIG 138 if (!Sized_binary_test<32, true>()) 139 ++fail; 140 CHECK(¶meters->target() == target_test_pointer_32_big); 141#endif 142 143#ifdef HAVE_TARGET_64_LITTLE 144 if (!Sized_binary_test<64, false>()) 145 ++fail; 146 CHECK(¶meters->target() == target_test_pointer_64_little); 147#endif 148 149#ifdef HAVE_TARGET_64_BIG 150 if (!Sized_binary_test<64, true>()) 151 ++fail; 152 CHECK(¶meters->target() == target_test_pointer_64_big); 153#endif 154 155 return fail == 0; 156} 157 158Register_test binary_register("Binary", Binary_test); 159 160} // End namespace gold_testsuite. 161