Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(407)

Side by Side Diff: experimental/visual_studio_plugin/src/elf_reader/elf_object.cc

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8
9 #include "common/types.h"
10 #include "elf_reader/elf_structs.h"
11 #include "elf_reader/elf_object.h"
12 #include "elf_reader/elf_reader.h"
13
14 namespace elf_reader {
15
16 static uint8_t s_ident[4] = { 0x7F, 'E', 'L', 'F' };
17
18 ElfObject::ElfObject()
19 : path_(NULL),
20 length_(0),
21 obj_(NULL),
22 strings_(NULL) {
23 data_.raw_ = 0;
24 shdr_.raw_ = 0;
25 phdr_.raw_ = 0;
26 }
27
28
29 ElfObject::~ElfObject() {
30 Unload();
31 }
32
33 void ElfObject::Unload() {
34 if (data_.raw_)
35 free(data_.raw_);
36
37 if (path_)
38 free(path_);
39
40 path_ = NULL;
41 length_ = 0;
42
43 data_.raw_ = NULL;
44 shdr_.raw_ = NULL;
45 phdr_.raw_ = NULL;
46 strings_ = NULL;
47 }
48
49 bool ElfObject::Load(const char *path) {
50 Unload();
51
52 if (NULL == path) return false;
53
54 FILE *fp = fopen(path, "rb");
55 if (fp) {
56 // Copy the path
57 path_ = reinterpret_cast<char *>(malloc(strlen(path) + 1));
58 strcpy(path_, path);
59
60 // Determine the length
61 fseek(fp, 0, SEEK_END);
62 length_ = ftell(fp);
63 fseek(fp, 0, SEEK_SET);
64
65 /// Verify this is large enough to process the headers
66 if (length_ < sizeof(ElfHdrDef)) {
67 CleanUp(fp);
68 return false;
69 }
70
71 // make sure we allocated enough
72 void *data = malloc(static_cast<size_t>(length_));
73 if (NULL == data) {
74 CleanUp(fp);
75 return false;
76 }
77 data_.raw_ = reinterpret_cast<uint8_t *>(data);
78
79 // Make sure we load the whole file
80 size_t loaded = fread(data_.raw_, 1, length_, fp);
81 if (loaded != length_) {
82 CleanUp(fp);
83 return false;
84 }
85
86 // Verify we have the expected ELF indentifier at the head of the file
87 if (memcmp(data_.def_->e_ident, s_ident, sizeof(s_ident))) {
88 CleanUp(fp);
89 return false;
90 }
91
92 // Set precomputed pointers and verify structure sizes
93 switch (GetClassSize()) {
94 case ELFCLASS32: {
95 // Get the index to the section containing section names
96 uint32_t strndx = data_.hdr32_->e_obj.e_shstrndx;
97
98 // Set precomputed header offsets
99 shdr_.raw_ = &data_.raw_[data_.hdr32_->e_shoff];
100 phdr_.raw_ = &data_.raw_[data_.hdr32_->e_phoff];
101 obj_ = &data_.hdr32_->e_obj;
102
103 // Verify headers are the expected sizes for this Class (machine width)
104 if (data_.hdr32_->e_obj.e_shentsize != sizeof(ElfShdr32) ||
105 data_.hdr32_->e_obj.e_phentsize != sizeof(ElfPhdr32)) {
106 CleanUp(fp);
107 return false;
108 }
109 // If everything checks out, we can precompute strings offset
110 uint8_t *string_offs = &data_.raw_[ shdr_.shdr32_[strndx].sh_offset ];
111 strings_ = reinterpret_cast<char *>(string_offs);
112 break;
113 }
114
115
116 case ELFCLASS64: {
117 // Get the index to the section containing section names
118 uint32_t strndx = data_.hdr64_->e_obj.e_shstrndx;
119
120 // Set precomputed offsets
121 shdr_.raw_ = &data_.raw_[data_.hdr64_->e_shoff];
122 phdr_.raw_ = &data_.raw_[data_.hdr64_->e_phoff];
123 obj_ = &data_.hdr64_->e_obj;
124
125 // Verify headers are the expected sizes for this Class (machine width)
126 if (data_.hdr64_->e_obj.e_shentsize != sizeof(ElfShdr64) ||
127 data_.hdr64_->e_obj.e_phentsize != sizeof(ElfPhdr64)) {
128 CleanUp(fp);
129 return false;
130 }
131 // If everything checks out, we can precompute strings offset
132 uint64_t offset = shdr_.shdr64_[strndx].sh_offset;
133 strings_ = reinterpret_cast<char *>(&data_.raw_[ offset ]);
134 break;
135 }
136
137 }
138
139 fclose(fp);
140 return true;
141 }
142
143 return false;
144 }
145
146 void ElfObject::CleanUp(FILE *fp) {
147 Unload();
148 fclose(fp);
149 }
150
151 ElfObject::ClassSize ElfObject::GetClassSize() const {
152 if (data_.def_)
153 return static_cast<ElfObject::ClassSize>(data_.def_->e_class);
154
155 return ELFCLASSERR;
156 }
157
158 ElfObject::Encoding ElfObject::GetEncoding() const {
159 if (data_.def_)
160 return static_cast<ElfObject::Encoding>(data_.def_->e_encoding);
161
162 return ELFDATAERR;
163 }
164
165 ElfObject::ObjectType ElfObject::GetObjectType() const {
166 if (data_.def_)
167 return static_cast<ElfObject::ObjectType>(data_.def_->e_type);
168
169 return ET_NONE;
170 }
171
172
173 const char * ElfObject::GetPath() const {
174 return path_;
175 }
176
177 const uint8_t *ElfObject::GetData() const {
178 return data_.raw_;
179 }
180
181 uint16_t ElfObject::GetProgramHeaderCount() const {
182 if (obj_) {
183 return obj_->e_phnum;
184 }
185
186 return 0;
187 }
188
189 uint16_t ElfObject::GetSectionHeaderCount() const {
190 if (obj_) {
191 return obj_->e_shnum;
192 }
193
194 return 0;
195 }
196
197 void ElfObject::Parse(IElfReader* reader) const {
198 if (NULL == reader)
199 return;
200
201 bool lsb = GetEncoding() == ELFDATA2LSB;
202 reader->Init(path_, data_.raw_, length_, GetClassSize(), lsb);
203
204 if (reader->SectionHeadersStart(GetSectionHeaderCount())) {
205 // NOTE: Section index 0, 0xFF00-0xFFFF are special, so we
206 // skip '0' since it is invalid and zero filled.
207 uint32_t a;
208 for (a = 1; a < GetSectionHeaderCount(); a++) {
209 const char *path;
210 uint32_t type;
211 uint32_t flags;
212 void* start;
213 uint64_t length;
214 uint64_t virt;
215
216 switch (GetClassSize()) {
217 case ELFCLASS32: {
218 ElfShdr32 *sec = &shdr_.shdr32_[a];
219 path = &strings_[sec->sh_name];
220 flags = sec->sh_flags;
221 length= sec->sh_size;
222 start = &data_.raw_[sec->sh_offset];
223 type = sec->sh_type;
224 virt = sec->sh_addr;
225 break;
226 }
227
228 case ELFCLASS64: {
229 ElfShdr64 *sec = &shdr_.shdr64_[a];
230 path = &strings_[sec->sh_name];
231 flags = static_cast<uint32_t>(sec->sh_flags);
232 length= sec->sh_size;
233 start = &data_.raw_[sec->sh_offset];
234 type = sec->sh_type;
235 virt = sec->sh_addr;
236 break;
237 }
238
239 // This is actually unreachible since we verified the class on load.
240 default:
241 continue;
242 }
243 reader->AddSectionHeader(path, start, virt, type, flags, length);
244 }
245 reader->SectionHeadersEnd();
246 }
247 }
248
249 } // namespace elf_reader
250
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698