1b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines/* 2b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Copyright 2011, The Android Open Source Project 3b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * 4b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 5b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * you may not use this file except in compliance with the License. 6b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * You may obtain a copy of the License at 7b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * 8b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * http://www.apache.org/licenses/LICENSE-2.0 9b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * 10b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Unless required by applicable law or agreed to in writing, software 11b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 12b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * See the License for the specific language governing permissions and 14b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * limitations under the License. 15b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines */ 16b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 17b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFObject.h" 18b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 19b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "utils/serialize.h" 20b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELF.h" 21b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 22b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <fcntl.h> 23b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <stdlib.h> 24b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <sys/mman.h> 25b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <sys/stat.h> 26b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <sys/types.h> 27b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <map> 28b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <stdio.h> 29b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <stdarg.h> 30b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 31b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesusing namespace std; 32b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 33b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesbool open_mmap_file(char const *filename, 34b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines int &fd, 35b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines unsigned char const *&image, 36b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines size_t &size); 37b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 38b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesvoid close_mmap_file(int fd, 39b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines unsigned char const *image, 40b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines size_t size); 41b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 42b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesvoid dump_and_run_file(unsigned char const *image, size_t size, 43b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines int argc, char **argv); 44b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 45b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesint main(int argc, char **argv) { 46b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Check arguments 47b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (argc < 2) { 48b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines llvm::errs() << "USAGE: " << argv[0] << " [ELFObjectFile] [ARGS]\n"; 49b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines exit(EXIT_FAILURE); 50b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 51b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 52b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Filename from argument 53b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines char const *filename = argv[1]; 54b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 55b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Open the file 56b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines int fd = -1; 57b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines unsigned char const *image = NULL; 58b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines size_t image_size = 0; 59b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 60b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (!open_mmap_file(filename, fd, image, image_size)) { 61b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines exit(EXIT_FAILURE); 62b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 63b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 64b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Dump and run the file 65b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines dump_and_run_file(image, image_size, argc - 1, argv + 1); 66b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 67b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Close the file 68b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines close_mmap_file(fd, image, image_size); 69b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 70b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return EXIT_SUCCESS; 71b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 72b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 73b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines// FIXME: I don't like these stub as well. However, before we implement 74b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines// x86 64bit far jump stub, we have to ensure find_sym only returns 75b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines// near address. 76b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 77b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesint stub_printf(char const *fmt, ...) { 78b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines va_list ap; 79b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines va_start(ap, fmt); 80b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines int result = vprintf(fmt, ap); 81b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines va_end(ap); 82b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return result; 83b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 84b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 85b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesint stub_scanf(char const *fmt, ...) { 86b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines va_list ap; 87b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines va_start(ap, fmt); 88b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines int result = vscanf(fmt, ap); 89b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines va_end(ap); 90b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return result; 91b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 92b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 93b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesvoid stub_srand(unsigned int seed) { 94b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines srand(seed); 95b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 96b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 97b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesint stub_rand() { 98b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return rand(); 99b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 100b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 101b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestime_t stub_time(time_t *output) { 102b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return time(output); 103b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 104b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 105b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesvoid *find_sym(void *context, char const *name) { 106b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines struct func_entry_t { 107b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines char const *name; 108b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines size_t name_len; 109b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void *addr; 110b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines }; 111b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 112b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines static func_entry_t const tab[] = { 113b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define DEF(NAME, ADDR) \ 114b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines { NAME, sizeof(NAME) - 1, (void *)(ADDR) }, 115b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 116b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines DEF("printf", stub_printf) 117b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines DEF("scanf", stub_scanf) 118b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines DEF("__isoc99_scanf", stub_scanf) 119b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines DEF("rand", stub_rand) 120b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines DEF("time", stub_time) 121b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines DEF("srand", stub_srand) 122b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#undef DEF 123b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines }; 124b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 125b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines static size_t const tab_size = sizeof(tab) / sizeof(func_entry_t); 126b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 127b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Note: Since our table is small, we are using trivial O(n) searching 128b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // function. For bigger table, it will be better to use binary 129b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // search or hash function. 130b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines size_t name_len = strlen(name); 131b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines for (size_t i = 0; i < tab_size; ++i) { 132b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (name_len == tab[i].name_len && strcmp(name, tab[i].name) == 0) { 133b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return tab[i].addr; 134b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 135b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 136b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 137b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines assert(0 && "Can't find symbol."); 138b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return 0; 139b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 140b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 141b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth, typename Archiver> 142b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesvoid dump_and_run_object(Archiver &AR, int argc, char **argv) { 143d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines std::unique_ptr<ELFObject<Bitwidth> > object(ELFObject<Bitwidth>::read(AR)); 144b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 145b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (!object) { 146b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines llvm::errs() << "ERROR: Unable to load object\n"; 147b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 148b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 149b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines object->print(); 150b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines out().flush(); 151b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 152b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionSymTab<Bitwidth> *symtab = 153b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines static_cast<ELFSectionSymTab<Bitwidth> *>( 154b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines object->getSectionByName(".symtab")); 155b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 156b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines object->relocate(find_sym, 0); 157b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines out() << "relocate finished!\n"; 158b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines out().flush(); 159b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 160b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines int machine = object->getHeader()->getMachine(); 161b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 162b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void *main_addr = symtab->getByName("main")->getAddress(machine); 163b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines out() << "main address: " << main_addr << "\n"; 164b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines out().flush(); 165b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 166b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ((int (*)(int, char **))main_addr)(argc, argv); 167b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines fflush(stdout); 168b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 169b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 170b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <typename Archiver> 171b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesvoid dump_and_run_file_from_archive(bool is32bit, Archiver &AR, 172b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines int argc, char **argv) { 173b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (is32bit) { 174b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines dump_and_run_object<32>(AR, argc, argv); 175b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } else { 176b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines dump_and_run_object<64>(AR, argc, argv); 177b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 178b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 179b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 180b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesvoid dump_and_run_file(unsigned char const *image, size_t size, 181b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines int argc, char **argv) { 182b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (size < EI_NIDENT) { 183b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines llvm::errs() << "ERROR: ELF identification corrupted.\n"; 184b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return; 185b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 186b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 187b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (image[EI_DATA] != ELFDATA2LSB && image[EI_DATA] != ELFDATA2MSB) { 188b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines llvm::errs() << "ERROR: Unknown endianness.\n"; 189b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return; 190b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 191b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 192b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (image[EI_CLASS] != ELFCLASS32 && image[EI_CLASS] != ELFCLASS64) { 193b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines llvm::errs() << "ERROR: Unknown machine class.\n"; 194b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return; 195b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 196b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 197b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines bool isLittleEndian = (image[EI_DATA] == ELFDATA2LSB); 198b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines bool is32bit = (image[EI_CLASS] == ELFCLASS32); 199b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 200b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (isLittleEndian) { 201b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ArchiveReaderLE AR(image, size); 202b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines dump_and_run_file_from_archive(is32bit, AR, argc, argv); 203b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } else { 204b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ArchiveReaderBE AR(image, size); 205b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines dump_and_run_file_from_archive(is32bit, AR, argc, argv); 206b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 207b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 208b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 209b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesbool open_mmap_file(char const *filename, 210b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines int &fd, 211b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines unsigned char const *&image, 212b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines size_t &size) { 213b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Query the file status 214b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines struct stat sb; 215b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (stat(filename, &sb) != 0) { 216b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines llvm::errs() << "ERROR: " << filename << " not found.\n"; 217b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return false; 218b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 219b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 220b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (!S_ISREG(sb.st_mode)) { 221b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines llvm::errs() << "ERROR: " << filename << " is not a regular file.\n"; 222b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return false; 223b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 224b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 225b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines size = (size_t)sb.st_size; 226b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 227b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Open the file in readonly mode 228b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines fd = open(filename, O_RDONLY); 229b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (fd < 0) { 230b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines llvm::errs() << "ERROR: Unable to open " << filename << "\n"; 231b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return false; 232b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 233b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 234b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Map the file image 235b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines image = static_cast<unsigned char const *>( 236b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0)); 237b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 238b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (image == MAP_FAILED) { 239b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines llvm::errs() << "ERROR: Unable to map " << filename << " to memory.\n"; 240b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines close(fd); 241b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return false; 242b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 243b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 244b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return true; 245b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 246b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 247b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesvoid close_mmap_file(int fd, 248b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines unsigned char const *image, 249b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines size_t size) { 250b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (image) { 251b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines munmap((void *)image, size); 252b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 253b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 254b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (fd >= 0) { 255b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines close(fd); 256b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 257b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 258