[ELF] Reduce the size of InputSection from 88 bytes to 72 bytes

This commit is contained in:
Rui Ueyama committed 2022-03-02 17:27:31 +09:00
1 parent 83e05dae28
commit 4dae896726
9 files changed
+66 -55

No files matched your search

+10 -10
View File
@@ -150,18 +150,18 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
#define G (sym.get_got_addr(ctx) - ctx.got->shdr.sh_addr)
#define GOT ctx.got->shdr.sh_addr
if (needs_dynrel[i]) {
*dynrel++ = {P, R_AARCH64_ABS64, (u32)sym.get_dynsym_idx(ctx), A};
*(u64 *)loc = A;
continue;
}
if (needs_baserel[i] && !is_relr_reloc(ctx, rel))
*dynrel++ = {P, R_AARCH64_RELATIVE, 0, (i64)(S + A)};
switch (rel.r_type) {
case R_AARCH64_ABS64:
*(u64 *)loc = S + A;
if (sym.is_absolute() || !ctx.arg.pic) {
*(u64 *)loc = S + A;
} else if (sym.is_imported) {
*dynrel++ = {P, R_AARCH64_ABS64, (u32)sym.get_dynsym_idx(ctx), A};
*(u64 *)loc = A;
} else {
if (!is_relr_reloc(ctx, rel))
*dynrel++ = {P, R_AARCH64_RELATIVE, 0, (i64)(S + A)};
*(u64 *)loc = S + A;
}
continue;
case R_AARCH64_LDST8_ABS_LO12_NC:
*(u32 *)loc |= bits(S + A, 11, 0) << 10;
+17 -10
View File
@@ -165,15 +165,6 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
#define G (sym.get_got_addr(ctx) - ctx.got->shdr.sh_addr)
#define GOTPLT ctx.gotplt->shdr.sh_addr
if (needs_dynrel[i]) {
*dynrel++ = {P, R_386_32, (u32)sym.get_dynsym_idx(ctx)};
write32(A);
continue;
}
if (needs_baserel[i] && !is_relr_reloc(ctx, rel))
*dynrel++ = {P, R_386_RELATIVE, 0};
switch (rel.r_type) {
case R_386_8:
write8(S + A);
@@ -182,7 +173,16 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
write16(S + A);
continue;
case R_386_32:
write32(S + A);
if (sym.is_absolute() || !ctx.arg.pic) {
write32(S + A);
} else if (sym.is_imported) {
*dynrel++ = {P, R_386_32, (u32)sym.get_dynsym_idx(ctx)};
write32(A);
} else {
if (!is_relr_reloc(ctx, rel))
*dynrel++ = {P, R_386_RELATIVE, 0};
write32(S + A);
}
continue;
case R_386_PC8:
write8s(S + A);
@@ -191,6 +191,13 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
write16s(S + A);
continue;
case R_386_PC32:
if (sym.is_absolute() || !sym.is_imported || !ctx.arg.shared) {
write32(S + A - P);
} else {
*dynrel++ = {P, R_386_32, (u32)sym.get_dynsym_idx(ctx)};
write32(A);
}
continue;
case R_386_PLT32:
write32(S + A - P);
continue;
+10 -10
View File
@@ -230,21 +230,21 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
#define G (sym.get_got_addr(ctx) - ctx.got->shdr.sh_addr)
#define GOT ctx.got->shdr.sh_addr
if (needs_dynrel[i]) {
*dynrel++ = {P, R_RISCV_64, (u32)sym.get_dynsym_idx(ctx), A};
*(u64 *)loc = A;
continue;
}
if (needs_baserel[i] && !is_relr_reloc(ctx, rel))
*dynrel++ = {P, R_RISCV_RELATIVE, 0, (i64)(S + A)};
switch (rel.r_type) {
case R_RISCV_32:
*(u32 *)loc = S + A;
break;
case R_RISCV_64:
*(u64 *)loc = S + A;
if (sym.is_absolute() || !ctx.arg.pic) {
*(u64 *)loc = S + A;
} else if (sym.is_imported) {
*dynrel++ = {P, R_RISCV_64, (u32)sym.get_dynsym_idx(ctx), A};
*(u64 *)loc = A;
} else {
if (!is_relr_reloc(ctx, rel))
*dynrel++ = {P, R_RISCV_RELATIVE, 0, (i64)(S + A)};
*(u64 *)loc = S + A;
}
break;
case R_RISCV_TLS_DTPMOD32:
case R_RISCV_TLS_DTPMOD64:
+16 -11
View File
@@ -277,15 +277,6 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
#define G (sym.get_got_addr(ctx) - ctx.gotplt->shdr.sh_addr)
#define GOT ctx.gotplt->shdr.sh_addr
if (needs_dynrel[i]) {
*dynrel++ = {P, R_X86_64_64, (u32)sym.get_dynsym_idx(ctx), A};
write64(A);
continue;
}
if (needs_baserel[i] && !is_relr_reloc(ctx, rel))
*dynrel++ = {P, R_X86_64_RELATIVE, 0, (i64)(S + A)};
switch (rel.r_type) {
case R_X86_64_8:
write8(S + A);
@@ -300,7 +291,16 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
write32s(S + A);
continue;
case R_X86_64_64:
write64(S + A);
if (sym.is_absolute() || !ctx.arg.pic) {
write64(S + A);
} else if (sym.is_imported) {
*dynrel++ = {P, R_X86_64_64, (u32)sym.get_dynsym_idx(ctx), A};
write64(A);
} else {
if (!is_relr_reloc(ctx, rel))
*dynrel++ = {P, R_X86_64_RELATIVE, 0, (i64)(S + A)};
write64(S + A);
}
continue;
case R_X86_64_PC8:
write8s(S + A - P);
@@ -312,7 +312,12 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
write32s(S + A - P);
continue;
case R_X86_64_PC64:
write64(S + A - P);
if (sym.is_absolute() || !sym.is_imported || !ctx.arg.shared) {
write64(S + A - P);
} else {
*dynrel++ = {P, R_X86_64_64, (u32)sym.get_dynsym_idx(ctx), A};
write64(A);
}
continue;
case R_X86_64_PLT32:
write32s(S + A - P);
+4
View File
@@ -986,6 +986,7 @@ struct X86_64 {
static constexpr u32 R_COPY = R_X86_64_COPY;
static constexpr u32 R_GLOB_DAT = R_X86_64_GLOB_DAT;
static constexpr u32 R_JUMP_SLOT = R_X86_64_JUMP_SLOT;
static constexpr u32 R_ABS = R_X86_64_64;
static constexpr u32 R_RELATIVE = R_X86_64_RELATIVE;
static constexpr u32 R_IRELATIVE = R_X86_64_IRELATIVE;
static constexpr u32 R_DTPOFF = R_X86_64_DTPOFF64;
@@ -1017,6 +1018,7 @@ struct I386 {
static constexpr u32 R_COPY = R_386_COPY;
static constexpr u32 R_GLOB_DAT = R_386_GLOB_DAT;
static constexpr u32 R_JUMP_SLOT = R_386_JUMP_SLOT;
static constexpr u32 R_ABS = R_386_32;
static constexpr u32 R_RELATIVE = R_386_RELATIVE;
static constexpr u32 R_IRELATIVE = R_386_IRELATIVE;
static constexpr u32 R_DTPOFF = R_386_TLS_DTPOFF32;
@@ -1048,6 +1050,7 @@ struct ARM64 {
static constexpr u32 R_COPY = R_AARCH64_COPY;
static constexpr u32 R_GLOB_DAT = R_AARCH64_GLOB_DAT;
static constexpr u32 R_JUMP_SLOT = R_AARCH64_JUMP_SLOT;
static constexpr u32 R_ABS = R_AARCH64_ABS64;
static constexpr u32 R_RELATIVE = R_AARCH64_RELATIVE;
static constexpr u32 R_IRELATIVE = R_AARCH64_IRELATIVE;
static constexpr u32 R_DTPOFF = R_AARCH64_TLS_DTPREL64;
@@ -1079,6 +1082,7 @@ struct RISCV64 {
static constexpr u32 R_COPY = R_RISCV_COPY;
static constexpr u32 R_GLOB_DAT = R_RISCV_64;
static constexpr u32 R_JUMP_SLOT = R_RISCV_JUMP_SLOT;
static constexpr u32 R_ABS = R_RISCV_64;
static constexpr u32 R_RELATIVE = R_RISCV_RELATIVE;
static constexpr u32 R_IRELATIVE = R_RISCV_IRELATIVE;
static constexpr u32 R_DTPOFF = R_RISCV_TLS_DTPREL64;
+1 -5
View File
@@ -202,12 +202,8 @@ void ObjectFile<E>::initialize_sections(Context<E> &ctx) {
if (std::unique_ptr<InputSection<E>> &target = sections[shdr.sh_info]) {
assert(target->relsec_idx == -1);
target->relsec_idx = i;
if (target->shdr().sh_flags & SHF_ALLOC) {
if (target->shdr().sh_flags & SHF_ALLOC)
i64 size = shdr.sh_size / sizeof(ElfRel<E>);
target->needs_dynrel.resize(size);
target->needs_baserel.resize(size);
}
}
}
}
-2
View File
@@ -181,7 +181,6 @@ void InputSection<E>::dispatch(Context<E> &ctx, Action table[3][4], i64 i,
}
assert(sym.is_imported);
needs_dynrel[i] = true;
file.num_dynrel++;
return;
case BASEREL:
@@ -194,7 +193,6 @@ void InputSection<E>::dispatch(Context<E> &ctx, Action table[3][4], i64 i,
ctx.has_textrel = true;
}
needs_baserel[i] = true;
if (!is_relr_reloc(ctx, rel))
file.num_dynrel++;
return;
+1 -3
View File
@@ -295,8 +295,6 @@ public:
std::string_view contents;
std::unique_ptr<SectionFragmentRef<E>[]> rel_fragments;
BitVector needs_dynrel;
BitVector needs_baserel;
i32 fde_begin = -1;
i32 fde_end = -1;
@@ -1985,7 +1983,7 @@ InputSection<E>::get_fragment(Context<E> &ctx, const ElfRel<E> &rel) {
}
template <typename E>
bool InputSection<E>::is_relr_reloc(Context<E> &ctx, const ElfRel<E> &rel) {
inline bool InputSection<E>::is_relr_reloc(Context<E> &ctx, const ElfRel<E> &rel) {
return ctx.arg.pack_dyn_relocs_relr &&
!(shdr().sh_flags & SHF_EXECINSTR) &&
(shdr().sh_addralign % E::word_size) == 0 &&
+7 -4
View File
@@ -896,6 +896,8 @@ static std::vector<T> encode_relr(const std::vector<T> &pos) {
template <typename E>
void OutputSection<E>::construct_relr(Context<E> &ctx) {
if (!ctx.arg.pic)
return;
if (!(this->shdr.sh_flags & SHF_ALLOC))
return;
if (this->shdr.sh_addralign % E::word_size)
@@ -914,10 +916,11 @@ void OutputSection<E>::construct_relr(Context<E> &ctx) {
if ((1 << isec.p2align) < E::word_size)
return;
std::span<ElfRel<E>> rels = isec.get_rels(ctx);
for (i64 j = 0; j < rels.size(); j++)
if (isec.needs_baserel[j] && (rels[j].r_offset % E::word_size) == 0)
shards[i].push_back(isec.offset + rels[j].r_offset);
for (ElfRel<E> &r : isec.get_rels(ctx))
if (r.r_type == E::R_ABS && (r.r_offset % E::word_size) == 0)
if (Symbol<E> &sym = *isec.file.symbols[r.r_sym];
!sym.is_absolute() && !sym.is_imported)
shards[i].push_back(isec.offset + r.r_offset);
});
// Compress them