linker: LoadSegments: Preparatory work for 16KiB App Compat

Introduce should_use_16kib_app_compat_ to ElfReader and pipe it through
to soinfo.

Introduce seg_align and use align_up()/align_down to align the segment
start and end, as it offers more flexiblility than
page_start()/page_end().

Use should_use_16kib_app_compat_ to skip steps that won't be needed in
compatbility mode.

No functional change is introduced in this patch.

Bug: 339709616
Test: atest linker-unit-tests
Change-Id: Ice110c6e2ad54a2ca65e70eb119d9e2b7973a963
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
diff --git a/linker/linker_phdr.h b/linker/linker_phdr.h
index 1d6bbe3..a30fe33 100644
--- a/linker/linker_phdr.h
+++ b/linker/linker_phdr.h
@@ -59,6 +59,7 @@
   bool is_mapped_by_caller() const { return mapped_by_caller_; }
   ElfW(Addr) entry_point() const { return header_.e_entry + load_bias_; }
   bool should_pad_segments() const { return should_pad_segments_; }
+  bool should_use_16kib_app_compat() const { return should_use_16kib_app_compat_; }
 
  private:
   [[nodiscard]] bool ReadElfHeader();
@@ -123,6 +124,9 @@
   // Pad gaps between segments when memory mapping?
   bool should_pad_segments_ = false;
 
+  // Use app compat mode when loading 4KiB max-page-size ELFs on 16KiB page-size devices?
+  bool should_use_16kib_app_compat_ = false;
+
   // Only used by AArch64 at the moment.
   GnuPropertySection note_gnu_property_ __unused;
 };
@@ -135,13 +139,16 @@
 
 int phdr_table_protect_segments(const ElfW(Phdr)* phdr_table, size_t phdr_count,
                                 ElfW(Addr) load_bias, bool should_pad_segments,
+                                bool should_use_16kib_app_compat,
                                 const GnuPropertySection* prop = nullptr);
 
 int phdr_table_unprotect_segments(const ElfW(Phdr)* phdr_table, size_t phdr_count,
-                                  ElfW(Addr) load_bias, bool should_pad_segments);
+                                  ElfW(Addr) load_bias, bool should_pad_segments,
+                                  bool should_use_16kib_app_compat);
 
 int phdr_table_protect_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count,
-                                 ElfW(Addr) load_bias, bool should_pad_segments);
+                                 ElfW(Addr) load_bias, bool should_pad_segments,
+                                 bool should_use_16kib_app_compat);
 
 int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count,
                                    ElfW(Addr) load_bias, int fd, size_t* file_offset);