mirror of
https://github.com/rui314/mold.git
synced 2024-12-27 10:23:41 +03:00
Support R_X86_64_SIZE32 and SIZE64 relocations
This commit is contained in:
parent
c2264a9291
commit
7d07b48c92
@ -136,6 +136,7 @@ static void overflow_check(InputSection *sec, Symbol &sym, u64 r_type, u64 val)
|
||||
case R_X86_64_DTPOFF32:
|
||||
case R_X86_64_GOTTPOFF:
|
||||
case R_X86_64_GOTPC32_TLSDESC:
|
||||
case R_X86_64_SIZE32:
|
||||
case R_X86_64_TLSDESC_CALL:
|
||||
if (val != (i32)val)
|
||||
Error() << *sec << ": relocation " << rel_to_string(r_type)
|
||||
@ -147,6 +148,7 @@ static void overflow_check(InputSection *sec, Symbol &sym, u64 r_type, u64 val)
|
||||
case R_X86_64_PC64:
|
||||
case R_X86_64_TPOFF64:
|
||||
case R_X86_64_DTPOFF64:
|
||||
case R_X86_64_SIZE64:
|
||||
return;
|
||||
}
|
||||
unreachable();
|
||||
@ -180,6 +182,7 @@ static void write_val(u64 r_type, u8 *loc, u64 val) {
|
||||
case R_X86_64_DTPOFF32:
|
||||
case R_X86_64_GOTTPOFF:
|
||||
case R_X86_64_GOTPC32_TLSDESC:
|
||||
case R_X86_64_SIZE32:
|
||||
case R_X86_64_TLSDESC_CALL:
|
||||
*(u32 *)loc = val;
|
||||
return;
|
||||
@ -187,6 +190,7 @@ static void write_val(u64 r_type, u8 *loc, u64 val) {
|
||||
case R_X86_64_PC64:
|
||||
case R_X86_64_TPOFF64:
|
||||
case R_X86_64_DTPOFF64:
|
||||
case R_X86_64_SIZE64:
|
||||
*(u64 *)loc = val;
|
||||
return;
|
||||
}
|
||||
@ -388,6 +392,9 @@ void InputSection::apply_reloc_alloc(u8 *base) {
|
||||
write(S + A - out::tls_end + 4);
|
||||
break;
|
||||
}
|
||||
case R_SIZE:
|
||||
write(sym.esym->st_size + A);
|
||||
break;
|
||||
case R_TLSDESC_CALL_RELAX:
|
||||
// call *(%rax) -> nop
|
||||
loc[0] = 0x66;
|
||||
@ -727,6 +734,10 @@ void InputSection::scan_relocations() {
|
||||
rel_types[i] = R_GOTPC_TLSDESC;
|
||||
}
|
||||
break;
|
||||
case R_X86_64_SIZE32:
|
||||
case R_X86_64_SIZE64:
|
||||
rel_types[i] = R_SIZE;
|
||||
break;
|
||||
case R_X86_64_TLSDESC_CALL:
|
||||
if (config.relax && !config.shared)
|
||||
rel_types[i] = R_TLSDESC_CALL_RELAX;
|
||||
|
2
main.cc
2
main.cc
@ -874,6 +874,8 @@ static i64 get_section_rank(OutputChunk *chunk) {
|
||||
(!relro << 6) | (!hasbits << 5)) + 4;
|
||||
}
|
||||
|
||||
// Returns the smallest number n such that
|
||||
// n >= val and n % align == skew.
|
||||
inline u64 align_with_skew(u64 val, u64 align, u64 skew) {
|
||||
return align_to(val + align - skew, align) - align + skew;
|
||||
}
|
||||
|
1
mold.h
1
mold.h
@ -353,6 +353,7 @@ enum RelType : u16 {
|
||||
R_GOTTPOFF_RELAX,
|
||||
R_GOTPC_TLSDESC,
|
||||
R_GOTPC_TLSDESC_RELAX_LE,
|
||||
R_SIZE,
|
||||
R_TLSDESC_CALL_RELAX,
|
||||
};
|
||||
|
||||
|
@ -21,6 +21,11 @@ int print(int x) {
|
||||
printf("%d\n", x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int print64(long x) {
|
||||
printf("%ld\n", x);
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
cc -shared -o $t/c.so $t/a.o $t/b.o
|
||||
@ -119,4 +124,40 @@ $t/exe | grep -q 76
|
||||
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/c.so $t/d.s -pie
|
||||
$t/exe | grep -q 76
|
||||
|
||||
# SIZE32
|
||||
cat <<'EOF' > $t/d.s
|
||||
.globl main
|
||||
main:
|
||||
mov $foo+2@SIZE, %edi
|
||||
call print@PLT
|
||||
ret
|
||||
|
||||
.data
|
||||
.globl foo
|
||||
.type foo, %object
|
||||
.size foo, 24
|
||||
foo:
|
||||
EOF
|
||||
|
||||
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/c.so $t/d.s
|
||||
$t/exe | grep -q 26
|
||||
|
||||
# SIZE64
|
||||
cat <<'EOF' > $t/d.s
|
||||
.globl main
|
||||
main:
|
||||
movabs $foo+5@SIZE, %rdi
|
||||
call print64@PLT
|
||||
ret
|
||||
|
||||
.data
|
||||
.globl foo
|
||||
.type foo, %object
|
||||
.size foo, 56
|
||||
foo:
|
||||
EOF
|
||||
|
||||
clang -fuse-ld=`pwd`/../mold -o $t/exe $t/c.so $t/d.s
|
||||
$t/exe | grep -q 61
|
||||
|
||||
echo OK
|
||||
|
Loading…
Reference in New Issue
Block a user