This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC: [PATCH] Properly handle relocs against absolute symbols


Relocations against absolute symbols in shared object should be resolved
at link-time if symbols are bounded locally.  For PC-relative relocation
against absolute symbols, they should be converted to non-PC-relative
relocation in target backend.  If conversion can't be performed, target
backend should detect it and issue an error.  This patch only fixes x86
backends.

Any comments?

H.J.
---
bfd/

	PR ld/19818
	* bfd-in.h (bfd_elf_record_link_assignment): Add a bfd_boolean.
	* bfd-in2.h: Regenerated.
	* elf-bfd.h (elf_link_hash_entry): Add def_linker and
	def_linker_abs.
	(RESOLVED_TO_ABS_IN_PIC): New macro.
	* elf32-i386.c (RESOLVED_TO_ZERO_OR_ABS): New macro.
	(elf_i386_allocate_dynrelocs): Replace
	UNDEFINED_WEAK_RESOLVED_TO_ZERO with RESOLVED_TO_ZERO_OR_ABS.
	Discard space for non-pc-relative relocs against symbols which
	are always resolved at link-time.
	(elf_i386_relocate_section): Replace
	UNDEFINED_WEAK_RESOLVED_TO_ZERO with RESOLVED_TO_ZERO_OR_ABS.
	Properly handle R_386_32 relocation against absolute symbol.
	* elf64-x86-64.c (RESOLVED_TO_ZERO_OR_ABS): New macro.
	(elf_x86_64_need_pic): Updated to check absolute symbol.
	(elf_x86_64_check_relocs): Don't check R_X86_64_32 nor
	R_X86_64_32S in shared object here.  Use elf_x86_64_need_pic.
	(elf_x86_64_allocate_dynrelocs): Replace
	UNDEFINED_WEAK_RESOLVED_TO_ZERO with RESOLVED_TO_ZERO_OR_ABS.
	Discard space for non-pc-relative relocs against symbols which
	are always resolved at link-time.
	(elf_x86_64_relocate_section): Replace
	UNDEFINED_WEAK_RESOLVED_TO_ZERO with RESOLVED_TO_ZERO_OR_ABS.
	Properly handle R_X86_64_PC32, R_X86_64_32, R_X86_64_32S amd
	R_X86_64_64 relocations against absolute symbol.
	* elflink.c (bfd_elf_record_link_assignment): Updated.  Set
	def_linker and defsym.

ld/

	PR ld/19818
	* emultempl/elf32.em (gld${EMULATION_NAME}_find_exp_assignment):
	Pass "exp->assign.defsym || !expld.rel_from_abs" to
	bfd_elf_record_link_assignment.
	(gld${EMULATION_NAME}_before_allocation): Set def_linker for
	"__ehdr_start".
	* testsuite/ld-i386/i386.exp: Run PR ld/19818 tests.
	* testsuite/ld-x86-64/x86-64.exp: Likewise.
	* testsuite/ld-elf/pr19818a.d: New file.
	* testsuite/ld-elf/pr19818a.s: Likewise.
	* testsuite/ld-elf/pr19818b.d: Likewise.
	* testsuite/ld-elf/pr19818b.s: Likewise.
	* testsuite/ld-i386/pr19818-1.t: Likewise.
	* testsuite/ld-i386/pr19818-1a.d: Likewise.
	* testsuite/ld-i386/pr19818-1a.s: Likewise.
	* testsuite/ld-i386/pr19818-1b.d: Likewise.
	* testsuite/ld-i386/pr19818-1b.s: Likewise.
	* testsuite/ld-i386/pr19818-1c.d: Likewise.
	* testsuite/ld-i386/pr19818-1c.s: Likewise.
	* testsuite/ld-i386/pr19818-1d.d: Likewise.
	* testsuite/ld-i386/pr19818-1e.d: Likewise.
	* testsuite/ld-i386/pr19818-1f.d: Likewise.
	* testsuite/ld-i386/pr19818-1g.d: Likewise.
	* testsuite/ld-i386/pr19818-1h.d: Likewise.
	* testsuite/ld-i386/pr19818-1i.d: Likewise.
	* testsuite/ld-i386/pr19818-1j.d: Likewise.
	* testsuite/ld-i386/pr19818-1k.d: Likewise.
	* testsuite/ld-i386/pr19818-1l.d: Likewise.
	* testsuite/ld-i386/pr19818-2.s: Likewise.
	* testsuite/ld-i386/pr19818-2a.d: Likewise.
	* testsuite/ld-i386/pr19818-2b.d: Likewise.
	* testsuite/ld-i386/pr19818-2c.d: Likewise.
	* testsuite/ld-i386/pr19818-2d.d: Likewise.
	* testsuite/ld-i386/pr19818-2e.d: Likewise.
	* testsuite/ld-i386/pr19818-2f.d: Likewise.
	* testsuite/ld-i386/pr19818-2g.d: Likewise.
	* testsuite/ld-i386/pr19818-2h.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1.t: Likewise.
	* testsuite/ld-x86-64/pr19818-1a.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1a.s: Likewise.
	* testsuite/ld-x86-64/pr19818-1b.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1b.s: Likewise.
	* testsuite/ld-x86-64/pr19818-1c.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1c.s: Likewise.
	* testsuite/ld-x86-64/pr19818-1d.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1e.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1f.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1g.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1h.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1i.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1j.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1k.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1l.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1m.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1n.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1o.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1p.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1q.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1r.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1s.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1t.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1u.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1v.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1w.d: Likewise.
	* testsuite/ld-x86-64/pr19818-1x.d: Likewise.
	* testsuite/ld-x86-64/pr19818-2.s: Likewise.
	* testsuite/ld-x86-64/pr19818-2a.d: Likewise.
	* testsuite/ld-x86-64/pr19818-2b.d: Likewise.
	* testsuite/ld-x86-64/pr19818-2c.d: Likewise.
	* testsuite/ld-x86-64/pr19818-2d.d: Likewise.
	* testsuite/ld-x86-64/pr19818-3.s: Likewise.
	* testsuite/ld-x86-64/pr19818-3a.d: Likewise.
	* testsuite/ld-x86-64/pr19818-3b.d: Likewise.
	* testsuite/ld-x86-64/pr19818-3c.d: Likewise.
	* testsuite/ld-x86-64/pr19818-3d.d: Likewise.
