aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/bfd-in.h2
-rw-r--r--bfd/bfd-in2.h4
-rw-r--r--bfd/elf-bfd.h14
-rw-r--r--bfd/elf32-i386.c151
-rw-r--r--bfd/elf64-x86-64.c274
-rw-r--r--bfd/elflink.c5
-rw-r--r--ld/emultempl/elf32.em7
-rw-r--r--ld/testsuite/ld-elf/pr19818a.d6
-rw-r--r--ld/testsuite/ld-elf/pr19818a.s12
-rw-r--r--ld/testsuite/ld-elf/pr19818b.d7
-rw-r--r--ld/testsuite/ld-elf/pr19818b.s2
-rw-r--r--ld/testsuite/ld-i386/i386.exp20
-rw-r--r--ld/testsuite/ld-i386/pr19818-1.t1
-rw-r--r--ld/testsuite/ld-i386/pr19818-1a.d6
-rw-r--r--ld/testsuite/ld-i386/pr19818-1a.s4
-rw-r--r--ld/testsuite/ld-i386/pr19818-1b.d13
-rw-r--r--ld/testsuite/ld-i386/pr19818-1b.s2
-rw-r--r--ld/testsuite/ld-i386/pr19818-1c.d7
-rw-r--r--ld/testsuite/ld-i386/pr19818-1c.s3
-rw-r--r--ld/testsuite/ld-i386/pr19818-1d.d14
-rw-r--r--ld/testsuite/ld-i386/pr19818-1e.d6
-rw-r--r--ld/testsuite/ld-i386/pr19818-1f.d13
-rw-r--r--ld/testsuite/ld-i386/pr19818-1g.d7
-rw-r--r--ld/testsuite/ld-i386/pr19818-1h.d14
-rw-r--r--ld/testsuite/ld-i386/pr19818-1i.d8
-rw-r--r--ld/testsuite/ld-i386/pr19818-1j.d9
-rw-r--r--ld/testsuite/ld-i386/pr19818-1k.d6
-rw-r--r--ld/testsuite/ld-i386/pr19818-1l.d13
-rw-r--r--ld/testsuite/ld-i386/pr19818-2.s4
-rw-r--r--ld/testsuite/ld-i386/pr19818-2a.d6
-rw-r--r--ld/testsuite/ld-i386/pr19818-2b.d13
-rw-r--r--ld/testsuite/ld-i386/pr19818-2c.d7
-rw-r--r--ld/testsuite/ld-i386/pr19818-2d.d14
-rw-r--r--ld/testsuite/ld-i386/pr19818-2e.d6
-rw-r--r--ld/testsuite/ld-i386/pr19818-2f.d13
-rw-r--r--ld/testsuite/ld-i386/pr19818-2g.d7
-rw-r--r--ld/testsuite/ld-i386/pr19818-2h.d14
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1.t1
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1a.d6
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1a.s4
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1b.d13
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1b.s2
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1c.d7
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1c.s3
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1d.d14
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1e.d6
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1f.d13
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1g.d7
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1h.d14
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1i.d6
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1j.d13
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1k.d7
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1l.d14
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1m.d6
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1n.d13
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1o.d7
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1p.d14
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1q.d4
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1r.d5
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1s.d8
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1t.d9
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1u.d6
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1v.d13
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1w.d6
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1x.d13
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-1y.d4
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-2.s4
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-2a.d4
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-2b.d5
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-2c.d4
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-2d.d5
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-3.s4
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-3a.d8
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-3b.d9
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-3c.d8
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-3d.d9
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-4.s5
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-4a.d5
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-4b.d14
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-5.s8
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-5a.d4
-rw-r--r--ld/testsuite/ld-x86-64/pr19818-5b.d4
-rw-r--r--ld/testsuite/ld-x86-64/x86-64.exp37
83 files changed, 913 insertions, 176 deletions
diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 5df2bab..b30ec71 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -649,7 +649,7 @@ enum notice_asneeded_action {
extern bfd_boolean bfd_elf_record_link_assignment
(bfd *, struct bfd_link_info *, const char *, bfd_boolean,
- bfd_boolean);
+ bfd_boolean, bfd_boolean);
extern struct bfd_link_needed_list *bfd_elf_get_needed_list
(bfd *, struct bfd_link_info *);
extern bfd_boolean bfd_elf_get_bfd_needed_list
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index dd7fb1a..be42ee1 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -656,7 +656,7 @@ enum notice_asneeded_action {
extern bfd_boolean bfd_elf_record_link_assignment
(bfd *, struct bfd_link_info *, const char *, bfd_boolean,
- bfd_boolean);
+ bfd_boolean, bfd_boolean);
extern struct bfd_link_needed_list *bfd_elf_get_needed_list
(bfd *, struct bfd_link_info *);
extern bfd_boolean bfd_elf_get_bfd_needed_list
@@ -1501,7 +1501,7 @@ typedef struct bfd_section
information. */
bfd_vma lma;
- /* The size of the section in octets, as it will be output.
+ /* The size of the section in *octets*, as it will be output.
Contains a value even if the section has no contents (e.g., the
size of <<.bss>>). */
bfd_size_type size;
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index ea4d59a..d5edd7c 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -212,6 +212,10 @@ struct elf_link_hash_entry
/* Symbol is defined by a shared library with non-default visibility
in a read/write section. */
unsigned int protected_def : 1;
+ /* Symbol is defiend by linker. */
+ unsigned int def_linker : 1;
+ /* Symbol is defiend by linker and absolue. */
+ unsigned int def_linker_abs : 1;
/* String table index in .dynstr if this is a dynamic symbol. */
unsigned long dynstr_index;
@@ -2645,6 +2649,16 @@ extern asection _bfd_elf_large_com_section;
(!(H)->unique_global \
&& ((INFO)->symbolic || ((INFO)->dynamic && !(H)->dynamic)))
+/* Will a relocation be resolved to absolute symbol in shared object. */
+#define RESOLVED_TO_ABS_IN_PIC(INFO, H) \
+ ((bfd_link_pie (INFO) \
+ || (bfd_link_dll (INFO) \
+ && (ELF_ST_VISIBILITY ((H)->other) != STV_DEFAULT \
+ || SYMBOLIC_BIND ((INFO), (H))))) \
+ && (H)->def_regular \
+ && (!(H)->def_linker || (H)->def_linker_abs) \
+ && bfd_is_abs_section ((H)->root.u.def.section))
+
#ifdef __cplusplus
}
#endif
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index ac3c2f4..d943872 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -751,6 +751,12 @@ static const struct elf_i386_backend_data elf_i386_arch_bed =
|| (EH)->has_non_got_reloc \
|| !(INFO)->dynamic_undefined_weak))
+/* Will a relocation be resolved to absolute value in shared object or
+ to zero? */
+#define RESOLVED_TO_ZERO_OR_ABS(INFO, EH) \
+ (UNDEFINED_WEAK_RESOLVED_TO_ZERO ((INFO), (EH)) \
+ || RESOLVED_TO_ABS_IN_PIC ((INFO), &(EH)->elf))
+
/* i386 ELF linker hash entry. */
struct elf_i386_link_hash_entry
@@ -2397,7 +2403,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
struct elf_i386_link_hash_entry *eh;
struct elf_dyn_relocs *p;
unsigned plt_entry_size;
- bfd_boolean resolved_to_zero;
+ bfd_boolean resolved_to_zero_or_abs;
if (h->root.type == bfd_link_hash_indirect)
return TRUE;
@@ -2411,7 +2417,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd);
- resolved_to_zero = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh);
+ resolved_to_zero_or_abs = RESOLVED_TO_ZERO_OR_ABS (info, eh);
/* Clear the reference count of function pointer relocations if
symbol isn't a normal function. */
@@ -2467,11 +2473,11 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
use_plt_got = eh->plt_got.refcount > 0;
- /* Make sure this symbol is output as a dynamic symbol.
- Undefined weak syms won't yet be marked as dynamic. */
+ /* Make sure this symbol is output as a dynamic symbol. Absolute
+ and undefined weak symbols won't yet be marked as dynamic. */
if (h->dynindx == -1
&& !h->forced_local
- && !resolved_to_zero)
+ && !resolved_to_zero_or_abs)
{
if (! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
@@ -2528,9 +2534,9 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
script. */
htab->elf.sgotplt->size += 4;
- /* There should be no PLT relocation against resolved
- undefined weak symbol in executable. */
- if (!resolved_to_zero)
+ /* There should be no PLT relocation against absolute
+ and resolved undefined weak symbols in executable. */
+ if (!resolved_to_zero_or_abs)
{
/* We also need to make an entry in the .rel.plt
section. */
@@ -2589,11 +2595,11 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
bfd_boolean dyn;
int tls_type = elf_i386_hash_entry(h)->tls_type;
- /* Make sure this symbol is output as a dynamic symbol.
- Undefined weak syms won't yet be marked as dynamic. */
+ /* Make sure this symbol is output as a dynamic symbol. Absolute
+ and undefined weak symbols won't yet be marked as dynamic. */
if (h->dynindx == -1
&& !h->forced_local
- && !resolved_to_zero)
+ && !resolved_to_zero_or_abs)
{
if (! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
@@ -2621,8 +2627,8 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
R_386_TLS_IE resp. R_386_TLS_GOTIE needs one dynamic relocation,
(but if both R_386_TLS_IE_32 and R_386_TLS_IE is present, we
need two), R_386_TLS_GD needs one if local symbol and two if
- global. No dynamic relocation against resolved undefined weak
- symbol in executable. */
+ global. No dynamic relocation against resolved absolute and
+ undefined weak symbols in executable. */
if (tls_type == GOT_TLS_IE_BOTH)
htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel);
else if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
@@ -2632,7 +2638,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel);
else if (! GOT_TLS_GDESC_P (tls_type)
&& ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
- && !resolved_to_zero)
+ && !resolved_to_zero_or_abs)
|| h->root.type != bfd_link_hash_undefweak)
&& (bfd_link_pic (info)
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
@@ -2654,6 +2660,8 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (bfd_link_pic (info))
{
+ struct elf_dyn_relocs **pp;
+
/* The only reloc that uses pc_count is R_386_PC32, which will
appear on a call or on something like ".long foo - .". We
want calls to protected symbols to resolve directly to the
@@ -2662,8 +2670,6 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
should avoid writing assembly like ".long foo - .". */
if (SYMBOL_CALLS_LOCAL (info, h))
{
- struct elf_dyn_relocs **pp;
-
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{
p->count -= p->pc_count;
@@ -2677,7 +2683,6 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (get_elf_i386_backend_data (info->output_bfd)->is_vxworks)
{
- struct elf_dyn_relocs **pp;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{
if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
@@ -2689,47 +2694,60 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
/* Also discard relocs on undefined weak syms with non-default
visibility or in PIE. */
- if (eh->dyn_relocs != NULL
- && h->root.type == bfd_link_hash_undefweak)
+ if (eh->dyn_relocs != NULL)
{
- /* Undefined weak symbol is never bound locally in shared
- library. */
- if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
- || resolved_to_zero)
+ if (h->root.type == bfd_link_hash_undefweak)
{
- if (h->non_got_ref)
+ /* Undefined weak symbol is never bound locally in shared
+ library. */
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ || resolved_to_zero_or_abs)
{
- /* Keep dynamic non-GOT/non-PLT relocation so that we
- can branch to 0 without PLT. */
- struct elf_dyn_relocs **pp;
-
- for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
- if (p->pc_count == 0)
- *pp = p->next;
- else
- {
- /* Remove non-R_386_PC32 relocation. */
- p->count = p->pc_count;
- pp = &p->next;
- }
-
- if (eh->dyn_relocs != NULL)
+ if (h->non_got_ref)
{
- /* Make sure undefined weak symbols are output
- as dynamic symbols in PIEs for dynamic non-GOT
- non-PLT reloations. */
- if (! bfd_elf_link_record_dynamic_symbol (info, h))
- return FALSE;
+ /* Keep dynamic non-GOT/non-PLT relocation so that we
+ can branch to 0 without PLT. */
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ if (p->pc_count == 0)
+ *pp = p->next;
+ else
+ {
+ /* Remove non-R_386_PC32 relocation. */
+ p->count = p->pc_count;
+ pp = &p->next;
+ }
+
+ if (eh->dyn_relocs != NULL)
+ {
+ /* Make sure undefined weak symbols are output
+ as dynamic symbols in PIEs for dynamic non-GOT
+ non-PLT reloations. */
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
}
+ else
+ eh->dyn_relocs = NULL;
+ }
+ else if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
}
- else
- eh->dyn_relocs = NULL;
}
- else if (h->dynindx == -1
- && !h->forced_local)
+ else if (resolved_to_zero_or_abs)
{
- if (! bfd_elf_link_record_dynamic_symbol (info, h))
- return FALSE;
+ /* Discard space for non-pc-relative relocs against
+ absolute symbols which are always resolved at
+ link-time. */
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ if (p->pc_count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
}
}
}
@@ -2743,7 +2761,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if ((!h->non_got_ref
|| eh->func_pointer_refcount > 0
|| (h->root.type == bfd_link_hash_undefweak
- && !resolved_to_zero))
+ && !resolved_to_zero_or_abs))
&& ((h->def_dynamic
&& !h->def_regular)
|| (htab->elf.dynamic_sections_created
@@ -2751,10 +2769,11 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|| h->root.type == bfd_link_hash_undefined))))
{
/* Make sure this symbol is output as a dynamic symbol.
- Undefined weak syms won't yet be marked as dynamic. */
+ Absolute and undefined weak symbols won't yet be marked
+ as dynamic. */
if (h->dynindx == -1
&& !h->forced_local
- && !resolved_to_zero)
+ && !resolved_to_zero_or_abs)
{
if (! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
@@ -3020,8 +3039,7 @@ elf_i386_convert_load (bfd *abfd, asection *sec,
/* Undefined weak symbol is only bound locally in executable
and its reference is resolved as 0. */
- if (UNDEFINED_WEAK_RESOLVED_TO_ZERO (link_info,
- elf_i386_hash_entry (h)))
+ if (RESOLVED_TO_ZERO_OR_ABS (link_info, elf_i386_hash_entry (h)))
{
if (opcode == 0xff)
{
@@ -3771,7 +3789,7 @@ elf_i386_relocate_section (bfd *output_bfd,
int tls_type;
bfd_vma st_size;
asection *resolved_plt;
- bfd_boolean resolved_to_zero;
+ bfd_boolean resolved_to_zero_or_abs;
r_type = ELF32_R_TYPE (rel->r_info);
if (r_type == R_386_GNU_VTINHERIT
@@ -4113,8 +4131,8 @@ elf_i386_relocate_section (bfd *output_bfd,
}
eh = (struct elf_i386_link_hash_entry *) h;
- resolved_to_zero = (eh != NULL
- && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh));
+ resolved_to_zero_or_abs = (eh != NULL
+ && RESOLVED_TO_ZERO_OR_ABS (info, eh));
switch (r_type)
{
@@ -4370,24 +4388,31 @@ r_386_got32:
unresolved_reloc = FALSE;
break;
+ case R_386_32:
+ /* R_386_32 relocation against absolute symbol or undefined
+ weak symbol in executable is resolved at link-time. */
+ if (resolved_to_zero_or_abs)
+ break;
+ goto direct;
+
case R_386_SIZE32:
/* Set to symbol size. */
relocation = st_size;
/* Fall through. */
- case R_386_32:
case R_386_PC32:
+direct:
if ((input_section->flags & SEC_ALLOC) == 0
|| is_vxworks_tls)
break;
/* Copy dynamic function pointer relocations. Don't generate
- dynamic relocations against resolved undefined weak symbols
- in PIE, except for R_386_PC32. */
+ dynamic relocations against absolute nor resolved undefined
+ weak symbols in PIE, except for R_386_PC32. */
if ((bfd_link_pic (info)
&& (h == NULL
|| ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
- && (!resolved_to_zero
+ && (!resolved_to_zero_or_abs
|| r_type == R_386_PC32))
|| h->root.type != bfd_link_hash_undefweak))
&& ((r_type != R_386_PC32 && r_type != R_386_SIZE32)
@@ -4399,7 +4424,7 @@ r_386_got32:
&& (!h->non_got_ref
|| eh->func_pointer_refcount > 0
|| (h->root.type == bfd_link_hash_undefweak
- && !resolved_to_zero))
+ && !resolved_to_zero_or_abs))
&& ((h->def_dynamic && !h->def_regular)
/* Undefined weak symbol is bound locally when
PIC is false. */
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 380376d..3519871 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -756,6 +756,12 @@ static const struct elf_x86_64_backend_data elf_x86_64_bnd_arch_bed =
|| (EH)->has_non_got_reloc \
|| !(INFO)->dynamic_undefined_weak))
+/* Will a relocation be resolved to absolute value in shared object or
+ to zero? */
+#define RESOLVED_TO_ZERO_OR_ABS(INFO, EH) \
+ (UNDEFINED_WEAK_RESOLVED_TO_ZERO ((INFO), (EH)) \
+ || RESOLVED_TO_ABS_IN_PIC ((INFO), &(EH)->elf))
+
/* x86-64 ELF linker hash entry. */
struct elf_x86_64_link_hash_entry
@@ -1581,6 +1587,58 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
return TRUE;
}
+static bfd_boolean
+elf_x86_64_need_pic (bfd *input_bfd, struct elf_link_hash_entry *h,
+ Elf_Internal_Shdr *symtab_hdr,
+ Elf_Internal_Sym *isym, reloc_howto_type *howto)
+{
+ const char *name;
+ const char *fmt = _("%B: relocation %s against %s `%s' can not be used when making a shared object%s");
+ const char *v;
+ const char *pic = "";
+
+ if (h)
+ {
+ name = h->root.root.string;
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_HIDDEN:
+ v = _("hidden symbol");
+ break;
+ case STV_INTERNAL:
+ v = _("internal symbol");
+ break;
+ case STV_PROTECTED:
+ v = _("protected symbol");
+ break;
+ default:
+ if (h->def_regular
+ && (!h->def_linker || h->def_linker_abs)
+ && bfd_is_abs_section (h->root.u.def.section))
+ v = _("absolute symbol");
+ else
+ {
+ v = _("symbol");
+ pic = _("; recompile with -fPIC");
+ }
+ break;
+ }
+ if (!h->def_regular)
+ fmt = _("%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s");
+ }
+ else
+ {
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr, isym, NULL);
+ v = _("symbol");
+ pic = _("; recompile with -fPIC");
+ }
+
+ (*_bfd_error_handler) (fmt, input_bfd, howto->name, v, name, pic);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+}
+
+
/* Rename some of the generic section flags to better document how they
are used here. */
#define need_convert_load sec_flg0
@@ -1964,12 +2022,8 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
size_reloc = TRUE;
goto do_size;
- case R_X86_64_32:
- if (!ABI_64_P (abfd))
- goto pointer;
case R_X86_64_8:
case R_X86_64_16:
- case R_X86_64_32S:
/* Let's help debug shared library creation. These relocs
cannot be used in shared libs. Don't error out for
sections we don't care about, such as debug sections or
@@ -1977,17 +2031,8 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
if (bfd_link_pic (info)
&& (sec->flags & SEC_ALLOC) != 0
&& (sec->flags & SEC_READONLY) != 0)
- {
- if (h)
- name = h->root.root.string;
- else
- name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
- (*_bfd_error_handler)
- (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
- abfd, x86_64_elf_howto_table[r_type].name, name);
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
- }
+ return elf_x86_64_need_pic (abfd, h, symtab_hdr, isym,
+ &x86_64_elf_howto_table[r_type]);
/* Fall through. */
case R_X86_64_PC8:
@@ -1995,8 +2040,9 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_X86_64_PC32:
case R_X86_64_PC32_BND:
case R_X86_64_PC64:
+ case R_X86_64_32:
+ case R_X86_64_32S:
case R_X86_64_64:
-pointer:
if (eh != NULL && (sec->flags & SEC_CODE) != 0)
eh->has_non_got_reloc = 1;
/* STT_GNU_IFUNC symbol must go through PLT even if it is
@@ -2610,7 +2656,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
struct elf_dyn_relocs *p;
const struct elf_backend_data *bed;
unsigned int plt_entry_size;
- bfd_boolean resolved_to_zero;
+ bfd_boolean resolved_to_zero_or_abs;
if (h->root.type == bfd_link_hash_indirect)
return TRUE;
@@ -2624,7 +2670,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
bed = get_elf_backend_data (info->output_bfd);
plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd);
- resolved_to_zero = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh);
+ resolved_to_zero_or_abs = RESOLVED_TO_ZERO_OR_ABS (info, eh);
/* We can't use the GOT PLT if pointer equality is needed since
finish_dynamic_symbol won't clear symbol value and the dynamic
@@ -2699,11 +2745,11 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
use_plt_got = eh->plt_got.refcount > 0;
- /* Make sure this symbol is output as a dynamic symbol.
- Undefined weak syms won't yet be marked as dynamic. */
+ /* Make sure this symbol is output as a dynamic symbol. Absolute
+ and undefined weak symbols won't yet be marked as dynamic. */
if (h->dynindx == -1
&& !h->forced_local
- && !resolved_to_zero)
+ && !resolved_to_zero_or_abs)
{
if (! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
@@ -2777,9 +2823,9 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
script. */
htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
- /* There should be no PLT relocation against resolved
- undefined weak symbol in executable. */
- if (!resolved_to_zero)
+ /* There should be no PLT relocation against absolute
+ and resolved undefined weak symbols in executable. */
+ if (!resolved_to_zero_or_abs)
{
/* We also need to make an entry in the .rela.plt
section. */
@@ -2819,11 +2865,11 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
bfd_boolean dyn;
int tls_type = elf_x86_64_hash_entry (h)->tls_type;
- /* Make sure this symbol is output as a dynamic symbol.
- Undefined weak syms won't yet be marked as dynamic. */
+ /* Make sure this symbol is output as a dynamic symbol. Absolute
+ and undefined weak symbols won't yet be marked as dynamic. */
if (h->dynindx == -1
&& !h->forced_local
- && !resolved_to_zero)
+ && !resolved_to_zero_or_abs)
{
if (! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
@@ -2848,8 +2894,8 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
dyn = htab->elf.dynamic_sections_created;
/* R_X86_64_TLSGD needs one dynamic relocation if local symbol
and two if global. R_X86_64_GOTTPOFF needs one dynamic
- relocation. No dynamic relocation against resolved undefined
- weak symbol in executable. */
+ relocation. No dynamic relocation against absolute and resolved
+ undefined weak symbols in executable. */
if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
|| tls_type == GOT_TLS_IE)
htab->elf.srelgot->size += bed->s->sizeof_rela;
@@ -2857,7 +2903,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
htab->elf.srelgot->size += 2 * bed->s->sizeof_rela;
else if (! GOT_TLS_GDESC_P (tls_type)
&& ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
- && !resolved_to_zero)
+ && !resolved_to_zero_or_abs)
|| h->root.type != bfd_link_hash_undefweak)
&& (bfd_link_pic (info)
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
@@ -2882,6 +2928,8 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
if (bfd_link_pic (info))
{
+ struct elf_dyn_relocs **pp;
+
/* Relocs that use pc_count are those that appear on a call
insn, or certain REL relocs that can generated via assembly.
We want calls to protected symbols to resolve directly to the
@@ -2890,8 +2938,6 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
should avoid writing weird assembly. */
if (SYMBOL_CALLS_LOCAL (info, h))
{
- struct elf_dyn_relocs **pp;
-
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
{
p->count -= p->pc_count;
@@ -2912,29 +2958,41 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
/* Undefined weak symbol is never bound locally in shared
library. */
if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
- || resolved_to_zero)
+ || resolved_to_zero_or_abs)
eh->dyn_relocs = NULL;
else if (h->dynindx == -1
&& ! h->forced_local
&& ! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
}
- /* For PIE, discard space for pc-relative relocs against
- symbols which turn out to need copy relocs. */
- else if (bfd_link_executable (info)
- && (h->needs_copy || eh->needs_copy)
- && h->def_dynamic
- && !h->def_regular)
+ else if (h->def_regular)
{
- struct elf_dyn_relocs **pp;
-
- for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
- {
- if (p->pc_count != 0)
- *pp = p->next;
- else
- pp = &p->next;
- }
+ /* Discard space for non-pc-relative relocs against
+ absolute symbols which are always resolved at
+ link-time. */
+ if (resolved_to_zero_or_abs)
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ if (p->pc_count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+ else
+ {
+ /* For PIE, discard space for pc-relative relocs against
+ symbols which turn out to need copy relocs. */
+ if (bfd_link_executable (info)
+ && (h->needs_copy || eh->needs_copy)
+ && h->def_dynamic)
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ if (p->pc_count != 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
}
}
}
@@ -2948,7 +3006,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
if ((!h->non_got_ref
|| eh->func_pointer_refcount > 0
|| (h->root.type == bfd_link_hash_undefweak
- && !resolved_to_zero))
+ && !resolved_to_zero_or_abs))
&& ((h->def_dynamic
&& !h->def_regular)
|| (htab->elf.dynamic_sections_created
@@ -2956,10 +3014,11 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
|| h->root.type == bfd_link_hash_undefined))))
{
/* Make sure this symbol is output as a dynamic symbol.
- Undefined weak syms won't yet be marked as dynamic. */
+ Absolute and undefined weak symbols won't yet be marked
+ as dynamic. */
if (h->dynindx == -1
&& ! h->forced_local
- && ! resolved_to_zero
+ && ! resolved_to_zero_or_abs
&& ! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
@@ -3225,8 +3284,8 @@ elf_x86_64_convert_load (bfd *abfd, asection *sec,
It is OK convert mov with R_X86_64_GOTPCREL to
R_X86_64_PC32. */
if ((relocx || opcode == 0x8b)
- && UNDEFINED_WEAK_RESOLVED_TO_ZERO (link_info,
- elf_x86_64_hash_entry (h)))
+ && RESOLVED_TO_ZERO_OR_ABS (link_info,
+ elf_x86_64_hash_entry (h)))
{
if (opcode == 0xff)
{
@@ -3256,12 +3315,9 @@ elf_x86_64_convert_load (bfd *abfd, asection *sec,
&& h != htab->elf.hdynamic
&& SYMBOL_REFERENCES_LOCAL (link_info, h))
{
- /* bfd_link_hash_new or bfd_link_hash_undefined is
- set by an assignment in a linker script in
+ /* This is set by an assignment in a linker script in
bfd_elf_record_link_assignment. */
- if (h->def_regular
- && (h->root.type == bfd_link_hash_new
- || h->root.type == bfd_link_hash_undefined))
+ if (h->def_linker)
{
/* Skip since R_X86_64_32/R_X86_64_32S may overflow. */
if (require_reloc_pc32)
@@ -4034,42 +4090,6 @@ is_32bit_relative_branch (bfd_byte *contents, bfd_vma offset)
&& (contents [offset - 1] & 0xf0) == 0x80));
}
-static bfd_boolean
-elf_x86_64_need_pic (bfd *input_bfd, struct elf_link_hash_entry *h,
- reloc_howto_type *howto)
-{
- const char *fmt;
- const char *v;
- const char *pic = "";
-
- switch (ELF_ST_VISIBILITY (h->other))
- {
- case STV_HIDDEN:
- v = _("hidden symbol");
- break;
- case STV_INTERNAL:
- v = _("internal symbol");
- break;
- case STV_PROTECTED:
- v = _("protected symbol");
- break;
- default:
- v = _("symbol");
- pic = _("; recompile with -fPIC");
- break;
- }
-
- if (h->def_regular)
- fmt = _("%B: relocation %s against %s `%s' can not be used when making a shared object%s");
- else
- fmt = _("%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s");
-
- (*_bfd_error_handler) (fmt, input_bfd, howto->name,
- v, h->root.root.string, pic);
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
-}
-
/* Relocate an x86_64 ELF section. */
static bfd_boolean
@@ -4122,7 +4142,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
int tls_type;
asection *base_got, *resolved_plt;
bfd_vma st_size;
- bfd_boolean resolved_to_zero;
+ bfd_boolean resolved_to_zero_or_abs;
r_type = ELF32_R_TYPE (rel->r_info);
if (r_type == (int) R_X86_64_GNU_VTINHERIT
@@ -4433,8 +4453,8 @@ elf_x86_64_relocate_section (bfd *output_bfd,
}
}
- resolved_to_zero = (eh != NULL
- && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh));
+ resolved_to_zero_or_abs = (eh != NULL
+ && RESOLVED_TO_ZERO_OR_ABS (info, eh));
/* When generating a shared object, the relocations handled here are
copied into the output file to be resolved at run time. */
@@ -4705,6 +4725,43 @@ elf_x86_64_relocate_section (bfd *output_bfd,
unresolved_reloc = FALSE;
break;
+ case R_X86_64_PC32:
+ /* R_X86_64_PC32 against absolute symbol can't be resolved
+ for shared object at link-time since the load address is
+ unknown. */
+ if (resolved_to_zero_or_abs
+ && h->root.type != bfd_link_hash_undefweak
+ && bfd_link_pic (info))
+ return elf_x86_64_need_pic (input_bfd, h, symtab_hdr, sym,
+ howto);
+
+ goto pc_relative;
+
+ case R_X86_64_32:
+ case R_X86_64_32S:
+ /* R_X86_64_32/R_X86_64_32S relocations against undefined weak
+ symbol in executable is resolved to zero. They against
+ absolute symbol are always resolved at link-time. */
+ if (resolved_to_zero_or_abs)
+ break;
+
+ if ((ABI_64_P (output_bfd)
+ || r_type == R_X86_64_32S)
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (input_section->flags & SEC_READONLY) != 0
+ && bfd_link_pic (info))
+ return elf_x86_64_need_pic (input_bfd, h, symtab_hdr, sym,
+ howto);
+
+ goto direct;
+
+ case R_X86_64_64:
+ /* R_X86_64_64 relocation against absolute symbol or undefined
+ weak symbol in executable is resolved at link-time. */
+ if (resolved_to_zero_or_abs)
+ break;
+ goto direct;
+
case R_X86_64_SIZE32:
case R_X86_64_SIZE64:
/* Set to symbol size. */
@@ -4713,16 +4770,17 @@ elf_x86_64_relocate_section (bfd *output_bfd,
case R_X86_64_PC8:
case R_X86_64_PC16:
- case R_X86_64_PC32:
case R_X86_64_PC32_BND:
+pc_relative:
/* Don't complain about -fPIC if the symbol is undefined when
- building executable unless it is unresolved weak symbol. */
+ building executable unless it is absolute or unresolved weak
+ symbol. */
if ((input_section->flags & SEC_ALLOC) != 0
&& (input_section->flags & SEC_READONLY) != 0
&& h != NULL
&& ((bfd_link_executable (info)
&& h->root.type == bfd_link_hash_undefweak
- && !resolved_to_zero)
+ && !resolved_to_zero_or_abs)
|| (bfd_link_pic (info)
&& !(bfd_link_pie (info)
&& h->root.type == bfd_link_hash_undefined))))
@@ -4750,15 +4808,14 @@ elf_x86_64_relocate_section (bfd *output_bfd,
}
if (fail)
- return elf_x86_64_need_pic (input_bfd, h, howto);
+ return elf_x86_64_need_pic (input_bfd, h, symtab_hdr,
+ sym, howto);
}
/* Fall through. */
case R_X86_64_8:
case R_X86_64_16:
- case R_X86_64_32:
case R_X86_64_PC64:
- case R_X86_64_64:
/* FIXME: The ABI says the linker should make sure the value is
the same when it's zeroextended to 64 bit. */
@@ -4770,7 +4827,7 @@ direct:
if the symbol needs copy reloc or the symbol is undefined
when building executable. Copy dynamic function pointer
relocations. Don't generate dynamic relocations against
- resolved undefined weak symbols in PIE. */
+ absolute nor resolved undefined weak symbols in PIE. */
if ((bfd_link_pic (info)
&& !(bfd_link_pie (info)
&& h != NULL
@@ -4780,7 +4837,7 @@ direct:
&& IS_X86_64_PCREL_TYPE (r_type))
&& (h == NULL
|| ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
- && !resolved_to_zero)
+ && !resolved_to_zero_or_abs)
|| h->root.type != bfd_link_hash_undefweak))
&& ((! IS_X86_64_PCREL_TYPE (r_type)
&& r_type != R_X86_64_SIZE32
@@ -4793,7 +4850,7 @@ direct:
&& (!h->non_got_ref
|| eh->func_pointer_refcount > 0
|| (h->root.type == bfd_link_hash_undefweak
- && !resolved_to_zero))
+ && !resolved_to_zero_or_abs))
&& ((h->def_dynamic && !h->def_regular)
/* Undefined weak symbol is bound locally when
PIC is false. */
@@ -4835,8 +4892,9 @@ direct:
if ((r_type != R_X86_64_PC64 && r_type != R_X86_64_64)
&& bfd_link_executable (info)
&& h->root.type == bfd_link_hash_undefweak
- && !resolved_to_zero)
- return elf_x86_64_need_pic (input_bfd, h, howto);
+ && !resolved_to_zero_or_abs)
+ return elf_x86_64_need_pic (input_bfd, h,
+ symtab_hdr, sym, howto);
outrel.r_info = htab->r_info (h->dynindx, r_type);
outrel.r_addend = rel->r_addend;
}
diff --git a/bfd/elflink.c b/bfd/elflink.c
index c2ad11b..26d1d24 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -543,7 +543,8 @@ bfd_elf_record_link_assignment (bfd *output_bfd,
struct bfd_link_info *info,
const char *name,
bfd_boolean provide,
- bfd_boolean hidden)
+ bfd_boolean hidden,
+ bfd_boolean abssym)
{
struct elf_link_hash_entry *h, *hv;
struct elf_link_hash_table *htab;
@@ -628,6 +629,8 @@ bfd_elf_record_link_assignment (bfd *output_bfd,
h->verinfo.verdef = NULL;
h->def_regular = 1;
+ h->def_linker = 1;
+ h->def_linker_abs = abssym;
if (hidden)
{
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 3e9f684..2f115af 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1354,10 +1354,14 @@ gld${EMULATION_NAME}_find_exp_assignment (etree_type *exp)
will do no harm. */
if (strcmp (exp->assign.dst, ".") != 0)
{
+ /* Symbol defined --defsym command-line option or absolute
+ symbol defined in linker script have absolute value. */
if (!bfd_elf_record_link_assignment (link_info.output_bfd,
&link_info,
exp->assign.dst, provide,
- exp->assign.hidden))
+ exp->assign.hidden,
+ (exp->assign.defsym
+ || !expld.rel_from_abs)))
einfo ("%P%F: failed to record assignment to %s: %E\n",
exp->assign.dst);
}
@@ -1506,6 +1510,7 @@ gld${EMULATION_NAME}_before_allocation (void)
library. */
ehdr_start = h;
ehdr_start_save = h->root;
+ h->def_linker = 1;
h->root.type = bfd_link_hash_defined;
h->root.u.def.section = bfd_abs_section_ptr;
h->root.u.def.value = 0;
diff --git a/ld/testsuite/ld-elf/pr19818a.d b/ld/testsuite/ld-elf/pr19818a.d
new file mode 100644
index 0000000..6e493c4
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr19818a.d
@@ -0,0 +1,6 @@
+#source: pr19818a.s
+#ld: -pie --defsym foo=0x7fffffff
+#readelf: -r --wide
+#target: *-*-linux* *-*-gnu* *-*-solaris*
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-elf/pr19818a.s b/ld/testsuite/ld-elf/pr19818a.s
new file mode 100644
index 0000000..447c06b
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr19818a.s
@@ -0,0 +1,12 @@
+ .text
+ .global start /* Used by SH targets. */
+start:
+ .global _start
+_start:
+ .global __start
+__start:
+ .global main /* Used by HPPA targets. */
+main:
+ .dc.a 0
+ .data
+ .dc.a foo
diff --git a/ld/testsuite/ld-elf/pr19818b.d b/ld/testsuite/ld-elf/pr19818b.d
new file mode 100644
index 0000000..2a025c8
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr19818b.d
@@ -0,0 +1,7 @@
+#source: pr19818a.s
+#source: pr19818b.s
+#ld: -pie
+#readelf: -r --wide
+#target: *-*-linux* *-*-gnu* *-*-solaris*
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-elf/pr19818b.s b/ld/testsuite/ld-elf/pr19818b.s
new file mode 100644
index 0000000..c72adaa
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr19818b.s
@@ -0,0 +1,2 @@
+ .globl foo
+ foo = 0x7fffffff
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index 1e52cdb..27c252a 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -364,6 +364,26 @@ run_dump_test "pr19609-2c"
run_dump_test "undefweaka"
run_dump_test "undefweakb"
run_dump_test "pr19539"
+run_dump_test "pr19818-1a"
+run_dump_test "pr19818-1b"
+run_dump_test "pr19818-1c"
+run_dump_test "pr19818-1a"
+run_dump_test "pr19818-1e"
+run_dump_test "pr19818-1f"
+run_dump_test "pr19818-1g"
+run_dump_test "pr19818-1h"
+run_dump_test "pr19818-1i"
+run_dump_test "pr19818-1j"
+run_dump_test "pr19818-1k"
+run_dump_test "pr19818-1l"
+run_dump_test "pr19818-2a"
+run_dump_test "pr19818-2b"
+run_dump_test "pr19818-2c"
+run_dump_test "pr19818-2d"
+run_dump_test "pr19818-2e"
+run_dump_test "pr19818-2f"
+run_dump_test "pr19818-2g"
+run_dump_test "pr19818-2h"
if { !([istarget "i?86-*-linux*"]
|| [istarget "i?86-*-gnu*"]
diff --git a/ld/testsuite/ld-i386/pr19818-1.t b/ld/testsuite/ld-i386/pr19818-1.t
new file mode 100644
index 0000000..591940b
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1.t
@@ -0,0 +1 @@
+foo = 0xffffffff;
diff --git a/ld/testsuite/ld-i386/pr19818-1a.d b/ld/testsuite/ld-i386/pr19818-1a.d
new file mode 100644
index 0000000..9f5a15f
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1a.d
@@ -0,0 +1,6 @@
+#source: pr19818-1a.s
+#as: --32
+#ld: -pie -m elf_i386 --defsym foo=0xffffffff
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-i386/pr19818-1a.s b/ld/testsuite/ld-i386/pr19818-1a.s
new file mode 100644
index 0000000..df03cd1
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1a.s
@@ -0,0 +1,4 @@
+ .text
+ .global _start
+_start:
+ movl $foo, %eax
diff --git a/ld/testsuite/ld-i386/pr19818-1b.d b/ld/testsuite/ld-i386/pr19818-1b.d
new file mode 100644
index 0000000..497c013
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1b.d
@@ -0,0 +1,13 @@
+#source: pr19818-1a.s
+#as: --32
+#ld: -pie -m elf_i386 --defsym foo=0xffffffff
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr19818-1b.s b/ld/testsuite/ld-i386/pr19818-1b.s
new file mode 100644
index 0000000..6f37759
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1b.s
@@ -0,0 +1,2 @@
+ .globl foo
+ foo = 0xffffffff
diff --git a/ld/testsuite/ld-i386/pr19818-1c.d b/ld/testsuite/ld-i386/pr19818-1c.d
new file mode 100644
index 0000000..7d15d1f
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1c.d
@@ -0,0 +1,7 @@
+#source: pr19818-1a.s
+#source: pr19818-1b.s
+#as: --32
+#ld: -pie -m elf_i386
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-i386/pr19818-1c.s b/ld/testsuite/ld-i386/pr19818-1c.s
new file mode 100644
index 0000000..5cdf8b9
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1c.s
@@ -0,0 +1,3 @@
+ .globl foo
+ .hidden foo
+ foo = 0xffffffff
diff --git a/ld/testsuite/ld-i386/pr19818-1d.d b/ld/testsuite/ld-i386/pr19818-1d.d
new file mode 100644
index 0000000..7eb1901
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1d.d
@@ -0,0 +1,14 @@
+#source: pr19818-1a.s
+#source: pr19818-1b.s
+#as: --32
+#ld: -pie -m elf_i386
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr19818-1e.d b/ld/testsuite/ld-i386/pr19818-1e.d
new file mode 100644
index 0000000..0edbf86
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1e.d
@@ -0,0 +1,6 @@
+#source: pr19818-1a.s
+#as: --32
+#ld: -shared -Bsymbolic -m elf_i386 --defsym foo=0xffffffff
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-i386/pr19818-1f.d b/ld/testsuite/ld-i386/pr19818-1f.d
new file mode 100644
index 0000000..d74cbce
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1f.d
@@ -0,0 +1,13 @@
+#source: pr19818-1a.s
+#as: --32
+#ld: -shared -Bsymbolic -m elf_i386 --defsym foo=0xffffffff
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr19818-1g.d b/ld/testsuite/ld-i386/pr19818-1g.d
new file mode 100644
index 0000000..3b5b689
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1g.d
@@ -0,0 +1,7 @@
+#source: pr19818-1a.s
+#source: pr19818-1c.s
+#as: --32
+#ld: -shared -m elf_i386
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-i386/pr19818-1h.d b/ld/testsuite/ld-i386/pr19818-1h.d
new file mode 100644
index 0000000..309ef23
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1h.d
@@ -0,0 +1,14 @@
+#source: pr19818-1a.s
+#source: pr19818-1c.s
+#as: --32
+#ld: -shared -m elf_i386
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr19818-1i.d b/ld/testsuite/ld-i386/pr19818-1i.d
new file mode 100644
index 0000000..d46f8f2
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1i.d
@@ -0,0 +1,8 @@
+#source: pr19818-1a.s
+#as: --32
+#ld: -shared -m elf_i386 --defsym foo=0xffffffff -z nocombreloc
+#readelf: -r --wide
+
+Relocation section '.rel.text' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset Info Type Sym. Value Symbol's Name
+[0-9a-f]+ +[0-9a-f]+ +R_386_32 +ffffffff +foo
diff --git a/ld/testsuite/ld-i386/pr19818-1j.d b/ld/testsuite/ld-i386/pr19818-1j.d
new file mode 100644
index 0000000..942fdca
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1j.d
@@ -0,0 +1,9 @@
+#source: pr19818-1a.s
+#source: pr19818-1b.s
+#as: --32
+#ld: -shared -m elf_i386 -z nocombreloc
+#readelf: -r --wide
+
+Relocation section '.rel.text' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset Info Type Sym. Value Symbol's Name
+[0-9a-f]+ +[0-9a-f]+ +R_386_32 +ffffffff +foo
diff --git a/ld/testsuite/ld-i386/pr19818-1k.d b/ld/testsuite/ld-i386/pr19818-1k.d
new file mode 100644
index 0000000..d4bdb84
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1k.d
@@ -0,0 +1,6 @@
+#source: pr19818-1a.s
+#as: --32
+#ld: -pie -m elf_i386 -T pr19818-1.t
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-i386/pr19818-1l.d b/ld/testsuite/ld-i386/pr19818-1l.d
new file mode 100644
index 0000000..b0cd6d0
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-1l.d
@@ -0,0 +1,13 @@
+#source: pr19818-1a.s
+#as: --32
+#ld: -pie -m elf_i386 -T pr19818-1.t
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr19818-2.s b/ld/testsuite/ld-i386/pr19818-2.s
new file mode 100644
index 0000000..65c0875
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-2.s
@@ -0,0 +1,4 @@
+ .text
+ .global _start
+_start:
+ movl foo@GOT(%ebx), %eax
diff --git a/ld/testsuite/ld-i386/pr19818-2a.d b/ld/testsuite/ld-i386/pr19818-2a.d
new file mode 100644
index 0000000..2de25e7
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-2a.d
@@ -0,0 +1,6 @@
+#source: pr19818-2.s
+#as: --32 -mrelax-relocations=no
+#ld: -pie -m elf_i386 --defsym foo=0xffffffff
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-i386/pr19818-2b.d b/ld/testsuite/ld-i386/pr19818-2b.d
new file mode 100644
index 0000000..c02a10d
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-2b.d
@@ -0,0 +1,13 @@
+#source: pr19818-2.s
+#as: --32
+#ld: -pie -m elf_i386 --defsym foo=0xffffffff
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: c7 c0 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr19818-2c.d b/ld/testsuite/ld-i386/pr19818-2c.d
new file mode 100644
index 0000000..bf235d4
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-2c.d
@@ -0,0 +1,7 @@
+#source: pr19818-2.s
+#source: pr19818-1b.s
+#as: --32
+#ld: -pie -m elf_i386
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-i386/pr19818-2d.d b/ld/testsuite/ld-i386/pr19818-2d.d
new file mode 100644
index 0000000..28a1701
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-2d.d
@@ -0,0 +1,14 @@
+#source: pr19818-2.s
+#source: pr19818-1b.s
+#as: --32
+#ld: -pie -m elf_i386
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: c7 c0 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr19818-2e.d b/ld/testsuite/ld-i386/pr19818-2e.d
new file mode 100644
index 0000000..30337e3
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-2e.d
@@ -0,0 +1,6 @@
+#source: pr19818-2.s
+#as: --32 -mrelax-relocations=no
+#ld: -shared -Bsymbolic -m elf_i386 --defsym foo=0xffffffff
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-i386/pr19818-2f.d b/ld/testsuite/ld-i386/pr19818-2f.d
new file mode 100644
index 0000000..9e238c5
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-2f.d
@@ -0,0 +1,13 @@
+#source: pr19818-2.s
+#as: --32
+#ld: -shared -Bsymbolic -m elf_i386 --defsym foo=0xffffffff
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: c7 c0 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-i386/pr19818-2g.d b/ld/testsuite/ld-i386/pr19818-2g.d
new file mode 100644
index 0000000..4ec0179
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-2g.d
@@ -0,0 +1,7 @@
+#source: pr19818-2.s
+#source: pr19818-1c.s
+#as: --32
+#ld: -shared -m elf_i386
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-i386/pr19818-2h.d b/ld/testsuite/ld-i386/pr19818-2h.d
new file mode 100644
index 0000000..ab3df88
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr19818-2h.d
@@ -0,0 +1,14 @@
+#source: pr19818-2.s
+#source: pr19818-1c.s
+#as: --32
+#ld: -shared -m elf_i386
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: c7 c0 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr19818-1.t b/ld/testsuite/ld-x86-64/pr19818-1.t
new file mode 100644
index 0000000..591940b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1.t
@@ -0,0 +1 @@
+foo = 0xffffffff;
diff --git a/ld/testsuite/ld-x86-64/pr19818-1a.d b/ld/testsuite/ld-x86-64/pr19818-1a.d
new file mode 100644
index 0000000..96a72c7
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1a.d
@@ -0,0 +1,6 @@
+#source: pr19818-1a.s
+#as: --64
+#ld: -pie -m elf_x86_64 --defsym foo=0xffffffff
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/pr19818-1a.s b/ld/testsuite/ld-x86-64/pr19818-1a.s
new file mode 100644
index 0000000..df03cd1
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1a.s
@@ -0,0 +1,4 @@
+ .text
+ .global _start
+_start:
+ movl $foo, %eax
diff --git a/ld/testsuite/ld-x86-64/pr19818-1b.d b/ld/testsuite/ld-x86-64/pr19818-1b.d
new file mode 100644
index 0000000..5b9fbef
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1b.d
@@ -0,0 +1,13 @@
+#source: pr19818-1a.s
+#as: --64
+#ld: -pie -m elf_x86_64 --defsym foo=0xffffffff
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr19818-1b.s b/ld/testsuite/ld-x86-64/pr19818-1b.s
new file mode 100644
index 0000000..6f37759
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1b.s
@@ -0,0 +1,2 @@
+ .globl foo
+ foo = 0xffffffff
diff --git a/ld/testsuite/ld-x86-64/pr19818-1c.d b/ld/testsuite/ld-x86-64/pr19818-1c.d
new file mode 100644
index 0000000..90d6a3c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1c.d
@@ -0,0 +1,7 @@
+#source: pr19818-1a.s
+#source: pr19818-1b.s
+#as: --64
+#ld: -pie -m elf_x86_64
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/pr19818-1c.s b/ld/testsuite/ld-x86-64/pr19818-1c.s
new file mode 100644
index 0000000..5cdf8b9
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1c.s
@@ -0,0 +1,3 @@
+ .globl foo
+ .hidden foo
+ foo = 0xffffffff
diff --git a/ld/testsuite/ld-x86-64/pr19818-1d.d b/ld/testsuite/ld-x86-64/pr19818-1d.d
new file mode 100644
index 0000000..63b65af
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1d.d
@@ -0,0 +1,14 @@
+#source: pr19818-1a.s
+#source: pr19818-1b.s
+#as: --64
+#ld: -pie -m elf_x86_64
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr19818-1e.d b/ld/testsuite/ld-x86-64/pr19818-1e.d
new file mode 100644
index 0000000..2e693c1
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1e.d
@@ -0,0 +1,6 @@
+#source: pr19818-1a.s
+#as: --x32
+#ld: -pie -m elf32_x86_64 --defsym foo=0xffffffff
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/pr19818-1f.d b/ld/testsuite/ld-x86-64/pr19818-1f.d
new file mode 100644
index 0000000..afc3ec7
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1f.d
@@ -0,0 +1,13 @@
+#source: pr19818-1a.s
+#as: --x32
+#ld: -pie -m elf32_x86_64 --defsym foo=0xffffffff
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr19818-1g.d b/ld/testsuite/ld-x86-64/pr19818-1g.d
new file mode 100644
index 0000000..ef9a482
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1g.d
@@ -0,0 +1,7 @@
+#source: pr19818-1a.s
+#source: pr19818-1b.s
+#as: --x32
+#ld: -pie -m elf32_x86_64
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/pr19818-1h.d b/ld/testsuite/ld-x86-64/pr19818-1h.d
new file mode 100644
index 0000000..7f591eb
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1h.d
@@ -0,0 +1,14 @@
+#source: pr19818-1a.s
+#source: pr19818-1b.s
+#as: --x32
+#ld: -pie -m elf32_x86_64
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr19818-1i.d b/ld/testsuite/ld-x86-64/pr19818-1i.d
new file mode 100644
index 0000000..cf1a226
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1i.d
@@ -0,0 +1,6 @@
+#source: pr19818-1a.s
+#as: --64
+#ld: -shared -Bsymbolic -m elf_x86_64 --defsym foo=0xffffffff
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/pr19818-1j.d b/ld/testsuite/ld-x86-64/pr19818-1j.d
new file mode 100644
index 0000000..9174c03
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1j.d
@@ -0,0 +1,13 @@
+#source: pr19818-1a.s
+#as: --64
+#ld: -shared -Bsymbolic -m elf_x86_64 --defsym foo=0xffffffff
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr19818-1k.d b/ld/testsuite/ld-x86-64/pr19818-1k.d
new file mode 100644
index 0000000..d61f964
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1k.d
@@ -0,0 +1,7 @@
+#source: pr19818-1a.s
+#source: pr19818-1c.s
+#as: --64
+#ld: -shared -m elf_x86_64
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/pr19818-1l.d b/ld/testsuite/ld-x86-64/pr19818-1l.d
new file mode 100644
index 0000000..bea7f2f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1l.d
@@ -0,0 +1,14 @@
+#source: pr19818-1a.s
+#source: pr19818-1c.s
+#as: --64
+#ld: -shared -m elf_x86_64
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr19818-1m.d b/ld/testsuite/ld-x86-64/pr19818-1m.d
new file mode 100644
index 0000000..e95b9f4
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1m.d
@@ -0,0 +1,6 @@
+#source: pr19818-1a.s
+#as: --x32
+#ld: -shared -Bsymbolic -m elf32_x86_64 --defsym foo=0xffffffff
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/pr19818-1n.d b/ld/testsuite/ld-x86-64/pr19818-1n.d
new file mode 100644
index 0000000..33e7b32
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1n.d
@@ -0,0 +1,13 @@
+#source: pr19818-1a.s
+#as: --x32
+#ld: -shared -Bsymbolic -m elf32_x86_64 --defsym foo=0xffffffff
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr19818-1o.d b/ld/testsuite/ld-x86-64/pr19818-1o.d
new file mode 100644
index 0000000..7470234
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1o.d
@@ -0,0 +1,7 @@
+#source: pr19818-1a.s
+#source: pr19818-1c.s
+#as: --x32
+#ld: -shared -m elf32_x86_64
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/pr19818-1p.d b/ld/testsuite/ld-x86-64/pr19818-1p.d
new file mode 100644
index 0000000..40d7ff6
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1p.d
@@ -0,0 +1,14 @@
+#source: pr19818-1a.s
+#source: pr19818-1c.s
+#as: --x32
+#ld: -shared -m elf32_x86_64
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr19818-1q.d b/ld/testsuite/ld-x86-64/pr19818-1q.d
new file mode 100644
index 0000000..28b4c09
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1q.d
@@ -0,0 +1,4 @@
+#source: pr19818-1a.s
+#as: --64 -mrelax-relocations=no
+#ld: -shared -m elf_x86_64 --defsym foo=0xffffffff
+#error: .*relocation R_X86_64_32 against absolute symbol `foo' can not be used when making a shared object
diff --git a/ld/testsuite/ld-x86-64/pr19818-1r.d b/ld/testsuite/ld-x86-64/pr19818-1r.d
new file mode 100644
index 0000000..de68580
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1r.d
@@ -0,0 +1,5 @@
+#source: pr19818-1a.s
+#source: pr19818-1b.s
+#as: --64 -mrelax-relocations=no
+#ld: -shared -m elf_x86_64
+#error: .*relocation R_X86_64_32 against absolute symbol `foo' can not be used when making a shared object
diff --git a/ld/testsuite/ld-x86-64/pr19818-1s.d b/ld/testsuite/ld-x86-64/pr19818-1s.d
new file mode 100644
index 0000000..fc27a50
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1s.d
@@ -0,0 +1,8 @@
+#source: pr19818-1a.s
+#as: --x32 -mrelax-relocations=no
+#ld: -shared -m elf32_x86_64 --defsym foo=0xffffffff -z nocombreloc
+#readelf: -r --wide
+
+Relocation section '.rela.text' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset Info Type Sym. Value Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +ffffffff +foo \+ 0
diff --git a/ld/testsuite/ld-x86-64/pr19818-1t.d b/ld/testsuite/ld-x86-64/pr19818-1t.d
new file mode 100644
index 0000000..19d775a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1t.d
@@ -0,0 +1,9 @@
+#source: pr19818-1a.s
+#source: pr19818-1b.s
+#as: --x32 -mrelax-relocations=no
+#ld: -shared -m elf32_x86_64 -z nocombreloc
+#readelf: -r --wide
+
+Relocation section '.rela.text' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset Info Type Sym. Value Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +ffffffff +foo \+ 0
diff --git a/ld/testsuite/ld-x86-64/pr19818-1u.d b/ld/testsuite/ld-x86-64/pr19818-1u.d
new file mode 100644
index 0000000..b6155ca
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1u.d
@@ -0,0 +1,6 @@
+#source: pr19818-1a.s
+#as: --64
+#ld: -pie -m elf_x86_64 -T pr19818-1.t
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/pr19818-1v.d b/ld/testsuite/ld-x86-64/pr19818-1v.d
new file mode 100644
index 0000000..6ff6046
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1v.d
@@ -0,0 +1,13 @@
+#source: pr19818-1a.s
+#as: --64
+#ld: -pie -m elf_x86_64 -T pr19818-1.t
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr19818-1w.d b/ld/testsuite/ld-x86-64/pr19818-1w.d
new file mode 100644
index 0000000..aa8028e
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1w.d
@@ -0,0 +1,6 @@
+#source: pr19818-1a.s
+#as: --x32
+#ld: -pie -m elf32_x86_64 -T pr19818-1.t
+#readelf: -r --wide
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/pr19818-1x.d b/ld/testsuite/ld-x86-64/pr19818-1x.d
new file mode 100644
index 0000000..ce043aa
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1x.d
@@ -0,0 +1,13 @@
+#source: pr19818-1a.s
+#as: --x32
+#ld: -pie -m elf32_x86_64 -T pr19818-1.t
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ff ff ff ff mov \$0xffffffff,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr19818-1y.d b/ld/testsuite/ld-x86-64/pr19818-1y.d
new file mode 100644
index 0000000..aac2e11
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-1y.d
@@ -0,0 +1,4 @@
+#source: pr19818-1a.s
+#as: --64
+#ld: -pie -melf_x86_64 --defsym foo=0x100000000
+#error: .*relocation truncated to fit: R_X86_64_32 .*
diff --git a/ld/testsuite/ld-x86-64/pr19818-2.s b/ld/testsuite/ld-x86-64/pr19818-2.s
new file mode 100644
index 0000000..d9541ff
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-2.s
@@ -0,0 +1,4 @@
+ .text
+ .global _start
+_start:
+ leal foo(%rip), %eax
diff --git a/ld/testsuite/ld-x86-64/pr19818-2a.d b/ld/testsuite/ld-x86-64/pr19818-2a.d
new file mode 100644
index 0000000..5ba6b0e
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-2a.d
@@ -0,0 +1,4 @@
+#source: pr19818-2.s
+#as: --64 -mrelax-relocations=no
+#ld: -pie -m elf_x86_64 --defsym foo=0xffffffff
+#error: .*relocation R_X86_64_PC32 against absolute symbol `foo' can not be used when making a shared object
diff --git a/ld/testsuite/ld-x86-64/pr19818-2b.d b/ld/testsuite/ld-x86-64/pr19818-2b.d
new file mode 100644
index 0000000..5e044c4
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-2b.d
@@ -0,0 +1,5 @@
+#source: pr19818-2.s
+#source: pr19818-1b.s
+#as: --64 -mrelax-relocations=no
+#ld: -pie -m elf_x86_64
+#error: .*relocation R_X86_64_PC32 against absolute symbol `foo' can not be used when making a shared object
diff --git a/ld/testsuite/ld-x86-64/pr19818-2c.d b/ld/testsuite/ld-x86-64/pr19818-2c.d
new file mode 100644
index 0000000..4dc13a2
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-2c.d
@@ -0,0 +1,4 @@
+#source: pr19818-2.s
+#as: --x32 -mrelax-relocations=no
+#ld: -pie -m elf32_x86_64 --defsym foo=0xffffffff
+#error: .*relocation R_X86_64_PC32 against absolute symbol `foo' can not be used when making a shared object
diff --git a/ld/testsuite/ld-x86-64/pr19818-2d.d b/ld/testsuite/ld-x86-64/pr19818-2d.d
new file mode 100644
index 0000000..e518ae3
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-2d.d
@@ -0,0 +1,5 @@
+#source: pr19818-2.s
+#source: pr19818-1b.s
+#as: --x32 -mrelax-relocations=no
+#ld: -pie -m elf32_x86_64
+#error: .*relocation R_X86_64_PC32 against absolute symbol `foo' can not be used when making a shared object
diff --git a/ld/testsuite/ld-x86-64/pr19818-3.s b/ld/testsuite/ld-x86-64/pr19818-3.s
new file mode 100644
index 0000000..d3b0660
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-3.s
@@ -0,0 +1,4 @@
+ .text
+ .global _start
+_start:
+ movabs $foo, %rax
diff --git a/ld/testsuite/ld-x86-64/pr19818-3a.d b/ld/testsuite/ld-x86-64/pr19818-3a.d
new file mode 100644
index 0000000..8031a03
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-3a.d
@@ -0,0 +1,8 @@
+#source: pr19818-3.s
+#as: --64 -mrelax-relocations=no
+#ld: -shared -m elf_x86_64 --defsym foo=0xffffffff -z nocombreloc
+#readelf: -r --wide
+
+Relocation section '.rela.text' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset Info Type Symbol's Value Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_64 +0+ffffffff +foo \+ 0
diff --git a/ld/testsuite/ld-x86-64/pr19818-3b.d b/ld/testsuite/ld-x86-64/pr19818-3b.d
new file mode 100644
index 0000000..0059a8c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-3b.d
@@ -0,0 +1,9 @@
+#source: pr19818-3.s
+#source: pr19818-1b.s
+#as: --64 -mrelax-relocations=no
+#ld: -shared -m elf_x86_64 -z nocombreloc
+#readelf: -r --wide
+
+Relocation section '.rela.text' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset Info Type Symbol's Value Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_64 +0+ffffffff +foo \+ 0
diff --git a/ld/testsuite/ld-x86-64/pr19818-3c.d b/ld/testsuite/ld-x86-64/pr19818-3c.d
new file mode 100644
index 0000000..c940773
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-3c.d
@@ -0,0 +1,8 @@
+#source: pr19818-3.s
+#as: --x32 -mrelax-relocations=no
+#ld: -shared -m elf32_x86_64 --defsym foo=0xffffffff -z nocombreloc
+#readelf: -r --wide
+
+Relocation section '.rela.text' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset Info Type Sym. Value Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +ffffffff +foo \+ 0
diff --git a/ld/testsuite/ld-x86-64/pr19818-3d.d b/ld/testsuite/ld-x86-64/pr19818-3d.d
new file mode 100644
index 0000000..cc7e79b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-3d.d
@@ -0,0 +1,9 @@
+#source: pr19818-3.s
+#source: pr19818-1b.s
+#as: --x32 -mrelax-relocations=no
+#ld: -shared -m elf32_x86_64 -z nocombreloc
+#readelf: -r --wide
+
+Relocation section '.rela.text' at offset 0x[0-9a-f]+ contains 1 entries:
+ Offset Info Type Sym. Value Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +ffffffff +foo \+ 0
diff --git a/ld/testsuite/ld-x86-64/pr19818-4.s b/ld/testsuite/ld-x86-64/pr19818-4.s
new file mode 100644
index 0000000..486ba0f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-4.s
@@ -0,0 +1,5 @@
+ .globl foo
+ .type foo, @object
+ .data
+foo:
+ .long 0
diff --git a/ld/testsuite/ld-x86-64/pr19818-4a.d b/ld/testsuite/ld-x86-64/pr19818-4a.d
new file mode 100644
index 0000000..1a48089
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-4a.d
@@ -0,0 +1,5 @@
+#source: pr19818-4.s
+#source: pr19818-1a.s
+#as: --64
+#ld: -pie -melf_x86_64
+#error: .*relocation R_X86_64_32 against symbol `foo' can not be used when making a shared object; recompile with -fPIC
diff --git a/ld/testsuite/ld-x86-64/pr19818-4b.d b/ld/testsuite/ld-x86-64/pr19818-4b.d
new file mode 100644
index 0000000..b2c4763
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-4b.d
@@ -0,0 +1,14 @@
+#source: pr19818-4.s
+#source: pr19818-1a.s
+#as: --x32
+#ld: -pie -melf32_x86_64
+#objdump: -dw
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+[a-f0-9]+ <_start>:
+[ ]*[a-f0-9]+: b8 ([0-9a-f]{2} ){4} mov \$0x[a-f0-9]+,%eax
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr19818-5.s b/ld/testsuite/ld-x86-64/pr19818-5.s
new file mode 100644
index 0000000..0870f6a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-5.s
@@ -0,0 +1,8 @@
+ .globl _start
+ .type _start, @function
+_start:
+ movq $foo, %rax
+ .size _start, .-_start
+ .data
+foo:
+ .quad 0
diff --git a/ld/testsuite/ld-x86-64/pr19818-5a.d b/ld/testsuite/ld-x86-64/pr19818-5a.d
new file mode 100644
index 0000000..21df19c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-5a.d
@@ -0,0 +1,4 @@
+#source: pr19818-5.s
+#as: --64
+#ld: -pie -melf_x86_64
+#error: .*relocation R_X86_64_32S against symbol `.data' can not be used when making a shared object; recompile with -fPIC
diff --git a/ld/testsuite/ld-x86-64/pr19818-5b.d b/ld/testsuite/ld-x86-64/pr19818-5b.d
new file mode 100644
index 0000000..a30858e
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr19818-5b.d
@@ -0,0 +1,4 @@
+#source: pr19818-5.s
+#as: --x32
+#ld: -pie -melf32_x86_64
+#error: .*relocation R_X86_64_32S against symbol `.data' can not be used when making a shared object; recompile with -fPIC
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 49f9fa3..3938597 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -247,6 +247,43 @@ run_dump_test "largecomm-1e"
run_dump_test "largecomm-1f"
run_dump_test "pr19539a"
run_dump_test "pr19539b"
+run_dump_test "pr19818-1a"
+run_dump_test "pr19818-1b"
+run_dump_test "pr19818-1c"
+run_dump_test "pr19818-1d"
+run_dump_test "pr19818-1e"
+run_dump_test "pr19818-1f"
+run_dump_test "pr19818-1g"
+run_dump_test "pr19818-1h"
+run_dump_test "pr19818-1i"
+run_dump_test "pr19818-1j"
+run_dump_test "pr19818-1k"
+run_dump_test "pr19818-1l"
+run_dump_test "pr19818-1m"
+run_dump_test "pr19818-1n"
+run_dump_test "pr19818-1o"
+run_dump_test "pr19818-1p"
+run_dump_test "pr19818-1q"
+run_dump_test "pr19818-1r"
+run_dump_test "pr19818-1s"
+run_dump_test "pr19818-1t"
+run_dump_test "pr19818-1u"
+run_dump_test "pr19818-1v"
+run_dump_test "pr19818-1w"
+run_dump_test "pr19818-1x"
+run_dump_test "pr19818-1y"
+run_dump_test "pr19818-2a"
+run_dump_test "pr19818-2b"
+run_dump_test "pr19818-2c"
+run_dump_test "pr19818-2d"
+run_dump_test "pr19818-3a"
+run_dump_test "pr19818-3b"
+run_dump_test "pr19818-3c"
+run_dump_test "pr19818-3d"
+run_dump_test "pr19818-4a"
+run_dump_test "pr19818-4b"
+run_dump_test "pr19818-5a"
+run_dump_test "pr19818-5b"
if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
return