Skip to content

Commit 50766f1

Browse files
committed
Remove endbr32 support
It looks like Linux is going to support CET only on x86-64 (i.e. endbr64), and it is very unlikely that x86-32 will get CET support. So I'll remove the instruction from the code we generate for x86-32.
1 parent 3496ad1 commit 50766f1

File tree

2 files changed

+31
-33
lines changed

2 files changed

+31
-33
lines changed

src/arch-i386.cc

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -108,71 +108,66 @@ template <>
108108
void write_plt_header(Context<E> &ctx, u8 *buf) {
109109
if (ctx.arg.pic) {
110110
static const u8 insn[] = {
111-
0xf3, 0x0f, 0x1e, 0xfb, // endbr32
112111
0x51, // push %ecx
113112
0x8d, 0x8b, 0, 0, 0, 0, // lea GOTPLT+4(%ebx), %ecx
114113
0xff, 0x31, // push (%ecx)
115114
0xff, 0x61, 0x04, // jmp *0x4(%ecx)
115+
0xcc, 0xcc, 0xcc, 0xcc, // (padding)
116116
};
117117
memcpy(buf, insn, sizeof(insn));
118-
*(ul32 *)(buf + 7) = ctx.gotplt->shdr.sh_addr - ctx.got->shdr.sh_addr + 4;
118+
*(ul32 *)(buf + 3) = ctx.gotplt->shdr.sh_addr - ctx.got->shdr.sh_addr + 4;
119119
} else {
120120
static const u8 insn[] = {
121-
0xf3, 0x0f, 0x1e, 0xfb, // endbr32
122-
0x51, // push %ecx
123-
0xb9, 0, 0, 0, 0, // mov GOTPLT+4, %ecx
124-
0xff, 0x31, // push (%ecx)
125-
0xff, 0x61, 0x04, // jmp *0x4(%ecx)
126-
0xcc, // (padding)
121+
0x51, // push %ecx
122+
0xb9, 0, 0, 0, 0, // mov GOTPLT+4, %ecx
123+
0xff, 0x31, // push (%ecx)
124+
0xff, 0x61, 0x04, // jmp *0x4(%ecx)
125+
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // (padding)
127126
};
128127
memcpy(buf, insn, sizeof(insn));
129-
*(ul32 *)(buf + 6) = ctx.gotplt->shdr.sh_addr + 4;
128+
*(ul32 *)(buf + 2) = ctx.gotplt->shdr.sh_addr + 4;
130129
}
131130
}
132131

133132
template <>
134133
void write_plt_entry(Context<E> &ctx, u8 *buf, Symbol<E> &sym) {
135134
if (ctx.arg.pic) {
136135
static const u8 insn[] = {
137-
0xf3, 0x0f, 0x1e, 0xfb, // endbr32
138-
0xb9, 0, 0, 0, 0, // mov $reloc_offset, %ecx
139-
0xff, 0xa3, 0, 0, 0, 0, // jmp *foo@GOT(%ebx)
140-
0xcc, // (padding)
136+
0xb9, 0, 0, 0, 0, // mov $reloc_offset, %ecx
137+
0xff, 0xa3, 0, 0, 0, 0, // jmp *foo@GOT(%ebx)
138+
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // (padding)
141139
};
142140
memcpy(buf, insn, sizeof(insn));
143-
*(ul32 *)(buf + 5) = sym.get_plt_idx(ctx) * sizeof(ElfRel<E>);
144-
*(ul32 *)(buf + 11) = sym.get_gotplt_addr(ctx) - ctx.got->shdr.sh_addr;
141+
*(ul32 *)(buf + 1) = sym.get_plt_idx(ctx) * sizeof(ElfRel<E>);
142+
*(ul32 *)(buf + 7) = sym.get_gotplt_addr(ctx) - ctx.got->shdr.sh_addr;
145143
} else {
146144
static const u8 insn[] = {
147-
0xf3, 0x0f, 0x1e, 0xfb, // endbr32
148-
0xb9, 0, 0, 0, 0, // mov $reloc_offset, %ecx
149-
0xff, 0x25, 0, 0, 0, 0, // jmp *foo@GOT
150-
0xcc, // (padding)
145+
0xb9, 0, 0, 0, 0, // mov $reloc_offset, %ecx
146+
0xff, 0x25, 0, 0, 0, 0, // jmp *foo@GOT
147+
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // (padding)
151148
};
152149
memcpy(buf, insn, sizeof(insn));
153-
*(ul32 *)(buf + 5) = sym.get_plt_idx(ctx) * sizeof(ElfRel<E>);
154-
*(ul32 *)(buf + 11) = sym.get_gotplt_addr(ctx);
150+
*(ul32 *)(buf + 1) = sym.get_plt_idx(ctx) * sizeof(ElfRel<E>);
151+
*(ul32 *)(buf + 7) = sym.get_gotplt_addr(ctx);
155152
}
156153
}
157154

