Skip to content

Commit

Permalink
Allow <4GB input sections
Browse files Browse the repository at this point in the history
Fixes #1126
  • Loading branch information
rui314 committed Oct 16, 2023
1 parent 01cd5d1 commit 0ce32d3
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 16 deletions.
2 changes: 1 addition & 1 deletion elf/mold.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ class InputSection {
i32 fde_begin = -1;
i32 fde_end = -1;

u32 offset = -1;
u64 offset = -1;
u32 shndx = -1;
u32 relsec_idx = -1;
u32 reldyn_offset = 0;
Expand Down
26 changes: 15 additions & 11 deletions elf/thunks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -212,16 +212,6 @@ void OutputSection<E>::create_range_extension_thunks(Context<E> &ctx) {
i64 t = 0;

while (b < m.size()) {
// Move D foward as far as we can jump from B to anywhere in a thunk at D.
while (d < m.size() &&
align_to(offset, 1 << m[d]->p2align) + m[d]->sh_size + max_thunk_size <
m[b]->offset + max_distance()) {
offset = align_to(offset, 1 << m[d]->p2align);
m[d]->offset = offset;
offset += m[d]->sh_size;
d++;
}

// Move C forward so that C is apart from B by BATCH_SIZE. We want
// to make sure that there's at least one section between B and C
// to ensure progress.
Expand All @@ -230,11 +220,25 @@ void OutputSection<E>::create_range_extension_thunks(Context<E> &ctx) {
m[c]->offset + m[c]->sh_size < m[b]->offset + batch_size)
c++;

// Move D foward as far as we can jump from B to anywhere in a thunk at D.
d = c;
while (d < m.size() &&
align_to(offset, 1 << m[d]->p2align) + m[d]->sh_size + max_thunk_size <
m[b]->offset + max_distance())
d++;

// Move A forward so that A is reachable from C.
i64 c_offset = (c == m.size()) ? offset : m[c]->offset;
while (a < m.size() && m[a]->offset + max_distance() < c_offset)
while (a < b && a < m.size() && m[a]->offset + max_distance() < c_offset)
a++;

// Assign offsets to all sections before D.
for (i64 i = b; i < d; i++) {
offset = align_to(offset, 1 << m[i]->p2align);
m[i]->offset = offset;
offset += m[i]->sh_size;
}

// Erase references to out-of-range thunks.
while (t < thunks.size() && thunks[t]->offset < m[a]->offset)
reset_thunk(*thunks[t++]);
Expand Down
14 changes: 10 additions & 4 deletions test/elf/x86_64_large-bss.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@
[ $MACHINE = x86_64 ] || skip

cat <<EOF | $CC -o $t/a.o -c -xc - 2> /dev/null || skip
volatile char arr[0x100000000];
#include <stdio.h>
char arr1[0xc0000000];
extern char arr2[0xc0000000];
int main() {
return arr[2000];
printf("%d %lx\n", arr1 < arr2, arr2 - arr1);
}
EOF

$CC -B. -o $t/exe $t/a.o
$QEMU $t/exe
cat <<EOF | $CC -o $t/b.o -c -xc - 2> /dev/null || skip
char arr2[0xc0000000];
EOF

$CC -B. -o $t/exe $t/a.o $t/b.o
$QEMU $t/exe | grep -Eq '^1 c0000000$'

0 comments on commit 0ce32d3

Please sign in to comment.