Home | History | Annotate | Download | only in testsuite
      1 // binary_unittest.cc -- test Binary_to_elf
      2 
      3 // Copyright (C) 2008-2016 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(&parameters->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(&parameters->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(&parameters->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(&parameters->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