---
 bfd/bfd-in.h                        |   2 +-
 bfd/bfd-in2.h                       |   4 +-
 bfd/elf-bfd.h                       |  15 ++
 bfd/elf32-i386.c                    | 151 +++++++++++---------
 bfd/elf64-x86-64.c                  | 274 ++++++++++++++++++++++--------------
 bfd/elflink.c                       |   5 +-
 ld/emultempl/elf32.em               |   7 +-
 ld/testsuite/ld-elf/pr19818a.d      |   6 +
 ld/testsuite/ld-elf/pr19818a.s      |  12 ++
 ld/testsuite/ld-elf/pr19818b.d      |   7 +
 ld/testsuite/ld-elf/pr19818b.s      |   2 +
 ld/testsuite/ld-i386/i386.exp       |  20 +++
 ld/testsuite/ld-i386/pr19818-1.t    |   1 +
 ld/testsuite/ld-i386/pr19818-1a.d   |   6 +
 ld/testsuite/ld-i386/pr19818-1a.s   |   4 +
 ld/testsuite/ld-i386/pr19818-1b.d   |  13 ++
 ld/testsuite/ld-i386/pr19818-1b.s   |   2 +
 ld/testsuite/ld-i386/pr19818-1c.d   |   7 +
 ld/testsuite/ld-i386/pr19818-1c.s   |   3 +
 ld/testsuite/ld-i386/pr19818-1d.d   |  14 ++
 ld/testsuite/ld-i386/pr19818-1e.d   |   6 +
 ld/testsuite/ld-i386/pr19818-1f.d   |  13 ++
 ld/testsuite/ld-i386/pr19818-1g.d   |   7 +
 ld/testsuite/ld-i386/pr19818-1h.d   |  14 ++
 ld/testsuite/ld-i386/pr19818-1i.d   |   8 ++
 ld/testsuite/ld-i386/pr19818-1j.d   |   9 ++
 ld/testsuite/ld-i386/pr19818-1k.d   |   6 +
 ld/testsuite/ld-i386/pr19818-1l.d   |  13 ++
 ld/testsuite/ld-i386/pr19818-2.s    |   4 +
 ld/testsuite/ld-i386/pr19818-2a.d   |   6 +
 ld/testsuite/ld-i386/pr19818-2b.d   |  13 ++
 ld/testsuite/ld-i386/pr19818-2c.d   |   7 +
 ld/testsuite/ld-i386/pr19818-2d.d   |  14 ++
 ld/testsuite/ld-i386/pr19818-2e.d   |   6 +
 ld/testsuite/ld-i386/pr19818-2f.d   |  13 ++
 ld/testsuite/ld-i386/pr19818-2g.d   |   7 +
 ld/testsuite/ld-i386/pr19818-2h.d   |  14 ++
 ld/testsuite/ld-x86-64/pr19818-1.t  |   1 +
 ld/testsuite/ld-x86-64/pr19818-1a.d |   6 +
 ld/testsuite/ld-x86-64/pr19818-1a.s |   4 +
 ld/testsuite/ld-x86-64/pr19818-1b.d |  13 ++
 ld/testsuite/ld-x86-64/pr19818-1b.s |   2 +
 ld/testsuite/ld-x86-64/pr19818-1c.d |   7 +
 ld/testsuite/ld-x86-64/pr19818-1c.s |   3 +
 ld/testsuite/ld-x86-64/pr19818-1d.d |  14 ++
 ld/testsuite/ld-x86-64/pr19818-1e.d |   6 +
 ld/testsuite/ld-x86-64/pr19818-1f.d |  13 ++
 ld/testsuite/ld-x86-64/pr19818-1g.d |   7 +
 ld/testsuite/ld-x86-64/pr19818-1h.d |  14 ++
 ld/testsuite/ld-x86-64/pr19818-1i.d |   6 +
 ld/testsuite/ld-x86-64/pr19818-1j.d |  13 ++
 ld/testsuite/ld-x86-64/pr19818-1k.d |   7 +
 ld/testsuite/ld-x86-64/pr19818-1l.d |  14 ++
 ld/testsuite/ld-x86-64/pr19818-1m.d |   6 +
 ld/testsuite/ld-x86-64/pr19818-1n.d |  13 ++
 ld/testsuite/ld-x86-64/pr19818-1o.d |   7 +
 ld/testsuite/ld-x86-64/pr19818-1p.d |  14 ++
 ld/testsuite/ld-x86-64/pr19818-1q.d |   4 +
 ld/testsuite/ld-x86-64/pr19818-1r.d |   5 +
 ld/testsuite/ld-x86-64/pr19818-1s.d |   8 ++
 ld/testsuite/ld-x86-64/pr19818-1t.d |   9 ++
 ld/testsuite/ld-x86-64/pr19818-1u.d |   6 +
 ld/testsuite/ld-x86-64/pr19818-1v.d |  13 ++
 ld/testsuite/ld-x86-64/pr19818-1w.d |   6 +
 ld/testsuite/ld-x86-64/pr19818-1x.d |  13 ++
 ld/testsuite/ld-x86-64/pr19818-2.s  |   4 +
 ld/testsuite/ld-x86-64/pr19818-2a.d |   4 +
 ld/testsuite/ld-x86-64/pr19818-2b.d |   5 +
 ld/testsuite/ld-x86-64/pr19818-2c.d |   4 +
 ld/testsuite/ld-x86-64/pr19818-2d.d |   5 +
 ld/testsuite/ld-x86-64/pr19818-3.s  |   4 +
 ld/testsuite/ld-x86-64/pr19818-3a.d |   8 ++
 ld/testsuite/ld-x86-64/pr19818-3b.d |   9 ++
 ld/testsuite/ld-x86-64/pr19818-3c.d |   8 ++
 ld/testsuite/ld-x86-64/pr19818-3d.d |   9 ++
 ld/testsuite/ld-x86-64/x86-64.exp   |  32 +++++
 76 files changed, 865 insertions(+), 176 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/pr19818a.d
 create mode 100644 ld/testsuite/ld-elf/pr19818a.s
 create mode 100644 ld/testsuite/ld-elf/pr19818b.d
 create mode 100644 ld/testsuite/ld-elf/pr19818b.s
 create mode 100644 ld/testsuite/ld-i386/pr19818-1.t
 create mode 100644 ld/testsuite/ld-i386/pr19818-1a.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-1a.s
 create mode 100644 ld/testsuite/ld-i386/pr19818-1b.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-1b.s
 create mode 100644 ld/testsuite/ld-i386/pr19818-1c.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-1c.s
 create mode 100644 ld/testsuite/ld-i386/pr19818-1d.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-1e.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-1f.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-1g.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-1h.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-1i.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-1j.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-1k.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-1l.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-2.s
 create mode 100644 ld/testsuite/ld-i386/pr19818-2a.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-2b.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-2c.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-2d.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-2e.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-2f.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-2g.d
 create mode 100644 ld/testsuite/ld-i386/pr19818-2h.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1.t
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1a.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1a.s
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1b.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1b.s
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1c.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1c.s
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1d.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1e.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1f.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1g.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1h.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1i.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1j.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1k.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1l.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1m.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1n.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1o.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1p.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1q.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1r.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1s.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1t.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1u.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1v.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1w.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-1x.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-2.s
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-2a.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-2b.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-2c.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-2d.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-3.s
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-3a.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-3b.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-3c.d
 create mode 100644 ld/testsuite/ld-x86-64/pr19818-3d.d

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..1949c4a 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,17 @@ 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))
+
+/* x86-64 ELF linker hash entry.  */
 #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-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/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 49f9fa3..0625d9b 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -247,6 +247,38 @@ 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-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"
 
 if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
     return
-- 
2.5.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]