binary_unittest.cc 4.9 KB

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