[PATCH v4] x86: Properly handle relocation against local ABS symbol
H.J. Lu
hjl.tools@gmail.com
Sat May 17 21:54:26 GMT 2025
On x86-64,
movq symbol@GOTPCREL(%rip), %rax
may be used to get the symbol address via GOT. If the symbol turns out
to be a local symbol, linker normally converts it into
leaq symbol(%rip), %rax
But if the symbol is an ABS symbol, RAX won't have the correct value at
run-time and it will have the symbol value + load address. If the symbol
is declared as hidden or protected, compiler will generate
leaq symbol(%rip), %rax
to get the symbol address. If symbol is a local ABS symbol, RAX will have
the same incorrect value at run-time. On i386,
movl symbol@GOT(%reg1), %reg2
may be used to get the symbol address via GOT. If the symbol turns out
to be a local symbol, a symbol is local if it is hidden/protected symbol
or the output is an executable, linker normally converts it into
leal symbol@GOTOFF(%reg1), %reg2
If the symbol is declared as hidden or protected, compiler will generate
leal symbol@GOTOFF(%reg1), %reg2
In both cases, if symbol is a local ABS symbol, REG2 will have the same
incorrect value at run-time. This patch changes the x86-64 linker to
convert
movq symbol@GOTPCREL(%rip), %rax
and
leaq symbol(%rip), %rax
to
movq $symbol, %rax
and changes the i386 linker to convert
movl symbol@GOT(%reg1), %reg2
and
leal symbol@GOTOFF(%reg1), %reg2
leal symbol@GOTOFF, %reg2
to
movl $symbol, %reg2
for local ABS symbols.
bfd/
PR ld/32443
* elf32-i386.c (elf_i386_convert_load_reloc): Convert
lea symbol@GOTOFF[(%reg1)], %reg2" to "mov $symbol, %reg2"
for R_386_GOTOFF relocation against local ABS symbols.
(elf_i386_scan_relocs): Call elf_i386_convert_load_reloc only
on executable sections. Also convert R_386_GOTOFF relocation
against global symbol.
(elf_i386_finish_dynamic_symbol): Don't generate dynamic
relocation against local ABS symbols.
* elf64-x86-64.c (elf_x86_64_convert_load_reloc): Convert
"lea symbol(%rip), %reg" to "mov $symbol, %reg" for R_X86_64_PC32
relocation against local ABS symbols.
(elf_x86_64_scan_relocs): Call elf_x86_64_convert_load_reloc only
on executable sections. Also convert R_X86_64_PC32 relocation
against global symbol.
(elf_x86_64_finish_dynamic_symbol): Don't generate dynamic
relocation against local ABS symbol.
* elfxx-x86.h (ABS_SYMBOL_P): Drop linker-script defined check.
(LOCAL_ABS_SYMBOL_P): New.
ld/
PR ld/32443
* testsuite/ld-elf/linux-x86.exp: Run PR ld/32443 tests. Allow
PC32 relocation against local ABS symbol in PIE.
* testsuite/ld-elf/pr25749-1b.err: Removed.
* testsuite/ld-elf/pr32443-hidden.rd: New file.
* testsuite/ld-elf/pr32443-hidden.t: Likewise.
* testsuite/ld-elf/pr32443.t: Likewise.
* testsuite/ld-elf/pr32443a.c: Likewise.
* testsuite/ld-elf/pr32443b.c: Likewise.
* testsuite/ld-i386/i386.exp: PR ld/32443 tests.
* testsuite/ld-i386/lea2.s: New file.
* testsuite/ld-i386/lea2a.d: Likewise.
* testsuite/ld-i386/lea2b.d: Likewise.
* testsuite/ld-i386/lea2c.d: Likewise.
* testsuite/ld-i386/lea3.d: Likewise.
* testsuite/ld-i386/lea3.s: Likewise.
* testsuite/ld-i386/mov4.s: Likewise.
* testsuite/ld-i386/mov4a.d: Likewise.
* testsuite/ld-i386/mov4b.d: Likewise.
* testsuite/ld-i386/mov4c.d: Likewise.
* testsuite/ld-x86-64/lea2.s: Likewise.
* testsuite/ld-x86-64/lea2a-x32.d: Likewise.
* testsuite/ld-x86-64/lea2a.d: Likewise.
* testsuite/ld-x86-64/lea2b-x32.d: Likewise.
* testsuite/ld-x86-64/lea2b.d: Likewise.
* testsuite/ld-x86-64/lea2c-x32.d: Likewise.
* testsuite/ld-x86-64/lea2c.d: Likewise.
* testsuite/ld-x86-64/lea2d-x32.d: Likewise.
* testsuite/ld-x86-64/lea2d.d: Likewise.
* testsuite/ld-x86-64/lea2e-x32.d: Likewise.
* testsuite/ld-x86-64/lea2e.d: Likewise.
* testsuite/ld-x86-64/lea3-x32.d: Likewise.
* testsuite/ld-x86-64/lea3.d: Likewise.
* testsuite/ld-x86-64/lea4-x32.d: Likewise.
* testsuite/ld-x86-64/lea4.d: Likewise.
* testsuite/ld-x86-64/mov3.s: Likewise.
* testsuite/ld-x86-64/mov3a-x32.d: Likewise.
* testsuite/ld-x86-64/mov3a.d: Likewise.
* testsuite/ld-x86-64/mov3b-x32.d: Likewise.
* testsuite/ld-x86-64/mov3b.d: Likewise.
* testsuite/ld-x86-64/mov3c-x32.d: Likewise.
* testsuite/ld-x86-64/mov3c.d: Likewise.
* testsuite/ld-x86-64/mov3d-x32.d: Likewise.
* testsuite/ld-x86-64/mov3d.d: Likewise.
* testsuite/ld-x86-64/mov3d-x32.d: Likewise.
* testsuite/ld-x86-64/mov3d.d: Likewise.
* testsuite/ld-x86-64/mov3e-x32.d: Likewise.
* testsuite/ld-x86-64/mov3e.d: Likewise.
* testsuite/ld-x86-64/mov3f-x32.d: Likewise.
* testsuite/ld-x86-64/mov3f.d: Likewise.
* testsuite/ld-x86-64/x86-64.exp: Run PR ld/32443 tests.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
bfd/elf32-i386.c | 84 ++++++++++++----
bfd/elf64-x86-64.c | 137 +++++++++++++++++++-------
bfd/elfxx-x86.h | 14 ++-
ld/testsuite/ld-elf/linux-x86.exp | 68 +++++++++++--
ld/testsuite/ld-elf/pr25749-1b.err | 3 -
ld/testsuite/ld-elf/pr32443-hidden.rd | 4 +
ld/testsuite/ld-elf/pr32443-hidden.t | 1 +
ld/testsuite/ld-elf/pr32443.t | 1 +
ld/testsuite/ld-elf/pr32443a.c | 15 +++
ld/testsuite/ld-elf/pr32443b.c | 7 ++
ld/testsuite/ld-i386/i386.exp | 7 ++
ld/testsuite/ld-i386/lea2.s | 12 +++
ld/testsuite/ld-i386/lea2a.d | 14 +++
ld/testsuite/ld-i386/lea2b.d | 14 +++
ld/testsuite/ld-i386/lea2c.d | 14 +++
ld/testsuite/ld-i386/lea3.d | 6 ++
ld/testsuite/ld-i386/lea3.s | 10 ++
ld/testsuite/ld-i386/mov4.s | 11 +++
ld/testsuite/ld-i386/mov4a.d | 13 +++
ld/testsuite/ld-i386/mov4b.d | 13 +++
ld/testsuite/ld-i386/mov4c.d | 13 +++
ld/testsuite/ld-x86-64/lea2.s | 11 +++
ld/testsuite/ld-x86-64/lea2a-x32.d | 13 +++
ld/testsuite/ld-x86-64/lea2a.d | 13 +++
ld/testsuite/ld-x86-64/lea2b-x32.d | 13 +++
ld/testsuite/ld-x86-64/lea2b.d | 13 +++
ld/testsuite/ld-x86-64/lea2c-x32.d | 13 +++
ld/testsuite/ld-x86-64/lea2c.d | 13 +++
ld/testsuite/ld-x86-64/lea2d-x32.d | 4 +
ld/testsuite/ld-x86-64/lea2d.d | 4 +
ld/testsuite/ld-x86-64/lea2e-x32.d | 4 +
ld/testsuite/ld-x86-64/lea2e.d | 4 +
ld/testsuite/ld-x86-64/lea3-x32.d | 7 ++
ld/testsuite/ld-x86-64/lea3.d | 6 ++
ld/testsuite/ld-x86-64/lea3.s | 10 ++
ld/testsuite/ld-x86-64/lea4-x32.d | 13 +++
ld/testsuite/ld-x86-64/lea4.d | 12 +++
ld/testsuite/ld-x86-64/lea4.s | 9 ++
ld/testsuite/ld-x86-64/mov3.s | 11 +++
ld/testsuite/ld-x86-64/mov3a-x32.d | 13 +++
ld/testsuite/ld-x86-64/mov3a.d | 13 +++
ld/testsuite/ld-x86-64/mov3b-x32.d | 13 +++
ld/testsuite/ld-x86-64/mov3b.d | 13 +++
ld/testsuite/ld-x86-64/mov3c-x32.d | 13 +++
ld/testsuite/ld-x86-64/mov3c.d | 13 +++
ld/testsuite/ld-x86-64/mov3d-x32.d | 13 +++
ld/testsuite/ld-x86-64/mov3d.d | 13 +++
ld/testsuite/ld-x86-64/mov3e-x32.d | 13 +++
ld/testsuite/ld-x86-64/mov3e.d | 13 +++
ld/testsuite/ld-x86-64/mov3f-x32.d | 13 +++
ld/testsuite/ld-x86-64/mov3f.d | 13 +++
ld/testsuite/ld-x86-64/x86-64.exp | 26 +++++
52 files changed, 744 insertions(+), 72 deletions(-)
delete mode 100644 ld/testsuite/ld-elf/pr25749-1b.err
create mode 100644 ld/testsuite/ld-elf/pr32443-hidden.rd
create mode 100644 ld/testsuite/ld-elf/pr32443-hidden.t
create mode 100644 ld/testsuite/ld-elf/pr32443.t
create mode 100644 ld/testsuite/ld-elf/pr32443a.c
create mode 100644 ld/testsuite/ld-elf/pr32443b.c
create mode 100644 ld/testsuite/ld-i386/lea2.s
create mode 100644 ld/testsuite/ld-i386/lea2a.d
create mode 100644 ld/testsuite/ld-i386/lea2b.d
create mode 100644 ld/testsuite/ld-i386/lea2c.d
create mode 100644 ld/testsuite/ld-i386/lea3.d
create mode 100644 ld/testsuite/ld-i386/lea3.s
create mode 100644 ld/testsuite/ld-i386/mov4.s
create mode 100644 ld/testsuite/ld-i386/mov4a.d
create mode 100644 ld/testsuite/ld-i386/mov4b.d
create mode 100644 ld/testsuite/ld-i386/mov4c.d
create mode 100644 ld/testsuite/ld-x86-64/lea2.s
create mode 100644 ld/testsuite/ld-x86-64/lea2a-x32.d
create mode 100644 ld/testsuite/ld-x86-64/lea2a.d
create mode 100644 ld/testsuite/ld-x86-64/lea2b-x32.d
create mode 100644 ld/testsuite/ld-x86-64/lea2b.d
create mode 100644 ld/testsuite/ld-x86-64/lea2c-x32.d
create mode 100644 ld/testsuite/ld-x86-64/lea2c.d
create mode 100644 ld/testsuite/ld-x86-64/lea2d-x32.d
create mode 100644 ld/testsuite/ld-x86-64/lea2d.d
create mode 100644 ld/testsuite/ld-x86-64/lea2e-x32.d
create mode 100644 ld/testsuite/ld-x86-64/lea2e.d
create mode 100644 ld/testsuite/ld-x86-64/lea3-x32.d
create mode 100644 ld/testsuite/ld-x86-64/lea3.d
create mode 100644 ld/testsuite/ld-x86-64/lea3.s
create mode 100644 ld/testsuite/ld-x86-64/lea4-x32.d
create mode 100644 ld/testsuite/ld-x86-64/lea4.d
create mode 100644 ld/testsuite/ld-x86-64/lea4.s
create mode 100644 ld/testsuite/ld-x86-64/mov3.s
create mode 100644 ld/testsuite/ld-x86-64/mov3a-x32.d
create mode 100644 ld/testsuite/ld-x86-64/mov3a.d
create mode 100644 ld/testsuite/ld-x86-64/mov3b-x32.d
create mode 100644 ld/testsuite/ld-x86-64/mov3b.d
create mode 100644 ld/testsuite/ld-x86-64/mov3c-x32.d
create mode 100644 ld/testsuite/ld-x86-64/mov3c.d
create mode 100644 ld/testsuite/ld-x86-64/mov3d-x32.d
create mode 100644 ld/testsuite/ld-x86-64/mov3d.d
create mode 100644 ld/testsuite/ld-x86-64/mov3e-x32.d
create mode 100644 ld/testsuite/ld-x86-64/mov3e.d
create mode 100644 ld/testsuite/ld-x86-64/mov3f-x32.d
create mode 100644 ld/testsuite/ld-x86-64/mov3f.d
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 5939548d0da..f8204f58ab9 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -1239,6 +1239,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
bfd_vma nop_offset;
bool is_pic, is_branch = false;
bool to_reloc_32;
+ bool reloc_gotoff;
bool abs_symbol;
unsigned int r_type;
unsigned int r_symndx;
@@ -1249,7 +1250,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
if (roff < 2)
return true;
- /* Addend for R_386_GOT32X relocations must be 0. */
+ /* Addend for R_386_GOT32X/R_386_GOTOFF relocations must be 0. */
addend = bfd_get_32 (abfd, contents + roff);
if (addend != 0)
return true;
@@ -1266,6 +1267,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
r_type = *r_type_p;
r_symndx = ELF32_R_SYM (irel->r_info);
+ reloc_gotoff = r_type == R_386_GOTOFF;
modrm = bfd_get_8 (abfd, contents + roff - 1);
baseless = (modrm & 0xc7) == 0x5;
@@ -1284,7 +1286,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
abs_symbol = isym->st_shndx == SHN_ABS;
}
- if (baseless && is_pic)
+ if (baseless && is_pic && !reloc_gotoff)
{
/* For PIC, disallow R_386_GOT32X without a base register
since we don't know what the GOT base is. */
@@ -1305,31 +1307,45 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
opcode = bfd_get_8 (abfd, contents + roff - 2);
- if (opcode == 0xff)
+ if (reloc_gotoff)
{
- switch (modrm & 0x38)
+ /* Only "lea symbol@GOTOFF[(%reg1)], %reg2" is allowed which will
+ be converted to "mov $symbol, %reg2" for a local ABS symbol. */
+ if (opcode != 0x8d)
+ return true;
+
+ /* Assuming it will be converted to R_386_32 against the local
+ ABS symbol. If it isn't case, it will be skipped. */
+ to_reloc_32 = true;
+ }
+ else
+ {
+ if (opcode == 0xff)
{
- case 0x10: /* CALL */
- case 0x20: /* JMP */
- is_branch = true;
- break;
+ switch (modrm & 0x38)
+ {
+ case 0x10: /* CALL */
+ case 0x20: /* JMP */
+ is_branch = true;
+ break;
- case 0x30: /* PUSH */
- break;
+ case 0x30: /* PUSH */
+ break;
- default:
- return true;
+ default:
+ return true;
+ }
}
- }
- /* Convert to R_386_32 if PIC is false (if PIC is true we already know
- there is a base register). */
- to_reloc_32 = !is_pic;
+ /* Convert R_386_GOT32X to R_386_32 if PIC is false (if PIC is
+ true we already know there is a base register). */
+ to_reloc_32 = !is_pic;
+ }
eh = elf_x86_hash_entry (h);
- /* Try to convert R_386_GOT32X. Get the symbol referred to by the
- reloc. */
+ /* Try to convert R_386_GOT32X/R_386_GOTOFF. Get the symbol referred
+ to by the reloc. */
if (h == NULL)
{
if (is_branch)
@@ -1341,6 +1357,29 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
"binop foo@GOT[(%reg1)], %reg2". */
goto convert_load;
}
+ else if (LOCAL_ABS_SYMBOL_P (link_info, h))
+ {
+ /* Covert relocation against a local ABS symbol to R_386_32 so
+ that we will get the absolute value for the ABS symbol at
+ run-time. Convert
+ leal symbol@GOTOFF[(%reg1)], %reg2
+ and
+ movl symbol@GOT(%reg1), %reg2
+ to
+ movl $symbol, %reg2
+ */
+ if (reloc_gotoff || opcode == 0x8b)
+ {
+ to_reloc_32 = true;
+ goto lea_to_mov;
+ }
+ return true;
+ }
+
+ /* R_386_GOTOFF can only be converted to R_386_32 against hidden or
+ protected ABS symbol. */
+ if (reloc_gotoff)
+ return true;
/* Undefined weak symbol is only bound locally in executable
and its reference is resolved as 0. */
@@ -1447,6 +1486,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
if (to_reloc_32)
{
+ lea_to_mov:
/* Convert "mov foo@GOT[(%reg1)], %reg2" to
"mov $foo, %reg2" with R_386_32. */
r_type = R_386_32;
@@ -1635,8 +1675,10 @@ elf_i386_scan_relocs (bfd *abfd,
h->ref_regular = 1;
}
- if (r_type == R_386_GOT32X
- && (h == NULL || h->type != STT_GNU_IFUNC))
+ if ((sec->flags & SEC_CODE) != 0
+ && (h == NULL || h->type != STT_GNU_IFUNC)
+ && (r_type == R_386_GOT32X
+ || (h != NULL && r_type == R_386_GOTOFF)))
{
Elf_Internal_Rela *irel = (Elf_Internal_Rela *) rel;
if (!elf_i386_convert_load_reloc (abfd, symtab_hdr, contents,
@@ -3991,7 +4033,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
&& SYMBOL_REFERENCES_LOCAL_P (info, h))
{
BFD_ASSERT((h->got.offset & 1) != 0);
- if (info->enable_dt_relr)
+ if (info->enable_dt_relr || LOCAL_ABS_SYMBOL_P (info, h))
generate_dynamic_reloc = false;
else
{
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 1baa8a01cee..4d730bab347 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -1791,6 +1791,8 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
bool relocx;
bool is_branch = false;
bool to_reloc_pc32;
+ bool reloc_pc32 = false;
+ bool to_reloc_32s = false;
bool abs_symbol;
bool local_ref;
asection *tsec = NULL;
@@ -1813,6 +1815,7 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
if (roff < 2)
return true;
relocx = (r_type == R_X86_64_GOTPCRELX);
+ reloc_pc32 = r_type == R_X86_64_PC32;
break;
case R_X86_64_REX_GOTPCRELX:
@@ -1887,31 +1890,40 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
opcode = bfd_get_8 (abfd, contents + roff - 2);
modrm = bfd_get_8 (abfd, contents + roff - 1);
- if (opcode == 0xff)
+ if (reloc_pc32)
{
- switch (modrm & 0x38)
+ /* Only "lea symbol(%rip), %reg" is allowed which will be converted
+ to "mov $symbol, %reg" for a local ABS symbol. */
+ if (opcode != 0x8d || modrm != 05)
+ return true;
+ }
+ else
+ {
+ if (opcode == 0xff)
{
- case 0x10: /* CALL */
- case 0x20: /* JMP */
- is_branch = true;
- break;
+ switch (modrm & 0x38)
+ {
+ case 0x10: /* CALL */
+ case 0x20: /* JMP */
+ is_branch = true;
+ break;
- case 0x30: /* PUSH */
- break;
+ case 0x30: /* PUSH */
+ break;
- default:
- return true;
+ default:
+ return true;
+ }
+ }
+ /* Convert mov to lea since it has been done for a while. */
+ else if (opcode != 0x8b)
+ {
+ /* Only convert R_X86_64_GOTPCRELX, R_X86_64_REX_GOTPCRELX
+ and R_X86_64_CODE_<n>_GOTPCRELX for call, jmp or one of adc,
+ add, and, cmp, or, sbb, sub, test, xor instructions. */
+ if (!relocx)
+ return true;
}
- }
-
- /* Convert mov to lea since it has been done for a while. */
- if (opcode != 0x8b)
- {
- /* Only convert R_X86_64_GOTPCRELX, R_X86_64_REX_GOTPCRELX
- and R_X86_64_CODE_<n>_GOTPCRELX for call, jmp or one of adc,
- add, and, cmp, or, sbb, sub, test, xor instructions. */
- if (!relocx)
- return true;
}
/* We convert only to R_X86_64_PC32:
@@ -1920,10 +1932,11 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
3. no_overflow is true.
4. PIC.
*/
- to_reloc_pc32 = (is_branch
- || !relocx
- || no_overflow
- || is_pic);
+ to_reloc_pc32 = (!reloc_pc32
+ && (is_branch
+ || !relocx
+ || no_overflow
+ || is_pic));
abs_symbol = false;
abs_relocation = 0;
@@ -1962,12 +1975,34 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
R_X86_64_PC32. */
struct elf_x86_link_hash_entry *eh = elf_x86_hash_entry (h);
- isym = NULL;
- tsec = NULL;
-
abs_symbol = ABS_SYMBOL_P (h);
abs_relocation = h->root.u.def.value;
+ if (LOCAL_ABS_SYMBOL_P (link_info, h))
+ {
+ /* Covert relocation against local ABS symbol to R_X86_64_32S
+ so that we will get the absolute value for the ABS symbol
+ at run-time. Convert
+ leaq symbol(%rip), %rax
+ and
+ movq symbol@GOTPCREL(%rip), %rax
+ to
+ movq $symbol, %rax
+ */
+ if (reloc_pc32 || opcode == 0x8b)
+ to_reloc_32s = true;
+ else
+ return true;
+ }
+
+ /* R_X86_64_PC32 can only be converted R_X86_64_32S against a
+ local ABS symbol. */
+ if (reloc_pc32 && !to_reloc_32s)
+ return true;
+
+ isym = NULL;
+ tsec = NULL;
+
/* NB: Also set linker_def via SYMBOL_REFERENCES_LOCAL_P. */
local_ref = SYMBOL_REFERENCES_LOCAL_P (link_info, h);
if ((relocx || opcode == 0x8b)
@@ -2292,13 +2327,17 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
else if (bfd_get_8 (abfd, contents + roff - 4) == 0x0f)
movrs = 4;
}
- else if (r_type == R_X86_64_REX_GOTPCRELX)
+ else if (reloc_pc32 || r_type == R_X86_64_REX_GOTPCRELX)
{
rex = bfd_get_8 (abfd, contents + roff - 3);
rex_w = (rex & REX_W) != 0;
}
- if (opcode == 0x8b)
+ /* Convert "lea symbol(%rip), %reg" to "mov $symbol, %reg". When
+ we get here, to_reloc_32s must be true. */
+ if (reloc_pc32)
+ goto lea_to_mov;
+ else if (opcode == 0x8b)
{
if (abs_symbol && local_ref && relocx)
to_reloc_pc32 = false;
@@ -2325,6 +2364,7 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
}
else
{
+ lea_to_mov:
/* Convert "mov foo@GOTPCREL(%rip), %reg" to
"mov $foo, %reg". */
opcode = 0xc7;
@@ -2415,7 +2455,26 @@ elf_x86_64_convert_load_reloc (bfd *abfd,
contents, irel->r_offset,
relocation, 0);
if (r == bfd_reloc_overflow)
- return true;
+ {
+ if ((r_type == (rex_w && ABI_64_P (link_info->output_bfd)
+ ? R_X86_64_32S : R_X86_64_32))
+ && reloc_pc32
+ && LOCAL_ABS_SYMBOL_P (link_info, h))
+ {
+ /* Since R_X86_64_PC32S/R_X86_64_32 relocation, which
+ is converted from R_X86_64_PC32, against a local
+ ABS symbol overflows, the unconverted R_X86_64_PC32
+ relocation will also overflow. */
+ howto = elf_x86_64_rtype_to_howto (abfd,
+ R_X86_64_PC32);
+ link_info->callbacks->reloc_overflow
+ (link_info, &h->root, h->root.root.string,
+ howto->name, (bfd_vma) 0, abfd, input_section,
+ irel->r_offset);
+ return false;
+ }
+ return true;
+ }
if (abs_relocation)
{
@@ -2638,13 +2697,15 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
}
converted_reloc = false;
- if ((r_type == R_X86_64_GOTPCREL
- || r_type == R_X86_64_GOTPCRELX
- || r_type == R_X86_64_REX_GOTPCRELX
- || r_type == R_X86_64_CODE_4_GOTPCRELX
- || r_type == R_X86_64_CODE_5_GOTPCRELX
- || r_type == R_X86_64_CODE_6_GOTPCRELX)
- && (h == NULL || h->type != STT_GNU_IFUNC))
+ if ((sec->flags & SEC_CODE) != 0
+ && (h == NULL || h->type != STT_GNU_IFUNC)
+ && (r_type == R_X86_64_GOTPCREL
+ || r_type == R_X86_64_GOTPCRELX
+ || r_type == R_X86_64_REX_GOTPCRELX
+ || r_type == R_X86_64_CODE_4_GOTPCRELX
+ || r_type == R_X86_64_CODE_5_GOTPCRELX
+ || r_type == R_X86_64_CODE_6_GOTPCRELX
+ || (h != NULL && r_type == R_X86_64_PC32)))
{
Elf_Internal_Rela *irel = (Elf_Internal_Rela *) rel;
if (!elf_x86_64_convert_load_reloc (abfd, sec, contents,
@@ -5462,7 +5523,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
if (!SYMBOL_DEFINED_NON_SHARED_P (h))
return false;
BFD_ASSERT((h->got.offset & 1) != 0);
- if (info->enable_dt_relr)
+ if (info->enable_dt_relr || LOCAL_ABS_SYMBOL_P (info, h))
generate_dynamic_reloc = false;
else
{
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index 88bfa05bce2..a1201367373 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -252,10 +252,16 @@
|| ELF_COMMON_DEF_P (H))
/* Return TRUE if the symbol described by a linker hash entry H is
- going to be absolute. Similar to bfd_is_abs_symbol, but excluding
- all linker-script defined symbols. */
-#define ABS_SYMBOL_P(H) \
- (bfd_is_abs_symbol (&(H)->root) && !(H)->root.ldscript_def)
+ going to be absolute. */
+#define ABS_SYMBOL_P(H) bfd_is_abs_symbol (&(H)->root)
+
+/* Return TRUE if the symbol described by a linker hash entry H is a
+ local symbol which is going to be absolute. */
+#define LOCAL_ABS_SYMBOL_P(INFO, H) \
+ (ABS_SYMBOL_P (H) \
+ && (bfd_link_executable (INFO) \
+ || ELF_ST_VISIBILITY ((H)->other) == STV_HIDDEN \
+ || ELF_ST_VISIBILITY ((H)->other) == STV_PROTECTED))
/* TRUE if relative relocation should be generated. GOT reference to
global symbol in PIC will lead to dynamic symbol. It becomes a
diff --git a/ld/testsuite/ld-elf/linux-x86.exp b/ld/testsuite/ld-elf/linux-x86.exp
index 27173b916da..681b7cda3f0 100644
--- a/ld/testsuite/ld-elf/linux-x86.exp
+++ b/ld/testsuite/ld-elf/linux-x86.exp
@@ -150,6 +150,30 @@ run_cc_link_tests [list \
{} \
"pr29377" \
] \
+ [list \
+ "Build pr32443a.so" \
+ "-shared $srcdir/$subdir/pr32443.t" \
+ "-O0 -fPIC" \
+ {pr32443a.c} \
+ {} \
+ "pr32443a.so" \
+ ] \
+ [list \
+ "Build pr32443b.so" \
+ "-shared $srcdir/$subdir/pr32443.t" \
+ "-O0 -fPIC -DHIDDEN" \
+ {pr32443a.c} \
+ {} \
+ "pr32443b.so" \
+ ] \
+ [list \
+ "Build pr32443-hidden.so" \
+ "-shared $srcdir/$subdir/pr32443-hidden.t" \
+ "-O0 -fPIC" \
+ {pr32443a.c} \
+ {{readelf {-Wr} pr32443-hidden.rd}} \
+ "pr32443-hidden.so" \
+ ] \
]
run_ld_link_exec_tests [list \
@@ -201,6 +225,42 @@ run_ld_link_exec_tests [list \
"" \
"tmpdir/indirect-extern-access-2.so" \
] \
+ [list \
+ "Run pr32443a with pr32443a.so" \
+ "" \
+ "" \
+ { pr32443b.c } \
+ "pr32443a" \
+ "pass.out" \
+ "" \
+ "" \
+ "" \
+ "tmpdir/pr32443a.so" \
+ ] \
+ [list \
+ "Run pr32443b with pr32443b.so" \
+ "" \
+ "" \
+ { pr32443b.c } \
+ "pr32443b" \
+ "pass.out" \
+ "" \
+ "" \
+ "" \
+ "tmpdir/pr32443b.so" \
+ ] \
+ [list \
+ "Run pr32443 with pr32443-hidden.so" \
+ "" \
+ "" \
+ { pr32443b.c } \
+ "pr32443-hidden" \
+ "pass.out" \
+ "" \
+ "" \
+ "" \
+ "tmpdir/pr32443-hidden.so" \
+ ] \
]
# Run-time tests which require working ifunc attribute support.
@@ -376,12 +436,8 @@ proc check_pr25749a {testname srcfilea srcfileb cflags ldflags lderror} {
check_pr25749a "pr25749-1a" "pr25749-1.c" "pr25749-1a.c" "$NOPIE_CFLAGS" "$NOPIE_LDFLAGS" ""
check_pr25749a "pr25749-1a" "pr25749-1.c" "pr25749-1a.c" "-fPIE" "-pie" ""
check_pr25749a "pr25749-1b" "pr25749-1.c" "pr25749-1b.c" "$NOPIE_CFLAGS" "$NOPIE_LDFLAGS" ""
-if { [istarget "i?86-*-linux*"] || ![at_least_gcc_version 5 1] } {
- check_pr25749a "pr25749-1b" "pr25749-1.c" "pr25749-1b.c" "-fPIE" "-pie" ""
-} else {
- check_pr25749a "pr25749-1b" "pr25749-1.c" "pr25749-1b.c" "-fPIE" "-pie" "pr25749-1b.err"
-}
-check_pr25749a "pr25749-1c" "pr25749-1.c" "pr25749-1c.c" "-fPIC" "-shared" "pr25749-1b.err"
+check_pr25749a "pr25749-1b" "pr25749-1.c" "pr25749-1b.c" "-fPIE" "-pie" ""
+check_pr25749a "pr25749-1c" "pr25749-1.c" "pr25749-1c.c" "-fPIE" "-pie" ""
check_pr25749a "pr25749-2a" "pr25749-2.c" "pr25749-2a.s" "$NOPIE_CFLAGS" "$NOPIE_LDFLAGS" ""
check_pr25749a "pr25749-2a" "pr25749-2.c" "pr25749-2a.s" "-fPIE" "-pie" ""
check_pr25749a "pr25749-2b" "pr25749-2.c" "pr25749-2b.s" "$NOPIE_CFLAGS" "$NOPIE_LDFLAGS" ""
diff --git a/ld/testsuite/ld-elf/pr25749-1b.err b/ld/testsuite/ld-elf/pr25749-1b.err
deleted file mode 100644
index bb389172f16..00000000000
--- a/ld/testsuite/ld-elf/pr25749-1b.err
+++ /dev/null
@@ -1,3 +0,0 @@
-#...
-.*: .* against absolute symbol `_binary_pr25749_1_c_size' .* is disallowed
-#pass
diff --git a/ld/testsuite/ld-elf/pr32443-hidden.rd b/ld/testsuite/ld-elf/pr32443-hidden.rd
new file mode 100644
index 00000000000..fbc68bf2688
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr32443-hidden.rd
@@ -0,0 +1,4 @@
+#failif
+#...
+[0-9a-f ]+R_.*_NONE.*
+#...
diff --git a/ld/testsuite/ld-elf/pr32443-hidden.t b/ld/testsuite/ld-elf/pr32443-hidden.t
new file mode 100644
index 00000000000..0754d57c012
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr32443-hidden.t
@@ -0,0 +1 @@
+PROVIDE_HIDDEN (value = 42);
diff --git a/ld/testsuite/ld-elf/pr32443.t b/ld/testsuite/ld-elf/pr32443.t
new file mode 100644
index 00000000000..9590849c5fb
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr32443.t
@@ -0,0 +1 @@
+PROVIDE (value = 42);
diff --git a/ld/testsuite/ld-elf/pr32443a.c b/ld/testsuite/ld-elf/pr32443a.c
new file mode 100644
index 00000000000..5111e373fdf
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr32443a.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdint.h>
+
+#ifdef HIDDEN
+extern int value __attribute__ ((visibility("hidden")));
+#else
+extern int value;
+#endif
+
+void
+lib_func (void)
+{
+ if ((uintptr_t) &value == 42)
+ printf ("PASS\n");
+}
diff --git a/ld/testsuite/ld-elf/pr32443b.c b/ld/testsuite/ld-elf/pr32443b.c
new file mode 100644
index 00000000000..a46c8e00f03
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr32443b.c
@@ -0,0 +1,7 @@
+extern void lib_func(void);
+int
+main(void)
+{
+ lib_func();
+ return 0;
+}
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index 67ad1e926c9..c8a6d8900d7 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -344,11 +344,18 @@ run_dump_test "lea1c"
run_dump_test "lea1d"
run_dump_test "lea1e"
run_dump_test "lea1f"
+run_dump_test "lea2a"
+run_dump_test "lea2b"
+run_dump_test "lea2c"
+run_dump_test "lea3"
run_dump_test "mov1a"
run_dump_test "mov1b"
run_dump_test "mov2a"
run_dump_test "mov2b"
run_dump_test "mov3"
+run_dump_test "mov4a"
+run_dump_test "mov4b"
+run_dump_test "mov4c"
run_dump_test "branch1"
run_dump_test "call1"
run_dump_test "call2"
diff --git a/ld/testsuite/ld-i386/lea2.s b/ld/testsuite/ld-i386/lea2.s
new file mode 100644
index 00000000000..d5f78831d67
--- /dev/null
+++ b/ld/testsuite/ld-i386/lea2.s
@@ -0,0 +1,12 @@
+ .text
+ .globl _start
+ .type _start, @function
+_start:
+ leal foo@GOTOFF(%ebx), %eax
+ leal foo@GOTOFF, %eax
+ .size _start, .-_start
+.ifdef __hidden__
+ .hidden foo
+.elseif __protected__ == 1
+ .protected foo
+.endif
diff --git a/ld/testsuite/ld-i386/lea2a.d b/ld/testsuite/ld-i386/lea2a.d
new file mode 100644
index 00000000000..7666508d65d
--- /dev/null
+++ b/ld/testsuite/ld-i386/lea2a.d
@@ -0,0 +1,14 @@
+#source: lea2.s
+#as: --32 -mrelax-relocations=yes --defsym __hidden__=1
+#ld: -shared -melf_i386 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: c7 c0 00 01 00 00 mov \$0x100,%eax
+[ ]*[a-f0-9]+: c7 c0 00 01 00 00 mov \$0x100,%eax
+#pass
diff --git a/ld/testsuite/ld-i386/lea2b.d b/ld/testsuite/ld-i386/lea2b.d
new file mode 100644
index 00000000000..de146dcf765
--- /dev/null
+++ b/ld/testsuite/ld-i386/lea2b.d
@@ -0,0 +1,14 @@
+#source: lea2.s
+#as: --32 -mrelax-relocations=yes --defsym __protected__=1
+#ld: -shared -melf_i386 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: c7 c0 00 01 00 00 mov \$0x100,%eax
+[ ]*[a-f0-9]+: c7 c0 00 01 00 00 mov \$0x100,%eax
+#pass
diff --git a/ld/testsuite/ld-i386/lea2c.d b/ld/testsuite/ld-i386/lea2c.d
new file mode 100644
index 00000000000..53032ea47ce
--- /dev/null
+++ b/ld/testsuite/ld-i386/lea2c.d
@@ -0,0 +1,14 @@
+#source: lea2.s
+#as: --32 -mrelax-relocations=yes
+#ld: -melf_i386 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: c7 c0 00 01 00 00 mov \$0x100,%eax
+[ ]*[a-f0-9]+: c7 c0 00 01 00 00 mov \$0x100,%eax
+#pass
diff --git a/ld/testsuite/ld-i386/lea3.d b/ld/testsuite/ld-i386/lea3.d
new file mode 100644
index 00000000000..e97eb998033
--- /dev/null
+++ b/ld/testsuite/ld-i386/lea3.d
@@ -0,0 +1,6 @@
+#as: --32 -mrelax-relocations=yes
+#ld: -melf_i386 --defsym foo=0x100 -z separate-code
+#readelf: -x .data
+
+Hex dump of section '\.data':
+ 0x08049000 8d050071 fbf7 ...q..
diff --git a/ld/testsuite/ld-i386/lea3.s b/ld/testsuite/ld-i386/lea3.s
new file mode 100644
index 00000000000..7c7e9655576
--- /dev/null
+++ b/ld/testsuite/ld-i386/lea3.s
@@ -0,0 +1,10 @@
+ .text
+ .globl _start
+ .type _start, @function
+_start:
+ nop
+ .size _start, .-_start
+ .data
+ .byte 0x8d
+ .byte 0x05
+ .long foo@GOTOFF
diff --git a/ld/testsuite/ld-i386/mov4.s b/ld/testsuite/ld-i386/mov4.s
new file mode 100644
index 00000000000..13544542601
--- /dev/null
+++ b/ld/testsuite/ld-i386/mov4.s
@@ -0,0 +1,11 @@
+ .text
+ .globl _start
+ .type _start, @function
+_start:
+ movl foo@GOT(%ebx), %eax
+ .size _start, .-_start
+.ifdef __hidden__
+ .hidden foo
+.elseif __protected__ == 1
+ .protected foo
+.endif
diff --git a/ld/testsuite/ld-i386/mov4a.d b/ld/testsuite/ld-i386/mov4a.d
new file mode 100644
index 00000000000..30216379bc8
--- /dev/null
+++ b/ld/testsuite/ld-i386/mov4a.d
@@ -0,0 +1,13 @@
+#source: mov4.s
+#as: --32 -mrelax-relocations=yes
+#ld: -shared -melf_i386 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 8b 83 ([0-9a-f]{2} ){4} * mov -0x[a-f0-9]+\(%ebx\),%eax
+#pass
diff --git a/ld/testsuite/ld-i386/mov4b.d b/ld/testsuite/ld-i386/mov4b.d
new file mode 100644
index 00000000000..61a8bbf93b4
--- /dev/null
+++ b/ld/testsuite/ld-i386/mov4b.d
@@ -0,0 +1,13 @@
+#source: mov4.s
+#as: --32 -mrelax-relocations=yes -defsym __hidden__=1
+#ld: -shared -melf_i386 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: c7 c0 00 01 00 00 mov \$0x100,%eax
+#pass
diff --git a/ld/testsuite/ld-i386/mov4c.d b/ld/testsuite/ld-i386/mov4c.d
new file mode 100644
index 00000000000..2fdfb878441
--- /dev/null
+++ b/ld/testsuite/ld-i386/mov4c.d
@@ -0,0 +1,13 @@
+#source: mov4.s
+#as: --32 -mrelax-relocations=yes -defsym __protected__=1
+#ld: -shared -melf_i386 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: c7 c0 00 01 00 00 mov \$0x100,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/lea2.s b/ld/testsuite/ld-x86-64/lea2.s
new file mode 100644
index 00000000000..307712079d6
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea2.s
@@ -0,0 +1,11 @@
+ .text
+ .globl _start
+ .type _start, @function
+_start:
+ leaq foo(%rip), %rax
+ .size _start, .-_start
+.ifdef __hidden__
+ .hidden foo
+.elseif __protected__ == 1
+ .protected foo
+.endif
diff --git a/ld/testsuite/ld-x86-64/lea2a-x32.d b/ld/testsuite/ld-x86-64/lea2a-x32.d
new file mode 100644
index 00000000000..a177c076e12
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea2a-x32.d
@@ -0,0 +1,13 @@
+#source: lea2.s
+#as: --x32 -mrelax-relocations=yes --defsym __hidden__=1
+#ld: -shared -melf32_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 40 c7 c0 00 01 00 00 rex mov \$0x100,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/lea2a.d b/ld/testsuite/ld-x86-64/lea2a.d
new file mode 100644
index 00000000000..afbcc348ee9
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea2a.d
@@ -0,0 +1,13 @@
+#source: lea2.s
+#as: --64 -mrelax-relocations=yes --defsym __hidden__=1
+#ld: -shared -melf_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 48 c7 c0 00 01 00 00 mov \$0x100,%rax
+#pass
diff --git a/ld/testsuite/ld-x86-64/lea2b-x32.d b/ld/testsuite/ld-x86-64/lea2b-x32.d
new file mode 100644
index 00000000000..3273d9ff7dc
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea2b-x32.d
@@ -0,0 +1,13 @@
+#source: lea2.s
+#as: --x32 -mrelax-relocations=yes
+#ld: -melf32_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 40 c7 c0 00 01 00 00 rex mov \$0x100,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/lea2b.d b/ld/testsuite/ld-x86-64/lea2b.d
new file mode 100644
index 00000000000..f792636731e
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea2b.d
@@ -0,0 +1,13 @@
+#source: lea2.s
+#as: --64 -mrelax-relocations=yes
+#ld: -melf_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 48 c7 c0 00 01 00 00 mov \$0x100,%rax
+#pass
diff --git a/ld/testsuite/ld-x86-64/lea2c-x32.d b/ld/testsuite/ld-x86-64/lea2c-x32.d
new file mode 100644
index 00000000000..f580f25214c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea2c-x32.d
@@ -0,0 +1,13 @@
+#source: lea2.s
+#as: --x32 -mrelax-relocations=yes --defsym __protected__=1
+#ld: -shared -melf32_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 40 c7 c0 00 01 00 00 rex mov \$0x100,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/lea2c.d b/ld/testsuite/ld-x86-64/lea2c.d
new file mode 100644
index 00000000000..618f7c27115
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea2c.d
@@ -0,0 +1,13 @@
+#source: lea2.s
+#as: --64 -mrelax-relocations=yes --defsym __protected__=1
+#ld: -shared -melf_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 48 c7 c0 00 01 00 00 mov \$0x100,%rax
+#pass
diff --git a/ld/testsuite/ld-x86-64/lea2d-x32.d b/ld/testsuite/ld-x86-64/lea2d-x32.d
new file mode 100644
index 00000000000..b5bc02c6d12
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea2d-x32.d
@@ -0,0 +1,4 @@
+#source: lea2.s
+#as: --x32 -mrelax-relocations=yes
+#ld: -melf32_x86_64 --defsym foo=0x100000000
+#error: .*relocation truncated to fit: R_X86_64_PC32 against symbol `foo' defined in \*ABS\* section in .*
diff --git a/ld/testsuite/ld-x86-64/lea2d.d b/ld/testsuite/ld-x86-64/lea2d.d
new file mode 100644
index 00000000000..24dc0c78c80
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea2d.d
@@ -0,0 +1,4 @@
+#source: lea2.s
+#as: --64 -mrelax-relocations=yes
+#ld: -melf_x86_64 --defsym foo=0x81000000
+#error: .*relocation truncated to fit: R_X86_64_PC32 against symbol `foo' defined in \*ABS\* section in .*
diff --git a/ld/testsuite/ld-x86-64/lea2e-x32.d b/ld/testsuite/ld-x86-64/lea2e-x32.d
new file mode 100644
index 00000000000..23e844d63be
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea2e-x32.d
@@ -0,0 +1,4 @@
+#source: lea2.s
+#as: --x32 -mrelax-relocations=yes --defsym __hidden__=1
+#ld: -shared -melf32_x86_64 --defsym foo=0x100000000
+#error: .*relocation truncated to fit: R_X86_64_PC32 against symbol `foo' defined in \*ABS\* section in .*
diff --git a/ld/testsuite/ld-x86-64/lea2e.d b/ld/testsuite/ld-x86-64/lea2e.d
new file mode 100644
index 00000000000..6b8a6216def
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea2e.d
@@ -0,0 +1,4 @@
+#source: lea2.s
+#as: --64 -mrelax-relocations=yes --defsym __hidden__=1
+#ld: -shared -melf_x86_64 --defsym foo=0x81000000
+#error: .*relocation truncated to fit: R_X86_64_PC32 against symbol `foo' defined in \*ABS\* section in .*
diff --git a/ld/testsuite/ld-x86-64/lea3-x32.d b/ld/testsuite/ld-x86-64/lea3-x32.d
new file mode 100644
index 00000000000..b41dea8f821
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea3-x32.d
@@ -0,0 +1,7 @@
+#source: lea3.s
+#as: --x32 -mrelax-relocations=yes
+#ld: -melf32_x86_64 --defsym foo=0x100 -z separate-code
+#readelf: -x .data
+
+Hex dump of section '\.data':
+ 0x00401000 8d05faf0 bfff ......
diff --git a/ld/testsuite/ld-x86-64/lea3.d b/ld/testsuite/ld-x86-64/lea3.d
new file mode 100644
index 00000000000..fa4336d7300
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea3.d
@@ -0,0 +1,6 @@
+#as: --64 -mrelax-relocations=yes
+#ld: -melf_x86_64 --defsym foo=0x100 -z separate-code
+#readelf: -x .data
+
+Hex dump of section '\.data':
+ 0x00401000 8d05faf0 bfff ......
diff --git a/ld/testsuite/ld-x86-64/lea3.s b/ld/testsuite/ld-x86-64/lea3.s
new file mode 100644
index 00000000000..eb9aceef3f3
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea3.s
@@ -0,0 +1,10 @@
+ .text
+ .globl _start
+ .type _start, @function
+_start:
+ nop
+ .size _start, .-_start
+ .data
+ .byte 0x8d
+ .byte 0x05
+ .long foo - 4 - .
diff --git a/ld/testsuite/ld-x86-64/lea4-x32.d b/ld/testsuite/ld-x86-64/lea4-x32.d
new file mode 100644
index 00000000000..95c20526497
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea4-x32.d
@@ -0,0 +1,13 @@
+#source: lea4.s
+#as: --x32 -mrelax-relocations=yes
+#ld: -melf32_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 48 8d 90 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%rax\),%rdx
+#pass
diff --git a/ld/testsuite/ld-x86-64/lea4.d b/ld/testsuite/ld-x86-64/lea4.d
new file mode 100644
index 00000000000..6e4476e0945
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea4.d
@@ -0,0 +1,12 @@
+#as: --64 -mrelax-relocations=yes
+#ld: -melf_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 48 8d 90 ([0-9a-f]{2} ){4} * lea -0x[a-f0-9]+\(%rax\),%rdx
+#pass
diff --git a/ld/testsuite/ld-x86-64/lea4.s b/ld/testsuite/ld-x86-64/lea4.s
new file mode 100644
index 00000000000..3620f5015d9
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/lea4.s
@@ -0,0 +1,9 @@
+ .text
+ .globl _start
+ .type _start, @function
+_start:
+ .byte 0x48
+ .byte 0x8d
+ .byte 0x90
+ .long foo - 4 - .
+ .size _start, .-_start
diff --git a/ld/testsuite/ld-x86-64/mov3.s b/ld/testsuite/ld-x86-64/mov3.s
new file mode 100644
index 00000000000..ad86f14fdce
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mov3.s
@@ -0,0 +1,11 @@
+ .text
+ .globl _start
+ .type _start, @function
+_start:
+ movq foo@GOTPCREL(%rip), %rax
+ .size _start, .-_start
+.ifdef __hidden__
+ .hidden foo
+.elseif __protected__ == 1
+ .protected foo
+.endif
diff --git a/ld/testsuite/ld-x86-64/mov3a-x32.d b/ld/testsuite/ld-x86-64/mov3a-x32.d
new file mode 100644
index 00000000000..a73e5e417b8
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mov3a-x32.d
@@ -0,0 +1,13 @@
+#source: mov3.s
+#as: --x32 -mrelax-relocations=yes
+#ld: -shared -melf32_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 48 8b 05 ([0-9a-f]{2} ){4} * mov 0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ <.*>
+#pass
diff --git a/ld/testsuite/ld-x86-64/mov3a.d b/ld/testsuite/ld-x86-64/mov3a.d
new file mode 100644
index 00000000000..06430c5368f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mov3a.d
@@ -0,0 +1,13 @@
+#source: mov3.s
+#as: --64 -mrelax-relocations=yes
+#ld: -shared -melf_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 48 8b 05 ([0-9a-f]{2} ){4} * mov 0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ <.*>
+#pass
diff --git a/ld/testsuite/ld-x86-64/mov3b-x32.d b/ld/testsuite/ld-x86-64/mov3b-x32.d
new file mode 100644
index 00000000000..8bf6684eae6
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mov3b-x32.d
@@ -0,0 +1,13 @@
+#source: mov3.s
+#as: --x32 -mrelax-relocations=yes --defsym __hidden__=1
+#ld: -shared -melf32_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 40 c7 c0 00 01 00 00 rex mov \$0x100,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/mov3b.d b/ld/testsuite/ld-x86-64/mov3b.d
new file mode 100644
index 00000000000..5ed26cbbfc1
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mov3b.d
@@ -0,0 +1,13 @@
+#source: mov3.s
+#as: --64 -mrelax-relocations=yes --defsym __hidden__=1
+#ld: -shared -melf_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 48 c7 c0 00 01 00 00 mov \$0x100,%rax
+#pass
diff --git a/ld/testsuite/ld-x86-64/mov3c-x32.d b/ld/testsuite/ld-x86-64/mov3c-x32.d
new file mode 100644
index 00000000000..9c684e358db
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mov3c-x32.d
@@ -0,0 +1,13 @@
+#source: mov3.s
+#as: --x32 -mrelax-relocations=yes
+#ld: -shared -melf32_x86_64 --defsym foo=0x100000000
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 48 8b 05 ([0-9a-f]{2} ){4} * mov 0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ <.*>
+#pass
diff --git a/ld/testsuite/ld-x86-64/mov3c.d b/ld/testsuite/ld-x86-64/mov3c.d
new file mode 100644
index 00000000000..ebdfcfbcf7a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mov3c.d
@@ -0,0 +1,13 @@
+#source: mov3.s
+#as: --64 -mrelax-relocations=yes
+#ld: -shared -melf_x86_64 --defsym foo=0x100000000
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 48 8b 05 ([0-9a-f]{2} ){4} * mov 0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ <.*>
+#pass
diff --git a/ld/testsuite/ld-x86-64/mov3d-x32.d b/ld/testsuite/ld-x86-64/mov3d-x32.d
new file mode 100644
index 00000000000..fde0d327966
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mov3d-x32.d
@@ -0,0 +1,13 @@
+#source: mov3.s
+#as: --x32 -mrelax-relocations=yes --defsym __hidden__=1
+#ld: -shared -melf32_x86_64 --defsym foo=0x100000000
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 48 8b 05 ([0-9a-f]{2} ){4} * mov 0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ <.*>
+#pass
diff --git a/ld/testsuite/ld-x86-64/mov3d.d b/ld/testsuite/ld-x86-64/mov3d.d
new file mode 100644
index 00000000000..3af4c42953c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mov3d.d
@@ -0,0 +1,13 @@
+#source: mov3.s
+#as: --64 -mrelax-relocations=yes --defsym __hidden__=1
+#ld: -shared -melf_x86_64 --defsym foo=0x100000000
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 48 8b 05 ([0-9a-f]{2} ){4} * mov 0x[a-f0-9]+\(%rip\),%rax # [a-f0-9]+ <.*>
+#pass
diff --git a/ld/testsuite/ld-x86-64/mov3e-x32.d b/ld/testsuite/ld-x86-64/mov3e-x32.d
new file mode 100644
index 00000000000..fe62229784d
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mov3e-x32.d
@@ -0,0 +1,13 @@
+#source: mov3.s
+#as: --x32 -mrelax-relocations=yes --defsym __protected__=1
+#ld: -shared -melf32_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 40 c7 c0 00 01 00 00 rex mov \$0x100,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/mov3e.d b/ld/testsuite/ld-x86-64/mov3e.d
new file mode 100644
index 00000000000..3531c64d8e4
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mov3e.d
@@ -0,0 +1,13 @@
+#source: mov3.s
+#as: --64 -mrelax-relocations=yes --defsym __protected__=1
+#ld: -shared -melf_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 48 c7 c0 00 01 00 00 mov \$0x100,%rax
+#pass
diff --git a/ld/testsuite/ld-x86-64/mov3f-x32.d b/ld/testsuite/ld-x86-64/mov3f-x32.d
new file mode 100644
index 00000000000..5a391ca8714
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mov3f-x32.d
@@ -0,0 +1,13 @@
+#source: mov3.s
+#as: --x32 -mrelax-relocations=yes
+#ld: -melf32_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 40 c7 c0 00 01 00 00 rex mov \$0x100,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/mov3f.d b/ld/testsuite/ld-x86-64/mov3f.d
new file mode 100644
index 00000000000..47d12c116bf
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/mov3f.d
@@ -0,0 +1,13 @@
+#source: mov3.s
+#as: --64 -mrelax-relocations=yes
+#ld: -melf_x86_64 --defsym foo=0x100
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+#...
+[ ]*[a-f0-9]+: 48 c7 c0 00 01 00 00 mov \$0x100,%rax
+#pass
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index a2159c0154c..11493a5e894 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -654,6 +654,20 @@ run_dump_test "lea1i"
run_dump_test "lea1j"
run_dump_test "lea1k"
run_dump_test "lea1l"
+run_dump_test "lea2a"
+run_dump_test "lea2a-x32"
+run_dump_test "lea2b"
+run_dump_test "lea2b-x32"
+run_dump_test "lea2c"
+run_dump_test "lea2c-x32"
+run_dump_test "lea2d"
+run_dump_test "lea2d-x32"
+run_dump_test "lea2e"
+run_dump_test "lea2e-x32"
+run_dump_test "lea3"
+run_dump_test "lea3-x32"
+run_dump_test "lea4"
+run_dump_test "lea4-x32"
run_dump_test "mov1a"
run_dump_test "mov1b"
run_dump_test "mov1c"
@@ -662,6 +676,18 @@ run_dump_test "mov2a"
run_dump_test "mov2b"
run_dump_test "mov2c"
run_dump_test "mov2d"
+run_dump_test "mov3a"
+run_dump_test "mov3a-x32"
+run_dump_test "mov3b"
+run_dump_test "mov3b-x32"
+run_dump_test "mov3c"
+run_dump_test "mov3c-x32"
+run_dump_test "mov3d"
+run_dump_test "mov3d-x32"
+run_dump_test "mov3e"
+run_dump_test "mov3e-x32"
+run_dump_test "mov3f"
+run_dump_test "mov3f-x32"
run_dump_test "ljmp1"
run_dump_test "ljmp2"
run_dump_test "load1a"
--
2.49.0
More information about the Binutils
mailing list