blob: c7be536673a5df89da26df37d332c064b12f1f1a [file] [log] [blame]
// Copyright 2021 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.
#ifndef SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_RELRO_H_
#define SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_RELRO_H_
#include <lib/stdcompat/span.h>
#include <optional>
#include <utility>
#include "layout.h"
namespace elfldltl {
// Returns {start, size} whole-page subregion of the segment, possibly {0, 0}.
template <class Phdr>
constexpr auto RelroBounds(const Phdr& phdr, decltype(phdr.memsz()) pagesize)
-> std::pair<decltype(phdr.vaddr()), decltype(phdr.memsz())> {
auto start = (phdr.vaddr + pagesize - 1) & -pagesize;
auto end = phdr.vaddr + phdr.memsz;
if (start >= end) {
return {};
}
end &= -pagesize;
if (start >= end) {
return {};
}
return {start, end - start};
}
// Given a span of all the phdrs, find and reduce the PT_GNU_RELRO segment.
template <class Phdr>
constexpr auto RelroBounds(cpp20::span<const Phdr> phdrs, decltype(phdrs[0].memsz()) pagesize)
-> std::pair<decltype(phdrs[0].vaddr()), decltype(phdrs[0].memsz())> {
for (const Phdr& phdr : phdrs) {
if (phdr.type == elfldltl::ElfPhdrType::kRelro) {
return RelroBounds(phdr, pagesize);
}
}
return {};
}
} // namespace elfldltl
#endif // SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_RELRO_H_