Skip to content

Commit

Permalink
Fill gaps in executable segments with trap or nop instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed Oct 23, 2023
1 parent f7dea3a commit c86a59a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 21 deletions.
17 changes: 16 additions & 1 deletion elf/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -1868,6 +1868,7 @@ struct X86_64 {
static constexpr u32 plt_hdr_size = 32;
static constexpr u32 plt_size = 16;
static constexpr u32 pltgot_size = 8;
static constexpr u8 filler[] = { 0xcc };

static constexpr u32 R_COPY = R_X86_64_COPY;
static constexpr u32 R_GLOB_DAT = R_X86_64_GLOB_DAT;
Expand All @@ -1892,6 +1893,7 @@ struct I386 {
static constexpr u32 plt_hdr_size = 16;
static constexpr u32 plt_size = 16;
static constexpr u32 pltgot_size = 16;
static constexpr u8 filler[] = { 0xcc };

static constexpr u32 R_COPY = R_386_COPY;
static constexpr u32 R_GLOB_DAT = R_386_GLOB_DAT;
Expand All @@ -1918,6 +1920,7 @@ struct ARM64 {
static constexpr u32 pltgot_size = 16;
static constexpr u32 thunk_hdr_size = 0;
static constexpr u32 thunk_size = 16;
static constexpr u8 filler[] = { 0x00, 0x7d, 0x20, 0xd4 };

static constexpr u32 R_COPY = R_AARCH64_COPY;
static constexpr u32 R_GLOB_DAT = R_AARCH64_GLOB_DAT;
Expand All @@ -1944,6 +1947,7 @@ struct ARM32 {
static constexpr u32 pltgot_size = 16;
static constexpr u32 thunk_hdr_size = 16;
static constexpr u32 thunk_size = 16;
static constexpr u8 filler[] = { 0xff, 0xde };

static constexpr u32 R_COPY = R_ARM_COPY;
static constexpr u32 R_GLOB_DAT = R_ARM_GLOB_DAT;
Expand All @@ -1969,6 +1973,7 @@ struct RV64 {
static constexpr u32 plt_hdr_size = 32;
static constexpr u32 plt_size = 16;
static constexpr u32 pltgot_size = 16;
static constexpr u8 filler[] = { 0x02, 0x90 };

static constexpr u32 R_COPY = R_RISCV_COPY;
static constexpr u32 R_GLOB_DAT = R_RISCV_64;
Expand Down Expand Up @@ -2001,6 +2006,7 @@ struct RV32 {
static constexpr u32 plt_hdr_size = 32;
static constexpr u32 plt_size = 16;
static constexpr u32 pltgot_size = 16;
static constexpr u8 filler[] = { 0x02, 0x90 };

static constexpr u32 R_COPY = R_RISCV_COPY;
static constexpr u32 R_GLOB_DAT = R_RISCV_32;
Expand Down Expand Up @@ -2037,7 +2043,7 @@ struct PPC32 {
static constexpr u32 pltgot_size = 36;
static constexpr u32 thunk_hdr_size = 0;
static constexpr u32 thunk_size = 36;

static constexpr u8 filler[] = { 0x7f, 0xe0, 0x00, 0x08 };

static constexpr u32 R_COPY = R_PPC_COPY;
static constexpr u32 R_GLOB_DAT = R_PPC_GLOB_DAT;
Expand Down Expand Up @@ -2079,6 +2085,7 @@ struct PPC64V1 : PPC64 {
static constexpr u32 pltgot_size = 0;
static constexpr u32 thunk_hdr_size = 0;
static constexpr u32 thunk_size = 28;
static constexpr u8 filler[] = { 0x7f, 0xe0, 0x00, 0x08 };
};

struct PPC64V2 : PPC64 {
Expand All @@ -2089,6 +2096,7 @@ struct PPC64V2 : PPC64 {
static constexpr u32 pltgot_size = 0;
static constexpr u32 thunk_hdr_size = 0;
static constexpr u32 thunk_size = 24;
static constexpr u8 filler[] = { 0x08, 0x00, 0xe0, 0x7f };
};

struct S390X {
Expand All @@ -2101,6 +2109,7 @@ struct S390X {
static constexpr u32 plt_hdr_size = 48;
static constexpr u32 plt_size = 16;
static constexpr u32 pltgot_size = 16;
static constexpr u8 filler[] = { 0x07, 0x00 };

static constexpr u32 R_COPY = R_390_COPY;
static constexpr u32 R_GLOB_DAT = R_390_GLOB_DAT;
Expand All @@ -2124,6 +2133,7 @@ struct SPARC64 {
static constexpr u32 plt_hdr_size = 128;
static constexpr u32 plt_size = 32;
static constexpr u32 pltgot_size = 32;
static constexpr u8 filler[] = { 0x91, 0xd0, 0x20, 0x05 };

static constexpr u32 R_COPY = R_SPARC_COPY;
static constexpr u32 R_GLOB_DAT = R_SPARC_GLOB_DAT;
Expand All @@ -2147,6 +2157,7 @@ struct M68K {
static constexpr u32 plt_hdr_size = 18;
static constexpr u32 plt_size = 14;
static constexpr u32 pltgot_size = 8;
static constexpr u8 filler[] = { 0x4a, 0xfc };

static constexpr u32 R_COPY = R_68K_COPY;
static constexpr u32 R_GLOB_DAT = R_68K_GLOB_DAT;
Expand All @@ -2169,6 +2180,7 @@ struct SH4 {
static constexpr u32 plt_hdr_size = 16;
static constexpr u32 plt_size = 16;
static constexpr u32 pltgot_size = 12;
static constexpr u8 filler[] = { 0x00, 0x00 };

static constexpr u32 R_COPY = R_SH_COPY;
static constexpr u32 R_GLOB_DAT = R_SH_GLOB_DAT;
Expand All @@ -2191,6 +2203,7 @@ struct ALPHA {
static constexpr u32 plt_hdr_size = 0;
static constexpr u32 plt_size = 0;
static constexpr u32 pltgot_size = 0;
static constexpr u8 filler[] = { 0x81, 0x00, 0x00, 0x00 };

static constexpr u32 R_COPY = R_ALPHA_COPY;
static constexpr u32 R_GLOB_DAT = R_ALPHA_GLOB_DAT;
Expand All @@ -2215,6 +2228,7 @@ struct LOONGARCH64 {
static constexpr u32 pltgot_size = 16;
static constexpr u32 thunk_hdr_size = 0;
static constexpr u32 thunk_size = 16;
static constexpr u8 filler[] = { 0x00, 0x00, 0x2a, 0x00 };

static constexpr u32 R_COPY = R_LARCH_COPY;
static constexpr u32 R_GLOB_DAT = R_LARCH_64;
Expand All @@ -2240,6 +2254,7 @@ struct LOONGARCH32 {
static constexpr u32 pltgot_size = 16;
static constexpr u32 thunk_hdr_size = 0;
static constexpr u32 thunk_size = 16;
static constexpr u8 filler[] = { 0x00, 0x00, 0x2a, 0x00 };

static constexpr u32 R_COPY = R_LARCH_COPY;
static constexpr u32 R_GLOB_DAT = R_LARCH_32;
Expand Down
39 changes: 19 additions & 20 deletions elf/output-chunks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -883,31 +883,30 @@ void OutputSection<E>::copy_buf(Context<E> &ctx) {

template <typename E>
void OutputSection<E>::write_to(Context<E> &ctx, u8 *buf) {
auto clear = [&](u8 *loc, i64 size) {
// As a special case, .init and .fini are filled with NOPs for s390x
// because the runtime executes the sections as if they were a single
// function. .init and .fini are superceded by .init_array and
// .fini_array but being actively used only on s390x.
if constexpr (is_s390x<E>) {
if (this->name == ".init" || this->name == ".fini") {
for (i64 i = 0; i < size; i += 2)
*(ub16 *)(loc + i) = 0x0700; // nop
return;
}
}
memset(loc, 0, size);
};

tbb::parallel_for((i64)0, (i64)members.size(), [&](i64 i) {
// Copy section contents to an output file
// Copy section contents to an output file.
InputSection<E> &isec = *members[i];
isec.write_to(ctx, buf + isec.offset);

// Clear trailing padding
// Clear trailing padding. We write trap or nop instructions for
// an executable segment so that a disassembler wouldn't try to
// disassemble garbage as instructions.
u64 this_end = isec.offset + isec.sh_size;
u64 next_start = (i == members.size() - 1) ?
(u64)this->shdr.sh_size : members[i + 1]->offset;
clear(buf + this_end, next_start - this_end);
u64 next_start;
if (i + 1 < members.size())
next_start = members[i + 1]->offset;
else
next_start = this->shdr.sh_size;

u8 *loc = buf + this_end;
i64 size = next_start - this_end;

if (this->shdr.sh_flags & SHF_EXECINSTR) {
for (i64 i = 0; i + sizeof(E::filler) <= size; i += sizeof(E::filler))
memcpy(loc + i, E::filler, sizeof(E::filler));
} else {
memset(loc, 0, size);
}
});

if constexpr (needs_thunk<E>) {
Expand Down

0 comments on commit c86a59a

Please sign in to comment.