@@ -108,71 +108,66 @@ template <>
108
108
void write_plt_header (Context<E> &ctx, u8 *buf) {
109
109
if (ctx.arg .pic ) {
110
110
static const u8 insn[] = {
111
- 0xf3 , 0x0f , 0x1e , 0xfb , // endbr32
112
111
0x51 , // push %ecx
113
112
0x8d , 0x8b , 0 , 0 , 0 , 0 , // lea GOTPLT+4(%ebx), %ecx
114
113
0xff , 0x31 , // push (%ecx)
115
114
0xff , 0x61 , 0x04 , // jmp *0x4(%ecx)
115
+ 0xcc , 0xcc , 0xcc , 0xcc , // (padding)
116
116
};
117
117
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 ;
119
119
} else {
120
120
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)
127
126
};
128
127
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 ;
130
129
}
131
130
}
132
131
133
132
template <>
134
133
void write_plt_entry (Context<E> &ctx, u8 *buf, Symbol<E> &sym) {
135
134
if (ctx.arg .pic ) {
136
135
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)
141
139
};
142
140
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 ;
145
143
} else {
146
144
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)
151
148
};
152
149
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);
155
152
}
156
153
}
157
154
158
155
template <>
159
156
void write_pltgot_entry (Context<E> &ctx, u8 *buf, Symbol<E> &sym) {
160
157
if (ctx.arg .pic ) {
161
158
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)
165
161
};
166
162
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 ;
168
164
} else {
169
165
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)
173
168
};
174
169
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);
176
171
}
177
172
}
178
173
@@ -242,11 +237,10 @@ static void relax_ld_to_le(u8 *loc, ElfRel<E> rel, u64 tls_size) {
242
237
case R_386_GOT32X: {
243
238
static const u8 insn[] = {
244
239
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
247
241
};
248
242
memcpy (loc - 2 , insn, sizeof (insn));
249
- *(ul32 *)(loc + 5 ) = tls_size;
243
+ *(ul32 *)(loc + 6 ) = tls_size;
250
244
break ;
251
245
}
252
246
default :
@@ -406,6 +400,10 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
406
400
// mov %reg, %eax
407
401
// call *(%eax)
408
402
// 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.)
409
407
if (sym.has_tlsdesc (ctx)) {
410
408
*(ul32 *)loc = sym.get_tlsdesc_addr (ctx) + A - GOT;
411
409
} else if (sym.has_gottp (ctx)) {
0 commit comments