gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
object_file.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002-2004 The Regents of The University of Michigan
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * Authors: Nathan Binkert
29  * Steve Reinhardt
30  */
31 
33 
34 #include <fcntl.h>
35 #include <sys/mman.h>
36 #include <sys/types.h>
37 #include <unistd.h>
38 #include <zlib.h>
39 
40 #include <cstdio>
41 #include <list>
42 #include <string>
43 
44 #include "base/cprintf.hh"
50 #include "base/loader/symtab.hh"
51 #include "mem/port_proxy.hh"
52 
53 using namespace std;
54 
55 ObjectFile::ObjectFile(const string &_filename,
56  size_t _len, uint8_t *_data,
57  Arch _arch, OpSys _op_sys)
58  : filename(_filename), fileData(_data), len(_len),
59  arch(_arch), opSys(_op_sys), entry(0), globalPtr(0),
60  text{0, nullptr, 0}, data{0, nullptr, 0}, bss{0, nullptr, 0}
61 {
62 }
63 
64 
66 {
67  if (fileData) {
68  ::munmap((char*)fileData, len);
69  fileData = NULL;
70  }
71 }
72 
73 
74 bool
75 ObjectFile::loadSection(Section *sec, PortProxy& mem_proxy, Addr addr_mask,
76  Addr offset)
77 {
78  if (sec->size != 0) {
79  Addr addr = (sec->baseAddr & addr_mask) + offset;
80  if (sec->fileImage) {
81  mem_proxy.writeBlob(addr, sec->fileImage, sec->size);
82  }
83  else {
84  // no image: must be bss
85  mem_proxy.memsetBlob(addr, 0, sec->size);
86  }
87  }
88  return true;
89 }
90 
91 
92 bool
94 {
95  return (loadSection(&text, mem_proxy, addr_mask, offset)
96  && loadSection(&data, mem_proxy, addr_mask, offset)
97  && loadSection(&bss, mem_proxy, addr_mask, offset));
98 }
99 
100 static bool
102 {
103  uint8_t buf[2] = {0};
104  size_t sz = pread(fd, buf, 2, 0);
105  panic_if(sz != 2, "Couldn't read magic bytes from object file");
106  return ((buf[0] == 0x1f) && (buf[1] == 0x8b));
107 }
108 
109 static int
111 {
112  const size_t blk_sz = 4096;
113 
114  gzFile fdz = gzdopen(fd, "rb");
115  if (!fdz) {
116  return -1;
117  }
118 
119  size_t tmp_len = strlen(P_tmpdir);
120  char *tmpnam = (char*) malloc(tmp_len + 20);
121  strcpy(tmpnam, P_tmpdir);
122  strcpy(tmpnam+tmp_len, "/gem5-gz-obj-XXXXXX"); // 19 chars
123  fd = mkstemp(tmpnam); // repurposing fd variable for output
124  if (fd < 0) {
125  free(tmpnam);
126  gzclose(fdz);
127  return fd;
128  }
129 
130  if (unlink(tmpnam) != 0)
131  warn("couldn't remove temporary file %s\n", tmpnam);
132 
133  free(tmpnam);
134 
135  auto buf = new uint8_t[blk_sz];
136  int r; // size of (r)emaining uncopied data in (buf)fer
137  while ((r = gzread(fdz, buf, blk_sz)) > 0) {
138  auto p = buf; // pointer into buffer
139  while (r > 0) {
140  auto sz = write(fd, p, r);
141  assert(sz <= r);
142  r -= sz;
143  p += sz;
144  }
145  }
146  delete[] buf;
147  gzclose(fdz);
148  if (r < 0) { // error
149  close(fd);
150  return -1;
151  }
152  assert(r == 0); // finished successfully
153  return fd; // return fd to decompressed temporary file for mmap()'ing
154 }
155 
156 ObjectFile *
157 createObjectFile(const string &fname, bool raw)
158 {
159  // open the file
160  int fd = open(fname.c_str(), O_RDONLY);
161  if (fd < 0) {
162  return NULL;
163  }
164 
165  // decompress GZ files
166  if (hasGzipMagic(fd)) {
167  fd = doGzipLoad(fd);
168  if (fd < 0) {
169  return NULL;
170  }
171  }
172 
173  // find the length of the file by seeking to the end
174  off_t off = lseek(fd, 0, SEEK_END);
175  fatal_if(off < 0,
176  "Failed to determine size of object file %s\n", fname);
177  auto len = static_cast<size_t>(off);
178 
179  // mmap the whole shebang
180  uint8_t *file_data = (uint8_t *)mmap(NULL, len, PROT_READ, MAP_SHARED,
181  fd, 0);
182  close(fd);
183 
184  if (file_data == MAP_FAILED) {
185  return NULL;
186  }
187 
188  ObjectFile *file_obj = NULL;
189 
190  // figure out what we have here
191  if ((file_obj = ElfObject::tryFile(fname, len, file_data)) != NULL) {
192  return file_obj;
193  }
194 
195  if ((file_obj = EcoffObject::tryFile(fname, len, file_data)) != NULL) {
196  return file_obj;
197  }
198 
199  if ((file_obj = AoutObject::tryFile(fname, len, file_data)) != NULL) {
200  return file_obj;
201  }
202 
203  if ((file_obj = DtbObject::tryFile(fname, len, file_data)) != NULL) {
204  return file_obj;
205  }
206 
207  if (raw)
208  return RawObject::tryFile(fname, len, file_data);
209 
210  // don't know what it is
211  munmap((char*)file_data, len);
212  return NULL;
213 }
static int doGzipLoad(int fd)
Definition: object_file.cc:110
static ObjectFile * tryFile(const std::string &fname, size_t len, uint8_t *data)
Definition: aout_object.cc:43
static bool hasGzipMagic(int fd)
Definition: object_file.cc:101
ip6_addr_t addr
Definition: inet.hh:335
panic_if(!root,"Invalid expression\n")
size_t len
Definition: object_file.hh:75
static ObjectFile * tryFile(const std::string &fname, size_t len, uint8_t *data)
Definition: raw_object.cc:38
This implements an object file format to support loading and modifying flattened device tree blobs fo...
Bitfield< 23, 0 > offset
Definition: types.hh:149
const char data[]
Definition: circlebuf.cc:43
#define warn(...)
Definition: misc.hh:219
static ObjectFile * tryFile(const std::string &fname, size_t len, uint8_t *data)
Definition: ecoff_object.cc:53
PortProxy Object Declaration.
ObjectFile(const std::string &_filename, size_t _len, uint8_t *_data, Arch _arch, OpSys _opSys)
Definition: object_file.cc:55
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
virtual bool loadSections(PortProxy &mem_proxy, Addr mask=maxAddr, Addr offset=0)
Definition: object_file.cc:93
This object is a proxy for a structural port, to be used for debug accesses.
Definition: port_proxy.hh:84
uint8_t * fileData
Definition: object_file.hh:74
static ObjectFile * tryFile(const std::string &fname, size_t len, uint8_t *data, bool skip_interp_check=false)
Definition: elf_object.cc:64
ObjectFile * createObjectFile(const string &fname, bool raw)
Definition: object_file.cc:157
virtual void writeBlob(Addr addr, const uint8_t *p, int size) const
Write size bytes from p to address.
Definition: port_proxy.cc:58
Bitfield< 18, 16 > len
Definition: miscregs.hh:1626
static ObjectFile * tryFile(const std::string &fname, size_t len, uint8_t *data)
Static function that tries to load file as a flattened device tree blob.
Definition: dtb_object.cc:43
virtual void memsetBlob(Addr addr, uint8_t v, int size) const
Fill size bytes starting at addr with byte value val.
Definition: port_proxy.cc:71
bool loadSection(Section *sec, PortProxy &mem_proxy, Addr mask, Addr offset=0)
Definition: object_file.cc:75
fatal_if(p->js_features.size() > 16,"Too many job slot feature registers specified (%i)\n", p->js_features.size())
Section data
Definition: object_file.hh:126
Section bss
Definition: object_file.hh:127
Section text
Definition: object_file.hh:125
Bitfield< 14, 12 > fd
Definition: types.hh:155
Bitfield< 0 > p
virtual ~ObjectFile()
Definition: object_file.cc:65

Generated on Fri Jun 9 2017 13:03:41 for gem5 by doxygen 1.8.6