@@ -346,18 +346,20 @@ void X86::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
346
346
347
347
static void relaxTlsGdToLe (uint8_t *loc, const Relocation &rel, uint64_t val) {
348
348
if (rel.type == R_386_TLS_GD) {
349
- // Convert
349
+ // Convert (loc[-2] == 0x04)
350
350
// leal x@tlsgd(, %ebx, 1), %eax
351
- // call __tls_get_addr@plt
351
+ // call ___tls_get_addr@plt
352
+ // or
353
+ // leal x@tlsgd(%reg), %eax
354
+ // call *___tls_get_addr@got(%reg)
352
355
// to
353
- // movl %gs:0, %eax
354
- // subl $x@tpoff, %eax
355
356
const uint8_t inst[] = {
356
357
0x65 , 0xa1 , 0x00 , 0x00 , 0x00 , 0x00 , // movl %gs:0, %eax
357
- 0x81 , 0xe8 , 0 , 0 , 0 , 0 , // subl val (%ebx), %eax
358
+ 0x81 , 0xe8 , 0 , 0 , 0 , 0 , // subl x@ntpoff (%ebx), %eax
358
359
};
359
- memcpy (loc - 3 , inst, sizeof (inst));
360
- write32le (loc + 5 , val);
360
+ uint8_t *w = loc[-2 ] == 0x04 ? loc - 3 : loc - 2 ;
361
+ memcpy (w, inst, sizeof (inst));
362
+ write32le (w + 8 , val);
361
363
} else if (rel.type == R_386_TLS_GOTDESC) {
362
364
// Convert leal x@tlsdesc(%ebx), %eax to leal x@ntpoff, %eax.
363
365
//
@@ -379,18 +381,19 @@ static void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) {
379
381
380
382
static void relaxTlsGdToIe (uint8_t *loc, const Relocation &rel, uint64_t val) {
381
383
if (rel.type == R_386_TLS_GD) {
382
- // Convert
384
+ // Convert (loc[-2] == 0x04)
383
385
// leal x@tlsgd(, %ebx, 1), %eax
384
- // call __tls_get_addr @plt
385
- // to
386
- // movl %gs:0 , %eax
387
- // addl x@gotntpoff(%ebx), %eax
386
+ // call ___tls_get_addr @plt
387
+ // or
388
+ // leal x@tlsgd(%reg) , %eax
389
+ // call *___tls_get_addr@got(%reg)
388
390
const uint8_t inst[] = {
389
391
0x65 , 0xa1 , 0x00 , 0x00 , 0x00 , 0x00 , // movl %gs:0, %eax
390
- 0x03 , 0x83 , 0 , 0 , 0 , 0 , // addl val (%ebx), %eax
392
+ 0x03 , 0x83 , 0 , 0 , 0 , 0 , // addl x@gottpoff (%ebx), %eax
391
393
};
392
- memcpy (loc - 3 , inst, sizeof (inst));
393
- write32le (loc + 5 , val);
394
+ uint8_t *w = loc[-2 ] == 0x04 ? loc - 3 : loc - 2 ;
395
+ memcpy (w, inst, sizeof (inst));
396
+ write32le (w + 8 , val);
394
397
} else if (rel.type == R_386_TLS_GOTDESC) {
395
398
// Convert leal x@tlsdesc(%ebx), %eax to movl x@gotntpoff(%ebx), %eax.
396
399
if (memcmp (loc - 2 , " \x8d\x83 " , 2 )) {
@@ -453,17 +456,27 @@ static void relaxTlsLdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) {
453
456
return ;
454
457
}
455
458
459
+ if (loc[4 ] == 0xe8 ) {
460
+ // Convert
461
+ // leal x(%reg),%eax
462
+ // call ___tls_get_addr@plt
463
+ // to
464
+ const uint8_t inst[] = {
465
+ 0x65 , 0xa1 , 0x00 , 0x00 , 0x00 , 0x00 , // movl %gs:0,%eax
466
+ 0x90 , // nop
467
+ 0x8d , 0x74 , 0x26 , 0x00 , // leal 0(%esi,1),%esi
468
+ };
469
+ memcpy (loc - 2 , inst, sizeof (inst));
470
+ return ;
471
+ }
472
+
456
473
// Convert
457
- // leal foo (%reg),%eax
458
- // call ___tls_get_addr
474
+ // leal x (%reg),%eax
475
+ // call * ___tls_get_addr@got(%reg)
459
476
// to
460
- // movl %gs:0,%eax
461
- // nop
462
- // leal 0(%esi,1),%esi
463
477
const uint8_t inst[] = {
464
478
0x65 , 0xa1 , 0x00 , 0x00 , 0x00 , 0x00 , // movl %gs:0,%eax
465
- 0x90 , // nop
466
- 0x8d , 0x74 , 0x26 , 0x00 , // leal 0(%esi,1),%esi
479
+ 0x8d , 0xb6 , 0x00 , 0x00 , 0x00 , 0x00 , // leal (%esi),%esi
467
480
};
468
481
memcpy (loc - 2 , inst, sizeof (inst));
469
482
}
0 commit comments