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

Side by Side Diff: third_party/android_crazy_linker/src/src/crazy_linker_zip.cpp

Issue 958473003: Asynchronously pre-fault the native library pages. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Whitespace. Created 5 years, 9 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
« no previous file with comments | « third_party/android_crazy_linker/src/src/crazy_linker_zip.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "crazy_linker_zip.h" 5 #include "crazy_linker_zip.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <sys/mman.h> 8 #include <sys/mman.h>
9 #include <sys/stat.h> 9 #include <sys/stat.h>
10 #include <unistd.h> 10 #include <unistd.h>
(...skipping 16 matching lines...) Expand all
27 const int kOffsetOfCentralDirLengthInEndOfCentralDirectory = 27 const int kOffsetOfCentralDirLengthInEndOfCentralDirectory =
28 kOffsetNumOfEntriesInEndOfCentralDirectory + 2 + 2; 28 kOffsetNumOfEntriesInEndOfCentralDirectory + 2 + 2;
29 const int kOffsetOfStartOfCentralDirInEndOfCentralDirectory = 29 const int kOffsetOfStartOfCentralDirInEndOfCentralDirectory =
30 kOffsetOfCentralDirLengthInEndOfCentralDirectory + 4; 30 kOffsetOfCentralDirLengthInEndOfCentralDirectory + 4;
31 31
32 // http://www.pkware.com/documents/casestudies/APPNOTE.TXT Section 4.3.12 32 // http://www.pkware.com/documents/casestudies/APPNOTE.TXT Section 4.3.12
33 // This marker appears at the start of the central directory 33 // This marker appears at the start of the central directory
34 const uint32_t kCentralDirHeaderMarker = 0x2014b50; 34 const uint32_t kCentralDirHeaderMarker = 0x2014b50;
35 35
36 // Offsets of fields in Central Directory Header. 36 // Offsets of fields in Central Directory Header.
37 const int kOffsetCompressedSizeInCentralDirectory = 4 + 2 + 2 + 2 + 2 + 2 + 2 + 4;
38 const int kOffsetUncompressedSizeInCentralDirectory =
39 kOffsetCompressedSizeInCentralDirectory + 4;
37 const int kOffsetFilenameLengthInCentralDirectory = 40 const int kOffsetFilenameLengthInCentralDirectory =
38 4 + 2 + 2 + 2 + 2 + 2 + 2 + 4 + 4 + 4; 41 kOffsetUncompressedSizeInCentralDirectory + 4;
39 const int kOffsetExtraFieldLengthInCentralDirectory = 42 const int kOffsetExtraFieldLengthInCentralDirectory =
40 kOffsetFilenameLengthInCentralDirectory + 2; 43 kOffsetFilenameLengthInCentralDirectory + 2;
41 const int kOffsetCommentLengthInCentralDirectory = 44 const int kOffsetCommentLengthInCentralDirectory =
42 kOffsetExtraFieldLengthInCentralDirectory + 2; 45 kOffsetExtraFieldLengthInCentralDirectory + 2;
43 const int kOffsetLocalHeaderOffsetInCentralDirectory = 46 const int kOffsetLocalHeaderOffsetInCentralDirectory =
44 kOffsetCommentLengthInCentralDirectory + 2 + 2 + 2 + 4; 47 kOffsetCommentLengthInCentralDirectory + 2 + 2 + 2 + 4;
45 const int kOffsetFilenameInCentralDirectory = 48 const int kOffsetFilenameInCentralDirectory =
46 kOffsetLocalHeaderOffsetInCentralDirectory + 4; 49 kOffsetLocalHeaderOffsetInCentralDirectory + 4;
47 50
48 // http://www.pkware.com/documents/casestudies/APPNOTE.TXT Section 4.3.7 51 // http://www.pkware.com/documents/casestudies/APPNOTE.TXT Section 4.3.7
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 (static_cast<uint32_t>(mem_bytes[offset + 2]) << 16) | 93 (static_cast<uint32_t>(mem_bytes[offset + 2]) << 16) |
91 (static_cast<uint32_t>(mem_bytes[offset + 3]) << 24); 94 (static_cast<uint32_t>(mem_bytes[offset + 3]) << 24);
92 } 95 }
93 96
94 } // unnamed namespace 97 } // unnamed namespace
95 98
96 namespace crazy { 99 namespace crazy {
97 100
98 const uint32_t kMaxZipFileLength = 1U << 31; // 2GB 101 const uint32_t kMaxZipFileLength = 1U << 31; // 2GB
99 102
100 int FindStartOffsetOfFileInZipFile(const char* zip_file, const char* filename) { 103
104 OffsetSize FindStartOffsetAndLengthOfFileInZipFile(const char* zip_file,
105 const char* filename) {
106 OffsetSize result(CRAZY_OFFSET_FAILED, -1);
101 // Open the file 107 // Open the file
102 FileDescriptor fd; 108 FileDescriptor fd;
103 if (!fd.OpenReadOnly(zip_file)) { 109 if (!fd.OpenReadOnly(zip_file)) {
104 LOG_ERRNO("%s: open failed trying to open zip file %s\n", 110 LOG_ERRNO("%s: open failed trying to open zip file %s\n",
105 __FUNCTION__, zip_file); 111 __FUNCTION__, zip_file);
106 return CRAZY_OFFSET_FAILED; 112 return result;
107 } 113 }
108 114
109 // Find the length of the file. 115 // Find the length of the file.
110 struct stat stat_buf; 116 struct stat stat_buf;
111 if (stat(zip_file, &stat_buf) == -1) { 117 if (stat(zip_file, &stat_buf) == -1) {
112 LOG_ERRNO("%s: stat failed trying to stat zip file %s\n", 118 LOG_ERRNO("%s: stat failed trying to stat zip file %s\n",
113 __FUNCTION__, zip_file); 119 __FUNCTION__, zip_file);
114 return CRAZY_OFFSET_FAILED; 120 return result;
115 } 121 }
116 122
117 if (stat_buf.st_size > kMaxZipFileLength) { 123 if (stat_buf.st_size > kMaxZipFileLength) {
118 LOG("%s: The size %ld of %s is too large to map\n", 124 LOG("%s: The size %ld of %s is too large to map\n",
119 __FUNCTION__, stat_buf.st_size, zip_file); 125 __FUNCTION__, stat_buf.st_size, zip_file);
120 return CRAZY_OFFSET_FAILED; 126 return result;
121 } 127 }
122 128
123 // Map the file into memory. 129 // Map the file into memory.
124 void* mem = fd.Map(NULL, stat_buf.st_size, PROT_READ, MAP_PRIVATE, 0); 130 void* mem = fd.Map(NULL, stat_buf.st_size, PROT_READ, MAP_PRIVATE, 0);
125 if (mem == MAP_FAILED) { 131 if (mem == MAP_FAILED) {
126 LOG_ERRNO("%s: mmap failed trying to mmap zip file %s\n", 132 LOG_ERRNO("%s: mmap failed trying to mmap zip file %s\n",
127 __FUNCTION__, zip_file); 133 __FUNCTION__, zip_file);
128 return CRAZY_OFFSET_FAILED; 134 return result;
129 } 135 }
130 ScopedMMap scoped_mmap(mem, stat_buf.st_size); 136 ScopedMMap scoped_mmap(mem, stat_buf.st_size);
131 137
132 // Scan backwards from the end of the file searching for the end of 138 // Scan backwards from the end of the file searching for the end of
133 // central directory marker. 139 // central directory marker.
134 uint8_t* mem_bytes = static_cast<uint8_t*>(mem); 140 uint8_t* mem_bytes = static_cast<uint8_t*>(mem);
135 int off; 141 int off;
136 for (off = stat_buf.st_size - sizeof(kEndOfCentralDirectoryMarker); 142 for (off = stat_buf.st_size - sizeof(kEndOfCentralDirectoryMarker);
137 off >= 0; --off) { 143 off >= 0; --off) {
138 if (ReadUInt32(mem_bytes, off) == kEndOfCentralDirectoryMarker) { 144 if (ReadUInt32(mem_bytes, off) == kEndOfCentralDirectoryMarker) {
139 break; 145 break;
140 } 146 }
141 } 147 }
142 if (off == -1) { 148 if (off == -1) {
143 LOG("%s: Failed to find end of central directory in %s\n", 149 LOG("%s: Failed to find end of central directory in %s\n",
144 __FUNCTION__, zip_file); 150 __FUNCTION__, zip_file);
145 return CRAZY_OFFSET_FAILED; 151 return result;
146 } 152 }
147 153
148 // We have located the end of central directory record, now locate 154 // We have located the end of central directory record, now locate
149 // the central directory by reading the end of central directory record. 155 // the central directory by reading the end of central directory record.
150 156
151 uint32_t length_of_central_dir = ReadUInt32( 157 uint32_t length_of_central_dir = ReadUInt32(
152 mem_bytes, off + kOffsetOfCentralDirLengthInEndOfCentralDirectory); 158 mem_bytes, off + kOffsetOfCentralDirLengthInEndOfCentralDirectory);
153 uint32_t start_of_central_dir = ReadUInt32( 159 uint32_t start_of_central_dir = ReadUInt32(
154 mem_bytes, off + kOffsetOfStartOfCentralDirInEndOfCentralDirectory); 160 mem_bytes, off + kOffsetOfStartOfCentralDirInEndOfCentralDirectory);
155 161
156 if (start_of_central_dir > off) { 162 if (start_of_central_dir > off) {
157 LOG("%s: Found out of range offset %u for start of directory in %s\n", 163 LOG("%s: Found out of range offset %u for start of directory in %s\n",
158 __FUNCTION__, start_of_central_dir, zip_file); 164 __FUNCTION__, start_of_central_dir, zip_file);
159 return CRAZY_OFFSET_FAILED; 165 return result;
160 } 166 }
161 167
162 uint32_t end_of_central_dir = start_of_central_dir + length_of_central_dir; 168 uint32_t end_of_central_dir = start_of_central_dir + length_of_central_dir;
163 if (end_of_central_dir > off) { 169 if (end_of_central_dir > off) {
164 LOG("%s: Found out of range offset %u for end of directory in %s\n", 170 LOG("%s: Found out of range offset %u for end of directory in %s\n",
165 __FUNCTION__, end_of_central_dir, zip_file); 171 __FUNCTION__, end_of_central_dir, zip_file);
166 return CRAZY_OFFSET_FAILED; 172 return result;
167 } 173 }
168 174
169 uint32_t num_entries = ReadUInt16( 175 uint32_t num_entries = ReadUInt16(
170 mem_bytes, off + kOffsetNumOfEntriesInEndOfCentralDirectory); 176 mem_bytes, off + kOffsetNumOfEntriesInEndOfCentralDirectory);
171 177
172 // Read the headers in the central directory and locate the file. 178 // Read the headers in the central directory and locate the file.
173 off = start_of_central_dir; 179 off = start_of_central_dir;
174 const int target_len = strlen(filename); 180 const int target_len = strlen(filename);
175 int n = 0; 181 int n = 0;
176 for (; n < num_entries && off < end_of_central_dir; ++n) { 182 for (; n < num_entries && off < end_of_central_dir; ++n) {
177 uint32_t marker = ReadUInt32(mem_bytes, off); 183 uint32_t marker = ReadUInt32(mem_bytes, off);
178 if (marker != kCentralDirHeaderMarker) { 184 if (marker != kCentralDirHeaderMarker) {
179 LOG("%s: Failed to find central directory header marker in %s. " 185 LOG("%s: Failed to find central directory header marker in %s. "
180 "Found 0x%x but expected 0x%x\n", __FUNCTION__, 186 "Found 0x%x but expected 0x%x\n", __FUNCTION__,
181 zip_file, marker, kCentralDirHeaderMarker); 187 zip_file, marker, kCentralDirHeaderMarker);
182 return CRAZY_OFFSET_FAILED; 188 return result;
183 } 189 }
190 uint32_t compressed_size =
191 ReadUInt32(mem_bytes, off + kOffsetCompressedSizeInCentralDirectory);
192 uint32_t uncompressed_size =
193 ReadUInt32(mem_bytes, off + kOffsetUncompressedSizeInCentralDirectory);
184 uint32_t file_name_length = 194 uint32_t file_name_length =
185 ReadUInt16(mem_bytes, off + kOffsetFilenameLengthInCentralDirectory); 195 ReadUInt16(mem_bytes, off + kOffsetFilenameLengthInCentralDirectory);
186 uint32_t extra_field_length = 196 uint32_t extra_field_length =
187 ReadUInt16(mem_bytes, off + kOffsetExtraFieldLengthInCentralDirectory); 197 ReadUInt16(mem_bytes, off + kOffsetExtraFieldLengthInCentralDirectory);
188 uint32_t comment_field_length = 198 uint32_t comment_field_length =
189 ReadUInt16(mem_bytes, off + kOffsetCommentLengthInCentralDirectory); 199 ReadUInt16(mem_bytes, off + kOffsetCommentLengthInCentralDirectory);
190 uint32_t header_length = kOffsetFilenameInCentralDirectory + 200 uint32_t header_length = kOffsetFilenameInCentralDirectory +
191 file_name_length + extra_field_length + comment_field_length; 201 file_name_length + extra_field_length + comment_field_length;
192 202
193 uint32_t local_header_offset = 203 uint32_t local_header_offset =
194 ReadUInt32(mem_bytes, off + kOffsetLocalHeaderOffsetInCentralDirectory); 204 ReadUInt32(mem_bytes, off + kOffsetLocalHeaderOffsetInCentralDirectory);
195 205
196 uint8_t* filename_bytes = 206 uint8_t* filename_bytes =
197 mem_bytes + off + kOffsetFilenameInCentralDirectory; 207 mem_bytes + off + kOffsetFilenameInCentralDirectory;
198 208
199 if (file_name_length == target_len && 209 if (file_name_length == target_len &&
200 memcmp(filename_bytes, filename, target_len) == 0) { 210 memcmp(filename_bytes, filename, target_len) == 0) {
201 // Filename matches. Read the local header and compute the offset. 211 // Filename matches. Read the local header and compute the offset.
202 uint32_t marker = ReadUInt32(mem_bytes, local_header_offset); 212 uint32_t marker = ReadUInt32(mem_bytes, local_header_offset);
203 if (marker != kLocalHeaderMarker) { 213 if (marker != kLocalHeaderMarker) {
204 LOG("%s: Failed to find local file header marker in %s. " 214 LOG("%s: Failed to find local file header marker in %s. "
205 "Found 0x%x but expected 0x%x\n", __FUNCTION__, 215 "Found 0x%x but expected 0x%x\n", __FUNCTION__,
206 zip_file, marker, kLocalHeaderMarker); 216 zip_file, marker, kLocalHeaderMarker);
207 return CRAZY_OFFSET_FAILED; 217 return result;
208 } 218 }
209 219
210 uint32_t compression_method = 220 uint32_t compression_method =
211 ReadUInt16( 221 ReadUInt16(
212 mem_bytes, 222 mem_bytes,
213 local_header_offset + kOffsetCompressionMethodInLocalHeader); 223 local_header_offset + kOffsetCompressionMethodInLocalHeader);
214 if (compression_method != kCompressionMethodStored) { 224 if (compression_method != kCompressionMethodStored) {
215 LOG("%s: %s is compressed within %s. " 225 LOG("%s: %s is compressed within %s. "
216 "Found compression method %u but expected %u\n", __FUNCTION__, 226 "Found compression method %u but expected %u\n", __FUNCTION__,
217 filename, zip_file, compression_method, kCompressionMethodStored); 227 filename, zip_file, compression_method, kCompressionMethodStored);
218 return CRAZY_OFFSET_FAILED; 228 return result;
229 }
230
231 if (uncompressed_size != compressed_size) {
232 LOG("%s: Uncompressed size (%d) differs from compressed size (%d).\n",
233 __FUNCTION__, filename, uncompressed_size, compressed_size);
234 return result;
219 } 235 }
220 236
221 uint32_t file_name_length = 237 uint32_t file_name_length =
222 ReadUInt16( 238 ReadUInt16(
223 mem_bytes, 239 mem_bytes,
224 local_header_offset + kOffsetFilenameLengthInLocalHeader); 240 local_header_offset + kOffsetFilenameLengthInLocalHeader);
225 uint32_t extra_field_length = 241 uint32_t extra_field_length =
226 ReadUInt16( 242 ReadUInt16(
227 mem_bytes, 243 mem_bytes,
228 local_header_offset + kOffsetExtraFieldLengthInLocalHeader); 244 local_header_offset + kOffsetExtraFieldLengthInLocalHeader);
229 uint32_t header_length = 245 uint32_t header_length =
230 kOffsetFilenameInLocalHeader + file_name_length + extra_field_length; 246 kOffsetFilenameInLocalHeader + file_name_length + extra_field_length;
231 247
232 return local_header_offset + header_length; 248 result.offset = local_header_offset + header_length;
249 result.size = compressed_size;
250 return result;
233 } 251 }
234 252
235 off += header_length; 253 off += header_length;
236 } 254 }
237 255
238 if (n < num_entries) { 256 if (n < num_entries) {
239 LOG("%s: Did not find all the expected entries in the central directory. " 257 LOG("%s: Did not find all the expected entries in the central directory. "
240 "Found %d but expected %d\n", __FUNCTION__, n, num_entries); 258 "Found %d but expected %d\n", __FUNCTION__, n, num_entries);
241 } 259 }
242 260
243 if (off < end_of_central_dir) { 261 if (off < end_of_central_dir) {
244 LOG("%s: There are %d extra bytes at the end of the central directory.\n", 262 LOG("%s: There are %d extra bytes at the end of the central directory.\n",
245 __FUNCTION__, end_of_central_dir - off); 263 __FUNCTION__, end_of_central_dir - off);
246 } 264 }
247 265
248 LOG("%s: Did not find %s in %s\n", __FUNCTION__, filename, zip_file); 266 LOG("%s: Did not find %s in %s\n", __FUNCTION__, filename, zip_file);
249 return CRAZY_OFFSET_FAILED; 267 return result;
268 }
269
270
271 int FindStartOffsetOfFileInZipFile(const char* zip_file, const char* filename) {
272 return FindStartOffsetAndLengthOfFileInZipFile(zip_file, filename).offset;
250 } 273 }
251 274
252 } // crazy namespace 275 } // crazy namespace
OLDNEW
« no previous file with comments | « third_party/android_crazy_linker/src/src/crazy_linker_zip.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698