WIP MachO binutils port assisted by AI I may consider upstreaming this in the future.
0

Configure Feed

Select the types of activity you want to include in your feed.

Add support for --format binary for input files.

Ian Lance Taylor (Feb 8, 2008, 7:06 AM UTC) bc644c6c 897b09ca

+849 -39
+2
gold/Makefile.am
··· 30 30 31 31 CCFILES = \ 32 32 archive.cc \ 33 + binary.cc \ 33 34 common.cc \ 34 35 compressed_output.cc \ 35 36 defstd.cc \ ··· 62 63 63 64 HFILES = \ 64 65 archive.h \ 66 + binary.h \ 65 67 common.h \ 66 68 compressed_output.h \ 67 69 defstd.h \
+4 -1
gold/Makefile.in
··· 71 71 ARFLAGS = cru 72 72 libgold_a_AR = $(AR) $(ARFLAGS) 73 73 libgold_a_LIBADD = 74 - am__objects_1 = archive.$(OBJEXT) common.$(OBJEXT) \ 74 + am__objects_1 = archive.$(OBJEXT) binary.$(OBJEXT) common.$(OBJEXT) \ 75 75 compressed_output.$(OBJEXT) defstd.$(OBJEXT) \ 76 76 dirsearch.$(OBJEXT) dynobj.$(OBJEXT) dwarf_reader.$(OBJEXT) \ 77 77 ehframe.$(OBJEXT) errors.$(OBJEXT) expression.$(OBJEXT) \ ··· 299 299 noinst_LIBRARIES = libgold.a 300 300 CCFILES = \ 301 301 archive.cc \ 302 + binary.cc \ 302 303 common.cc \ 303 304 compressed_output.cc \ 304 305 defstd.cc \ ··· 331 332 332 333 HFILES = \ 333 334 archive.h \ 335 + binary.h \ 334 336 common.h \ 335 337 compressed_output.h \ 336 338 defstd.h \ ··· 499 501 500 502 @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/pread.Po@am__quote@ 501 503 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/archive.Po@am__quote@ 504 + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/binary.Po@am__quote@ 502 505 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@ 503 506 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compressed_output.Po@am__quote@ 504 507 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/defstd.Po@am__quote@
+356
gold/binary.cc
··· 1 + // binary.cc -- binary input files for gold 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 <cerrno> 26 + #include <cstring> 27 + #include "safe-ctype.h" 28 + 29 + #include "elfcpp.h" 30 + #include "stringpool.h" 31 + #include "fileread.h" 32 + #include "output.h" 33 + #include "binary.h" 34 + 35 + // Support for reading binary files as input. These become blobs in 36 + // the final output. These files are treated as though they have a 37 + // single .data section and define three symbols: 38 + // _binary_FILENAME_start, _binary_FILENAME_end, _binary_FILENAME_end. 39 + // The FILENAME is the name of the input file, with any 40 + // non-alphanumeric character changed to an underscore. 41 + 42 + // We implement this by creating an ELF file in memory. 43 + 44 + namespace gold 45 + { 46 + 47 + // class Binary_to_elf. 48 + 49 + Binary_to_elf::Binary_to_elf(elfcpp::EM machine, int size, bool big_endian, 50 + const std::string& filename) 51 + : elf_machine_(machine), size_(size), big_endian_(big_endian), 52 + filename_(filename), data_(NULL), filesize_(0) 53 + { 54 + } 55 + 56 + Binary_to_elf::~Binary_to_elf() 57 + { 58 + if (this->data_ != NULL) 59 + delete[] this->data_; 60 + } 61 + 62 + // Given FILENAME, create a buffer which looks like an ELF file with 63 + // the contents of FILENAME as the contents of the only section. The 64 + // TASK parameters is mainly for debugging, and records who holds 65 + // locks. 66 + 67 + bool 68 + Binary_to_elf::convert(const Task* task) 69 + { 70 + if (this->size_ == 32) 71 + { 72 + if (!this->big_endian_) 73 + { 74 + #ifdef HAVE_TARGET_32_LITTLE 75 + return this->sized_convert<32, false>(task); 76 + #else 77 + gold_unreachable(); 78 + #endif 79 + } 80 + else 81 + { 82 + #ifdef HAVE_TARGET_32_BIG 83 + return this->sized_convert<32, true>(task); 84 + #else 85 + gold_unreachable(); 86 + #endif 87 + } 88 + } 89 + else if (this->size_ == 64) 90 + { 91 + if (!this->big_endian_) 92 + { 93 + #ifdef HAVE_TARGET_64_LITTLE 94 + return this->sized_convert<64, false>(task); 95 + #else 96 + gold_unreachable(); 97 + #endif 98 + } 99 + else 100 + { 101 + #ifdef HAVE_TARGET_64_BIG 102 + return this->sized_convert<64, true>(task); 103 + #else 104 + gold_unreachable(); 105 + #endif 106 + } 107 + } 108 + else 109 + gold_unreachable(); 110 + } 111 + 112 + // We are going to create: 113 + // * The ELF file header. 114 + // * Five sections: null section, .data, .symtab, .strtab, .shstrtab 115 + // * The contents of the file. 116 + // * Four symbols: null, begin, end, size. 117 + // * Three symbol names. 118 + // * Four section names. 119 + 120 + template<int size, bool big_endian> 121 + bool 122 + Binary_to_elf::sized_convert(const Task* task) 123 + { 124 + // Read the input file. 125 + 126 + File_read f; 127 + if (!f.open(task, this->filename_)) 128 + { 129 + gold_error(_("cannot open %s: %s:"), this->filename_.c_str(), 130 + strerror(errno)); 131 + return false; 132 + } 133 + 134 + section_size_type filesize = convert_to_section_size_type(f.filesize()); 135 + const unsigned char* fileview = f.get_view(0, filesize, false); 136 + 137 + unsigned int align; 138 + if (size == 32) 139 + align = 4; 140 + else if (size == 64) 141 + align = 8; 142 + else 143 + gold_unreachable(); 144 + section_size_type aligned_filesize = align_address(filesize, align); 145 + 146 + // Build the stringpool for the symbol table. 147 + 148 + std::string mangled_name = this->filename_; 149 + for (std::string::iterator p = mangled_name.begin(); 150 + p != mangled_name.end(); 151 + ++p) 152 + if (!ISALNUM(*p)) 153 + *p = '_'; 154 + mangled_name = "_binary_" + mangled_name; 155 + std::string start_symbol_name = mangled_name + "_start"; 156 + std::string end_symbol_name = mangled_name + "_end"; 157 + std::string size_symbol_name = mangled_name + "_size"; 158 + 159 + Stringpool strtab; 160 + strtab.add(start_symbol_name.c_str(), false, NULL); 161 + strtab.add(end_symbol_name.c_str(), false, NULL); 162 + strtab.add(size_symbol_name.c_str(), false, NULL); 163 + strtab.set_string_offsets(); 164 + 165 + // Build the stringpool for the section name table. 166 + 167 + Stringpool shstrtab; 168 + shstrtab.add(".data", false, NULL); 169 + shstrtab.add(".symtab", false, NULL); 170 + shstrtab.add(".strtab", false, NULL); 171 + shstrtab.add(".shstrtab", false, NULL); 172 + shstrtab.set_string_offsets(); 173 + 174 + // Work out the size of the generated file, and the offsets of the 175 + // various sections, and allocate a buffer. 176 + 177 + const int sym_size = elfcpp::Elf_sizes<size>::sym_size; 178 + 179 + size_t output_size = (elfcpp::Elf_sizes<size>::ehdr_size 180 + + 5 * elfcpp::Elf_sizes<size>::shdr_size); 181 + size_t data_offset = output_size; 182 + output_size += aligned_filesize; 183 + size_t symtab_offset = output_size; 184 + output_size += 4 * sym_size; 185 + size_t strtab_offset = output_size; 186 + output_size += strtab.get_strtab_size(); 187 + size_t shstrtab_offset = output_size; 188 + output_size += shstrtab.get_strtab_size(); 189 + 190 + unsigned char* buffer = new unsigned char[output_size]; 191 + 192 + // Write out the data. 193 + 194 + unsigned char* pout = buffer; 195 + 196 + this->write_file_header<size, big_endian>(&pout); 197 + 198 + this->write_section_header<size, big_endian>("", &shstrtab, elfcpp::SHT_NULL, 199 + 0, 0, 0, 0, 0, 200 + 0, 0, &pout); 201 + // Having the section be named ".data" and having it be writable is 202 + // because th GNU linker does it that way, and existing linker 203 + // script expect it. 204 + this->write_section_header<size, big_endian>(".data", &shstrtab, 205 + elfcpp::SHT_PROGBITS, 206 + (elfcpp::SHF_ALLOC 207 + | elfcpp::SHF_WRITE), 208 + data_offset, 209 + filesize, 0, 0, 210 + align, 0, &pout); 211 + this->write_section_header<size, big_endian>(".symtab", &shstrtab, 212 + elfcpp::SHT_SYMTAB, 213 + 0, symtab_offset, 4 * sym_size, 214 + 3, 1, align, sym_size, &pout); 215 + this->write_section_header<size, big_endian>(".strtab", &shstrtab, 216 + elfcpp::SHT_STRTAB, 217 + 0, strtab_offset, 218 + strtab.get_strtab_size(), 219 + 0, 0, 1, 0, &pout); 220 + this->write_section_header<size, big_endian>(".shstrtab", &shstrtab, 221 + elfcpp::SHT_STRTAB, 222 + 0, shstrtab_offset, 223 + shstrtab.get_strtab_size(), 224 + 0, 0, 1, 0, &pout); 225 + 226 + memcpy(pout, fileview, filesize); 227 + pout += filesize; 228 + memset(pout, 0, aligned_filesize - filesize); 229 + pout += aligned_filesize - filesize; 230 + 231 + this->write_symbol<size, big_endian>("", &strtab, 0, 0, &pout); 232 + this->write_symbol<size, big_endian>(start_symbol_name, &strtab, 0, 1, 233 + &pout); 234 + this->write_symbol<size, big_endian>(end_symbol_name, &strtab, filesize, 1, 235 + &pout); 236 + this->write_symbol<size, big_endian>(size_symbol_name, &strtab, filesize, 237 + elfcpp::SHN_ABS, &pout); 238 + 239 + strtab.write_to_buffer(pout, strtab.get_strtab_size()); 240 + pout += strtab.get_strtab_size(); 241 + 242 + shstrtab.write_to_buffer(pout, shstrtab.get_strtab_size()); 243 + pout += shstrtab.get_strtab_size(); 244 + 245 + gold_assert(static_cast<size_t>(pout - buffer) == output_size); 246 + 247 + this->data_ = buffer; 248 + this->filesize_ = output_size; 249 + 250 + f.unlock(task); 251 + 252 + return true; 253 + } 254 + 255 + // Write out the file header. 256 + 257 + template<int size, bool big_endian> 258 + void 259 + Binary_to_elf::write_file_header(unsigned char** ppout) 260 + { 261 + elfcpp::Ehdr_write<size, big_endian> oehdr(*ppout); 262 + 263 + unsigned char e_ident[elfcpp::EI_NIDENT]; 264 + memset(e_ident, 0, elfcpp::EI_NIDENT); 265 + e_ident[elfcpp::EI_MAG0] = elfcpp::ELFMAG0; 266 + e_ident[elfcpp::EI_MAG1] = elfcpp::ELFMAG1; 267 + e_ident[elfcpp::EI_MAG2] = elfcpp::ELFMAG2; 268 + e_ident[elfcpp::EI_MAG3] = elfcpp::ELFMAG3; 269 + if (size == 32) 270 + e_ident[elfcpp::EI_CLASS] = elfcpp::ELFCLASS32; 271 + else if (size == 64) 272 + e_ident[elfcpp::EI_CLASS] = elfcpp::ELFCLASS64; 273 + else 274 + gold_unreachable(); 275 + e_ident[elfcpp::EI_DATA] = (big_endian 276 + ? elfcpp::ELFDATA2MSB 277 + : elfcpp::ELFDATA2LSB); 278 + e_ident[elfcpp::EI_VERSION] = elfcpp::EV_CURRENT; 279 + oehdr.put_e_ident(e_ident); 280 + 281 + oehdr.put_e_type(elfcpp::ET_REL); 282 + oehdr.put_e_machine(this->elf_machine_); 283 + oehdr.put_e_version(elfcpp::EV_CURRENT); 284 + oehdr.put_e_entry(0); 285 + oehdr.put_e_phoff(0); 286 + oehdr.put_e_shoff(elfcpp::Elf_sizes<size>::ehdr_size); 287 + oehdr.put_e_flags(0); 288 + oehdr.put_e_ehsize(elfcpp::Elf_sizes<size>::ehdr_size); 289 + oehdr.put_e_phentsize(0); 290 + oehdr.put_e_phnum(0); 291 + oehdr.put_e_shentsize(elfcpp::Elf_sizes<size>::shdr_size); 292 + oehdr.put_e_shnum(5); 293 + oehdr.put_e_shstrndx(4); 294 + 295 + *ppout += elfcpp::Elf_sizes<size>::ehdr_size; 296 + } 297 + 298 + // Write out a section header. 299 + 300 + template<int size, bool big_endian> 301 + void 302 + Binary_to_elf::write_section_header( 303 + const char* name, 304 + const Stringpool* shstrtab, 305 + elfcpp::SHT type, 306 + unsigned int flags, 307 + section_size_type offset, 308 + section_size_type section_size, 309 + unsigned int link, 310 + unsigned int info, 311 + unsigned int addralign, 312 + unsigned int entsize, 313 + unsigned char** ppout) 314 + { 315 + elfcpp::Shdr_write<size, big_endian> oshdr(*ppout); 316 + 317 + oshdr.put_sh_name(*name == '\0' ? 0 : shstrtab->get_offset(name)); 318 + oshdr.put_sh_type(type); 319 + oshdr.put_sh_flags(flags); 320 + oshdr.put_sh_addr(0); 321 + oshdr.put_sh_offset(offset); 322 + oshdr.put_sh_size(section_size); 323 + oshdr.put_sh_link(link); 324 + oshdr.put_sh_info(info); 325 + oshdr.put_sh_addralign(addralign); 326 + oshdr.put_sh_entsize(entsize); 327 + 328 + *ppout += elfcpp::Elf_sizes<size>::shdr_size; 329 + } 330 + 331 + // Write out a symbol. 332 + 333 + template<int size, bool big_endian> 334 + void 335 + Binary_to_elf::write_symbol( 336 + const std::string& name, 337 + const Stringpool* strtab, 338 + section_size_type value, 339 + unsigned int shndx, 340 + unsigned char** ppout) 341 + { 342 + unsigned char* pout = *ppout; 343 + 344 + elfcpp::Sym_write<size, big_endian> osym(pout); 345 + osym.put_st_name(name.empty() ? 0 : strtab->get_offset(name.c_str())); 346 + osym.put_st_value(value); 347 + osym.put_st_size(0); 348 + osym.put_st_info(name.empty() ? elfcpp::STB_LOCAL : elfcpp::STB_GLOBAL, 349 + elfcpp::STT_NOTYPE); 350 + osym.put_st_other(elfcpp::STV_DEFAULT, 0); 351 + osym.put_st_shndx(shndx); 352 + 353 + *ppout += elfcpp::Elf_sizes<size>::sym_size; 354 + } 355 + 356 + } // End namespace gold.
+116
gold/binary.h
··· 1 + // binary.h -- binary input files for gold -*- C++ -*- 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 + // Support binary input files by making them look like an ELF file. 24 + 25 + #ifndef GOLD_BINARY_H 26 + #define GOLD_BINARY_H 27 + 28 + #include <string> 29 + 30 + #include "elfcpp.h" 31 + 32 + namespace gold 33 + { 34 + 35 + class Task; 36 + 37 + template<typename Stringpool_char> 38 + class Stringpool_template; 39 + 40 + // This class takes a file name and creates a buffer which looks like 41 + // an ELF file read into memory. 42 + 43 + class Binary_to_elf 44 + { 45 + public: 46 + Binary_to_elf(elfcpp::EM machine, int size, bool big_endian, 47 + const std::string& filename); 48 + 49 + ~Binary_to_elf(); 50 + 51 + // Read contents and create an ELF buffer. Return true if this 52 + // succeeds, false otherwise. 53 + bool 54 + convert(const Task*); 55 + 56 + // Return a pointer to the contents of the ELF file. 57 + const unsigned char* 58 + converted_data() const 59 + { return this->data_; } 60 + 61 + // Return a pointer to the contents of the ELF file and let the 62 + // caller take charge of it. It was allocated using new[]. 63 + unsigned char* 64 + converted_data_leak() 65 + { 66 + unsigned char* ret = this->data_; 67 + this->data_ = NULL; 68 + return ret; 69 + } 70 + 71 + // Return the size of the ELF file. 72 + size_t 73 + converted_size() const 74 + { return this->filesize_; } 75 + 76 + private: 77 + Binary_to_elf(const Binary_to_elf&); 78 + Binary_to_elf& operator=(const Binary_to_elf&); 79 + 80 + template<int size, bool big_endian> 81 + bool 82 + sized_convert(const Task*); 83 + 84 + template<int size, bool big_endian> 85 + void 86 + write_file_header(unsigned char**); 87 + 88 + template<int size, bool big_endian> 89 + void 90 + write_section_header(const char*, const Stringpool_template<char>*, 91 + elfcpp::SHT, unsigned int, section_size_type, 92 + section_size_type, unsigned int, unsigned int, 93 + unsigned int, unsigned int, unsigned char**); 94 + 95 + template<int size, bool big_endian> 96 + void 97 + write_symbol(const std::string&, const Stringpool_template<char>*, 98 + section_size_type, unsigned int, unsigned char**); 99 + 100 + // The ELF machine code of the file to create. 101 + elfcpp::EM elf_machine_; 102 + // The size of the file to create, 32 or 64. 103 + int size_; 104 + // Whether to create a big endian file. 105 + bool big_endian_; 106 + // The name of the file to read. 107 + std::string filename_; 108 + // The ELF file data, allocated by new []. 109 + unsigned char* data_; 110 + // The ELF file size. 111 + section_size_type filesize_; 112 + }; 113 + 114 + } // End namespace gold. 115 + 116 + #endif // !defined(GOLD_BINARY_H)
+49 -2
gold/fileread.cc
··· 30 30 #include <sys/uio.h> 31 31 #include "filenames.h" 32 32 33 + #include "parameters.h" 33 34 #include "options.h" 34 35 #include "dirsearch.h" 36 + #include "target.h" 37 + #include "binary.h" 35 38 #include "fileread.h" 36 39 37 40 namespace gold ··· 122 125 return this->descriptor_ >= 0; 123 126 } 124 127 125 - // Open the file for testing purposes. 128 + // Open the file with the contents in memory. 126 129 127 130 bool 128 131 File_read::open(const Task* task, const std::string& name, ··· 686 689 } 687 690 688 691 // Now that we've figured out where the file lives, try to open it. 689 - if (!this->file_.open(task, name)) 692 + 693 + General_options::Object_format format = 694 + this->input_argument_->options().input_format(); 695 + bool ok; 696 + if (format == General_options::OBJECT_FORMAT_ELF) 697 + ok = this->file_.open(task, name); 698 + else 699 + { 700 + gold_assert(format == General_options::OBJECT_FORMAT_BINARY); 701 + ok = this->open_binary(task, name); 702 + } 703 + 704 + if (!ok) 690 705 { 691 706 gold_error(_("cannot open %s: %s"), 692 707 name.c_str(), strerror(errno)); ··· 694 709 } 695 710 696 711 return true; 712 + } 713 + 714 + // Open a file for --format binary. 715 + 716 + bool 717 + Input_file::open_binary(const Task* task, const std::string& name) 718 + { 719 + // In order to open a binary file, we need machine code, size, and 720 + // endianness. If we have a target already, use it, otherwise use 721 + // the defaults. 722 + elfcpp::EM machine; 723 + int size; 724 + bool big_endian; 725 + if (parameters->is_target_valid()) 726 + { 727 + Target* target = parameters->target(); 728 + machine = target->machine_code(); 729 + size = target->get_size(); 730 + big_endian = target->is_big_endian(); 731 + } 732 + else 733 + { 734 + machine = elfcpp::GOLD_DEFAULT_MACHINE; 735 + size = GOLD_DEFAULT_SIZE; 736 + big_endian = GOLD_DEFAULT_BIG_ENDIAN; 737 + } 738 + 739 + Binary_to_elf binary_to_elf(machine, size, big_endian, name); 740 + if (!binary_to_elf.convert(task)) 741 + return false; 742 + return this->file_.open(task, name, binary_to_elf.converted_data_leak(), 743 + binary_to_elf.converted_size()); 697 744 } 698 745 699 746 } // End namespace gold.
+4
gold/fileread.h
··· 426 426 Input_file(const Input_file&); 427 427 Input_file& operator=(const Input_file&); 428 428 429 + // Open a binary file. 430 + bool 431 + open_binary(const Task* task, const std::string& name); 432 + 429 433 // The argument from the command line. 430 434 const Input_file_argument* input_argument_; 431 435 // The name under which we opened the file. This is like the name
+1 -1
gold/gold.cc
··· 196 196 gold_error(_("cannot mix -r with dynamic object %s"), 197 197 (*input_objects->dynobj_begin())->name().c_str()); 198 198 if (!doing_static_link 199 - && options.output_format() != General_options::OUTPUT_FORMAT_ELF) 199 + && options.output_format() != General_options::OBJECT_FORMAT_ELF) 200 200 gold_fatal(_("cannot use non-ELF output format with dynamic object %s"), 201 201 (*input_objects->dynobj_begin())->name().c_str()); 202 202
+4 -4
gold/layout.cc
··· 57 57 // Now we know the final size of the output file and we know where 58 58 // each piece of information goes. 59 59 Output_file* of = new Output_file(parameters->output_file_name()); 60 - if (this->options_.output_format() != General_options::OUTPUT_FORMAT_ELF) 60 + if (this->options_.output_format() != General_options::OBJECT_FORMAT_ELF) 61 61 of->set_is_temporary(); 62 62 of->open(file_size); 63 63 ··· 951 951 else 952 952 load_seg = this->find_first_load_seg(); 953 953 954 - if (this->options_.output_format() != General_options::OUTPUT_FORMAT_ELF) 954 + if (this->options_.output_format() != General_options::OBJECT_FORMAT_ELF) 955 955 load_seg = NULL; 956 956 957 957 gold_assert(phdr_seg == NULL || load_seg != NULL); ··· 2502 2502 Layout::write_binary(Output_file* in) const 2503 2503 { 2504 2504 gold_assert(this->options_.output_format() 2505 - == General_options::OUTPUT_FORMAT_BINARY); 2505 + == General_options::OBJECT_FORMAT_BINARY); 2506 2506 2507 2507 // Get the size of the binary file. 2508 2508 uint64_t max_load_address = 0; ··· 2672 2672 Close_task_runner::run(Workqueue*, const Task*) 2673 2673 { 2674 2674 // If we've been asked to create a binary file, we do so here. 2675 - if (this->options_->output_format() != General_options::OUTPUT_FORMAT_ELF) 2675 + if (this->options_->output_format() != General_options::OBJECT_FORMAT_ELF) 2676 2676 this->layout_->write_binary(this->of_); 2677 2677 2678 2678 this->of_->close();
+40 -15
gold/options.cc
··· 135 135 namespace 136 136 { 137 137 138 + // Recognize input and output target names. The GNU linker accepts 139 + // these with --format and --oformat. This code is intended to be 140 + // minimally compatible. In practice for an ELF target this would be 141 + // the same target as the input files; that name always start with 142 + // "elf". Non-ELF targets would be "srec", "symbolsrec", "tekhex", 143 + // "binary", "ihex". 144 + 145 + gold::General_options::Object_format 146 + string_to_object_format(const char* arg) 147 + { 148 + if (strncmp(arg, "elf", 3) == 0) 149 + return gold::General_options::OBJECT_FORMAT_ELF; 150 + else if (strcmp(arg, "binary") == 0) 151 + return gold::General_options::OBJECT_FORMAT_BINARY; 152 + else 153 + { 154 + gold::gold_error(_("format '%s' not supported " 155 + "(supported formats: elf, binary)"), 156 + arg); 157 + return gold::General_options::OBJECT_FORMAT_ELF; 158 + } 159 + } 160 + 138 161 // Handle the special -l option, which adds an input file. 139 162 140 163 int ··· 428 451 &Position_dependent_options::set_static_search), 429 452 GENERAL_NOARG('\0', "Bsymbolic", N_("Bind defined symbols locally"), 430 453 NULL, ONE_DASH, &General_options::set_symbolic), 454 + POSDEP_ARG('b', "format", N_("Set input format (elf, binary)"), 455 + N_("-b FORMAT, --format FORMAT"), TWO_DASHES, 456 + &Position_dependent_options::set_input_format), 431 457 #ifdef HAVE_ZLIB_H 432 458 # define ZLIB_STR ",zlib" 433 459 #else ··· 608 634 search_path_(), 609 635 optimization_level_(0), 610 636 output_file_name_("a.out"), 611 - output_format_(OUTPUT_FORMAT_ELF), 637 + output_format_(OBJECT_FORMAT_ELF), 612 638 is_relocatable_(false), 613 639 strip_(STRIP_NONE), 614 640 allow_shlib_undefined_(false), ··· 647 673 this->script_options_->define_symbol(arg); 648 674 } 649 675 650 - // Handle the --oformat option. The GNU linker accepts a target name 651 - // with --oformat. In practice for an ELF target this would be the 652 - // same target as the input files. That name always start with "elf". 653 - // Non-ELF targets would be "srec", "symbolsrec", "tekhex", "binary", 654 - // "ihex". 676 + // Handle the --oformat option. 655 677 656 678 void 657 679 General_options::set_output_format(const char* arg) 658 680 { 659 - if (strncmp(arg, "elf", 3) == 0) 660 - this->output_format_ = OUTPUT_FORMAT_ELF; 661 - else if (strcmp(arg, "binary") == 0) 662 - this->output_format_ = OUTPUT_FORMAT_BINARY; 663 - else 664 - gold_error(_("format '%s' not supported (supported formats: elf, binary)"), 665 - arg); 681 + this->output_format_ = string_to_object_format(arg); 666 682 } 667 683 668 684 // Handle the -z option. ··· 738 754 Position_dependent_options::Position_dependent_options() 739 755 : do_static_search_(false), 740 756 as_needed_(false), 741 - include_whole_archive_(false) 757 + include_whole_archive_(false), 758 + input_format_(General_options::OBJECT_FORMAT_ELF) 742 759 { 760 + } 761 + 762 + // Set the input format. 763 + 764 + void 765 + Position_dependent_options::set_input_format(const char* arg) 766 + { 767 + this->input_format_ = string_to_object_format(arg); 743 768 } 744 769 745 770 // Search_directory methods. ··· 1045 1070 if (this->options_.is_shared() && this->options_.is_relocatable()) 1046 1071 gold_fatal(_("-shared and -r are incompatible")); 1047 1072 1048 - if (this->options_.output_format() != General_options::OUTPUT_FORMAT_ELF 1073 + if (this->options_.output_format() != General_options::OBJECT_FORMAT_ELF 1049 1074 && (this->options_.is_shared() || this->options_.is_relocatable())) 1050 1075 gold_fatal(_("binary output format not compatible with -shared or -r")); 1051 1076
+21 -10
gold/options.h
··· 109 109 class General_options 110 110 { 111 111 public: 112 + enum Object_format 113 + { 114 + // Ordinary ELF. 115 + OBJECT_FORMAT_ELF, 116 + // Straight binary format. 117 + OBJECT_FORMAT_BINARY 118 + }; 119 + 112 120 General_options(Script_options*); 113 121 114 122 // -e: set entry address. ··· 150 158 151 159 // --oformat: Output format. 152 160 153 - enum Output_format 154 - { 155 - // Ordinary ELF. 156 - OUTPUT_FORMAT_ELF, 157 - // Straight binary format. 158 - OUTPUT_FORMAT_BINARY 159 - }; 160 - 161 - Output_format 161 + Object_format 162 162 output_format() const 163 163 { return this->output_format_; } 164 164 ··· 561 561 Dir_list search_path_; 562 562 int optimization_level_; 563 563 const char* output_file_name_; 564 - Output_format output_format_; 564 + Object_format output_format_; 565 565 bool is_relocatable_; 566 566 Strip strip_; 567 567 bool allow_shlib_undefined_; ··· 593 593 class Position_dependent_options 594 594 { 595 595 public: 596 + typedef General_options::Object_format Object_format; 597 + 596 598 Position_dependent_options(); 597 599 598 600 // -Bdynamic/-Bstatic: Whether we are searching for a static archive ··· 612 614 bool 613 615 include_whole_archive() const 614 616 { return this->include_whole_archive_; } 617 + 618 + // --format: The format of the input file. 619 + Object_format 620 + input_format() const 621 + { return this->input_format_; } 615 622 616 623 void 617 624 set_static_search() ··· 637 644 clear_whole_archive() 638 645 { this->include_whole_archive_ = false; } 639 646 647 + void 648 + set_input_format(const char*); 649 + 640 650 private: 641 651 bool do_static_search_; 642 652 bool as_needed_; 643 653 bool include_whole_archive_; 654 + Object_format input_format_; 644 655 }; 645 656 646 657 // A single file or library argument from the command line.
+13
gold/testsuite/Makefile.am
··· 53 53 check_PROGRAMS += object_unittest 54 54 object_unittest_SOURCES = object_unittest.cc 55 55 56 + check_PROGRAMS += binary_unittest 57 + binary_unittest_SOURCES = binary_unittest.cc 58 + 56 59 57 60 # --------------------------------------------------------------------- 58 61 # These tests test the output of gold (end-to-end tests). In ··· 549 552 $(CXXCOMPILE) -c -o $@ $< 550 553 justsyms_2r.o: justsyms_2.o gcctestdir/ld 551 554 gcctestdir/ld -o $@ -r -T $(srcdir)/justsyms.t justsyms_2.o 555 + 556 + check_PROGRAMS += binary_test 557 + binary_test_SOURCES = binary_test.cc 558 + binary_test_DEPENDENCIES = gcctestdir/ld binary.txt 559 + binary_test_LDFLAGS = -Bgcctestdir/ -Wl,--format,binary,binary.txt,--format,elf 560 + # Copy the file to the build directory to avoid worrying about the 561 + # full pathname in the generated symbols. 562 + binary.txt: $(srcdir)/binary.in 563 + rm -f $@ 564 + $(LN_S) $< $@ 552 565 553 566 if OBJDUMP_AND_CPPFILT 554 567 check_SCRIPTS += ver_matching_test.sh
+45 -6
gold/testsuite/Makefile.in
··· 42 42 build_triplet = @build@ 43 43 host_triplet = @host@ 44 44 target_triplet = @target@ 45 - check_PROGRAMS = object_unittest$(EXEEXT) $(am__EXEEXT_1) \ 46 - $(am__EXEEXT_2) $(am__EXEEXT_3) $(am__EXEEXT_4) \ 47 - $(am__EXEEXT_5) $(am__EXEEXT_6) $(am__EXEEXT_7) \ 48 - $(am__EXEEXT_8) 45 + check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \ 46 + $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ 47 + $(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6) \ 48 + $(am__EXEEXT_7) $(am__EXEEXT_8) 49 49 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_1 = basic_test \ 50 50 @GCC_TRUE@@NATIVE_LINKER_TRUE@ basic_static_test basic_pic_test \ 51 51 @GCC_TRUE@@NATIVE_LINKER_TRUE@ basic_static_pic_test \ ··· 176 176 @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_o_specialfile \ 177 177 @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_o_specialfile_and_compress_debug_sections \ 178 178 @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test script_test_1 \ 179 - @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_2 justsyms 179 + @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_2 justsyms \ 180 + @GCC_TRUE@@NATIVE_LINKER_TRUE@ binary_test 180 181 @GCC_FALSE@script_test_1_DEPENDENCIES = libgoldtest.a ../libgold.a \ 181 182 @GCC_FALSE@ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \ 182 183 @GCC_FALSE@ $(am__DEPENDENCIES_1) ··· 195 196 @GCC_FALSE@ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \ 196 197 @GCC_FALSE@ $(am__DEPENDENCIES_1) 197 198 @NATIVE_LINKER_FALSE@justsyms_DEPENDENCIES = libgoldtest.a \ 199 + @NATIVE_LINKER_FALSE@ ../libgold.a ../../libiberty/libiberty.a \ 200 + @NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) \ 201 + @NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) 202 + @GCC_FALSE@binary_test_DEPENDENCIES = libgoldtest.a ../libgold.a \ 203 + @GCC_FALSE@ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \ 204 + @GCC_FALSE@ $(am__DEPENDENCIES_1) 205 + @NATIVE_LINKER_FALSE@binary_test_DEPENDENCIES = libgoldtest.a \ 198 206 @NATIVE_LINKER_FALSE@ ../libgold.a ../../libiberty/libiberty.a \ 199 207 @NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) \ 200 208 @NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) ··· 272 280 @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test$(EXEEXT) \ 273 281 @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_1$(EXEEXT) \ 274 282 @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_2$(EXEEXT) \ 275 - @GCC_TRUE@@NATIVE_LINKER_TRUE@ justsyms$(EXEEXT) 283 + @GCC_TRUE@@NATIVE_LINKER_TRUE@ justsyms$(EXEEXT) \ 284 + @GCC_TRUE@@NATIVE_LINKER_TRUE@ binary_test$(EXEEXT) 276 285 @GCC_TRUE@@NATIVE_LINKER_TRUE@@OBJDUMP_AND_CPPFILT_TRUE@am__EXEEXT_8 = script_test_3$(EXEEXT) 277 286 basic_pic_test_SOURCES = basic_pic_test.c 278 287 basic_pic_test_OBJECTS = basic_pic_test.$(OBJEXT) ··· 297 306 basic_test_OBJECTS = basic_test.$(OBJEXT) 298 307 basic_test_LDADD = $(LDADD) 299 308 basic_test_DEPENDENCIES = libgoldtest.a ../libgold.a \ 309 + ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \ 310 + $(am__DEPENDENCIES_1) 311 + am__binary_test_SOURCES_DIST = binary_test.cc 312 + @GCC_TRUE@@NATIVE_LINKER_TRUE@am_binary_test_OBJECTS = \ 313 + @GCC_TRUE@@NATIVE_LINKER_TRUE@ binary_test.$(OBJEXT) 314 + binary_test_OBJECTS = $(am_binary_test_OBJECTS) 315 + binary_test_LDADD = $(LDADD) 316 + am_binary_unittest_OBJECTS = binary_unittest.$(OBJEXT) 317 + binary_unittest_OBJECTS = $(am_binary_unittest_OBJECTS) 318 + binary_unittest_LDADD = $(LDADD) 319 + binary_unittest_DEPENDENCIES = libgoldtest.a ../libgold.a \ 300 320 ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \ 301 321 $(am__DEPENDENCIES_1) 302 322 am__constructor_static_test_SOURCES_DIST = constructor_test.cc ··· 577 597 -o $@ 578 598 SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c \ 579 599 basic_static_pic_test.c basic_static_test.c basic_test.c \ 600 + $(binary_test_SOURCES) $(binary_unittest_SOURCES) \ 580 601 $(constructor_static_test_SOURCES) $(constructor_test_SOURCES) \ 581 602 $(exception_same_shared_test_SOURCES) \ 582 603 $(exception_separate_shared_12_test_SOURCES) \ ··· 612 633 $(ver_test_SOURCES) $(weak_test_SOURCES) 613 634 DIST_SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c \ 614 635 basic_static_pic_test.c basic_static_test.c basic_test.c \ 636 + $(am__binary_test_SOURCES_DIST) $(binary_unittest_SOURCES) \ 615 637 $(am__constructor_static_test_SOURCES_DIST) \ 616 638 $(am__constructor_test_SOURCES_DIST) \ 617 639 $(am__exception_same_shared_test_SOURCES_DIST) \ ··· 826 848 $(THREADSLIB) 827 849 828 850 object_unittest_SOURCES = object_unittest.cc 851 + binary_unittest_SOURCES = binary_unittest.cc 829 852 @GCC_TRUE@@NATIVE_LINKER_TRUE@constructor_test_SOURCES = constructor_test.cc 830 853 @GCC_TRUE@@NATIVE_LINKER_TRUE@constructor_test_DEPENDENCIES = gcctestdir/ld 831 854 @GCC_TRUE@@NATIVE_LINKER_TRUE@constructor_test_LDFLAGS = -Bgcctestdir/ ··· 1025 1048 @GCC_TRUE@@NATIVE_LINKER_TRUE@justsyms_SOURCES = justsyms_1.cc 1026 1049 @GCC_TRUE@@NATIVE_LINKER_TRUE@justsyms_DEPENDENCIES = gcctestdir/ld justsyms_2r.o 1027 1050 @GCC_TRUE@@NATIVE_LINKER_TRUE@justsyms_LDFLAGS = -Bgcctestdir/ -Wl,-R,justsyms_2r.o 1051 + @GCC_TRUE@@NATIVE_LINKER_TRUE@binary_test_SOURCES = binary_test.cc 1052 + @GCC_TRUE@@NATIVE_LINKER_TRUE@binary_test_DEPENDENCIES = gcctestdir/ld binary.txt 1053 + @GCC_TRUE@@NATIVE_LINKER_TRUE@binary_test_LDFLAGS = -Bgcctestdir/ -Wl,--format,binary,binary.txt,--format,elf 1028 1054 all: all-am 1029 1055 1030 1056 .SUFFIXES: ··· 1092 1118 @NATIVE_LINKER_FALSE@basic_test$(EXEEXT): $(basic_test_OBJECTS) $(basic_test_DEPENDENCIES) 1093 1119 @NATIVE_LINKER_FALSE@ @rm -f basic_test$(EXEEXT) 1094 1120 @NATIVE_LINKER_FALSE@ $(LINK) $(basic_test_LDFLAGS) $(basic_test_OBJECTS) $(basic_test_LDADD) $(LIBS) 1121 + binary_test$(EXEEXT): $(binary_test_OBJECTS) $(binary_test_DEPENDENCIES) 1122 + @rm -f binary_test$(EXEEXT) 1123 + $(CXXLINK) $(binary_test_LDFLAGS) $(binary_test_OBJECTS) $(binary_test_LDADD) $(LIBS) 1124 + binary_unittest$(EXEEXT): $(binary_unittest_OBJECTS) $(binary_unittest_DEPENDENCIES) 1125 + @rm -f binary_unittest$(EXEEXT) 1126 + $(CXXLINK) $(binary_unittest_LDFLAGS) $(binary_unittest_OBJECTS) $(binary_unittest_LDADD) $(LIBS) 1095 1127 constructor_static_test$(EXEEXT): $(constructor_static_test_OBJECTS) $(constructor_static_test_DEPENDENCIES) 1096 1128 @rm -f constructor_static_test$(EXEEXT) 1097 1129 $(CXXLINK) $(constructor_static_test_LDFLAGS) $(constructor_static_test_OBJECTS) $(constructor_static_test_LDADD) $(LIBS) ··· 1250 1282 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basic_static_pic_test.Po@am__quote@ 1251 1283 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basic_static_test.Po@am__quote@ 1252 1284 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basic_test.Po@am__quote@ 1285 + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/binary_test.Po@am__quote@ 1286 + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/binary_unittest.Po@am__quote@ 1253 1287 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/constructor_test.Po@am__quote@ 1254 1288 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exception_test_1.Po@am__quote@ 1255 1289 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exception_test_2.Po@am__quote@ ··· 1718 1752 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -c -o $@ $< 1719 1753 @GCC_TRUE@@NATIVE_LINKER_TRUE@justsyms_2r.o: justsyms_2.o gcctestdir/ld 1720 1754 @GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld -o $@ -r -T $(srcdir)/justsyms.t justsyms_2.o 1755 + # Copy the file to the build directory to avoid worrying about the 1756 + # full pathname in the generated symbols. 1757 + @GCC_TRUE@@NATIVE_LINKER_TRUE@binary.txt: $(srcdir)/binary.in 1758 + @GCC_TRUE@@NATIVE_LINKER_TRUE@ rm -f $@ 1759 + @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(LN_S) $< $@ 1721 1760 @GCC_TRUE@@NATIVE_LINKER_TRUE@@OBJDUMP_AND_CPPFILT_TRUE@ver_matching_def.so: ver_matching_def.cc gcctestdir/ld 1722 1761 @GCC_TRUE@@NATIVE_LINKER_TRUE@@OBJDUMP_AND_CPPFILT_TRUE@ $(CXXLINK) -O0 -Bgcctestdir/ -shared $(srcdir)/ver_matching_def.cc -Wl,--version-script=$(srcdir)/version_script.map 1723 1762 @GCC_TRUE@@NATIVE_LINKER_TRUE@@OBJDUMP_AND_CPPFILT_TRUE@ver_matching_test.stdout: ver_matching_def.so
+1
gold/testsuite/binary.in
··· 1 + This file is used for the binary test.
+46
gold/testsuite/binary_test.cc
··· 1 + // binary_test.cc -- test --format binary for gold 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 + // This program is linked with a small text file named binary.txt 24 + // using --formatbinary. 25 + 26 + #include <cassert> 27 + #include <cstddef> 28 + #include <cstring> 29 + #include <stdint.h> 30 + 31 + extern char _binary_binary_txt_start[]; 32 + extern char _binary_binary_txt_end[]; 33 + extern char _binary_binary_txt_size[]; 34 + 35 + int 36 + main(int, char**) 37 + { 38 + int size = reinterpret_cast<uintptr_t>(_binary_binary_txt_size); 39 + assert(size == _binary_binary_txt_end - _binary_binary_txt_start); 40 + 41 + const char* const txt = "This file is used for the binary test.\n"; 42 + assert(strncmp(txt, _binary_binary_txt_start, size) == 0); 43 + assert(static_cast<size_t>(size) == strlen(txt)); 44 + 45 + return 0; 46 + }
+147
gold/testsuite/binary_unittest.cc
··· 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 + 40 + namespace gold_testsuite 41 + { 42 + 43 + using namespace gold; 44 + 45 + template<int size, bool big_endian> 46 + bool 47 + Sized_binary_test(Target* target) 48 + { 49 + // We need a pretend Task. 50 + const Task* task = reinterpret_cast<const Task*>(-1); 51 + 52 + // Use the executable itself as the binary data. 53 + struct stat st; 54 + CHECK(::stat(gold::program_name, &st) == 0); 55 + int o = ::open(gold::program_name, O_RDONLY); 56 + CHECK(o >= 0); 57 + unsigned char* filedata = new unsigned char[st.st_size]; 58 + CHECK(::read(o, filedata, st.st_size) == st.st_size); 59 + CHECK(::close(o) == 0); 60 + 61 + Binary_to_elf binary(static_cast<elfcpp::EM>(0xffff), size, big_endian, 62 + gold::program_name); 63 + 64 + CHECK(binary.convert(task)); 65 + 66 + Input_file input_file(task, "test.o", binary.converted_data(), 67 + binary.converted_size()); 68 + Object* object = make_elf_object("test.o", &input_file, 0, 69 + binary.converted_data(), 70 + binary.converted_size()); 71 + CHECK(object != NULL); 72 + if (object == NULL) 73 + return false; 74 + 75 + CHECK(!object->is_dynamic()); 76 + CHECK(object->target() == target); 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 == 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 + delete sd.section_names; 91 + delete sd.symbols; 92 + delete sd.symbol_names; 93 + 94 + Sized_relobj<size, big_endian>* relobj = 95 + static_cast<Sized_relobj<size, big_endian>*>(object); 96 + typename Sized_relobj<size, big_endian>::Address value; 97 + CHECK(relobj->symbol_section_and_value(0, &value) == 0); 98 + CHECK(value == 0); 99 + CHECK(relobj->symbol_section_and_value(1, &value) == 1); 100 + CHECK(value == 0); 101 + CHECK(relobj->symbol_section_and_value(2, &value) == 1); 102 + CHECK(static_cast<off_t>(value) == st.st_size); 103 + CHECK(relobj->symbol_section_and_value(3, &value) == elfcpp::SHN_ABS); 104 + CHECK(static_cast<off_t>(value) == st.st_size); 105 + 106 + object->unlock(task); 107 + return true; 108 + } 109 + 110 + bool 111 + Binary_test(Test_report*) 112 + { 113 + Errors errors(gold::program_name); 114 + initialize_parameters(&errors); 115 + 116 + Script_options script_options; 117 + General_options options(&script_options); 118 + set_parameters_from_options(&options); 119 + 120 + int fail = 0; 121 + 122 + #ifdef HAVE_TARGET_32_LITTLE 123 + if (!Sized_binary_test<32, false>(target_test_pointer_32_little)) 124 + ++fail; 125 + #endif 126 + 127 + #ifdef HAVE_TARGET_32_BIG 128 + if (!Sized_binary_test<32, true>(target_test_pointer_32_big)) 129 + ++fail; 130 + #endif 131 + 132 + #ifdef HAVE_TARGET_64_LITTLE 133 + if (!Sized_binary_test<64, false>(target_test_pointer_64_little)) 134 + ++fail; 135 + #endif 136 + 137 + #ifdef HAVE_TARGET_64_BIG 138 + if (!Sized_binary_test<64, true>(target_test_pointer_64_big)) 139 + ++fail; 140 + #endif 141 + 142 + return fail == 0; 143 + } 144 + 145 + Register_test binary_register("Binary", Binary_test); 146 + 147 + } // End namespace gold_testsuite.