158155
template <>
159156
void write_pltgot_entry(Context<E> &ctx, u8 *buf, Symbol<E> &sym) {
160157
if (ctx.arg.pic) {
161158
static const u8 insn[] = {
162-
0xf3, 0x0f, 0x1e, 0xfb, // endbr32
163-
0xff, 0xa3, 0, 0, 0, 0, // jmp *foo@GOT(%ebx)
164-
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // (padding)
159+
0xff, 0xa3, 0, 0, 0, 0, // jmp *foo@GOT(%ebx)
160+
0xcc, 0xcc, // (padding)
165161
};
166162
memcpy(buf, insn, sizeof(insn));
167-
*(ul32 *)(buf + 6) = sym.get_got_pltgot_addr(ctx) - ctx.got->shdr.sh_addr;
163+
*(ul32 *)(buf + 2) = sym.get_got_pltgot_addr(ctx) - ctx.got->shdr.sh_addr;
168164
} else {
169165
static const u8 insn[] = {
170-
0xf3, 0x0f, 0x1e, 0xfb, // endbr32
171-
0xff, 0x25, 0, 0, 0, 0, // jmp *foo@GOT
172-
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, // (padding)
166+
0xff, 0x25, 0, 0, 0, 0, // jmp *foo@GOT
167+
0xcc, 0xcc, // (padding)
173168
};
174169
memcpy(buf, insn, sizeof(insn));
175-
*(ul32 *)(buf + 6) = sym.get_got_pltgot_addr(ctx);
170+
*(ul32 *)(buf + 2) = sym.get_got_pltgot_addr(ctx);
176171
}
177172
}
178173

@@ -242,11 +237,10 @@ static void relax_ld_to_le(u8 *loc, ElfRel<E> rel, u64 tls_size) {
242237
case R_386_GOT32X: {
243238
static const u8 insn[] = {
244239
0x65, 0xa1, 0, 0, 0, 0, // mov %gs:0, %eax
245-
0x2d, 0, 0, 0, 0, // sub $tls_size, %eax
246-
0x90, // nop
240+
0x2e, 0x2d, 0, 0, 0, 0, // sub $tls_size, %eax
247241
};
248242
memcpy(loc - 2, insn, sizeof(insn));
249-
*(ul32 *)(loc + 5) = tls_size;
243+
*(ul32 *)(loc + 6) = tls_size;
250244
break;
251245
}
252246
default:
@@ -406,6 +400,10 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
406400
// mov %reg, %eax
407401
// call *(%eax)
408402
// R_386_TLS_DESC_CALL foo
403+
//
404+
// Note that the compiler always uses the local-exec TLS model
405+
// for -fno-pic, so TLSDESC code is always PIC (i.e. uses %ebx to
406+
// store the address of GOT.)
409407
if (sym.has_tlsdesc(ctx)) {
410408
*(ul32 *)loc = sym.get_tlsdesc_addr(ctx) + A - GOT;
411409
} else if (sym.has_gottp(ctx)) {

src/elf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1870,7 +1870,7 @@ struct I386 {
18701870
static constexpr u32 e_machine = EM_386;
18711871
static constexpr u32 plt_hdr_size = 16;
18721872
static constexpr u32 plt_size = 16;
1873-
static constexpr u32 pltgot_size = 16;
1873+
static constexpr u32 pltgot_size = 8;
18741874
static constexpr u8 filler[] = { 0xcc }; // int3
18751875

18761876
static constexpr u32 R_COPY = R_386_COPY;

0 commit comments

Comments
 (0)