Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed Aug 16, 2023
1 parent c983321 commit bb40248
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 45 deletions.
6 changes: 3 additions & 3 deletions elf/arch-arm32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -336,12 +336,12 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
break;
}

// Just like THM_CALL, ARM_CALL relocation refers either BL or
// Just like THM_CALL, ARM_CALL relocation refers to either BL or
// BLX instruction. We may need to rewrite BL → BLX or BLX → BL.
bool is_bl = ((*(ul32 *)loc & 0xff00'0000) == 0xeb00'0000);
bool is_blx = ((*(ul32 *)loc & 0xfe00'0000) == 0xfa00'0000);
if (!is_bl && !is_blx)
Fatal(ctx) << *this << ": R_ARM_CALL refers neither BL nor BLX";
Fatal(ctx) << *this << ": R_ARM_CALL refers to neither BL nor BLX";

u64 val = S + A - P;
if (is_jump_reachable(val)) {
Expand All @@ -364,7 +364,7 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
break;
}

// These relocs refers a B (unconditional branch) instruction.
// These relocs refers to a B (unconditional branch) instruction.
// Unlike BL or BLX, we can't rewrite B to BX in place when the
// processor mode switch is required because BX doesn't takes an
// immediate; it takes only a register. So if mode switch is
Expand Down
1 change: 0 additions & 1 deletion elf/arch-loongarch.cc
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,6 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
check(sym.get_tlsgd_addr(ctx) + A - P, -(1LL << 31), 1LL << 31);
write_j20(loc, hi20(sym.get_tlsgd_addr(ctx) + A, P));
break;

case R_LARCH_TLS_LD_HI20:
case R_LARCH_TLS_GD_HI20:
write_j20(loc, (sym.get_tlsgd_addr(ctx) + A) >> 12);
Expand Down
29 changes: 10 additions & 19 deletions elf/arch-riscv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@

#include "mold.h"

#include <regex>
#include <tbb/parallel_for.h>
#include <tbb/parallel_for_each.h>

Expand Down Expand Up @@ -958,11 +959,13 @@ i64 riscv_resize_sections<E>(Context<E> &ctx) {
//
// The following functions takes care of ISA strings.

namespace {
struct Extn {
std::string name;
i64 major;
i64 minor;
};
}

// As per the RISC-V spec, the extension names must be sorted in a very
// specific way, and unfortunately that's not just an alphabetical order.
Expand Down Expand Up @@ -1003,26 +1006,14 @@ static bool extn_version_less(const Extn &e1, const Extn &e2) {
}

static std::optional<Extn> read_extn_string(std::string_view &str) {
Extn extn;

size_t pos = str.find_first_of("0123456789");
if (pos == str.npos)
return {};

extn.name = str.substr(0, pos);
str = str.substr(pos);
auto flags = std::regex_constants::optimize | std::regex_constants::ECMAScript;
static std::regex re(R"(^([a-z]+)(\d+)p(\d+))", flags);

size_t nread;
extn.major = std::stoul(std::string(str), &nread, 10);
str = str.substr(nread);
if (str.size() < 2 || str[0] != 'p')
return {};
str = str.substr(1);

extn.minor = std::stoul(std::string(str), &nread, 10);
str = str.substr(nread);
if (str.empty() || str[0] == '_')
return extn;
std::cmatch m;
if (std::regex_search(str.begin(), str.end(), m, re)) {
str = str.substr(m.length());
return Extn{m[1], (i64)std::stoul(m[2]), (i64)std::stoul(m[3])};
}
return {};
}

Expand Down
37 changes: 15 additions & 22 deletions elf/arch-x86-64.cc
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ static void relax_gd_to_ie(u8 *loc, ElfRel<E> rel, u64 val) {
// sequence. The difference from relax_gd_to_le is that we are
// materializing a Dynamic Thread Pointer for the current ELF module
// instead of an address for a particular thread-local variable.
static void relax_ld_to_le(u8 *loc, ElfRel<E> rel, u64 val) {
static void relax_ld_to_le(u8 *loc, ElfRel<E> rel, u64 tls_size) {
switch (rel.r_type) {
case R_X86_64_PLT32:
case R_X86_64_PC32: {
Expand All @@ -281,7 +281,7 @@ static void relax_ld_to_le(u8 *loc, ElfRel<E> rel, u64 val) {
0x48, 0x2d, 0, 0, 0, 0, // sub $tls_size, %rax
};
memcpy(loc - 3, insn, sizeof(insn));
*(ul32 *)(loc + 5) = val;
*(ul32 *)(loc + 5) = tls_size;
break;
}
case R_X86_64_GOTPCREL:
Expand All @@ -297,7 +297,7 @@ static void relax_ld_to_le(u8 *loc, ElfRel<E> rel, u64 val) {
0x90, // nop
};
memcpy(loc - 3, insn, sizeof(insn));
*(ul32 *)(loc + 5) = val;
*(ul32 *)(loc + 5) = tls_size;
break;
}
case R_X86_64_PLTOFF64: {
Expand All @@ -308,14 +308,12 @@ static void relax_ld_to_le(u8 *loc, ElfRel<E> rel, u64 val) {
// 48 01 d8 add %rbx, %rax
// ff d0 call *%rax
static const u8 insn[] = {
0x31, 0xc0, // xor %eax, %eax
0x64, 0x48, 0x8b, 0x00, // mov %fs:(%rax), %rax
0x48, 0x2d, 0, 0, 0, 0, // sub $tls_size, %rax
0x0f, 0x1f, 0x44, 0x00, 0x00, // nop
0x0f, 0x1f, 0x44, 0x00, 0x00, // nop
0x64, 0x48, 0x8b, 0x04, 0x25, 0, 0, 0, 0, // mov %fs:0, %rax
0x48, 0x2d, 0, 0, 0, 0, // sub $tls_size, %rax
0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, // nop
};
memcpy(loc - 3, insn, sizeof(insn));
*(ul32 *)(loc + 5) = val;
*(ul32 *)(loc + 8) = tls_size;
break;
}
default:
Expand Down Expand Up @@ -452,23 +450,18 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
write32s(G + GOTPLT + A - P);
break;
case R_X86_64_TLSGD:
if (sym.has_tlsgd(ctx)) {
if (sym.has_tlsgd(ctx))
write32s(sym.get_tlsgd_addr(ctx) + A - P);
} else if (sym.has_gottp(ctx)) {
relax_gd_to_ie(loc, rels[i + 1], sym.get_gottp_addr(ctx) - P);
i++;
} else {
relax_gd_to_le(loc, rels[i + 1], S - ctx.tp_addr);
i++;
}
else if (sym.has_gottp(ctx))
relax_gd_to_ie(loc, rels[++i], sym.get_gottp_addr(ctx) - P);
else
relax_gd_to_le(loc, rels[++i], S - ctx.tp_addr);
break;
case R_X86_64_TLSLD:
if (ctx.got->has_tlsld(ctx)) {
if (ctx.got->has_tlsld(ctx))
write32s(ctx.got->get_tlsld_addr(ctx) + A - P);
} else {
relax_ld_to_le(loc, rels[i + 1], ctx.tp_addr - ctx.tls_begin);
i++;
}
else
relax_ld_to_le(loc, rels[++i], ctx.tp_addr - ctx.tls_begin);
break;
case R_X86_64_DTPOFF32:
write32s(S + A - ctx.dtp_addr);
Expand Down

0 comments on commit bb40248

Please sign in to comment.