blob: a8391d8e52b25c07a50d2a0899ce5715894950bc [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "lib/elfldltl/mapped-fd-file.h"
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <zircon/assert.h>
namespace elfldltl {
fit::result<int> MappedFdFile::Init(int fd) {
// Stat the file to get its size.
struct stat st;
if (fstat(fd, &st) < 0) {
return fit::error{errno};
}
// If it's not a regular file, st_size doesn't mean something useful.
if (!S_ISREG(st.st_mode)) {
return fit::error{ENOTSUP};
}
const size_t file_size = static_cast<size_t>(st.st_size);
if (st.st_size > static_cast<ssize_t>(file_size)) {
return fit::error{EFBIG};
}
void* mapped = mmap(nullptr, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (mapped == MAP_FAILED) {
return fit::error{errno};
}
set_image({static_cast<std::byte*>(mapped), file_size});
return fit::ok();
}
MappedFdFile::~MappedFdFile() {
if (!image().empty() && munmap(image().data(), image().size_bytes()) < 0) {
ZX_DEBUG_ASSERT_MSG(false, "munmap(%p, %#zx): %s", image().data(), image().size_bytes(),
strerror(errno));
}
}
} // namespace elfldltl