@@ -49,7 +49,6 @@ static uint8_t* align_pointer(void* ptr, size_t alignment) {
4949 addr = (addr | (alignment - 1 )) + 1 ;
5050 return reinterpret_cast <uint8_t *>(addr);
5151}
52-
5352} // namespace
5453
5554FileDataLoader::~FileDataLoader () {
@@ -143,19 +142,6 @@ Result<FreeableBuffer> FileDataLoader::load(
143142 return FreeableBuffer (nullptr , 0 , /* free_fn=*/ nullptr );
144143 }
145144
146- // Seek to the right place in the file.
147- off_t seek_offset = ::lseek (fd_, offset, SEEK_SET);
148- if (seek_offset != offset) {
149- ET_LOG (
150- Error,
151- " Seeking %s to offset %zu returned %zd: %s" ,
152- file_name_,
153- offset,
154- (ssize_t )seek_offset,
155- strerror (errno));
156- return Error::AccessFailed;
157- }
158-
159145 // Allocate memory for the FreeableBuffer.
160146 size_t alloc_size = size;
161147 if (alignment_ > alignof (std::max_align_t )) {
@@ -187,9 +173,75 @@ Result<FreeableBuffer> FileDataLoader::load(
187173 buffer,
188174 alloc_size);
189175
176+ auto err = load_into (offset, size, segment_info, aligned_buffer);
177+ if (err != Error::Ok) {
178+ // Free `buffer`, which is what malloc() gave us, not `aligned_buffer`.
179+ std::free (buffer);
180+ return err;
181+ }
182+
183+ // We can't naively free this pointer, since it may not be what malloc() gave
184+ // us. Pass the offset to the real buffer as context. This is the number of
185+ // bytes that need to be subtracted from the FreeableBuffer::data() pointer to
186+ // find the actual pointer to free.
187+ return FreeableBuffer (
188+ aligned_buffer,
189+ size,
190+ FreeSegment,
191+ /* free_fn_context=*/
192+ reinterpret_cast <void *>(
193+ // Using signed types here because it will produce a signed ptrdiff_t
194+ // value, though for us it will always be non-negative.
195+ reinterpret_cast <intptr_t >(aligned_buffer) -
196+ reinterpret_cast <intptr_t >(buffer)));
197+ }
198+
199+ Result<size_t > FileDataLoader::size () const {
200+ ET_CHECK_OR_RETURN_ERROR (
201+ // Probably had its value moved to another instance.
202+ fd_ >= 0 ,
203+ InvalidState,
204+ " Uninitialized" );
205+ return file_size_;
206+ }
207+
208+ __ET_NODISCARD Error FileDataLoader::load_into (
209+ size_t offset,
210+ size_t size,
211+ __ET_UNUSED const SegmentInfo& segment_info,
212+ void * buffer) {
213+ ET_CHECK_OR_RETURN_ERROR (
214+ // Probably had its value moved to another instance.
215+ fd_ >= 0 ,
216+ InvalidState,
217+ " Uninitialized" );
218+ ET_CHECK_OR_RETURN_ERROR (
219+ offset + size <= file_size_,
220+ InvalidArgument,
221+ " File %s: offset %zu + size %zu > file_size_ %zu" ,
222+ file_name_,
223+ offset,
224+ size,
225+ file_size_);
226+ ET_CHECK_OR_RETURN_ERROR (
227+ buffer != nullptr , InvalidArgument, " Provided buffer cannot be null" );
228+
229+ // Seek to the right place in the file.
230+ off_t seek_offset = ::lseek (fd_, offset, SEEK_SET);
231+ if (seek_offset != offset) {
232+ ET_LOG (
233+ Error,
234+ " Seeking %s to offset %zu returned %zd: %s" ,
235+ file_name_,
236+ offset,
237+ (ssize_t )seek_offset,
238+ strerror (errno));
239+ return Error::AccessFailed;
240+ }
241+
190242 // Read the data into the aligned address.
191243 size_t needed = size;
192- uint8_t * buf = reinterpret_cast <uint8_t *>(aligned_buffer );
244+ uint8_t * buf = reinterpret_cast <uint8_t *>(buffer );
193245 while (needed > 0 ) {
194246 // Reads on macos will fail with EINVAL if size > INT32_MAX.
195247 ssize_t nread = ::read (
@@ -211,37 +263,12 @@ Result<FreeableBuffer> FileDataLoader::load(
211263 size,
212264 offset,
213265 nread == 0 ? " EOF" : strerror (errno));
214- // Free `buffer`, which is what malloc() gave us, not `aligned_buffer`.
215- std::free (buffer);
216266 return Error::AccessFailed;
217267 }
218268 needed -= nread;
219269 buf += nread;
220270 }
221-
222- // We can't naively free this pointer, since it may not be what malloc() gave
223- // us. Pass the offset to the real buffer as context. This is the number of
224- // bytes that need to be subtracted from the FreeableBuffer::data() pointer to
225- // find the actual pointer to free.
226- return FreeableBuffer (
227- aligned_buffer,
228- size,
229- FreeSegment,
230- /* free_fn_context=*/
231- reinterpret_cast <void *>(
232- // Using signed types here because it will produce a signed ptrdiff_t
233- // value, though for us it will always be non-negative.
234- reinterpret_cast <intptr_t >(aligned_buffer) -
235- reinterpret_cast <intptr_t >(buffer)));
236- }
237-
238- Result<size_t > FileDataLoader::size () const {
239- ET_CHECK_OR_RETURN_ERROR (
240- // Probably had its value moved to another instance.
241- fd_ >= 0 ,
242- InvalidState,
243- " Uninitialized" );
244- return file_size_;
271+ return Error::Ok;
245272}
246273
247274} // namespace util
0 commit comments