From 087d8f9ae33b7328a121f02a63a8ef70742d755a Mon Sep 17 00:00:00 2001
From: Petr Shumilov
Date: Wed, 27 Nov 2024 15:47:17 +0300
Subject: [PATCH] Add stats collecting for relative relocations
---
src/arch-arm32.cc | 5 +++++
src/arch-arm64.cc | 10 ++++++++++
src/arch-i386.cc | 10 ++++++++++
src/arch-loongarch.cc | 5 +++++
src/arch-m68k.cc | 5 +++++
src/arch-ppc64v1.cc | 10 ++++++++++
src/arch-ppc64v2.cc | 5 +++++
src/arch-riscv.cc | 5 +++++
src/arch-s390x.cc | 10 ++++++++++
src/arch-sparc64.cc | 10 ++++++++++
src/arch-x86-64.cc | 10 ++++++++++
src/mold.h | 45 +++++++++++++++++++++++++++++++++++++++++++
src/passes.cc | 14 ++++++++++++++
13 files changed, 144 insertions(+)
diff --git a/src/arch-arm32.cc b/src/arch-arm32.cc
index 043cf0ce88..64688b1965 100644
--- a/src/arch-arm32.cc
+++ b/src/arch-arm32.cc
@@ -253,6 +253,7 @@ static bool is_jump_reachable(i64 val) {
template <>
void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
auto get_tls_trampoline_addr = [&, i = 0](u64 addr) mutable {
for (; i < output_section->thunks.size(); i++) {
@@ -273,6 +274,8 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -532,6 +535,8 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
Error(ctx) << *this << ": unknown relocation: " << rel;
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
template <>
diff --git a/src/arch-arm64.cc b/src/arch-arm64.cc
index 541a251112..1ef47ba8eb 100644
--- a/src/arch-arm64.cc
+++ b/src/arch-arm64.cc
@@ -146,6 +146,7 @@ static bool is_add(u8 *loc) {
template <>
void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
for (i64 i = 0; i < rels.size(); i++) {
const ElfRel &rel = rels[i];
@@ -156,6 +157,8 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -434,11 +437,14 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
unreachable();
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
template <>
void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
for (i64 i = 0; i < rels.size(); i++) {
const ElfRel &rel = rels[i];
@@ -449,6 +455,8 @@ void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -481,6 +489,8 @@ void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
break;
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
template <>
diff --git a/src/arch-i386.cc b/src/arch-i386.cc
index 008faaf014..99ec485f18 100644
--- a/src/arch-i386.cc
+++ b/src/arch-i386.cc
@@ -285,6 +285,7 @@ static u32 relax_tlsdesc_to_le(u8 *loc) {
template <>
void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
for (i64 i = 0; i < rels.size(); i++) {
const ElfRel &rel = rels[i];
@@ -295,6 +296,8 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -435,11 +438,14 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
unreachable();
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
template <>
void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
for (i64 i = 0; i < rels.size(); i++) {
const ElfRel &rel = rels[i];
@@ -450,6 +456,8 @@ void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -509,6 +517,8 @@ void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
unreachable();
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
template <>
diff --git a/src/arch-loongarch.cc b/src/arch-loongarch.cc
index dda138e99a..1cae6eb3ff 100644
--- a/src/arch-loongarch.cc
+++ b/src/arch-loongarch.cc
@@ -265,6 +265,7 @@ void EhFrameSection::apply_eh_reloc(Context &ctx, const ElfRel &rel,
template <>
void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
auto get_r_delta = [&](i64 idx) {
return extra.r_deltas.empty() ? 0 : extra.r_deltas[idx];
@@ -284,6 +285,8 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
u8 *loc = base + r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -657,6 +660,8 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
unreachable();
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
template <>
diff --git a/src/arch-m68k.cc b/src/arch-m68k.cc
index edffe04801..67284ca542 100644
--- a/src/arch-m68k.cc
+++ b/src/arch-m68k.cc
@@ -77,6 +77,7 @@ void EhFrameSection::apply_eh_reloc(Context &ctx, const ElfRel &rel,
template <>
void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
for (i64 i = 0; i < rels.size(); i++) {
const ElfRel &rel = rels[i];
@@ -87,6 +88,8 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -207,6 +210,8 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
unreachable();
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
template <>
diff --git a/src/arch-ppc64v1.cc b/src/arch-ppc64v1.cc
index e3ec1c5557..535487b451 100644
--- a/src/arch-ppc64v1.cc
+++ b/src/arch-ppc64v1.cc
@@ -153,6 +153,7 @@ void EhFrameSection::apply_eh_reloc(Context &ctx, const ElfRel &rel,
template <>
void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
for (i64 i = 0; i < rels.size(); i++) {
const ElfRel &rel = rels[i];
@@ -163,6 +164,8 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -279,11 +282,14 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
unreachable();
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
template <>
void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
for (i64 i = 0; i < rels.size(); i++) {
const ElfRel &rel = rels[i];
@@ -294,6 +300,8 @@ void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -328,6 +336,8 @@ void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
<< rel;
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
template <>
diff --git a/src/arch-ppc64v2.cc b/src/arch-ppc64v2.cc
index fdb5d568c1..492558912b 100644
--- a/src/arch-ppc64v2.cc
+++ b/src/arch-ppc64v2.cc
@@ -344,6 +344,7 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
template <>
void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
for (i64 i = 0; i < rels.size(); i++) {
const ElfRel &rel = rels[i];
@@ -354,6 +355,8 @@ void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -388,6 +391,8 @@ void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
<< rel;
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
template <>
diff --git a/src/arch-riscv.cc b/src/arch-riscv.cc
index b69c988aa7..943663f14e 100644
--- a/src/arch-riscv.cc
+++ b/src/arch-riscv.cc
@@ -208,6 +208,7 @@ static inline bool is_hi20(const ElfRel &rel) {
template <>
void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
u64 GP = ctx.__global_pointer ? ctx.__global_pointer->get_addr(ctx) : 0;
auto get_r_delta = [&](i64 idx) {
@@ -225,6 +226,8 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
u8 *loc = base + r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -620,6 +623,8 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
unreachable();
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
template <>
diff --git a/src/arch-s390x.cc b/src/arch-s390x.cc
index dedc607c76..a0590168f5 100644
--- a/src/arch-s390x.cc
+++ b/src/arch-s390x.cc
@@ -115,6 +115,7 @@ void EhFrameSection::apply_eh_reloc(Context &ctx, const ElfRel &rel,
template <>
void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
for (i64 i = 0; i < rels.size(); i++) {
const ElfRel &rel = rels[i];
@@ -125,6 +126,8 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -323,11 +326,14 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
unreachable();
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
template <>
void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
for (i64 i = 0; i < rels.size(); i++) {
const ElfRel &rel = rels[i];
@@ -338,6 +344,8 @@ void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -372,6 +380,8 @@ void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
Fatal(ctx) << *this << ": apply_reloc_nonalloc: " << rel;
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
template <>
diff --git a/src/arch-sparc64.cc b/src/arch-sparc64.cc
index b04bb3011a..773eec3600 100644
--- a/src/arch-sparc64.cc
+++ b/src/arch-sparc64.cc
@@ -141,6 +141,7 @@ void EhFrameSection::apply_eh_reloc(Context &ctx, const ElfRel &rel,
template <>
void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
for (i64 i = 0; i < rels.size(); i++) {
const ElfRel &rel = rels[i];
@@ -151,6 +152,8 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -452,11 +455,14 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
unreachable();
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
template <>
void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
for (i64 i = 0; i < rels.size(); i++) {
const ElfRel &rel = rels[i];
@@ -467,6 +473,8 @@ void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -505,6 +513,8 @@ void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
Fatal(ctx) << *this << ": apply_reloc_nonalloc: " << rel;
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
template <>
diff --git a/src/arch-x86-64.cc b/src/arch-x86-64.cc
index 4e0b5f9353..3fc7a94b4b 100644
--- a/src/arch-x86-64.cc
+++ b/src/arch-x86-64.cc
@@ -367,6 +367,7 @@ static void relax_ld_to_le(u8 *loc, ElfRel rel, i64 tls_size) {
template <>
void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
for (i64 i = 0; i < rels.size(); i++) {
const ElfRel &rel = rels[i];
@@ -377,6 +378,8 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -589,6 +592,8 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
unreachable();
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
// This function is responsible for applying relocations against
@@ -606,6 +611,7 @@ void InputSection::apply_reloc_alloc(Context &ctx, u8 *base) {
template <>
void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
std::span> rels = get_rels(ctx);
+ RelocationsStats rels_stats;
for (i64 i = 0; i < rels.size(); i++) {
const ElfRel &rel = rels[i];
@@ -616,6 +622,8 @@ void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
u8 *loc = base + rel.r_offset;
auto check = [&](i64 val, i64 lo, i64 hi) {
+ if (ctx.arg.stats)
+ update_relocation_stats(rels_stats, i, val, lo, hi);
if (val < lo || hi <= val)
Error(ctx) << *this << ": relocation " << rel << " against "
<< sym << " out of range: " << val << " is not in ["
@@ -693,6 +701,8 @@ void InputSection::apply_reloc_nonalloc(Context &ctx, u8 *base) {
break;
}
}
+ if (ctx.arg.stats)
+ save_relocation_stats(ctx, *this, rels_stats);
}
// Linker has to create data structures in an output file to apply
diff --git a/src/mold.h b/src/mold.h
index ce74a26e48..64f246fc53 100644
--- a/src/mold.h
+++ b/src/mold.h
@@ -310,6 +310,12 @@ class __attribute__((aligned(4))) InputSection {
bool icf_eligible = false;
bool icf_leaf = false;
+ // For stats recovering
+ struct {
+ Atomic relative_relocations_offset_supremum = -1;
+ Atomic relative_relocations_offset_infimum = -1;
+ } stats;
+
[[no_unique_address]] InputSectionExtras extra;
private:
@@ -329,6 +335,39 @@ class __attribute__((aligned(4))) InputSection {
std::optional get_tombstone(Symbol &sym, SectionFragment *frag);
};
+struct RelocationsStats {
+ i64 min_offset_lower_bound {std::numeric_limits::max()};
+ i64 min_offset_upper_bound {std::numeric_limits::max()};
+ i64 min_offset_lower_bound_rel_idx {-1};
+ i64 min_offset_upper_bound_rel_idx {-1};
+};
+
+inline void update_relocation_stats(RelocationsStats &stats, const i64 i, const i64 val, const i64 lo, const i64 hi) {
+ const auto to_lo = std::abs(lo - val);
+ const auto to_hi = std::abs(hi - val);
+ if (to_lo < stats.min_offset_lower_bound) {
+ stats.min_offset_lower_bound = to_lo;
+ stats.min_offset_lower_bound_rel_idx = i;
+ }
+ if (to_hi < stats.min_offset_upper_bound) {
+ stats.min_offset_upper_bound = to_hi;
+ stats.min_offset_upper_bound_rel_idx = i;
+ }
+}
+
+template
+inline void save_relocation_stats(Context &ctx, InputSection &isec, const RelocationsStats &stats) {
+ if (stats.min_offset_lower_bound < ctx.stats.relative_relocations_offset_infimum) {
+ ctx.stats.relative_relocations_offset_infimum = stats.min_offset_lower_bound;
+ isec.stats.relative_relocations_offset_infimum = stats.min_offset_lower_bound;
+ }
+ if (stats.min_offset_upper_bound < ctx.stats.relative_relocations_offset_supremum) {
+ ctx.stats.relative_relocations_offset_supremum = stats.min_offset_upper_bound;
+ isec.stats.relative_relocations_offset_supremum = stats.min_offset_upper_bound;
+ }
+}
+
+
//
// tls.cc
//
@@ -2148,6 +2187,12 @@ struct Context {
Symbol *end = nullptr;
Symbol *etext = nullptr;
+ struct {
+ // Extra statistic for "free space" observation in output binary
+ Atomic relative_relocations_offset_infimum = std::numeric_limits::max();
+ Atomic relative_relocations_offset_supremum = std::numeric_limits::max();
+ } stats;
+
[[no_unique_address]] ContextExtras extra;
};
diff --git a/src/passes.cc b/src/passes.cc
index aeac428db2..5cdc8b76b6 100644
--- a/src/passes.cc
+++ b/src/passes.cc
@@ -3214,10 +3214,24 @@ void show_stats(Context &ctx) {
thunk_bytes += thunk->size();
}
+ static Counter alloc_dist_to_lower_limit("rel_reloc_offset_infimum", ctx.stats.relative_relocations_offset_infimum);
+ static Counter alloc_dist_to_upper_limit("rel_reloc_offset_supremum", ctx.stats.relative_relocations_offset_supremum);
+
Counter::print();
for (std::unique_ptr> &sec : ctx.merged_sections)
sec->print_stats(ctx);
+
+ for (ObjectFile *obj : ctx.objs) {
+ for (std::unique_ptr> &sec : obj->sections) {
+ if (!sec || !sec->is_alive)
+ continue;
+ if (ctx.stats.relative_relocations_offset_infimum == sec->stats.relative_relocations_offset_infimum)
+ Out(ctx) << "'rel_reloc_offset_infimum' is relevant for " << *sec;
+ if (ctx.stats.relative_relocations_offset_supremum == sec->stats.relative_relocations_offset_supremum)
+ Out(ctx) << "'rel_reloc_offset_supremum' is relevant for " << *sec;
+ }
+ }
}
using E = MOLD_TARGET;