[v2] readelf: Add --plt-contents

Message ID 20250909184936.3782844-1-hjl.tools@gmail.com
State New
Headers
Series [v2] readelf: Add --plt-contents |

Commit Message

H.J. Lu Sept. 9, 2025, 6:49 p.m. UTC
  Add --plt-contents option to readelf to display contents of PLT sections.
--plt-contents option requires:

1. The DT_JMPREL dynamic section for relocations associated with PLT
entries.
2. Detailed PLT layout information to extract PLT relocation index and
GOT index from PLT entries.

When --plt-contents option is used:

1. Allocate an array, plt_relocations, to hold PLT relocations from the
DT_JMPREL dynamic section.
2. Allocate an array, all_relocations, to hold all relocations to map
GOT entries to corresponding symbols.
3. Process each PLT entry by extracting PLT relocation index and/or GOT
index to display symbols or relocation associated with the PLT entry.

Only i386 and x86-64 PLTs are supported.

$ readelf --plt-contents libfoo.so

Procedure Linkage Table '.plt' contains 3 entries:
 Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
     0: 00000150
     1: 00000160      3: 00200250      0: func
     2: 00000170      4: 00200258      1: bar

Procedure Linkage Table '.plt.got' contains 1 entry:
 Index:  Address GOT Idx GOT Addr Symbol/Reloc
     0: 00000180     -1: 00200230 foo

binutils/

	PR binutils/33349
	* NEWS: Mention readelf --plt-contents.
	* readelf.c (do_plt_section_contents): New.
	(filedata): Add dynamic_info_DT_TLSDESC_PLT.
	(plt_relocations): New.
	(plt_relocations_count): Likewise.
	(update_all_relocations): Support do_plt_section_contents.
	(dump_relocations): Add 2 bool arguments to handle DT_JMPREL.
	Allocate and populate plt_relocations if needed.
	(long_option_values): Add OPTION_PLT_CONTENTS.
	(options): Add --plt-contents.
	(usage): Add --plt-contents.
	(parse_args): Support --plt-contents.
	(display_relocations): Pass false, false to dump_relocations.
	(process_relocs): Add a bool argument, get_jmprel, to collect
	relocations in DT_JMPREL.
	(process_dynamic_section): Set dynamic_info_DT_TLSDESC_PLT.
	(elf_x86_plt_type): New.
	(elf_x86_non_lazy_plt_layout): Likewise.
	(elf_x86_plt_layout): Likewise.
	(elf_i386_lazy_plt0_entry): Likewise.
	(elf_i386_lazy_plt_entry): Likewise.
	(elf_i386_pic_lazy_plt0_entry): Likewise.
	(elf_i386_pic_lazy_plt_entry): Likewise.
	(elf_i386_non_lazy_plt_entry): Likewise.
	(elf_i386_pic_non_lazy_plt_entry): Likewise.
	(elf_i386_lazy_ibt_plt0_entry): Likewise.
	(elf_i386_lazy_ibt_plt_entry): Likewise.
	(elf_i386_pic_lazy_ibt_plt0_entry): Likewise.
	(elf_i386_non_lazy_ibt_plt_entry): Likewise.
	(elf_i386_pic_non_lazy_ibt_plt_entry): Likewise.
	(elf_i386_plt): Likewise.
	(elf_i386_ibt_plt): Likewise.
	(elf_x86_64_lazy_plt0_entry): Likewise.
	(elf_x86_64_lazy_plt_entry): Likewise.
	(elf_x86_64_lazy_ibt_plt_entry): Likewise.
	(elf_x86_64_non_lazy_plt_entry): Likewise.
	(elf_x86_64_non_lazy_ibt_plt_entry): Likewise.
	(elf_x86_64_plt): Likewise.
	(elf_x86_64_ibt_plt): Likewise.
	(display_elf_plt_relocation_at): Likewise.
	(get_elf_i386_plt_type): Likewise.
	(get_elf_x86_64_plt_type): Likewise.
	(display_elf_x86_lazy_plt): Likewise.
	(display_elf_x86_non_lazey_plt): Likewise.
	(display_x86_plt_sections): Likewise.
	(process_plt_section_contents): Likewise.
	(process_object): Pass false to process_relocs.  Call
	process_plt_section_contents.
	(process_object): Pass false to process_relocs.
	* doc/binutils.texi: Document --plt-contents.

ld/

	PR binutils/33349
	* testsuite/ld-i386/binutils.exp: Run PR binutils/33349 tests.
	* testsuite/ld-x86-64/binutils.exp: Likewise.
	* testsuite/ld-i386/libplt-1a-a.rd: New file.
	* testsuite/ld-i386/libplt-1a-b.rd: Likewise.
	* testsuite/ld-i386/libplt-1a-c.rd: Likewise.
	* testsuite/ld-i386/libplt-1a-d.rd: Likewise.
	* testsuite/ld-i386/libplt-1a-e.rd: Likewise.
	* testsuite/ld-i386/libplt-1b-a.rd: Likewise.
	* testsuite/ld-i386/libplt-1b-b.rd: Likewise.
	* testsuite/ld-i386/libplt-1b-c.rd: Likewise.
	* testsuite/ld-i386/libplt-1b-d.rd: Likewise.
	* testsuite/ld-i386/libplt-1b-e.rd: Likewise.
	* testsuite/ld-i386/plt-1.s: Likewise.
	* testsuite/ld-x86-64/libplt-1a-a.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1a-b.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1a-c.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1a-d.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1a-e.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1a-x32-a.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1a-x32-b.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1a-x32-c.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1a-x32-d.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1a-x32-e.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1b-a.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1b-b.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1b-c.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1b-d.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1b-e.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1b-x32-a.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1b-x32-b.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1b-x32-c.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1b-x32-d.rd: Likewise.
	* testsuite/ld-x86-64/libplt-1b-x32-e.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2a-a.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2a-b.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2a-c.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2a-d.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2a-e.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2a-x32-a.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2a-x32-b.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2a-x32-c.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2a-x32-d.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2a-x32-e.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2b-a.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2b-b.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2b-c.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2b-d.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2b-e.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2b-x32-a.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2b-x32-b.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2b-x32-c.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2b-x32-d.rd: Likewise.
	* testsuite/ld-x86-64/libplt-2b-x32-e.rd: Likewise.
	* testsuite/ld-x86-64/plt-1.s: Likewise.
	* testsuite/ld-x86-64/plt-2.s: Likewise.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 binutils/NEWS                             |   3 +
 binutils/doc/binutils.texi                |  10 +-
 binutils/readelf.c                        | 968 +++++++++++++++++++++-
 ld/testsuite/ld-i386/binutils.exp         |  31 +
 ld/testsuite/ld-i386/libplt-1a-a.rd       |  10 +
 ld/testsuite/ld-i386/libplt-1a-b.rd       | 145 ++++
 ld/testsuite/ld-i386/libplt-1a-c.rd       |  16 +
 ld/testsuite/ld-i386/libplt-1a-d.rd       |  16 +
 ld/testsuite/ld-i386/libplt-1a-e.rd       |  23 +
 ld/testsuite/ld-i386/libplt-1b-a.rd       |  10 +
 ld/testsuite/ld-i386/libplt-1b-b.rd       | 139 ++++
 ld/testsuite/ld-i386/libplt-1b-c.rd       |  11 +
 ld/testsuite/ld-i386/libplt-1b-d.rd       |  11 +
 ld/testsuite/ld-i386/libplt-1b-e.rd       |  18 +
 ld/testsuite/ld-i386/plt-1.s              |   9 +
 ld/testsuite/ld-x86-64/binutils.exp       | 128 +++
 ld/testsuite/ld-x86-64/libplt-1a-a.rd     |  10 +
 ld/testsuite/ld-x86-64/libplt-1a-b.rd     | 145 ++++
 ld/testsuite/ld-x86-64/libplt-1a-c.rd     |  16 +
 ld/testsuite/ld-x86-64/libplt-1a-d.rd     |  16 +
 ld/testsuite/ld-x86-64/libplt-1a-e.rd     |  23 +
 ld/testsuite/ld-x86-64/libplt-1a-x32-a.rd |  10 +
 ld/testsuite/ld-x86-64/libplt-1a-x32-b.rd | 145 ++++
 ld/testsuite/ld-x86-64/libplt-1a-x32-c.rd |  16 +
 ld/testsuite/ld-x86-64/libplt-1a-x32-d.rd |  16 +
 ld/testsuite/ld-x86-64/libplt-1a-x32-e.rd |  23 +
 ld/testsuite/ld-x86-64/libplt-1b-a.rd     |  10 +
 ld/testsuite/ld-x86-64/libplt-1b-b.rd     | 139 ++++
 ld/testsuite/ld-x86-64/libplt-1b-c.rd     |  11 +
 ld/testsuite/ld-x86-64/libplt-1b-d.rd     |  11 +
 ld/testsuite/ld-x86-64/libplt-1b-e.rd     |  18 +
 ld/testsuite/ld-x86-64/libplt-1b-x32-a.rd |  10 +
 ld/testsuite/ld-x86-64/libplt-1b-x32-b.rd | 139 ++++
 ld/testsuite/ld-x86-64/libplt-1b-x32-c.rd |  11 +
 ld/testsuite/ld-x86-64/libplt-1b-x32-d.rd |  11 +
 ld/testsuite/ld-x86-64/libplt-1b-x32-e.rd |  18 +
 ld/testsuite/ld-x86-64/libplt-2a-a.rd     |  12 +
 ld/testsuite/ld-x86-64/libplt-2a-b.rd     | 159 ++++
 ld/testsuite/ld-x86-64/libplt-2a-c.rd     |  17 +
 ld/testsuite/ld-x86-64/libplt-2a-d.rd     |  17 +
 ld/testsuite/ld-x86-64/libplt-2a-e.rd     |  26 +
 ld/testsuite/ld-x86-64/libplt-2a-x32-a.rd |  12 +
 ld/testsuite/ld-x86-64/libplt-2a-x32-b.rd | 159 ++++
 ld/testsuite/ld-x86-64/libplt-2a-x32-c.rd |  17 +
 ld/testsuite/ld-x86-64/libplt-2a-x32-d.rd |  17 +
 ld/testsuite/ld-x86-64/libplt-2a-x32-e.rd |  26 +
 ld/testsuite/ld-x86-64/libplt-2b-a.rd     |  12 +
 ld/testsuite/ld-x86-64/libplt-2b-b.rd     | 153 ++++
 ld/testsuite/ld-x86-64/libplt-2b-c.rd     |  12 +
 ld/testsuite/ld-x86-64/libplt-2b-d.rd     |  12 +
 ld/testsuite/ld-x86-64/libplt-2b-e.rd     |  21 +
 ld/testsuite/ld-x86-64/libplt-2b-x32-a.rd |  12 +
 ld/testsuite/ld-x86-64/libplt-2b-x32-b.rd | 153 ++++
 ld/testsuite/ld-x86-64/libplt-2b-x32-c.rd |  12 +
 ld/testsuite/ld-x86-64/libplt-2b-x32-d.rd |  12 +
 ld/testsuite/ld-x86-64/libplt-2b-x32-e.rd |  21 +
 ld/testsuite/ld-x86-64/plt-1.s            |   9 +
 ld/testsuite/ld-x86-64/plt-2.s            |  15 +
 58 files changed, 3231 insertions(+), 21 deletions(-)
 create mode 100644 ld/testsuite/ld-i386/libplt-1a-a.rd
 create mode 100644 ld/testsuite/ld-i386/libplt-1a-b.rd
 create mode 100644 ld/testsuite/ld-i386/libplt-1a-c.rd
 create mode 100644 ld/testsuite/ld-i386/libplt-1a-d.rd
 create mode 100644 ld/testsuite/ld-i386/libplt-1a-e.rd
 create mode 100644 ld/testsuite/ld-i386/libplt-1b-a.rd
 create mode 100644 ld/testsuite/ld-i386/libplt-1b-b.rd
 create mode 100644 ld/testsuite/ld-i386/libplt-1b-c.rd
 create mode 100644 ld/testsuite/ld-i386/libplt-1b-d.rd
 create mode 100644 ld/testsuite/ld-i386/libplt-1b-e.rd
 create mode 100644 ld/testsuite/ld-i386/plt-1.s
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1a-a.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1a-b.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1a-c.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1a-d.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1a-e.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1a-x32-a.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1a-x32-b.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1a-x32-c.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1a-x32-d.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1a-x32-e.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1b-a.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1b-b.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1b-c.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1b-d.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1b-e.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1b-x32-a.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1b-x32-b.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1b-x32-c.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1b-x32-d.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-1b-x32-e.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2a-a.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2a-b.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2a-c.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2a-d.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2a-e.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2a-x32-a.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2a-x32-b.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2a-x32-c.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2a-x32-d.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2a-x32-e.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2b-a.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2b-b.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2b-c.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2b-d.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2b-e.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2b-x32-a.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2b-x32-b.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2b-x32-c.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2b-x32-d.rd
 create mode 100644 ld/testsuite/ld-x86-64/libplt-2b-x32-e.rd
 create mode 100644 ld/testsuite/ld-x86-64/plt-1.s
 create mode 100644 ld/testsuite/ld-x86-64/plt-2.s
  

Patch

diff --git a/binutils/NEWS b/binutils/NEWS
index 0a4ed3bcc43..a46f4609c13 100644
--- a/binutils/NEWS
+++ b/binutils/NEWS
@@ -1,5 +1,8 @@ 
 -*- text -*-
 
+* Add --plt-contents option to readelf to display the contents of
+  Procedure Linkage Table (PLT) sections for i386 and x86-64.
+
 * Add --got-contents option to readelf to display the contents of
   Global Offset Table (GOT) sections.
 
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 89425b8a15b..ce9008be8e6 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -5076,7 +5076,7 @@  readelf [@option{-a}|@option{--all}]
         [@option{--ctf-strings=}@var{section}]
         [@option{--sframe=}@var{section}]
         [@option{-I}|@option{--histogram}]
-        [@option{--got-contents}]
+        [@option{--got-contents}] [@option{--plt-contents}]
         [@option{-v}|@option{--version}]
         [@option{-W}|@option{--wide}]
         [@option{-T}|@option{--silent-truncation}]
@@ -5112,7 +5112,7 @@  given.
 Equivalent to specifying @option{--file-header},
 @option{--program-headers}, @option{--sections}, @option{--symbols},
 @option{--relocs}, @option{--dynamic}, @option{--notes},
-@option{--got-contents}, @option{--version-info},
+@option{--got-contents}, @option{--plt-contents}, @option{--version-info},
 @option{--arch-specific}, @option{--unwind},
 @option{--section-groups} and @option{--histogram}.
 
@@ -5397,6 +5397,12 @@  if it has any.  For MIPS, this option is similar to
 @option{--arch-specific}, but it only displays the GOT related contents
 and it is ignored when @option{--arch-specific} is used.
 
+@item --plt-contents
+@cindex ELF section information
+@cindex ELF reloc information
+Displays the contents of the file's Procedure Linkage Table (PLT)
+sections, if it has any.   Supported for i386 and x86-64.
+
 @item -I
 @itemx --histogram
 Display a histogram of bucket list lengths when displaying the contents
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 8162cbb7003..a90204cc85c 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -230,6 +230,7 @@  static bool do_lto_syms = false;
 static bool do_reloc = false;
 static bool do_sections = false;
 static bool do_got_section_contents = false;
+static bool do_plt_section_contents = false;
 static bool do_section_groups = false;
 static bool do_section_details = false;
 static bool do_segments = false;
@@ -314,6 +315,7 @@  typedef struct filedata
   uint64_t             dynamic_info[DT_RELRENT + 1];
   uint64_t             dynamic_info_DT_GNU_HASH;
   uint64_t             dynamic_info_DT_MIPS_XHASH;
+  uint64_t             dynamic_info_DT_TLSDESC_PLT;
   elf_section_list *   symtab_shndx_list;
   size_t               group_count;
   struct group *       section_groups;
@@ -387,6 +389,8 @@  typedef struct elf_relocation
 static elf_relocation *all_relocations_root;
 static elf_relocation *all_relocations;
 static size_t all_relocations_count;
+static elf_relocation *plt_relocations;
+static size_t plt_relocations_count;
 
 static int
 fseek64 (FILE *stream, int64_t offset, int whence)
@@ -1788,7 +1792,7 @@  update_all_relocations (size_t nentries)
 {
   size_t sz;
 
-  if (!do_got_section_contents)
+  if (!do_got_section_contents && !do_plt_section_contents)
     return;
 
   if (!all_relocations_root)
@@ -2197,7 +2201,10 @@  dump_relr_relocations (Filedata *          filedata,
 
 /* Display the contents of the relocation data found at the specified
    offset.  If DUMP_RELOC is false, don't display relocations, just
-   collect relocations for displaying GOT section contents later.  */
+   collect relocations for displaying GOT section contents later.  If
+   IS_JMPREL is true, the relocation data is from DT_JMPREL.  If
+   GET_JMPREL is true, just fill PLT_RELOCATIONS with the relocation
+   data.  */
 
 static bool
 dump_relocations (Filedata *          filedata,
@@ -2209,7 +2216,9 @@  dump_relocations (Filedata *          filedata,
 		  uint64_t            strtablen,
 		  relocation_type     rel_type,
 		  bool                is_dynsym,
-		  bool                dump_reloc)
+		  bool                dump_reloc,
+		  bool                is_jmprel,
+		  bool                get_jmprel)
 {
   size_t i;
   Elf_Internal_Rela * rels;
@@ -2234,6 +2243,15 @@  dump_relocations (Filedata *          filedata,
       return false;
     }
 
+  bool collect_jmprel = get_jmprel;
+  if (is_jmprel)
+    {
+      size_t sz = rel_size * sizeof (elf_relocation);
+      plt_relocations = (elf_relocation *) xmalloc (sz);
+      plt_relocations_count = rel_size;
+      collect_jmprel = true;
+    }
+
   if (dump_reloc)
     {
       if (is_32bit_elf)
@@ -2736,7 +2754,8 @@  dump_relocations (Filedata *          filedata,
 		  else
 		    name = strtab + psym->st_name;
 
-		  if (do_got_section_contents)
+		  if (do_got_section_contents
+		      || do_plt_section_contents)
 		    {
 		      if (version_string)
 			symbol_name = concat (name,
@@ -2774,7 +2793,8 @@  dump_relocations (Filedata *          filedata,
 		    sec_name = printable_section_name_from_index
 		      (filedata, psym->st_shndx, NULL);
 
-		  if (do_got_section_contents)
+		  if (do_got_section_contents
+		      || do_plt_section_contents)
 		    symbol_name = xstrdup (sec_name);
 		  if (dump_reloc)
 		    print_symbol_name (22, sec_name);
@@ -2804,7 +2824,8 @@  dump_relocations (Filedata *          filedata,
 				? "@@%s" : "@%s",
 				version_string);
 		    }
-		  if (do_got_section_contents)
+		  if (do_got_section_contents
+		      || do_plt_section_contents)
 		    {
 		      if (version_string)
 			symbol_name = concat (strtab + psym->st_name,
@@ -2838,7 +2859,17 @@  dump_relocations (Filedata *          filedata,
 	    printf ("%" PRIx64, off);
 	}
 
-      if (do_got_section_contents)
+      if (collect_jmprel)
+	{
+	  plt_relocations[i].r_offset = offset;
+	  plt_relocations[i].r_name = rtype;
+	  plt_relocations[i].r_symbol = symbol_name;
+	  plt_relocations[i].r_addend = rels[i].r_addend;
+	  plt_relocations[i].r_type = rel_type;
+	}
+
+      if (!get_jmprel
+	  && (do_got_section_contents || do_plt_section_contents))
 	{
 	  all_relocations[i].r_offset = offset;
 	  all_relocations[i].r_name = rtype;
@@ -6434,7 +6465,8 @@  enum long_option_values
   OPTION_NO_DEMANGLING,
   OPTION_NO_EXTRA_SYM_INFO,
   OPTION_SYM_BASE,
-  OPTION_GOT_CONTENTS
+  OPTION_GOT_CONTENTS,
+  OPTION_PLT_CONTENTS
 };
 
 static struct option options[] =
@@ -6498,6 +6530,7 @@  static struct option options[] =
   {"sframe",	       optional_argument, 0, OPTION_SFRAME_DUMP},
   {"sym-base",	       optional_argument, 0, OPTION_SYM_BASE},
   {"got-contents",     no_argument, 0, OPTION_GOT_CONTENTS},
+  {"plt-contents",     no_argument, 0, OPTION_PLT_CONTENTS},
 
   {0,		       no_argument, 0, 0}
 };
@@ -6509,7 +6542,8 @@  usage (FILE * stream)
   fprintf (stream, _(" Display information about the contents of ELF format files\n"));
   fprintf (stream, _(" Options are:\n"));
   fprintf (stream, _("\
-  -a --all               Equivalent to: -h -l -S -s -r -d -V -A -I --got-contents\n"));
+  -a --all               Equivalent to: -h -l -S -s -r -d -V -A -I\n\
+                           --got-contents --plt-contents\n"));
   fprintf (stream, _("\
   -h --file-header       Display the ELF file header\n"));
   fprintf (stream, _("\
@@ -6657,6 +6691,8 @@  usage (FILE * stream)
   fprintf (stream, _("\
   --got-contents         Display GOT section contents\n"));
   fprintf (stream, _("\
+  --plt-contents         Display PLT section contents (i386 and x86-64 only)\n"));
+  fprintf (stream, _("\
   -W --wide              Allow output width to exceed 80 characters\n"));
   fprintf (stream, _("\
   -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
@@ -6782,6 +6818,7 @@  parse_args (struct dump_data *dumpdata, int argc, char ** argv)
 	  do_arch = true;
 	  do_notes = true;
 	  do_got_section_contents = true;
+	  do_plt_section_contents = true;
 	  break;
 
 	case 'g':
@@ -7046,6 +7083,11 @@  parse_args (struct dump_data *dumpdata, int argc, char ** argv)
 	  do_dump = true;
 	  break;
 
+	case OPTION_PLT_CONTENTS:
+	  do_plt_section_contents = true;
+	  do_dump = true;
+	  break;
+
 	default:
 	  /* xgettext:c-format */
 	  error (_("Invalid option '-%c'\n"), c);
@@ -9896,26 +9938,29 @@  display_relocations (Elf_Internal_Shdr *  section,
 			    rel_type,
 			    symsec == NULL
 			    ? false : symsec->sh_type == SHT_DYNSYM,
-			    dump_reloc);
+			    dump_reloc, false, false);
   free (strtab);
   free (symtab);
 
   return res;
 }
 
-/* Process the reloc section.  */
+/* Process the reloc section.  If GET_JMPREL is true, populate
+   PLT_RELOCATIONS with dynamic relocations in the DT_JMPREL section.  */
 
 static bool
-process_relocs (Filedata * filedata)
+process_relocs (Filedata * filedata, bool get_jmprel)
 {
   uint64_t rel_size;
   uint64_t rel_offset;
   unsigned int rel_entsz;
 
-  if (!do_reloc && !do_got_section_contents)
+  if (!do_reloc
+      && !do_got_section_contents
+      && !do_plt_section_contents)
     return true;
 
-  if (do_using_dynamic)
+  if (do_using_dynamic || get_jmprel)
     {
       relocation_type rel_type;
       const char * name;
@@ -9932,16 +9977,18 @@  process_relocs (Filedata * filedata)
 	  if (!rel_size)
 	    continue;
 
-	  has_dynamic_reloc = true;
+	  has_dynamic_reloc = do_using_dynamic;
 
 	  rel_type = dynamic_relocations [i].rel_type;
 	  name = dynamic_relocations [i].name;
 	  rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
 
+	  bool is_jmprel;
 	  if (rel_type == reltype_unknown)
 	    {
 	      if (dynamic_relocations [i].reloc != DT_JMPREL)
 		abort ();
+	      is_jmprel = true;
 	      switch (filedata->dynamic_info[DT_PLTREL])
 		{
 		case DT_REL:
@@ -9952,6 +9999,13 @@  process_relocs (Filedata * filedata)
 		  break;
 		}
 	    }
+	  else
+	    {
+	      /* Skip if not DT_JMPREL.  */
+	      if (get_jmprel)
+		continue;
+	      is_jmprel = false;
+	    }
 
 	  switch (rel_type)
 	    {
@@ -10005,7 +10059,10 @@  process_relocs (Filedata * filedata)
 		  continue;
 		}
 
-	      update_all_relocations (rel_size / rel_entsz);
+	      size_t nentries = rel_size / rel_entsz;
+
+	      if (!get_jmprel)
+		update_all_relocations (nentries);
 
 	      dump_relocations (filedata,
 				offset_from_vma (filedata, rel_offset,
@@ -10016,7 +10073,7 @@  process_relocs (Filedata * filedata)
 				filedata->dynamic_strings,
 				filedata->dynamic_strings_length,
 				rel_type, true /* is_dynamic */,
-				do_reloc);
+				do_reloc, is_jmprel, get_jmprel);
 	    }
 	}
 
@@ -13520,6 +13577,15 @@  the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
 	    }
 	  break;
 
+	case DT_TLSDESC_PLT:
+	  filedata->dynamic_info_DT_TLSDESC_PLT = entry->d_un.d_val;
+	  if (do_dynamic)
+	    {
+	      print_vma (entry->d_un.d_val, PREFIX_HEX);
+	      putchar ('\n');
+	    }
+	  break;
+
 	default:
 	  if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
 	    filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
@@ -21210,6 +21276,867 @@  process_got_section_contents (Filedata * filedata)
   return res;
 }
 
+enum elf_x86_plt_type
+{
+  plt_non_lazy = 0,
+  plt_lazy = 1 << 0,
+  plt_second = 1 << 1,
+  plt_unknown = -1
+};
+
+struct elf_x86_non_lazy_plt_layout
+{
+  /* Entries in a non-lazy procedure linkage table look like this.  */
+  const bfd_byte *plt_entry;
+  /* Entries in a PIC non-lazy procedure linkage table look like this.
+     This is only used for i386 where absolute PLT and PIC PLT are
+     different.  */
+  const bfd_byte *pic_plt_entry;
+
+  unsigned int plt_entry_size;		/* Size of each PLT entry.  */
+
+  /* Offsets into plt_entry that are to be replaced with...  */
+  unsigned int plt_got_offset;    /* ... address of this symbol in .got. */
+
+  /* Length of the PC-relative instruction containing plt_got_offset.
+     This is used for x86-64 only.  */
+  unsigned int plt_got_insn_size;
+};
+
+struct elf_x86_plt_layout
+{
+  /* The first entry in a lazy procedure linkage table looks like this.  */
+  const bfd_byte *plt0_entry;
+  unsigned int plt0_entry_size;		 /* Size of PLT0 entry.  */
+
+  /* Later entries in a lazy procedure linkage table look like this.  */
+  const bfd_byte *plt_entry;
+  unsigned int plt_entry_size;		/* Size of each PLT entry.  */
+
+  /* The TLSDESC entry in a lazy procedure linkage table looks like
+     this.  This is for x86-64 only.  */
+  const bfd_byte *plt_tlsdesc_entry;
+  unsigned int plt_tlsdesc_entry_size;	 /* Size of TLSDESC entry.  */
+
+  /* Offset into the TLSDESC entry that are to be replaced with
+     GOT+TDG.  This is for x86-64 only.  */
+  unsigned int plt_tlsdesc_got2_offset;
+
+  /* Offset of the end of the PC-relative instructions containing
+     plt_tlsdesc_got2_offset.  This is for x86-64 only.  */
+  unsigned int plt_tlsdesc_got2_insn_end;
+
+  /* Offsets into plt0_entry that are to be replaced with GOT[1] and
+     GOT[2].  */
+  unsigned int plt0_got1_offset;
+  unsigned int plt0_got2_offset;
+
+  /* Offset of the end of the PC-relative instruction containing
+     plt0_got2_offset.  This is for x86-64 only.  */
+  unsigned int plt0_got2_insn_end;
+
+  /* Offsets into plt_entry that are to be replaced with...  */
+  unsigned int plt_got_offset;    /* ... address of this symbol in .got. */
+  unsigned int plt_reloc_offset;  /* ... offset into relocation table. */
+  unsigned int plt_plt_offset;    /* ... offset to start of .plt. */
+
+  /* Length of the PC-relative instruction containing plt_got_offset.
+     This is used for x86-64 only.  */
+  unsigned int plt_got_insn_size;
+
+  /* The first entry in a PIC lazy procedure linkage table looks like
+     this.  */
+  const bfd_byte *pic_plt0_entry;
+
+  /* Subsequent entries in a PIC lazy procedure linkage table look
+     like this.  */
+  const bfd_byte *pic_plt_entry;
+
+  /* Non-lazy PLT layout.  */
+  struct elf_x86_non_lazy_plt_layout non_lazy;
+};
+
+/* The first entry in an absolute lazy procedure linkage table looks
+   like this.  See the SVR4 ABI i386 supplement to see how this works.
+   Will be padded to LAZY_PLT_ENTRY_SIZE with lazy_plt->plt0_pad_byte.  */
+
+static const bfd_byte elf_i386_lazy_plt0_entry[12] =
+{
+  0xff, 0x35,	/* pushl contents of address */
+  0, 0, 0, 0,	/* replaced with address of .got + 4.  */
+  0xff, 0x25,	/* jmp indirect */
+  0, 0, 0, 0	/* replaced with address of .got + 8.  */
+};
+
+/* Subsequent entries in an absolute lazy procedure linkage table look
+   like this.  */
+
+static const bfd_byte elf_i386_lazy_plt_entry[16] =
+{
+  0xff, 0x25,	/* jmp indirect */
+  0, 0, 0, 0,	/* replaced with address of this symbol in .got.  */
+  0x68,		/* pushl immediate */
+  0, 0, 0, 0,	/* replaced with offset into relocation table.  */
+  0xe9,		/* jmp relative */
+  0, 0, 0, 0	/* replaced with offset to start of .plt.  */
+};
+
+/* The first entry in a PIC lazy procedure linkage table look like
+   this.  Will be padded to LAZY_PLT_ENTRY_SIZE with
+   lazy_plt->plt0_pad_byte.  */
+
+static const bfd_byte elf_i386_pic_lazy_plt0_entry[12] =
+{
+  0xff, 0xb3, 4, 0, 0, 0,	/* pushl 4(%ebx) */
+  0xff, 0xa3, 8, 0, 0, 0	/* jmp *8(%ebx) */
+};
+
+/* Subsequent entries in a PIC lazy procedure linkage table look like
+   this.  */
+
+static const bfd_byte elf_i386_pic_lazy_plt_entry[16] =
+{
+  0xff, 0xa3,	/* jmp *offset(%ebx) */
+  0, 0, 0, 0,	/* replaced with offset of this symbol in .got.  */
+  0x68,		/* pushl immediate */
+  0, 0, 0, 0,	/* replaced with offset into relocation table.  */
+  0xe9,		/* jmp relative */
+  0, 0, 0, 0	/* replaced with offset to start of .plt.  */
+};
+
+/* Entries in the non-lazy procedure linkage table look like this.  */
+
+static const bfd_byte elf_i386_non_lazy_plt_entry[8] =
+{
+  0xff, 0x25,	/* jmp indirect */
+  0, 0, 0, 0,	/* replaced with offset of this symbol in .got.  */
+  0x66, 0x90	/* xchg %ax,%ax  */
+};
+
+/* Entries in the PIC non-lazy procedure linkage table look like
+   this.  */
+
+static const bfd_byte elf_i386_pic_non_lazy_plt_entry[8] =
+{
+  0xff, 0xa3,	/* jmp *offset(%ebx)  */
+  0, 0, 0, 0,	/* replaced with offset of this symbol in .got.  */
+  0x66, 0x90	/* xchg %ax,%ax  */
+};
+
+/* The first entry in an absolute IBT-enabled lazy procedure linkage
+   table looks like this.  */
+
+static const bfd_byte elf_i386_lazy_ibt_plt0_entry[16] =
+{
+  0xff, 0x35, 0, 0, 0, 0,	/* pushl GOT[1]	      */
+  0xff, 0x25, 0, 0, 0, 0,	/* jmp *GOT[2]	      */
+  0x0f, 0x1f, 0x40, 0x00	/* nopl 0(%rax)	      */
+};
+
+/* Subsequent entries for an absolute IBT-enabled lazy procedure linkage
+   table look like this.  Subsequent entries for a PIC IBT-enabled lazy
+   procedure linkage table are the same.  */
+
+static const bfd_byte elf_i386_lazy_ibt_plt_entry[16] =
+{
+  0xf3, 0x0f, 0x1e, 0xfb,	/* endbr32		      */
+  0x68, 0, 0, 0, 0,		/* pushl immediate	      */
+  0xe9, 0, 0, 0, 0,		/* jmp relative		      */
+  0x66, 0x90			/* xchg %ax,%ax		      */
+};
+
+/* The first entry in a PIC IBT-enabled lazy procedure linkage table
+   look like.  */
+
+static const bfd_byte elf_i386_pic_lazy_ibt_plt0_entry[16] =
+{
+  0xff, 0xb3, 4, 0, 0, 0,	/* pushl 4(%ebx)      */
+  0xff, 0xa3, 8, 0, 0, 0,	/* jmp *8(%ebx)	      */
+  0x0f, 0x1f, 0x40, 0x00	/* nopl 0(%rax)	      */
+};
+
+/* Entries for branches with IBT-enabled in the absolute non-lazey
+   procedure linkage table look like this.  They have the same size
+   as the lazy PLT entry.  */
+
+static const bfd_byte elf_i386_non_lazy_ibt_plt_entry[16] =
+{
+  0xf3, 0x0f, 0x1e, 0xfb,	     /* endbr32		      */
+  0xff, 0x25, 0, 0, 0, 0,	     /* jmp *name@GOT	      */
+  0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1) */
+};
+
+/* Entries for branches with IBT-enabled in the PIC non-lazey procedure
+   linkage table look like this.  They have the same size as the lazy
+   PLT entry.  */
+
+static const bfd_byte elf_i386_pic_non_lazy_ibt_plt_entry[16] =
+{
+  0xf3, 0x0f, 0x1e, 0xfb,	     /* endbr32		      */
+  0xff, 0xa3, 0, 0, 0, 0,	     /* jmp *name@GOT(%ebx)   */
+  0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1) */
+};
+
+/* These are the standard parameters.  */
+static const struct elf_x86_plt_layout elf_i386_plt =
+  {
+    elf_i386_lazy_plt0_entry,		/* plt0_entry */
+    sizeof (elf_i386_lazy_plt0_entry),	/* plt0_entry_size */
+    elf_i386_lazy_plt_entry,		/* plt_entry */
+    16,					/* plt_entry_size */
+    NULL,				/* plt_tlsdesc_entry */
+    0,					/* plt_tlsdesc_entry_size*/
+    0,					/* plt_tlsdesc_got2_offset */
+    0,					/* plt_tlsdesc_got2_insn_end */
+    2,					/* plt0_got1_offset */
+    8,					/* plt0_got2_offset */
+    0,					/* plt0_got2_insn_end */
+    2,					/* plt_got_offset */
+    7,					/* plt_reloc_offset */
+    12,					/* plt_plt_offset */
+    0,					/* plt_got_insn_size */
+    elf_i386_pic_lazy_plt0_entry,	/* pic_plt0_entry */
+    elf_i386_pic_lazy_plt_entry,	/* pic_plt_entry */
+    /* non_lazy */
+    {
+      elf_i386_non_lazy_plt_entry,	/* plt_entry */
+      elf_i386_pic_non_lazy_plt_entry,	/* pic_plt_entry */
+      8,				/* plt_entry_size */
+      2,				/* plt_got_offset */
+      0					/* plt_got_insn_size */
+    }
+  };
+
+static const struct elf_x86_plt_layout elf_i386_ibt_plt =
+  {
+    elf_i386_lazy_ibt_plt0_entry,	/* plt0_entry */
+    sizeof (elf_i386_lazy_ibt_plt0_entry), /* plt0_entry_size */
+    elf_i386_lazy_ibt_plt_entry,	/* plt_entry */
+    16,					/* plt_entry_size */
+    NULL,				/* plt_tlsdesc_entry */
+    0,					/* plt_tlsdesc_entry_size*/
+    0,					/* plt_tlsdesc_got2_offset */
+    0,					/* plt_tlsdesc_got2_insn_end */
+    2,					/* plt0_got1_offset */
+    8,					/* plt0_got2_offset */
+    0,					/* plt0_got2_insn_end */
+    4+2,				/* plt_got_offset */
+    4+1,				/* plt_reloc_offset */
+    4+6,				/* plt_plt_offset */
+    0,					/* plt_got_insn_size */
+    elf_i386_pic_lazy_ibt_plt0_entry,	/* pic_plt0_entry */
+    elf_i386_lazy_ibt_plt_entry,	/* pic_plt_entry */
+    /* non_lazy */
+    {
+      elf_i386_non_lazy_ibt_plt_entry,	/* plt_entry */
+      elf_i386_pic_non_lazy_ibt_plt_entry,/* pic_plt_entry */
+      16,				/* plt_entry_size */
+      4+2,				/* plt_got_offset */
+      0					/* plt_got_insn_size */
+    }
+  };
+
+/* The first entry in a lazy procedure linkage table looks like this.
+   See the SVR4 ABI i386 supplement and the x86-64 ABI to see how this
+   works.  */
+
+static const bfd_byte elf_x86_64_lazy_plt0_entry[16] =
+{
+  0xff, 0x35, 8, 0, 0, 0,	/* pushq GOT+8(%rip)  */
+  0xff, 0x25, 16, 0, 0, 0,	/* jmpq *GOT+16(%rip) */
+  0x0f, 0x1f, 0x40, 0x00	/* nopl 0(%rax)       */
+};
+
+/* Subsequent entries in a lazy procedure linkage table look like this.  */
+
+static const bfd_byte elf_x86_64_lazy_plt_entry[16] =
+{
+  0xff, 0x25,	/* jmpq *name@GOTPC(%rip) */
+  0, 0, 0, 0,	/* replaced with offset to this symbol in .got.	 */
+  0x68,		/* pushq immediate */
+  0, 0, 0, 0,	/* replaced with index into relocation table.  */
+  0xe9,		/* jmp relative */
+  0, 0, 0, 0	/* replaced with offset to start of .plt0.  */
+};
+
+/* The first entry in the IBT-enabled lazy procedure linkage table
+   is the same as the normal lazy PLT.  Subsequent entries for an
+   IBT-enabled lazy procedure linkage table look like this.  */
+
+static const bfd_byte elf_x86_64_lazy_ibt_plt_entry[16] =
+{
+  0xf3, 0x0f, 0x1e, 0xfa,	/* endbr64		      */
+  0x68, 0, 0, 0, 0,		/* pushq immediate	      */
+  0xe9, 0, 0, 0, 0,		/* jmpq relative	      */
+  0x66, 0x90			/* xchg %ax,%ax		      */
+};
+
+/* Entries in the non-lazey procedure linkage table look like this.  */
+
+static const bfd_byte elf_x86_64_non_lazy_plt_entry[8] =
+{
+  0xff, 0x25,	     /* jmpq *name@GOTPC(%rip)			      */
+  0, 0, 0, 0,	     /* replaced with offset to this symbol in .got.  */
+  0x66, 0x90	     /* xchg %ax,%ax				      */
+};
+
+/* Entries for branches with IBT-enabled in the non-lazey procedure
+   linkage table look like this.  They have the same size as the lazy
+   PLT entry.  */
+
+static const bfd_byte elf_x86_64_non_lazy_ibt_plt_entry[16] =
+{
+  0xf3, 0x0f, 0x1e, 0xfa,	     /* endbr64		       */
+  0xff, 0x25,			     /* jmpq *name@GOTPC(%rip) */
+  0, 0, 0, 0,  /* replaced with offset to this symbol in .got. */
+  0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1)  */
+};
+
+/* The TLSDESC entry in a lazy procedure linkage table.  */
+static const bfd_byte elf_x86_64_tlsdesc_plt_entry[16] =
+{
+  0xf3, 0x0f, 0x1e, 0xfa,	     /* endbr64		       */
+  0xff, 0x35, 8, 0, 0, 0,	     /* pushq GOT+8(%rip)	*/
+  0xff, 0x25, 16, 0, 0, 0	     /* jmpq *GOT+TDG(%rip)	*/
+};
+
+static const struct elf_x86_plt_layout elf_x86_64_plt =
+  {
+    elf_x86_64_lazy_plt0_entry,		/* plt0_entry */
+    16,					/* plt0_entry_size */
+    elf_x86_64_lazy_plt_entry,		/* plt_entry */
+    16,					/* plt_entry_size */
+    elf_x86_64_tlsdesc_plt_entry,	/* plt_tlsdesc_entry */
+    16,					/* plt_tlsdesc_entry_size */
+    12,					/* plt_tlsdesc_got2_offset */
+    16,					/* plt_tlsdesc_got2_insn_end */
+    2,					/* plt0_got1_offset */
+    8,					/* plt0_got2_offset */
+    12,					/* plt0_got2_insn_end */
+    2,					/* plt_got_offset */
+    7,					/* plt_reloc_offset */
+    12,					/* plt_plt_offset */
+    6,					/* plt_got_insn_size */
+    elf_x86_64_lazy_plt0_entry,		/* pic_plt0_entry */
+    elf_x86_64_lazy_plt_entry,		/* pic_plt_entry */
+    /* non_lazy */
+    {
+      elf_x86_64_non_lazy_plt_entry,	/* plt_entry */
+      elf_x86_64_non_lazy_plt_entry,	/* pic_plt_entry */
+      8,				/* plt_entry_size */
+      2,				/* plt_got_offset */
+      6					/* plt_got_insn_size */
+    }
+  };
+
+static const struct elf_x86_plt_layout elf_x86_64_ibt_plt =
+  {
+    elf_x86_64_lazy_plt0_entry,		/* plt0_entry */
+    16,					/* plt0_entry_size */
+    elf_x86_64_lazy_ibt_plt_entry,	/* plt_entry */
+    16,					/* plt_entry_size */
+    elf_x86_64_tlsdesc_plt_entry,	/* plt_tlsdesc_entry */
+    16,					/* plt_tlsdesc_entry_size */
+    12,					/* plt_tlsdesc_got2_offset */
+    16,					/* plt_tlsdesc_got2_insn_end */
+    2,					/* plt0_got1_offset */
+    8,					/* plt0_got2_offset */
+    12,					/* plt0_got2_insn_end */
+    4+2,				/* plt_got_offset */
+    4+1,				/* plt_reloc_offset */
+    4+6,				/* plt_plt_offset */
+    4+6,				/* plt_got_insn_size */
+    elf_x86_64_lazy_plt0_entry,		/* pic_plt0_entry */
+    elf_x86_64_lazy_ibt_plt_entry,	/* pic_plt_entry */
+    /* non_lazy */
+    {
+      elf_x86_64_non_lazy_ibt_plt_entry,/* plt_entry */
+      elf_x86_64_non_lazy_ibt_plt_entry,/* pic_plt_entry */
+      16,				/* plt_entry_size */
+      4+2,				/* plt_got_offset */
+      4+6				/* plt_got_insn_size */
+    }
+  };
+
+static void
+display_elf_plt_relocation_at (uint32_t idx, uint64_t offset,
+			       bool is_index)
+{
+  int width = is_32bit_elf ? 45 : 37;
+  if (is_index)
+    {
+      if (plt_relocations[idx].r_symbol)
+	print_symbol_name (width, plt_relocations[idx].r_symbol);
+      else
+	printf ("%s", plt_relocations[idx].r_name);
+      if (offset != 0 && plt_relocations[idx].r_offset != offset)
+	abort ();
+    }
+  else
+    for (size_t i = 0; i < all_relocations_count; i++)
+      if (all_relocations_root[i].r_offset == offset)
+	{
+	  if (all_relocations_root[i].r_symbol)
+	    print_symbol_name (width, all_relocations_root[i].r_symbol);
+	  else
+	    printf ("%s", all_relocations_root[i].r_name);
+	}
+  putchar ('\n');
+}
+
+static enum elf_x86_plt_type
+get_elf_i386_plt_type (Elf_Internal_Shdr *section, unsigned char *data,
+		       uint32_t *entsz_p,
+		       const struct elf_x86_plt_layout **plt_p)
+{
+  const struct elf_x86_plt_layout *plt = &elf_i386_plt;
+  const struct elf_x86_plt_layout *ibt_plt = &elf_i386_ibt_plt;
+  enum elf_x86_plt_type plt_type = plt_unknown;
+  if (section->sh_size >= plt->plt_entry_size + plt->plt_entry_size)
+    {
+      /* Match lazy PLT first.  */
+      if (memcmp (data, plt->plt0_entry, plt->plt0_got1_offset)
+	  == 0)
+	{
+	  /* The fist entry in the lazy IBT PLT is the same as the
+	     normal lazy PLT.  */
+	  if (memcmp (data + ibt_plt->plt0_entry_size,
+		      ibt_plt->plt_entry,
+		      ibt_plt->plt_reloc_offset) == 0)
+	    {
+	      plt_type = plt_lazy | plt_second;
+	      plt = ibt_plt;
+	    }
+	  else
+	    plt_type = plt_lazy;
+	}
+      else if (memcmp (data, plt->pic_plt0_entry,
+		       plt->plt0_got1_offset) == 0)
+	{
+	  /* The fist entry in the PIC lazy IBT PLT is the same as
+	     the normal PIC lazy PLT.  */
+	  if (memcmp (data + ibt_plt->plt0_entry_size,
+		      ibt_plt->pic_plt_entry,
+		      ibt_plt->plt_reloc_offset) == 0)
+	    {
+	      plt_type = plt_lazy | plt_second;
+	      plt = ibt_plt;
+	    }
+	  else
+	    plt_type = plt_lazy;
+	}
+    }
+
+  if (plt_type == plt_unknown
+      && section->sh_size >= plt->non_lazy.plt_entry_size)
+    {
+      /* Match non-lazy PLT.  */
+      if (memcmp (data, plt->non_lazy.plt_entry,
+		  plt->non_lazy.plt_got_offset) == 0)
+	plt_type = plt_non_lazy;
+      else if (memcmp (data, plt->non_lazy.pic_plt_entry,
+		       plt->non_lazy.plt_got_offset) == 0)
+	plt_type = plt_non_lazy;
+    }
+
+  if (plt_type == plt_unknown || plt_type == plt_second)
+    {
+      if (memcmp (data, ibt_plt->non_lazy.plt_entry,
+		  ibt_plt->non_lazy.plt_got_offset) == 0)
+	{
+	  /* Match IBT PLT.  */
+	  plt_type = plt_second;
+	  plt = ibt_plt;
+	}
+      else if (memcmp (data, ibt_plt->non_lazy.pic_plt_entry,
+		       ibt_plt->non_lazy.plt_got_offset) == 0)
+	{
+	  /* Match PIC IBT PLT.  */
+	  plt_type = plt_second;
+	  plt = ibt_plt;
+	}
+    }
+
+  if ((plt_type & plt_lazy))
+    *entsz_p = plt->plt_entry_size;
+  else
+    *entsz_p = plt->non_lazy.plt_entry_size;
+  *plt_p = plt;
+
+  return plt_type;
+}
+
+static enum elf_x86_plt_type
+get_elf_x86_64_plt_type (Elf_Internal_Shdr *section,
+			 unsigned char *data, uint32_t *entsz_p,
+			 const struct elf_x86_plt_layout **plt_p)
+{
+  const struct elf_x86_plt_layout *plt = &elf_x86_64_plt;
+  const struct elf_x86_plt_layout *ibt_plt = &elf_x86_64_ibt_plt;
+  enum elf_x86_plt_type plt_type = plt_unknown;
+  if (section->sh_size >= plt->plt_entry_size + plt->plt_entry_size)
+    {
+      /* Match lazy PLT first.  Need to check the first two
+	 instructions.   */
+      if (memcmp (data, plt->plt0_entry, plt->plt0_got1_offset) == 0
+	  && memcmp (data + 6, plt->plt0_entry + 6, 2) == 0)
+	{
+	  if (memcmp (data + plt->plt_entry_size, ibt_plt->plt_entry,
+		      ibt_plt->plt_reloc_offset) == 0)
+	    {
+	      /* The fist entry in the lazy IBT PLT is the same as
+		 the normal lazy PLT.  */
+	      plt_type = plt_lazy | plt_second;
+	      plt = ibt_plt;
+	    }
+	  else
+	    plt_type = plt_lazy;
+	}
+    }
+
+  if (plt_type == plt_unknown
+      && section->sh_size >= plt->non_lazy.plt_entry_size)
+    {
+      /* Match non-lazy PLT.  */
+      if (memcmp (data, plt->non_lazy.plt_entry,
+		  plt->non_lazy.plt_got_offset) == 0)
+	plt_type = plt_non_lazy;
+    }
+
+  if (plt_type == plt_unknown || plt_type == plt_second)
+    {
+      if (section->sh_size >= ibt_plt->plt_entry_size
+	  && (memcmp (data, ibt_plt->non_lazy.plt_entry,
+		      ibt_plt->non_lazy.plt_got_offset) == 0))
+	{
+	  /* Match IBT PLT.  */
+	  plt_type = plt_second;
+	  plt = ibt_plt;
+	}
+    }
+
+  if ((plt_type & plt_lazy))
+    *entsz_p = plt->plt_entry_size;
+  else
+    *entsz_p = plt->non_lazy.plt_entry_size;
+  *plt_p = plt;
+
+  return plt_type;
+}
+
+static void
+display_elf_x86_lazy_plt (Filedata *filedata, bool ibt,
+			  const struct elf_x86_plt_layout *plt,
+			  unsigned char *entry, uint64_t addr,
+			  uint32_t entsz, uint32_t entries)
+{
+  bool is_x86_64 = filedata->file_header.e_machine == EM_X86_64;
+  uint64_t pltgot = filedata->dynamic_info[DT_PLTGOT];
+  uint64_t tlsdesc_plt = filedata->dynamic_info_DT_TLSDESC_PLT;
+  uint32_t relentsz = filedata->dynamic_info[DT_RELENT];
+  uint64_t got_addr;
+  uint32_t l, reloc_index, got_index;
+
+  if (is_32bit_elf)
+    printf (_(" Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc\n"));
+	    /* |--7--| |---8--| |--7--| |---8--| |--7--| |...........  */
+  else if (do_wide)
+    printf (_(" Index:     Address      GOT Idx   GOT Address    Rel Idx Symbol/Reloc\n"));
+	    /* |--7--| |------16------| |--7--| |------16------| |--7--| |...........  */
+  else
+    printf (_(" Index:    Address   GOT Idx   GOT Addr   Rel Idx Symbol/Reloc\n"));
+	    /* |--7--| |----12----| |--7--| |----12----| |--7--| |...........  */
+
+  for (l = 0; l < entries; l++, addr += entsz, entry += entsz)
+    if (l == 0 || (tlsdesc_plt != 0 && addr >= tlsdesc_plt))
+      {
+	if (l == 0)
+	  {
+	    got_addr = byte_get (entry + plt->plt0_got2_offset, 4);
+	    if (is_x86_64)
+	      {
+		got_addr += addr + plt->plt0_got2_insn_end;
+		got_index = ((int32_t) (got_addr - pltgot)) / 8;
+	      }
+	    else
+	      {
+		got_index = ((int32_t) got_addr) / 4;
+		got_addr = (uint32_t) got_addr + pltgot;
+	      }
+	  }
+	else if (tlsdesc_plt != 0 && addr >= tlsdesc_plt)
+	  {
+	    if (l + 1 != entries)
+	      abort ();
+
+	    got_addr = byte_get (entry + plt->plt_tlsdesc_got2_offset, 4);
+	    got_addr += addr + plt->plt_tlsdesc_got2_insn_end;
+	    got_index = ((int32_t) (got_addr - pltgot)) / 8;
+	  }
+
+	if (is_32bit_elf)
+	  printf ("%6" PRIu32 ": %8.8" PRIx32
+		  " %6" PRId32 ": %8.8" PRIx32 "\n",
+		  l, (uint32_t) addr,
+		  got_index, (uint32_t) got_addr);
+	else if (do_wide)
+	  printf ("%6" PRIu32 ": %16.16" PRIx64
+		  " %6" PRId32 ": %16.16" PRIx64 "\n",
+		  l, addr, got_index, got_addr);
+	else
+	  printf ("%6" PRIu32 ": %12.12" PRIx64
+		  " %6" PRId32 ": %12.12" PRIx64 "\n",
+		  l, addr, got_index, got_addr);
+      }
+    else
+      {
+	reloc_index = byte_get (entry + plt->plt_reloc_offset, 4);
+	if (!is_x86_64)
+	  reloc_index /= relentsz;
+	if (ibt)
+	  {
+	    got_addr = 0;
+	    if (is_32bit_elf)
+	      printf ("%6" PRIu32 ": %8.8" PRIx32 "%*c%6" PRIu32 ": ",
+		      l, (uint32_t) addr, 18, ' ', reloc_index);
+	    else if (do_wide)
+	      printf ("%6" PRIu32 ": %16.16" PRIx64 "%*c%6" PRIu32 ": ",
+		      l, addr, 26, ' ', reloc_index);
+	    else
+	      printf ("%6" PRIu32 ": %12.12" PRIx64 "%*c%6" PRIu32 ": ",
+		      l, addr, 22, ' ', reloc_index);
+	  }
+	else
+	  {
+	    got_addr = byte_get (entry + plt->plt_got_offset, 4);
+	    if (is_x86_64)
+	      {
+		got_addr += addr + plt->plt_got_insn_size;
+		got_index = ((int32_t) (got_addr - pltgot)) / 8;
+	      }
+	    else
+	      {
+		got_index = ((int32_t) got_addr) / 4;
+		got_addr = (uint32_t) got_addr + pltgot;
+	      }
+	    if (is_32bit_elf)
+	      printf ("%6" PRIu32 ": %8.8" PRIx32 " %6" PRId32
+		      ": %8.8" PRIx32 " %6" PRIu32 ": ",
+		      l, (uint32_t) addr, got_index,
+		      (uint32_t) got_addr, reloc_index);
+	    else if (do_wide)
+	      printf ("%6" PRIu32 ": %16.16" PRIx64 " %6" PRId32
+		      ": %16.16" PRIx64 " %6" PRIu32 ": ",
+		      l, addr, got_index, got_addr, reloc_index);
+	    else
+	      printf ("%6" PRIu32 ": %12.12" PRIx64 " %6" PRId32
+		      ": %12.12" PRIx64 " %6" PRIu32 ": ",
+		      l, addr, got_index, got_addr, reloc_index);
+	  }
+
+	display_elf_plt_relocation_at (reloc_index, got_addr, true);
+      }
+}
+
+static void
+display_elf_x86_non_lazey_plt (Filedata *filedata,
+			       const struct elf_x86_plt_layout *plt,
+			       unsigned char *entry, uint64_t addr,
+			       uint32_t entsz, uint32_t entries)
+{
+  bool is_x86_64 = filedata->file_header.e_machine == EM_X86_64;
+  uint32_t pltgot = filedata->dynamic_info[DT_PLTGOT];
+  uint64_t got_addr;
+  uint32_t l;
+  int32_t got_index;
+
+  if (is_32bit_elf)
+    printf (_(" Index:  Address GOT Idx GOT Addr Symbol/Reloc\n"));
+	    /* |--7--| |---8--| |--7--| |---8--| |...........  */
+  else if (do_wide)
+    printf (_(" Index:     Address      GOT Idx   GOT Address    Symbol/Reloc\n"));
+	    /* |--7--| |------16------| |--7--| |------16------| |...........  */
+  else
+    printf (_(" Index:    Address   GOT Idx   GOT Addr   Symbol/Reloc\n"));
+	    /* |--7--| |----12----| |--7--| |----12----| |...........  */
+
+  for (l = 0; l < entries; l++, addr += entsz, entry += entsz)
+    {
+      got_addr = byte_get (entry + plt->non_lazy.plt_got_offset, 4);
+      if (is_x86_64)
+	{
+	  got_addr += addr + plt->non_lazy.plt_got_insn_size;
+	  got_index = ((int32_t) (got_addr - pltgot)) / 8;
+	}
+      else
+	{
+	  got_index = ((int32_t) got_addr) / 4;
+	  got_addr = (uint32_t) got_addr + pltgot;
+	}
+      if (is_32bit_elf)
+	printf ("%6" PRIu32 ": %8.8" PRIx32
+		" %6" PRId32 ": %8.8" PRIx32 " ",
+		l, (uint32_t) addr,
+		got_index, (uint32_t) got_addr);
+      else if (do_wide)
+	printf ("%6" PRIu32 ": %16.16" PRIx64
+		" %6" PRId32 ": %16.16" PRIx64 " ",
+		l, addr, got_index, got_addr);
+      else
+	printf ("%6" PRIu32 ": %12.12" PRIx64
+		" %6" PRId32 ": %12.12" PRIx64 " ",
+		l, addr, got_index, got_addr);
+      display_elf_plt_relocation_at (0, got_addr, false);
+    }
+}
+
+static bool
+display_x86_plt_sections (Filedata * filedata)
+{
+  bool found = false;
+
+  if (plt_relocations_count == 0 && !process_relocs (filedata, true))
+    return found;
+
+  initialise_dumps_byname (filedata);
+
+  static const char * const plts[] =
+    {
+      ".plt",
+      ".plt.got",
+      ".plt.sec"
+    };
+  const struct elf_x86_plt_layout *plt;
+  enum elf_x86_plt_type plt_type;
+  Elf_Internal_Shdr * section;
+  unsigned int i, j;
+
+  for (i = 0, section = filedata->section_headers;
+       i < filedata->file_header.e_shnum;
+       i++, section++)
+    if (section->sh_type == SHT_PROGBITS
+	&& section->sh_size != 0
+	&& (section->sh_flags & SHF_EXECINSTR) != 0)
+      {
+	const char *name = printable_section_name (filedata, section);
+
+	if (!startswith (name, ".plt"))
+	  continue;
+
+	for (j = 0; j < ARRAY_SIZE (plts); j++)
+	  if (strcmp (plts[j], name) == 0)
+	    break;
+
+	if (j >= ARRAY_SIZE (plts))
+	  {
+	    putchar ('\n');
+	    warn (_("Unknown PLT section '%s'\n"), name);
+	    continue;
+	  }
+
+	found = true;
+
+	unsigned char *data
+	  = (unsigned char *) get_section_contents (section, filedata);
+	if (data == NULL)
+	  goto out;
+
+	uint32_t entsz;
+	/* Check what kind of PLT it is.  NB: Also get i386 entry size
+	   since .plt section sh_entsize is set to 4 to be compatible
+	   with UnixWare.  */
+	if (filedata->file_header.e_machine == EM_X86_64)
+	  plt_type = get_elf_x86_64_plt_type (section, data, &entsz,
+					      &plt);
+	else
+	  plt_type = get_elf_i386_plt_type (section, data, &entsz,
+					    &plt);
+
+	if (plt_type == plt_unknown)
+	  {
+	    putchar ('\n');
+	    warn (_("Unknown PLT type in section '%s'\n"), name);
+	    continue;
+	  }
+
+	uint32_t entries = section->sh_size / entsz;
+	if (entries == 1)
+	  printf (_("\nProcedure Linkage Table '%s' contains 1 entry:\n"),
+		  name);
+	else
+	  printf (_("\nProcedure Linkage Table '%s' contains %" PRIu32
+		    " entries:\n"), name, entries);
+
+	if ((plt_type & plt_lazy) != 0)
+	  display_elf_x86_lazy_plt (filedata, plt_type != plt_lazy,
+				    plt, data, section->sh_addr, entsz,
+				    entries);
+	else if (plt_type == plt_second || plt_type == plt_non_lazy)
+	  display_elf_x86_non_lazey_plt (filedata, plt, data,
+					 section->sh_addr,
+					 entsz, entries);
+	else
+	  abort ();
+
+	free (data);
+      }
+
+ out:
+  for (size_t p = 0; p < plt_relocations_count; p++)
+    free (plt_relocations[p].r_symbol);
+  free (plt_relocations);
+  plt_relocations = NULL;
+  plt_relocations_count = 0;
+
+  return found;
+}
+
+static bool
+process_plt_section_contents (Filedata * filedata)
+{
+  bool found = false;
+
+  if (!do_plt_section_contents)
+    return true;
+
+  switch (filedata->file_header.e_type)
+    {
+    case ET_DYN:
+    case ET_EXEC:
+      break;
+    default:
+      goto out;
+    }
+
+  switch (filedata->file_header.e_machine)
+    {
+    default:
+      if (filedata->is_separate)
+	warn (_("Unsupported PLT contents in linked file '%s'\n"),
+	      filedata->file_name);
+      else
+	warn (_("Unsupported PLT contents in this file\n"));
+      return false;
+    case EM_386:
+    case EM_IAMCU:
+    case EM_X86_64:
+      found = display_x86_plt_sections (filedata);
+      break;
+    }
+
+ out:
+  if (! found)
+    {
+      if (filedata->is_separate)
+	printf (_("\nThere is no PLT section in linked file '%s'.\n"),
+		filedata->file_name);
+      else
+	printf (_("\nThere is no PLT section in this file.\n"));
+    }
+
+  return true;
+}
+
 static bool
 process_gnu_liblist (Filedata * filedata)
 {
@@ -24459,7 +25386,7 @@  process_object (Filedata * filedata)
 
   res = process_dynamic_section (filedata);
 
-  if (! process_relocs (filedata))
+  if (! process_relocs (filedata, false))
     res = false;
 
   if (! process_unwind (filedata))
@@ -24488,6 +25415,9 @@  process_object (Filedata * filedata)
   if (! process_got_section_contents (filedata))
     res = false;
 
+  if (! process_plt_section_contents (filedata))
+    res = false;
+
   if (have_separate_files)
     {
       separate_info * d;
@@ -24509,7 +25439,7 @@  process_object (Filedata * filedata)
 	      process_program_headers (d->handle);
 	      if (! process_dynamic_section (d->handle))
 		res = false;
-	      if (! process_relocs (d->handle))
+	      if (! process_relocs (d->handle, false))
 		res = false;
 	      if (! process_unwind (d->handle))
 		res = false;
diff --git a/ld/testsuite/ld-i386/binutils.exp b/ld/testsuite/ld-i386/binutils.exp
index 11384487e21..a03986e6569 100644
--- a/ld/testsuite/ld-i386/binutils.exp
+++ b/ld/testsuite/ld-i386/binutils.exp
@@ -45,5 +45,36 @@  if { $status == 0 } {
 	     {readelf {--got-contents -W} libgot-1d.rd}} \
 	    "libgot-1-i386.so" \
 	] \
+	[list \
+	    "Build libplt-1a-i386.so" \
+	    "-shared -melf_i386 --no-ld-generated-unwind-info \
+	     -z noseparate-code -z max-page-size=0x200000 \
+	     --hash-style=sysv -z ibtplt $NO_DT_RELR_LDFLAGS \
+	     --rosegment" \
+	    "" \
+	    "--32 -mx86-used-note=no --generate-missing-build-notes=no" \
+	    {plt-1.s} \
+	    {{readelf -rW libplt-1a-a.rd} \
+	     {readelf -aW libplt-1a-b.rd} \
+	     {readelf --plt-contents libplt-1a-c.rd} \
+	     {readelf {--plt-contents -W} libplt-1a-d.rd} \
+	     {readelf {--plt-contents -D -s} libplt-1a-e.rd}} \
+	    "libplt-1a-i386.so" \
+	] \
+	[list \
+	    "Build libplt-1b-i386.so" \
+	    "-shared -melf_i386 --no-ld-generated-unwind-info \
+	     -z noseparate-code -z max-page-size=0x200000 \
+	     --rosegment --hash-style=sysv $NO_DT_RELR_LDFLAGS" \
+	    "" \
+	    "--32 -mx86-used-note=no --generate-missing-build-notes=no" \
+	    {plt-1.s} \
+	    {{readelf -rW libplt-1b-a.rd} \
+	     {readelf -aW libplt-1b-b.rd} \
+	     {readelf --plt-contents libplt-1b-c.rd} \
+	     {readelf {--plt-contents -W} libplt-1b-d.rd} \
+	     {readelf {--plt-contents -D -s} libplt-1b-e.rd}} \
+	    "libplt-1b-i386.so" \
+	] \
     ]
 }
diff --git a/ld/testsuite/ld-i386/libplt-1a-a.rd b/ld/testsuite/ld-i386/libplt-1a-a.rd
new file mode 100644
index 00000000000..61485c74538
--- /dev/null
+++ b/ld/testsuite/ld-i386/libplt-1a-a.rd
@@ -0,0 +1,10 @@ 
+
+Relocation section '.rel.dyn' at offset 0x128 contains 1 entry:
+ Offset     Info    Type                Sym. Value  Symbol's Name
+0+200248  00000206 R_386_GLOB_DAT         00000000   foo
+
+Relocation section '.rel.plt' at offset 0x130 contains 2 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name
+0+200258  00000107 R_386_JUMP_SLOT        000001a0   func
+0+20025c  00000307 R_386_JUMP_SLOT        00000000   bar
+#pass
diff --git a/ld/testsuite/ld-i386/libplt-1a-b.rd b/ld/testsuite/ld-i386/libplt-1a-b.rd
new file mode 100644
index 00000000000..73c91dab864
--- /dev/null
+++ b/ld/testsuite/ld-i386/libplt-1a-b.rd
@@ -0,0 +1,145 @@ 
+ELF Header:
+  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
+  Class:                             ELF32
+  Data:                              2's complement, little endian
+  Version:                           1 \(current\)
+  OS/ABI:                            UNIX - System V
+  ABI Version:                       0
+  Type:                              DYN \(Shared object file\)
+  Machine:                           Intel 80386
+  Version:                           0x1
+  Entry point address:               0x0
+  Start of program headers:          52 \(bytes into file\)
+  Start of section headers:          860 \(bytes into file\)
+  Flags:                             0x0
+  Size of this header:               52 \(bytes\)
+  Size of program headers:           32 \(bytes\)
+  Number of program headers:         4
+  Size of section headers:           40 \(bytes\)
+  Number of section headers:         16
+  Section header string table index: 15
+
+Section Headers:
+  \[Nr\] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
+  \[ 0\]                   NULL            00000000 000000 000000 00      0   0  0
+  \[ 1\] .hash             HASH            000000b4 0000b4 000024 04   A  2   0  4
+  \[ 2\] .dynsym           DYNSYM          000000d8 0000d8 000040 10   A  3   1  4
+  \[ 3\] .dynstr           STRTAB          00000118 000118 00000e 00   A  0   0  1
+  \[ 4\] .rel.dyn          REL             00000128 000128 000008 08   A  2   0  4
+  \[ 5\] .rel.plt          REL             00000130 000130 000010 08  AI  2  12  4
+  \[ 6\] .plt              PROGBITS        00000140 000140 000030 04  AX  0   0 16
+  \[ 7\] .plt.got          PROGBITS        00000170 000170 000010 10  AX  0   0 16
+  \[ 8\] .plt.sec          PROGBITS        00000180 000180 000020 10  AX  0   0 16
+  \[ 9\] .text             PROGBITS        000001a0 0001a0 000015 00  AX  0   0  1
+  \[10\] .dynamic          DYNAMIC         002001b8 0001b8 000090 08  WA  3   0  4
+  \[11\] .got              PROGBITS        00200248 000248 000004 04  WA  0   0  4
+  \[12\] .got.plt          PROGBITS        0020024c 00024c 000014 04  WA  0   0  4
+  \[13\] .symtab           SYMTAB          00000000 000260 000060 10     14   3  4
+  \[14\] .strtab           STRTAB          00000000 0002c0 00002d 00      0   0  1
+  \[15\] .shstrtab         STRTAB          00000000 0002ed 00006d 00      0   0  1
+Key to Flags:
+  W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\), I \(info\),
+  L \(link order\), O \(extra OS processing required\), G \(group\), T \(TLS\),
+  C \(compressed\), x \(unknown\), o \(OS specific\), E \(exclude\),
+  D \(mbind\), p \(processor specific\)
+
+There are no section groups in this file.
+
+Program Headers:
+  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
+  LOAD           0x000000 0x00000000 0x00000000 0x001b5 0x001b5 R E 0x200000
+  LOAD           0x0001b8 0x002001b8 0x002001b8 0x000a8 0x000a8 RW  0x200000
+  DYNAMIC        0x0001b8 0x002001b8 0x002001b8 0x00090 0x00090 RW  0x4
+  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
+
+ Section to Segment mapping:
+  Segment Sections...
+   00     .hash .dynsym .dynstr .rel.dyn .rel.plt .plt .plt.got .plt.sec .text 
+   01     .dynamic .got .got.plt 
+   02     .dynamic 
+   03     
+
+Dynamic section at offset 0x1b8 contains 13 entries:
+  Tag        Type                         Name/Value
+ 0x00000004 \(HASH\)                       0xb4
+ 0x00000005 \(STRTAB\)                     0x118
+ 0x00000006 \(SYMTAB\)                     0xd8
+ 0x0000000a \(STRSZ\)                      14 \(bytes\)
+ 0x0000000b \(SYMENT\)                     16 \(bytes\)
+ 0x00000003 \(PLTGOT\)                     0x20024c
+ 0x00000002 \(PLTRELSZ\)                   16 \(bytes\)
+ 0x00000014 \(PLTREL\)                     REL
+ 0x00000017 \(JMPREL\)                     0x130
+ 0x00000011 \(REL\)                        0x128
+ 0x00000012 \(RELSZ\)                      8 \(bytes\)
+ 0x00000013 \(RELENT\)                     8 \(bytes\)
+ 0x00000000 \(NULL\)                       0x0
+
+Relocation section '.rel.dyn' at offset 0x128 contains 1 entry:
+ Offset     Info    Type                Sym. Value  Symbol's Name
+0+200248  00000206 R_386_GLOB_DAT         00000000   foo
+
+Relocation section '.rel.plt' at offset 0x130 contains 2 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name
+0+200258  00000107 R_386_JUMP_SLOT        000001a0   func
+0+20025c  00000307 R_386_JUMP_SLOT        00000000   bar
+No processor specific unwind information to decode
+
+Symbol table '.dynsym' contains 4 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 000001a0     0 FUNC    GLOBAL DEFAULT    9 func
+     2: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     3: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Symbol table '.symtab' contains 6 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 002001b8     0 OBJECT  LOCAL  DEFAULT   10 _DYNAMIC
+     2: 0020024c     0 OBJECT  LOCAL  DEFAULT   12 _GLOBAL_OFFSET_TABLE_
+     3: 000001a0     0 FUNC    GLOBAL DEFAULT    9 func
+     4: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     5: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Histogram for bucket list length \(total of 3 buckets\):
+ Length  Number     % of total  Coverage
+      0  1          \( 33.3%\)
+      1  1          \( 33.3%\)     33.3%
+      2  1          \( 33.3%\)    100.0%
+
+No version information found in this file.
+
+Global Offset Table '.got' contains 1 entry:
+   Index:  Address      Reloc             Sym. Name \+ Addend/Value
+       0: 00200248 R_386_GLOB_DAT         foo \+ 0
+
+Global Offset Table '.got.plt' contains 5 entries:
+   Index:  Address      Reloc             Sym. Name \+ Addend/Value
+       0: 0020024c                        2001b8
+       1: 00200250                        0
+       2: 00200254                        0
+       3: 00200258 R_386_JUMP_SLOT        func \+ 150
+       4: 0020025c R_386_JUMP_SLOT        bar \+ 160
+
+'PLT' relocation section at offset 0x130 contains 16 bytes:
+ Offset     Info    Type                Sym. Value  Symbol's Name
+0+200258  00000107 R_386_JUMP_SLOT        000001a0   func
+0+20025c  00000307 R_386_JUMP_SLOT        00000000   bar
+
+There are no dynamic relocations in this file.
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000140      2: 00200254
+     1: 00000150                       0: func
+     2: 00000160                       1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000170     -1: 00200248 
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000180      3: 00200258 
+     1: 00000190      4: 0020025c 
+#pass
diff --git a/ld/testsuite/ld-i386/libplt-1a-c.rd b/ld/testsuite/ld-i386/libplt-1a-c.rd
new file mode 100644
index 00000000000..7bab9d8a650
--- /dev/null
+++ b/ld/testsuite/ld-i386/libplt-1a-c.rd
@@ -0,0 +1,16 @@ 
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000140      2: 00200254
+     1: 00000150                       0: func
+     2: 00000160                       1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000170     -1: 00200248 foo
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000180      3: 00200258 func
+     1: 00000190      4: 0020025c bar
+#pass
diff --git a/ld/testsuite/ld-i386/libplt-1a-d.rd b/ld/testsuite/ld-i386/libplt-1a-d.rd
new file mode 100644
index 00000000000..7bab9d8a650
--- /dev/null
+++ b/ld/testsuite/ld-i386/libplt-1a-d.rd
@@ -0,0 +1,16 @@ 
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000140      2: 00200254
+     1: 00000150                       0: func
+     2: 00000160                       1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000170     -1: 00200248 foo
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000180      3: 00200258 func
+     1: 00000190      4: 0020025c bar
+#pass
diff --git a/ld/testsuite/ld-i386/libplt-1a-e.rd b/ld/testsuite/ld-i386/libplt-1a-e.rd
new file mode 100644
index 00000000000..d1cefd6a917
--- /dev/null
+++ b/ld/testsuite/ld-i386/libplt-1a-e.rd
@@ -0,0 +1,23 @@ 
+
+Symbol table for image contains 4 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 000001a0     0 FUNC    GLOBAL DEFAULT    9 func
+     2: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     3: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000140      2: 00200254
+     1: 00000150                       0: func
+     2: 00000160                       1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000170     -1: 00200248 foo
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000180      3: 00200258 func
+     1: 00000190      4: 0020025c bar
+#pass
diff --git a/ld/testsuite/ld-i386/libplt-1b-a.rd b/ld/testsuite/ld-i386/libplt-1b-a.rd
new file mode 100644
index 00000000000..eca16f73022
--- /dev/null
+++ b/ld/testsuite/ld-i386/libplt-1b-a.rd
@@ -0,0 +1,10 @@ 
+
+Relocation section '.rel.dyn' at offset 0x128 contains 1 entry:
+ Offset     Info    Type                Sym. Value  Symbol's Name
+0+200220  00000206 R_386_GLOB_DAT         00000000   foo
+
+Relocation section '.rel.plt' at offset 0x130 contains 2 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name
+0+200230  00000107 R_386_JUMP_SLOT        00000178   func
+0+200234  00000307 R_386_JUMP_SLOT        00000000   bar
+#pass
diff --git a/ld/testsuite/ld-i386/libplt-1b-b.rd b/ld/testsuite/ld-i386/libplt-1b-b.rd
new file mode 100644
index 00000000000..134936b2225
--- /dev/null
+++ b/ld/testsuite/ld-i386/libplt-1b-b.rd
@@ -0,0 +1,139 @@ 
+ELF Header:
+  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
+  Class:                             ELF32
+  Data:                              2's complement, little endian
+  Version:                           1 \(current\)
+  OS/ABI:                            UNIX - System V
+  ABI Version:                       0
+  Type:                              DYN \(Shared object file\)
+  Machine:                           Intel 80386
+  Version:                           0x1
+  Entry point address:               0x0
+  Start of program headers:          52 \(bytes into file\)
+  Start of section headers:          812 \(bytes into file\)
+  Flags:                             0x0
+  Size of this header:               52 \(bytes\)
+  Size of program headers:           32 \(bytes\)
+  Number of program headers:         4
+  Size of section headers:           40 \(bytes\)
+  Number of section headers:         15
+  Section header string table index: 14
+
+Section Headers:
+  \[Nr\] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
+  \[ 0\]                   NULL            00000000 000000 000000 00      0   0  0
+  \[ 1\] .hash             HASH            000000b4 0000b4 000024 04   A  2   0  4
+  \[ 2\] .dynsym           DYNSYM          000000d8 0000d8 000040 10   A  3   1  4
+  \[ 3\] .dynstr           STRTAB          00000118 000118 00000e 00   A  0   0  1
+  \[ 4\] .rel.dyn          REL             00000128 000128 000008 08   A  2   0  4
+  \[ 5\] .rel.plt          REL             00000130 000130 000010 08  AI  2  11  4
+  \[ 6\] .plt              PROGBITS        00000140 000140 000030 04  AX  0   0 16
+  \[ 7\] .plt.got          PROGBITS        00000170 000170 000008 08  AX  0   0  8
+  \[ 8\] .text             PROGBITS        00000178 000178 000015 00  AX  0   0  1
+  \[ 9\] .dynamic          DYNAMIC         00200190 000190 000090 08  WA  3   0  4
+  \[10\] .got              PROGBITS        00200220 000220 000004 04  WA  0   0  4
+  \[11\] .got.plt          PROGBITS        00200224 000224 000014 04  WA  0   0  4
+  \[12\] .symtab           SYMTAB          00000000 000238 000060 10     13   3  4
+  \[13\] .strtab           STRTAB          00000000 000298 00002d 00      0   0  1
+  \[14\] .shstrtab         STRTAB          00000000 0002c5 000064 00      0   0  1
+Key to Flags:
+  W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\), I \(info\),
+  L \(link order\), O \(extra OS processing required\), G \(group\), T \(TLS\),
+  C \(compressed\), x \(unknown\), o \(OS specific\), E \(exclude\),
+  D \(mbind\), p \(processor specific\)
+
+There are no section groups in this file.
+
+Program Headers:
+  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
+  LOAD           0x000000 0x00000000 0x00000000 0x0018d 0x0018d R E 0x200000
+  LOAD           0x000190 0x00200190 0x00200190 0x000a8 0x000a8 RW  0x200000
+  DYNAMIC        0x000190 0x00200190 0x00200190 0x00090 0x00090 RW  0x4
+  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
+
+ Section to Segment mapping:
+  Segment Sections...
+   00     .hash .dynsym .dynstr .rel.dyn .rel.plt .plt .plt.got .text 
+   01     .dynamic .got .got.plt 
+   02     .dynamic 
+   03     
+
+Dynamic section at offset 0x190 contains 13 entries:
+  Tag        Type                         Name/Value
+ 0x00000004 \(HASH\)                       0xb4
+ 0x00000005 \(STRTAB\)                     0x118
+ 0x00000006 \(SYMTAB\)                     0xd8
+ 0x0000000a \(STRSZ\)                      14 \(bytes\)
+ 0x0000000b \(SYMENT\)                     16 \(bytes\)
+ 0x00000003 \(PLTGOT\)                     0x200224
+ 0x00000002 \(PLTRELSZ\)                   16 \(bytes\)
+ 0x00000014 \(PLTREL\)                     REL
+ 0x00000017 \(JMPREL\)                     0x130
+ 0x00000011 \(REL\)                        0x128
+ 0x00000012 \(RELSZ\)                      8 \(bytes\)
+ 0x00000013 \(RELENT\)                     8 \(bytes\)
+ 0x00000000 \(NULL\)                       0x0
+
+Relocation section '.rel.dyn' at offset 0x128 contains 1 entry:
+ Offset     Info    Type                Sym. Value  Symbol's Name
+0+200220  00000206 R_386_GLOB_DAT         00000000   foo
+
+Relocation section '.rel.plt' at offset 0x130 contains 2 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name
+0+200230  00000107 R_386_JUMP_SLOT        00000178   func
+0+200234  00000307 R_386_JUMP_SLOT        00000000   bar
+No processor specific unwind information to decode
+
+Symbol table '.dynsym' contains 4 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 00000178     0 FUNC    GLOBAL DEFAULT    8 func
+     2: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     3: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Symbol table '.symtab' contains 6 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 00200190     0 OBJECT  LOCAL  DEFAULT    9 _DYNAMIC
+     2: 00200224     0 OBJECT  LOCAL  DEFAULT   11 _GLOBAL_OFFSET_TABLE_
+     3: 00000178     0 FUNC    GLOBAL DEFAULT    8 func
+     4: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     5: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Histogram for bucket list length \(total of 3 buckets\):
+ Length  Number     % of total  Coverage
+      0  1          \( 33.3%\)
+      1  1          \( 33.3%\)     33.3%
+      2  1          \( 33.3%\)    100.0%
+
+No version information found in this file.
+
+Global Offset Table '.got' contains 1 entry:
+   Index:  Address      Reloc             Sym. Name \+ Addend/Value
+       0: 00200220 R_386_GLOB_DAT         foo \+ 0
+
+Global Offset Table '.got.plt' contains 5 entries:
+   Index:  Address      Reloc             Sym. Name \+ Addend/Value
+       0: 00200224                        200190
+       1: 00200228                        0
+       2: 0020022c                        0
+       3: 00200230 R_386_JUMP_SLOT        func \+ 156
+       4: 00200234 R_386_JUMP_SLOT        bar \+ 166
+
+'PLT' relocation section at offset 0x130 contains 16 bytes:
+ Offset     Info    Type                Sym. Value  Symbol's Name
+0+200230  00000107 R_386_JUMP_SLOT        00000178   func
+0+200234  00000307 R_386_JUMP_SLOT        00000000   bar
+
+There are no dynamic relocations in this file.
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000140      2: 0020022c
+     1: 00000150      3: 00200230      0: func
+     2: 00000160      4: 00200234      1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000170     -1: 00200220 
+#pass
diff --git a/ld/testsuite/ld-i386/libplt-1b-c.rd b/ld/testsuite/ld-i386/libplt-1b-c.rd
new file mode 100644
index 00000000000..98a0e1eb9a6
--- /dev/null
+++ b/ld/testsuite/ld-i386/libplt-1b-c.rd
@@ -0,0 +1,11 @@ 
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000140      2: 0020022c
+     1: 00000150      3: 00200230      0: func
+     2: 00000160      4: 00200234      1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000170     -1: 00200220 foo
+#pass
diff --git a/ld/testsuite/ld-i386/libplt-1b-d.rd b/ld/testsuite/ld-i386/libplt-1b-d.rd
new file mode 100644
index 00000000000..98a0e1eb9a6
--- /dev/null
+++ b/ld/testsuite/ld-i386/libplt-1b-d.rd
@@ -0,0 +1,11 @@ 
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000140      2: 0020022c
+     1: 00000150      3: 00200230      0: func
+     2: 00000160      4: 00200234      1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000170     -1: 00200220 foo
+#pass
diff --git a/ld/testsuite/ld-i386/libplt-1b-e.rd b/ld/testsuite/ld-i386/libplt-1b-e.rd
new file mode 100644
index 00000000000..540a64160f8
--- /dev/null
+++ b/ld/testsuite/ld-i386/libplt-1b-e.rd
@@ -0,0 +1,18 @@ 
+
+Symbol table for image contains 4 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 00000178     0 FUNC    GLOBAL DEFAULT    8 func
+     2: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     3: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000140      2: 0020022c
+     1: 00000150      3: 00200230      0: func
+     2: 00000160      4: 00200234      1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000170     -1: 00200220 foo
+#pass
diff --git a/ld/testsuite/ld-i386/plt-1.s b/ld/testsuite/ld-i386/plt-1.s
new file mode 100644
index 00000000000..35f7654e884
--- /dev/null
+++ b/ld/testsuite/ld-i386/plt-1.s
@@ -0,0 +1,9 @@ 
+	.text
+	.globl	func
+	.type	func, @function
+func:
+	call	func@PLT
+	call	foo@PLT
+	call	*foo@GOT(%ebx)
+	jmp	bar@PLT
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/binutils.exp b/ld/testsuite/ld-x86-64/binutils.exp
index 4a0b211f100..81376afbe9f 100644
--- a/ld/testsuite/ld-x86-64/binutils.exp
+++ b/ld/testsuite/ld-x86-64/binutils.exp
@@ -46,6 +46,70 @@  if { $status == 0 } {
 	     {readelf {--got-contents -W} libgot-1d.rd}} \
 	    "libgot-1-x64.so" \
 	] \
+	[list \
+	    "Build libplt-1a-x64.so" \
+	    "-shared -melf_x86_64 --no-ld-generated-unwind-info \
+	     -z noseparate-code -z max-page-size=0x200000 \
+	     --hash-style=sysv -z nomark-plt -z ibtplt \
+	     --rosegment $NO_DT_RELR_LDFLAGS" \
+	    "" \
+	    "--64 -mx86-used-note=no --generate-missing-build-notes=no" \
+	    {plt-1.s} \
+	    {{readelf -rW libplt-1a-a.rd} \
+	     {readelf -aW libplt-1a-b.rd} \
+	     {readelf --plt-contents libplt-1a-c.rd} \
+	     {readelf {--plt-contents -W} libplt-1a-d.rd} \
+	     {readelf {--plt-contents -D -s} libplt-1a-e.rd}} \
+	    "libplt-1a-x64.so" \
+	] \
+	[list \
+	    "Build libplt-1b-x64.so" \
+	    "-shared -melf_x86_64 --no-ld-generated-unwind-info \
+	     -z noseparate-code -z max-page-size=0x200000 \
+	     --hash-style=sysv -z nomark-plt $NO_DT_RELR_LDFLAGS \
+	     --rosegment" \
+	    "" \
+	    "--64 -mx86-used-note=no --generate-missing-build-notes=no" \
+	    {plt-1.s} \
+	    {{readelf -rW libplt-1b-a.rd} \
+	     {readelf -aW libplt-1b-b.rd} \
+	     {readelf --plt-contents libplt-1b-c.rd} \
+	     {readelf {--plt-contents -W} libplt-1b-d.rd} \
+	     {readelf {--plt-contents -D -s} libplt-1b-e.rd}} \
+	    "libplt-1b-x64.so" \
+	] \
+	[list \
+	    "Build libplt-2a-x64.so" \
+	    "-shared -melf_x86_64 --no-ld-generated-unwind-info \
+	     -z noseparate-code -z max-page-size=0x200000 \
+	     --hash-style=sysv -z nomark-plt -z ibtplt \
+	     --rosegment $NO_DT_RELR_LDFLAGS" \
+	    "" \
+	    "--64 -mx86-used-note=no --generate-missing-build-notes=no" \
+	    {plt-2.s} \
+	    {{readelf -rW libplt-2a-a.rd} \
+	     {readelf -aW libplt-2a-b.rd} \
+	     {readelf --plt-contents libplt-2a-c.rd} \
+	     {readelf {--plt-contents -W} libplt-2a-d.rd} \
+	     {readelf {--plt-contents -D -s} libplt-2a-e.rd}} \
+	    "libplt-2a-x64.so" \
+	] \
+	[list \
+	    "Build libplt-2b-x64.so" \
+	    "-shared -melf_x86_64 --no-ld-generated-unwind-info \
+	     -z noseparate-code -z max-page-size=0x200000 \
+	     --hash-style=sysv -z nomark-plt $NO_DT_RELR_LDFLAGS \
+	     --rosegment" \
+	    "" \
+	    "--64 -mx86-used-note=no --generate-missing-build-notes=no" \
+	    {plt-2.s} \
+	    {{readelf -rW libplt-2b-a.rd} \
+	     {readelf -aW libplt-2b-b.rd} \
+	     {readelf --plt-contents libplt-2b-c.rd} \
+	     {readelf {--plt-contents -W} libplt-2b-d.rd} \
+	     {readelf {--plt-contents -D -s} libplt-2b-e.rd}} \
+	    "libplt-2b-x64.so" \
+	] \
     ]
 }
 
@@ -68,5 +132,69 @@  if { $status == 0 } {
 	     {readelf {--got-contents -W} libgot-1d-x32.rd}} \
 	    "libgot-1-x32.so" \
 	] \
+	[list \
+	    "Build libplt-1a-x32.so" \
+	    "-shared -melf32_x86_64 --no-ld-generated-unwind-info \
+	     -z noseparate-code -z max-page-size=0x200000 \
+	     --hash-style=sysv -z nomark-plt -z ibtplt \
+	     --rosegment $NO_DT_RELR_LDFLAGS" \
+	    "" \
+	    "--x32 -mx86-used-note=no --generate-missing-build-notes=no" \
+	    {plt-1.s} \
+	    {{readelf -rW libplt-1a-x32-a.rd} \
+	     {readelf -aW libplt-1a-x32-b.rd} \
+	     {readelf --plt-contents libplt-1a-x32-c.rd} \
+	     {readelf {--plt-contents -W} libplt-1a-x32-d.rd} \
+	     {readelf {--plt-contents -D -s} libplt-1a-x32-e.rd}} \
+	    "libplt-1a-x32.so" \
+	] \
+	[list \
+	    "Build libplt-1b-x32.so" \
+	    "-shared -melf32_x86_64 --no-ld-generated-unwind-info \
+	     -z noseparate-code -z max-page-size=0x200000 \
+	     --hash-style=sysv -z nomark-plt $NO_DT_RELR_LDFLAGS \
+	     --rosegment" \
+	    "" \
+	    "--x32 -mx86-used-note=no --generate-missing-build-notes=no" \
+	    {plt-1.s} \
+	    {{readelf -rW libplt-1b-x32-a.rd} \
+	     {readelf -aW libplt-1b-x32-b.rd} \
+	     {readelf --plt-contents libplt-1b-x32-c.rd} \
+	     {readelf {--plt-contents -W} libplt-1b-x32-d.rd} \
+	     {readelf {--plt-contents -D -s} libplt-1b-x32-e.rd}} \
+	    "libplt-1b-x32.so" \
+	] \
+	[list \
+	    "Build libplt-2a-x32.so" \
+	    "-shared -melf32_x86_64 --no-ld-generated-unwind-info \
+	     -z noseparate-code -z max-page-size=0x200000 \
+	     --hash-style=sysv -z nomark-plt -z ibtplt \
+	     --rosegment $NO_DT_RELR_LDFLAGS" \
+	    "" \
+	    "--x32 -mx86-used-note=no --generate-missing-build-notes=no" \
+	    {plt-2.s} \
+	    {{readelf -rW libplt-2a-x32-a.rd} \
+	     {readelf -aW libplt-2a-x32-b.rd} \
+	     {readelf --plt-contents libplt-2a-x32-c.rd} \
+	     {readelf {--plt-contents -W} libplt-2a-x32-d.rd} \
+	     {readelf {--plt-contents -D -s} libplt-2a-x32-e.rd}} \
+	    "libplt-2a-x32.so" \
+	] \
+	[list \
+	    "Build libplt-2b-x32.so" \
+	    "-shared -melf32_x86_64 --no-ld-generated-unwind-info \
+	     -z noseparate-code -z max-page-size=0x200000 \
+	     --hash-style=sysv -z nomark-plt $NO_DT_RELR_LDFLAGS \
+	     --rosegment" \
+	    "" \
+	    "--x32 -mx86-used-note=no --generate-missing-build-notes=no" \
+	    {plt-2.s} \
+	    {{readelf -rW libplt-2b-x32-a.rd} \
+	     {readelf -aW libplt-2b-x32-b.rd} \
+	     {readelf --plt-contents libplt-2b-x32-c.rd} \
+	     {readelf {--plt-contents -W} libplt-2b-x32-d.rd} \
+	     {readelf {--plt-contents -D -s} libplt-2b-x32-e.rd}} \
+	    "libplt-2b-x32.so" \
+	] \
     ]
 }
diff --git a/ld/testsuite/ld-x86-64/libplt-1a-a.rd b/ld/testsuite/ld-x86-64/libplt-1a-a.rd
new file mode 100644
index 00000000000..2329122fff4
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1a-a.rd
@@ -0,0 +1,10 @@ 
+
+Relocation section '.rela.dyn' at offset 0x1b8 contains 1 entry:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200398  0000000200000006 R_X86_64_GLOB_DAT      0000000000000000 foo \+ 0
+
+Relocation section '.rela.plt' at offset 0x1d0 contains 2 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+2003b8  0000000100000007 R_X86_64_JUMP_SLOT     0000000000000260 func \+ 0
+0+2003c0  0000000300000007 R_X86_64_JUMP_SLOT     0000000000000000 bar \+ 0
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1a-b.rd b/ld/testsuite/ld-x86-64/libplt-1a-b.rd
new file mode 100644
index 00000000000..08408055c1a
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1a-b.rd
@@ -0,0 +1,145 @@ 
+ELF Header:
+  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
+  Class:                             ELF64
+  Data:                              2's complement, little endian
+  Version:                           1 \(current\)
+  OS/ABI:                            UNIX - System V
+  ABI Version:                       0
+  Type:                              DYN \(Shared object file\)
+  Machine:                           Advanced Micro Devices X86-64
+  Version:                           0x1
+  Entry point address:               0x0
+  Start of program headers:          64 \(bytes into file\)
+  Start of section headers:          1272 \(bytes into file\)
+  Flags:                             0x0
+  Size of this header:               64 \(bytes\)
+  Size of program headers:           56 \(bytes\)
+  Number of program headers:         4
+  Size of section headers:           64 \(bytes\)
+  Number of section headers:         16
+  Section header string table index: 15
+
+Section Headers:
+  \[Nr\] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
+  \[ 0\]                   NULL            0000000000000000 000000 000000 00      0   0  0
+  \[ 1\] .hash             HASH            0000000000000120 000120 000024 04   A  2   0  8
+  \[ 2\] .dynsym           DYNSYM          0000000000000148 000148 000060 18   A  3   1  8
+  \[ 3\] .dynstr           STRTAB          00000000000001a8 0001a8 00000e 00   A  0   0  1
+  \[ 4\] .rela.dyn         RELA            00000000000001b8 0001b8 000018 18   A  2   0  8
+  \[ 5\] .rela.plt         RELA            00000000000001d0 0001d0 000030 18  AI  2  12  8
+  \[ 6\] .plt              PROGBITS        0000000000000200 000200 000030 10  AX  0   0 16
+  \[ 7\] .plt.got          PROGBITS        0000000000000230 000230 000010 10  AX  0   0 16
+  \[ 8\] .plt.sec          PROGBITS        0000000000000240 000240 000020 10  AX  0   0 16
+  \[ 9\] .text             PROGBITS        0000000000000260 000260 000015 00  AX  0   0  1
+  \[10\] .dynamic          DYNAMIC         0000000000200278 000278 000120 10  WA  3   0  8
+  \[11\] .got              PROGBITS        0000000000200398 000398 000008 08  WA  0   0  8
+  \[12\] .got.plt          PROGBITS        00000000002003a0 0003a0 000028 08  WA  0   0  8
+  \[13\] .symtab           SYMTAB          0000000000000000 0003c8 000090 18     14   3  8
+  \[14\] .strtab           STRTAB          0000000000000000 000458 00002d 00      0   0  1
+  \[15\] .shstrtab         STRTAB          0000000000000000 000485 00006f 00      0   0  1
+Key to Flags:
+  W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\), I \(info\),
+  L \(link order\), O \(extra OS processing required\), G \(group\), T \(TLS\),
+  C \(compressed\), x \(unknown\), o \(OS specific\), E \(exclude\),
+  D \(mbind\), l \(large\), p \(processor specific\)
+
+There are no section groups in this file.
+
+Program Headers:
+  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
+  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x000275 0x000275 R E 0x200000
+  LOAD           0x000278 0x0000000000200278 0x0000000000200278 0x000150 0x000150 RW  0x200000
+  DYNAMIC        0x000278 0x0000000000200278 0x0000000000200278 0x000120 0x000120 RW  0x8
+  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10
+
+ Section to Segment mapping:
+  Segment Sections...
+   00     .hash .dynsym .dynstr .rela.dyn .rela.plt .plt .plt.got .plt.sec .text 
+   01     .dynamic .got .got.plt 
+   02     .dynamic 
+   03     
+
+Dynamic section at offset 0x278 contains 13 entries:
+  Tag        Type                         Name/Value
+ 0x0000000000000004 \(HASH\)               0x120
+ 0x0000000000000005 \(STRTAB\)             0x1a8
+ 0x0000000000000006 \(SYMTAB\)             0x148
+ 0x000000000000000a \(STRSZ\)              14 \(bytes\)
+ 0x000000000000000b \(SYMENT\)             24 \(bytes\)
+ 0x0000000000000003 \(PLTGOT\)             0x2003a0
+ 0x0000000000000002 \(PLTRELSZ\)           48 \(bytes\)
+ 0x0000000000000014 \(PLTREL\)             RELA
+ 0x0000000000000017 \(JMPREL\)             0x1d0
+ 0x0000000000000007 \(RELA\)               0x1b8
+ 0x0000000000000008 \(RELASZ\)             24 \(bytes\)
+ 0x0000000000000009 \(RELAENT\)            24 \(bytes\)
+ 0x0000000000000000 \(NULL\)               0x0
+
+Relocation section '.rela.dyn' at offset 0x1b8 contains 1 entry:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200398  0000000200000006 R_X86_64_GLOB_DAT      0000000000000000 foo \+ 0
+
+Relocation section '.rela.plt' at offset 0x1d0 contains 2 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+2003b8  0000000100000007 R_X86_64_JUMP_SLOT     0000000000000260 func \+ 0
+0+2003c0  0000000300000007 R_X86_64_JUMP_SLOT     0000000000000000 bar \+ 0
+No processor specific unwind information to decode
+
+Symbol table '.dynsym' contains 4 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000000260     0 FUNC    GLOBAL DEFAULT    9 func
+     2: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     3: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Symbol table '.symtab' contains 6 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000200278     0 OBJECT  LOCAL  DEFAULT   10 _DYNAMIC
+     2: 00000000002003a0     0 OBJECT  LOCAL  DEFAULT   12 _GLOBAL_OFFSET_TABLE_
+     3: 0000000000000260     0 FUNC    GLOBAL DEFAULT    9 func
+     4: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     5: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Histogram for bucket list length \(total of 3 buckets\):
+ Length  Number     % of total  Coverage
+      0  1          \( 33.3%\)
+      1  1          \( 33.3%\)     33.3%
+      2  1          \( 33.3%\)    100.0%
+
+No version information found in this file.
+
+Global Offset Table '.got' contains 1 entry:
+   Index:      Address          Reloc             Sym. Name \+ Addend/Value
+       0: 0000000000200398 R_X86_64_GLOB_DAT      foo \+ 0
+
+Global Offset Table '.got.plt' contains 5 entries:
+   Index:      Address          Reloc             Sym. Name \+ Addend/Value
+       0: 00000000002003a0                        200278
+       1: 00000000002003a8                        0
+       2: 00000000002003b0                        0
+       3: 00000000002003b8 R_X86_64_JUMP_SLOT     func \+ 0
+       4: 00000000002003c0 R_X86_64_JUMP_SLOT     bar \+ 0
+
+'PLT' relocation section at offset 0x1d0 contains 48 bytes:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+2003b8  0000000100000007 R_X86_64_JUMP_SLOT     0000000000000260 func \+ 0
+0+2003c0  0000000300000007 R_X86_64_JUMP_SLOT     0000000000000000 bar \+ 0
+
+There are no dynamic relocations in this file.
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:     Address      GOT Idx   GOT Address    Rel Idx Symbol/Reloc
+     0: 0000000000000200      2: 00000000002003b0
+     1: 0000000000000210                               0: func
+     2: 0000000000000220                               1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:     Address      GOT Idx   GOT Address    Symbol/Reloc
+     0: 0000000000000230     -1: 0000000000200398 
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:     Address      GOT Idx   GOT Address    Symbol/Reloc
+     0: 0000000000000240      3: 00000000002003b8 
+     1: 0000000000000250      4: 00000000002003c0 
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1a-c.rd b/ld/testsuite/ld-x86-64/libplt-1a-c.rd
new file mode 100644
index 00000000000..ed7eec4de74
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1a-c.rd
@@ -0,0 +1,16 @@ 
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:    Address   GOT Idx   GOT Addr   Rel Idx Symbol/Reloc
+     0: 000000000200      2: 0000002003b0
+     1: 000000000210                           0: func
+     2: 000000000220                           1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:    Address   GOT Idx   GOT Addr   Symbol/Reloc
+     0: 000000000230     -1: 000000200398 foo
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:    Address   GOT Idx   GOT Addr   Symbol/Reloc
+     0: 000000000240      3: 0000002003b8 func
+     1: 000000000250      4: 0000002003c0 bar
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1a-d.rd b/ld/testsuite/ld-x86-64/libplt-1a-d.rd
new file mode 100644
index 00000000000..083cba82fc5
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1a-d.rd
@@ -0,0 +1,16 @@ 
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:     Address      GOT Idx   GOT Address    Rel Idx Symbol/Reloc
+     0: 0000000000000200      2: 00000000002003b0
+     1: 0000000000000210                               0: func
+     2: 0000000000000220                               1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:     Address      GOT Idx   GOT Address    Symbol/Reloc
+     0: 0000000000000230     -1: 0000000000200398 foo
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:     Address      GOT Idx   GOT Address    Symbol/Reloc
+     0: 0000000000000240      3: 00000000002003b8 func
+     1: 0000000000000250      4: 00000000002003c0 bar
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1a-e.rd b/ld/testsuite/ld-x86-64/libplt-1a-e.rd
new file mode 100644
index 00000000000..3bc949e6d9b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1a-e.rd
@@ -0,0 +1,23 @@ 
+
+Symbol table for image contains 4 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000000260     0 FUNC    GLOBAL DEFAULT    9 func
+     2: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     3: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:    Address   GOT Idx   GOT Addr   Rel Idx Symbol/Reloc
+     0: 000000000200      2: 0000002003b0
+     1: 000000000210                           0: func
+     2: 000000000220                           1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:    Address   GOT Idx   GOT Addr   Symbol/Reloc
+     0: 000000000230     -1: 000000200398 foo
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:    Address   GOT Idx   GOT Addr   Symbol/Reloc
+     0: 000000000240      3: 0000002003b8 func
+     1: 000000000250      4: 0000002003c0 bar
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1a-x32-a.rd b/ld/testsuite/ld-x86-64/libplt-1a-x32-a.rd
new file mode 100644
index 00000000000..63f6e08780f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1a-x32-a.rd
@@ -0,0 +1,10 @@ 
+
+Relocation section '.rela.dyn' at offset 0x128 contains 1 entry:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+200258  00000206 R_X86_64_GLOB_DAT      00000000   foo \+ 0
+
+Relocation section '.rela.plt' at offset 0x134 contains 2 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+200278  00000107 R_X86_64_JUMP_SLOT     000001b0   func \+ 0
+0+200280  00000307 R_X86_64_JUMP_SLOT     00000000   bar \+ 0
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1a-x32-b.rd b/ld/testsuite/ld-x86-64/libplt-1a-x32-b.rd
new file mode 100644
index 00000000000..c81769af6d2
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1a-x32-b.rd
@@ -0,0 +1,145 @@ 
+ELF Header:
+  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
+  Class:                             ELF32
+  Data:                              2's complement, little endian
+  Version:                           1 \(current\)
+  OS/ABI:                            UNIX - System V
+  ABI Version:                       0
+  Type:                              DYN \(Shared object file\)
+  Machine:                           Advanced Micro Devices X86-64
+  Version:                           0x1
+  Entry point address:               0x0
+  Start of program headers:          52 \(bytes into file\)
+  Start of section headers:          900 \(bytes into file\)
+  Flags:                             0x0
+  Size of this header:               52 \(bytes\)
+  Size of program headers:           32 \(bytes\)
+  Number of program headers:         4
+  Size of section headers:           40 \(bytes\)
+  Number of section headers:         16
+  Section header string table index: 15
+
+Section Headers:
+  \[Nr\] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
+  \[ 0\]                   NULL            00000000 000000 000000 00      0   0  0
+  \[ 1\] .hash             HASH            000000b4 0000b4 000024 04   A  2   0  4
+  \[ 2\] .dynsym           DYNSYM          000000d8 0000d8 000040 10   A  3   1  4
+  \[ 3\] .dynstr           STRTAB          00000118 000118 00000e 00   A  0   0  1
+  \[ 4\] .rela.dyn         RELA            00000128 000128 00000c 0c   A  2   0  4
+  \[ 5\] .rela.plt         RELA            00000134 000134 000018 0c  AI  2  12  4
+  \[ 6\] .plt              PROGBITS        00000150 000150 000030 10  AX  0   0 16
+  \[ 7\] .plt.got          PROGBITS        00000180 000180 000010 10  AX  0   0 16
+  \[ 8\] .plt.sec          PROGBITS        00000190 000190 000020 10  AX  0   0 16
+  \[ 9\] .text             PROGBITS        000001b0 0001b0 000015 00  AX  0   0  1
+  \[10\] .dynamic          DYNAMIC         002001c8 0001c8 000090 08  WA  3   0  4
+  \[11\] .got              PROGBITS        00200258 000258 000008 08  WA  0   0  8
+  \[12\] .got.plt          PROGBITS        00200260 000260 000028 08  WA  0   0  8
+  \[13\] .symtab           SYMTAB          00000000 000288 000060 10     14   3  4
+  \[14\] .strtab           STRTAB          00000000 0002e8 00002d 00      0   0  1
+  \[15\] .shstrtab         STRTAB          00000000 000315 00006f 00      0   0  1
+Key to Flags:
+  W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\), I \(info\),
+  L \(link order\), O \(extra OS processing required\), G \(group\), T \(TLS\),
+  C \(compressed\), x \(unknown\), o \(OS specific\), E \(exclude\),
+  D \(mbind\), l \(large\), p \(processor specific\)
+
+There are no section groups in this file.
+
+Program Headers:
+  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
+  LOAD           0x000000 0x00000000 0x00000000 0x001c5 0x001c5 R E 0x200000
+  LOAD           0x0001c8 0x002001c8 0x002001c8 0x000c0 0x000c0 RW  0x200000
+  DYNAMIC        0x0001c8 0x002001c8 0x002001c8 0x00090 0x00090 RW  0x4
+  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
+
+ Section to Segment mapping:
+  Segment Sections...
+   00     .hash .dynsym .dynstr .rela.dyn .rela.plt .plt .plt.got .plt.sec .text 
+   01     .dynamic .got .got.plt 
+   02     .dynamic 
+   03     
+
+Dynamic section at offset 0x1c8 contains 13 entries:
+  Tag        Type                         Name/Value
+ 0x00000004 \(HASH\)                       0xb4
+ 0x00000005 \(STRTAB\)                     0x118
+ 0x00000006 \(SYMTAB\)                     0xd8
+ 0x0000000a \(STRSZ\)                      14 \(bytes\)
+ 0x0000000b \(SYMENT\)                     16 \(bytes\)
+ 0x00000003 \(PLTGOT\)                     0x200260
+ 0x00000002 \(PLTRELSZ\)                   24 \(bytes\)
+ 0x00000014 \(PLTREL\)                     RELA
+ 0x00000017 \(JMPREL\)                     0x134
+ 0x00000007 \(RELA\)                       0x128
+ 0x00000008 \(RELASZ\)                     12 \(bytes\)
+ 0x00000009 \(RELAENT\)                    12 \(bytes\)
+ 0x00000000 \(NULL\)                       0x0
+
+Relocation section '.rela.dyn' at offset 0x128 contains 1 entry:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+200258  00000206 R_X86_64_GLOB_DAT      00000000   foo \+ 0
+
+Relocation section '.rela.plt' at offset 0x134 contains 2 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+200278  00000107 R_X86_64_JUMP_SLOT     000001b0   func \+ 0
+0+200280  00000307 R_X86_64_JUMP_SLOT     00000000   bar \+ 0
+No processor specific unwind information to decode
+
+Symbol table '.dynsym' contains 4 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 000001b0     0 FUNC    GLOBAL DEFAULT    9 func
+     2: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     3: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Symbol table '.symtab' contains 6 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 002001c8     0 OBJECT  LOCAL  DEFAULT   10 _DYNAMIC
+     2: 00200260     0 OBJECT  LOCAL  DEFAULT   12 _GLOBAL_OFFSET_TABLE_
+     3: 000001b0     0 FUNC    GLOBAL DEFAULT    9 func
+     4: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     5: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Histogram for bucket list length \(total of 3 buckets\):
+ Length  Number     % of total  Coverage
+      0  1          \( 33.3%\)
+      1  1          \( 33.3%\)     33.3%
+      2  1          \( 33.3%\)    100.0%
+
+No version information found in this file.
+
+Global Offset Table '.got' contains 1 entry:
+   Index:  Address      Reloc             Sym. Name \+ Addend/Value
+       0: 00200258 R_X86_64_GLOB_DAT      foo \+ 0
+
+Global Offset Table '.got.plt' contains 5 entries:
+   Index:  Address      Reloc             Sym. Name \+ Addend/Value
+       0: 00200260                        2001c8
+       1: 00200268                        0
+       2: 00200270                        0
+       3: 00200278 R_X86_64_JUMP_SLOT     func \+ 0
+       4: 00200280 R_X86_64_JUMP_SLOT     bar \+ 0
+
+'PLT' relocation section at offset 0x134 contains 24 bytes:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+200278  00000107 R_X86_64_JUMP_SLOT     000001b0   func \+ 0
+0+200280  00000307 R_X86_64_JUMP_SLOT     00000000   bar \+ 0
+
+There are no dynamic relocations in this file.
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000150      2: 00200270
+     1: 00000160                       0: func
+     2: 00000170                       1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000180     -1: 00200258 
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000190      3: 00200278 
+     1: 000001a0      4: 00200280 
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1a-x32-c.rd b/ld/testsuite/ld-x86-64/libplt-1a-x32-c.rd
new file mode 100644
index 00000000000..ecf59a1c061
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1a-x32-c.rd
@@ -0,0 +1,16 @@ 
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000150      2: 00200270
+     1: 00000160                       0: func
+     2: 00000170                       1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000180     -1: 00200258 foo
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000190      3: 00200278 func
+     1: 000001a0      4: 00200280 bar
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1a-x32-d.rd b/ld/testsuite/ld-x86-64/libplt-1a-x32-d.rd
new file mode 100644
index 00000000000..ecf59a1c061
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1a-x32-d.rd
@@ -0,0 +1,16 @@ 
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000150      2: 00200270
+     1: 00000160                       0: func
+     2: 00000170                       1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000180     -1: 00200258 foo
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000190      3: 00200278 func
+     1: 000001a0      4: 00200280 bar
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1a-x32-e.rd b/ld/testsuite/ld-x86-64/libplt-1a-x32-e.rd
new file mode 100644
index 00000000000..e4842679d5e
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1a-x32-e.rd
@@ -0,0 +1,23 @@ 
+
+Symbol table for image contains 4 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 000001b0     0 FUNC    GLOBAL DEFAULT    9 func
+     2: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     3: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000150      2: 00200270
+     1: 00000160                       0: func
+     2: 00000170                       1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000180     -1: 00200258 foo
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000190      3: 00200278 func
+     1: 000001a0      4: 00200280 bar
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1b-a.rd b/ld/testsuite/ld-x86-64/libplt-1b-a.rd
new file mode 100644
index 00000000000..a99afd5c449
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1b-a.rd
@@ -0,0 +1,10 @@ 
+
+Relocation section '.rela.dyn' at offset 0x1b8 contains 1 entry:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200370  0000000200000006 R_X86_64_GLOB_DAT      0000000000000000 foo \+ 0
+
+Relocation section '.rela.plt' at offset 0x1d0 contains 2 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200390  0000000100000007 R_X86_64_JUMP_SLOT     0000000000000238 func \+ 0
+0+200398  0000000300000007 R_X86_64_JUMP_SLOT     0000000000000000 bar \+ 0
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1b-b.rd b/ld/testsuite/ld-x86-64/libplt-1b-b.rd
new file mode 100644
index 00000000000..04538f12350
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1b-b.rd
@@ -0,0 +1,139 @@ 
+ELF Header:
+  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
+  Class:                             ELF64
+  Data:                              2's complement, little endian
+  Version:                           1 \(current\)
+  OS/ABI:                            UNIX - System V
+  ABI Version:                       0
+  Type:                              DYN \(Shared object file\)
+  Machine:                           Advanced Micro Devices X86-64
+  Version:                           0x1
+  Entry point address:               0x0
+  Start of program headers:          64 \(bytes into file\)
+  Start of section headers:          1224 \(bytes into file\)
+  Flags:                             0x0
+  Size of this header:               64 \(bytes\)
+  Size of program headers:           56 \(bytes\)
+  Number of program headers:         4
+  Size of section headers:           64 \(bytes\)
+  Number of section headers:         15
+  Section header string table index: 14
+
+Section Headers:
+  \[Nr\] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
+  \[ 0\]                   NULL            0000000000000000 000000 000000 00      0   0  0
+  \[ 1\] .hash             HASH            0000000000000120 000120 000024 04   A  2   0  8
+  \[ 2\] .dynsym           DYNSYM          0000000000000148 000148 000060 18   A  3   1  8
+  \[ 3\] .dynstr           STRTAB          00000000000001a8 0001a8 00000e 00   A  0   0  1
+  \[ 4\] .rela.dyn         RELA            00000000000001b8 0001b8 000018 18   A  2   0  8
+  \[ 5\] .rela.plt         RELA            00000000000001d0 0001d0 000030 18  AI  2  11  8
+  \[ 6\] .plt              PROGBITS        0000000000000200 000200 000030 10  AX  0   0 16
+  \[ 7\] .plt.got          PROGBITS        0000000000000230 000230 000008 08  AX  0   0  8
+  \[ 8\] .text             PROGBITS        0000000000000238 000238 000015 00  AX  0   0  1
+  \[ 9\] .dynamic          DYNAMIC         0000000000200250 000250 000120 10  WA  3   0  8
+  \[10\] .got              PROGBITS        0000000000200370 000370 000008 08  WA  0   0  8
+  \[11\] .got.plt          PROGBITS        0000000000200378 000378 000028 08  WA  0   0  8
+  \[12\] .symtab           SYMTAB          0000000000000000 0003a0 000090 18     13   3  8
+  \[13\] .strtab           STRTAB          0000000000000000 000430 00002d 00      0   0  1
+  \[14\] .shstrtab         STRTAB          0000000000000000 00045d 000066 00      0   0  1
+Key to Flags:
+  W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\), I \(info\),
+  L \(link order\), O \(extra OS processing required\), G \(group\), T \(TLS\),
+  C \(compressed\), x \(unknown\), o \(OS specific\), E \(exclude\),
+  D \(mbind\), l \(large\), p \(processor specific\)
+
+There are no section groups in this file.
+
+Program Headers:
+  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
+  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x00024d 0x00024d R E 0x200000
+  LOAD           0x000250 0x0000000000200250 0x0000000000200250 0x000150 0x000150 RW  0x200000
+  DYNAMIC        0x000250 0x0000000000200250 0x0000000000200250 0x000120 0x000120 RW  0x8
+  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10
+
+ Section to Segment mapping:
+  Segment Sections...
+   00     .hash .dynsym .dynstr .rela.dyn .rela.plt .plt .plt.got .text 
+   01     .dynamic .got .got.plt 
+   02     .dynamic 
+   03     
+
+Dynamic section at offset 0x250 contains 13 entries:
+  Tag        Type                         Name/Value
+ 0x0000000000000004 \(HASH\)               0x120
+ 0x0000000000000005 \(STRTAB\)             0x1a8
+ 0x0000000000000006 \(SYMTAB\)             0x148
+ 0x000000000000000a \(STRSZ\)              14 \(bytes\)
+ 0x000000000000000b \(SYMENT\)             24 \(bytes\)
+ 0x0000000000000003 \(PLTGOT\)             0x200378
+ 0x0000000000000002 \(PLTRELSZ\)           48 \(bytes\)
+ 0x0000000000000014 \(PLTREL\)             RELA
+ 0x0000000000000017 \(JMPREL\)             0x1d0
+ 0x0000000000000007 \(RELA\)               0x1b8
+ 0x0000000000000008 \(RELASZ\)             24 \(bytes\)
+ 0x0000000000000009 \(RELAENT\)            24 \(bytes\)
+ 0x0000000000000000 \(NULL\)               0x0
+
+Relocation section '.rela.dyn' at offset 0x1b8 contains 1 entry:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200370  0000000200000006 R_X86_64_GLOB_DAT      0000000000000000 foo \+ 0
+
+Relocation section '.rela.plt' at offset 0x1d0 contains 2 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200390  0000000100000007 R_X86_64_JUMP_SLOT     0000000000000238 func \+ 0
+0+200398  0000000300000007 R_X86_64_JUMP_SLOT     0000000000000000 bar \+ 0
+No processor specific unwind information to decode
+
+Symbol table '.dynsym' contains 4 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000000238     0 FUNC    GLOBAL DEFAULT    8 func
+     2: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     3: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Symbol table '.symtab' contains 6 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000200250     0 OBJECT  LOCAL  DEFAULT    9 _DYNAMIC
+     2: 0000000000200378     0 OBJECT  LOCAL  DEFAULT   11 _GLOBAL_OFFSET_TABLE_
+     3: 0000000000000238     0 FUNC    GLOBAL DEFAULT    8 func
+     4: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     5: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Histogram for bucket list length \(total of 3 buckets\):
+ Length  Number     % of total  Coverage
+      0  1          \( 33.3%\)
+      1  1          \( 33.3%\)     33.3%
+      2  1          \( 33.3%\)    100.0%
+
+No version information found in this file.
+
+Global Offset Table '.got' contains 1 entry:
+   Index:      Address          Reloc             Sym. Name \+ Addend/Value
+       0: 0000000000200370 R_X86_64_GLOB_DAT      foo \+ 0
+
+Global Offset Table '.got.plt' contains 5 entries:
+   Index:      Address          Reloc             Sym. Name \+ Addend/Value
+       0: 0000000000200378                        200250
+       1: 0000000000200380                        0
+       2: 0000000000200388                        0
+       3: 0000000000200390 R_X86_64_JUMP_SLOT     func \+ 0
+       4: 0000000000200398 R_X86_64_JUMP_SLOT     bar \+ 0
+
+'PLT' relocation section at offset 0x1d0 contains 48 bytes:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200390  0000000100000007 R_X86_64_JUMP_SLOT     0000000000000238 func \+ 0
+0+200398  0000000300000007 R_X86_64_JUMP_SLOT     0000000000000000 bar \+ 0
+
+There are no dynamic relocations in this file.
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:     Address      GOT Idx   GOT Address    Rel Idx Symbol/Reloc
+     0: 0000000000000200      2: 0000000000200388
+     1: 0000000000000210      3: 0000000000200390      0: func
+     2: 0000000000000220      4: 0000000000200398      1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:     Address      GOT Idx   GOT Address    Symbol/Reloc
+     0: 0000000000000230     -1: 0000000000200370 
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1b-c.rd b/ld/testsuite/ld-x86-64/libplt-1b-c.rd
new file mode 100644
index 00000000000..c8831f2b4e7
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1b-c.rd
@@ -0,0 +1,11 @@ 
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:    Address   GOT Idx   GOT Addr   Rel Idx Symbol/Reloc
+     0: 000000000200      2: 000000200388
+     1: 000000000210      3: 000000200390      0: func
+     2: 000000000220      4: 000000200398      1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:    Address   GOT Idx   GOT Addr   Symbol/Reloc
+     0: 000000000230     -1: 000000200370 foo
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1b-d.rd b/ld/testsuite/ld-x86-64/libplt-1b-d.rd
new file mode 100644
index 00000000000..fe240dc0996
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1b-d.rd
@@ -0,0 +1,11 @@ 
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:     Address      GOT Idx   GOT Address    Rel Idx Symbol/Reloc
+     0: 0000000000000200      2: 0000000000200388
+     1: 0000000000000210      3: 0000000000200390      0: func
+     2: 0000000000000220      4: 0000000000200398      1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:     Address      GOT Idx   GOT Address    Symbol/Reloc
+     0: 0000000000000230     -1: 0000000000200370 foo
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1b-e.rd b/ld/testsuite/ld-x86-64/libplt-1b-e.rd
new file mode 100644
index 00000000000..e070c2c2dff
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1b-e.rd
@@ -0,0 +1,18 @@ 
+
+Symbol table for image contains 4 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000000238     0 FUNC    GLOBAL DEFAULT    8 func
+     2: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     3: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:    Address   GOT Idx   GOT Addr   Rel Idx Symbol/Reloc
+     0: 000000000200      2: 000000200388
+     1: 000000000210      3: 000000200390      0: func
+     2: 000000000220      4: 000000200398      1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:    Address   GOT Idx   GOT Addr   Symbol/Reloc
+     0: 000000000230     -1: 000000200370 foo
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1b-x32-a.rd b/ld/testsuite/ld-x86-64/libplt-1b-x32-a.rd
new file mode 100644
index 00000000000..6d84cf93ff5
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1b-x32-a.rd
@@ -0,0 +1,10 @@ 
+
+Relocation section '.rela.dyn' at offset 0x128 contains 1 entry:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+200230  00000206 R_X86_64_GLOB_DAT      00000000   foo \+ 0
+
+Relocation section '.rela.plt' at offset 0x134 contains 2 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+200250  00000107 R_X86_64_JUMP_SLOT     00000188   func \+ 0
+0+200258  00000307 R_X86_64_JUMP_SLOT     00000000   bar \+ 0
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1b-x32-b.rd b/ld/testsuite/ld-x86-64/libplt-1b-x32-b.rd
new file mode 100644
index 00000000000..17a79af4230
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1b-x32-b.rd
@@ -0,0 +1,139 @@ 
+ELF Header:
+  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
+  Class:                             ELF32
+  Data:                              2's complement, little endian
+  Version:                           1 \(current\)
+  OS/ABI:                            UNIX - System V
+  ABI Version:                       0
+  Type:                              DYN \(Shared object file\)
+  Machine:                           Advanced Micro Devices X86-64
+  Version:                           0x1
+  Entry point address:               0x0
+  Start of program headers:          52 \(bytes into file\)
+  Start of section headers:          852 \(bytes into file\)
+  Flags:                             0x0
+  Size of this header:               52 \(bytes\)
+  Size of program headers:           32 \(bytes\)
+  Number of program headers:         4
+  Size of section headers:           40 \(bytes\)
+  Number of section headers:         15
+  Section header string table index: 14
+
+Section Headers:
+  \[Nr\] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
+  \[ 0\]                   NULL            00000000 000000 000000 00      0   0  0
+  \[ 1\] .hash             HASH            000000b4 0000b4 000024 04   A  2   0  4
+  \[ 2\] .dynsym           DYNSYM          000000d8 0000d8 000040 10   A  3   1  4
+  \[ 3\] .dynstr           STRTAB          00000118 000118 00000e 00   A  0   0  1
+  \[ 4\] .rela.dyn         RELA            00000128 000128 00000c 0c   A  2   0  4
+  \[ 5\] .rela.plt         RELA            00000134 000134 000018 0c  AI  2  11  4
+  \[ 6\] .plt              PROGBITS        00000150 000150 000030 10  AX  0   0 16
+  \[ 7\] .plt.got          PROGBITS        00000180 000180 000008 08  AX  0   0  8
+  \[ 8\] .text             PROGBITS        00000188 000188 000015 00  AX  0   0  1
+  \[ 9\] .dynamic          DYNAMIC         002001a0 0001a0 000090 08  WA  3   0  4
+  \[10\] .got              PROGBITS        00200230 000230 000008 08  WA  0   0  8
+  \[11\] .got.plt          PROGBITS        00200238 000238 000028 08  WA  0   0  8
+  \[12\] .symtab           SYMTAB          00000000 000260 000060 10     13   3  4
+  \[13\] .strtab           STRTAB          00000000 0002c0 00002d 00      0   0  1
+  \[14\] .shstrtab         STRTAB          00000000 0002ed 000066 00      0   0  1
+Key to Flags:
+  W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\), I \(info\),
+  L \(link order\), O \(extra OS processing required\), G \(group\), T \(TLS\),
+  C \(compressed\), x \(unknown\), o \(OS specific\), E \(exclude\),
+  D \(mbind\), l \(large\), p \(processor specific\)
+
+There are no section groups in this file.
+
+Program Headers:
+  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
+  LOAD           0x000000 0x00000000 0x00000000 0x0019d 0x0019d R E 0x200000
+  LOAD           0x0001a0 0x002001a0 0x002001a0 0x000c0 0x000c0 RW  0x200000
+  DYNAMIC        0x0001a0 0x002001a0 0x002001a0 0x00090 0x00090 RW  0x4
+  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
+
+ Section to Segment mapping:
+  Segment Sections...
+   00     .hash .dynsym .dynstr .rela.dyn .rela.plt .plt .plt.got .text 
+   01     .dynamic .got .got.plt 
+   02     .dynamic 
+   03     
+
+Dynamic section at offset 0x1a0 contains 13 entries:
+  Tag        Type                         Name/Value
+ 0x00000004 \(HASH\)                       0xb4
+ 0x00000005 \(STRTAB\)                     0x118
+ 0x00000006 \(SYMTAB\)                     0xd8
+ 0x0000000a \(STRSZ\)                      14 \(bytes\)
+ 0x0000000b \(SYMENT\)                     16 \(bytes\)
+ 0x00000003 \(PLTGOT\)                     0x200238
+ 0x00000002 \(PLTRELSZ\)                   24 \(bytes\)
+ 0x00000014 \(PLTREL\)                     RELA
+ 0x00000017 \(JMPREL\)                     0x134
+ 0x00000007 \(RELA\)                       0x128
+ 0x00000008 \(RELASZ\)                     12 \(bytes\)
+ 0x00000009 \(RELAENT\)                    12 \(bytes\)
+ 0x00000000 \(NULL\)                       0x0
+
+Relocation section '.rela.dyn' at offset 0x128 contains 1 entry:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+200230  00000206 R_X86_64_GLOB_DAT      00000000   foo \+ 0
+
+Relocation section '.rela.plt' at offset 0x134 contains 2 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+200250  00000107 R_X86_64_JUMP_SLOT     00000188   func \+ 0
+0+200258  00000307 R_X86_64_JUMP_SLOT     00000000   bar \+ 0
+No processor specific unwind information to decode
+
+Symbol table '.dynsym' contains 4 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 00000188     0 FUNC    GLOBAL DEFAULT    8 func
+     2: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     3: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Symbol table '.symtab' contains 6 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 002001a0     0 OBJECT  LOCAL  DEFAULT    9 _DYNAMIC
+     2: 00200238     0 OBJECT  LOCAL  DEFAULT   11 _GLOBAL_OFFSET_TABLE_
+     3: 00000188     0 FUNC    GLOBAL DEFAULT    8 func
+     4: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     5: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Histogram for bucket list length \(total of 3 buckets\):
+ Length  Number     % of total  Coverage
+      0  1          \( 33.3%\)
+      1  1          \( 33.3%\)     33.3%
+      2  1          \( 33.3%\)    100.0%
+
+No version information found in this file.
+
+Global Offset Table '.got' contains 1 entry:
+   Index:  Address      Reloc             Sym. Name \+ Addend/Value
+       0: 00200230 R_X86_64_GLOB_DAT      foo \+ 0
+
+Global Offset Table '.got.plt' contains 5 entries:
+   Index:  Address      Reloc             Sym. Name \+ Addend/Value
+       0: 00200238                        2001a0
+       1: 00200240                        0
+       2: 00200248                        0
+       3: 00200250 R_X86_64_JUMP_SLOT     func \+ 0
+       4: 00200258 R_X86_64_JUMP_SLOT     bar \+ 0
+
+'PLT' relocation section at offset 0x134 contains 24 bytes:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+200250  00000107 R_X86_64_JUMP_SLOT     00000188   func \+ 0
+0+200258  00000307 R_X86_64_JUMP_SLOT     00000000   bar \+ 0
+
+There are no dynamic relocations in this file.
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000150      2: 00200248
+     1: 00000160      3: 00200250      0: func
+     2: 00000170      4: 00200258      1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000180     -1: 00200230 
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1b-x32-c.rd b/ld/testsuite/ld-x86-64/libplt-1b-x32-c.rd
new file mode 100644
index 00000000000..58eeacecf16
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1b-x32-c.rd
@@ -0,0 +1,11 @@ 
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000150      2: 00200248
+     1: 00000160      3: 00200250      0: func
+     2: 00000170      4: 00200258      1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000180     -1: 00200230 foo
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1b-x32-d.rd b/ld/testsuite/ld-x86-64/libplt-1b-x32-d.rd
new file mode 100644
index 00000000000..58eeacecf16
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1b-x32-d.rd
@@ -0,0 +1,11 @@ 
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000150      2: 00200248
+     1: 00000160      3: 00200250      0: func
+     2: 00000170      4: 00200258      1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000180     -1: 00200230 foo
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-1b-x32-e.rd b/ld/testsuite/ld-x86-64/libplt-1b-x32-e.rd
new file mode 100644
index 00000000000..084eebf703b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-1b-x32-e.rd
@@ -0,0 +1,18 @@ 
+
+Symbol table for image contains 4 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 00000188     0 FUNC    GLOBAL DEFAULT    8 func
+     2: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     3: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Procedure Linkage Table '.plt' contains 3 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 00000150      2: 00200248
+     1: 00000160      3: 00200250      0: func
+     2: 00000170      4: 00200258      1: bar
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 00000180     -1: 00200230 foo
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2a-a.rd b/ld/testsuite/ld-x86-64/libplt-2a-a.rd
new file mode 100644
index 00000000000..f8604506c0b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2a-a.rd
@@ -0,0 +1,12 @@ 
+
+Relocation section '.rela.dyn' at offset 0x1f8 contains 3 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200460  0000000400000006 R_X86_64_GLOB_DAT      0000000000000000 foo \+ 0
+0+200498  0000000100000024 R_X86_64_TLSDESC       0000000000000000 tls1 \+ 0
+0+2004a8  0000000200000024 R_X86_64_TLSDESC       0000000000000000 tls2 \+ 0
+
+Relocation section '.rela.plt' at offset 0x240 contains 2 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200488  0000000300000007 R_X86_64_JUMP_SLOT     00000000000002e0 func \+ 0
+0+200490  0000000500000007 R_X86_64_JUMP_SLOT     0000000000000000 bar \+ 0
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2a-b.rd b/ld/testsuite/ld-x86-64/libplt-2a-b.rd
new file mode 100644
index 00000000000..17fc2953b52
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2a-b.rd
@@ -0,0 +1,159 @@ 
+ELF Header:
+  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
+  Class:                             ELF64
+  Data:                              2's complement, little endian
+  Version:                           1 \(current\)
+  OS/ABI:                            UNIX - System V
+  ABI Version:                       0
+  Type:                              DYN \(Shared object file\)
+  Machine:                           Advanced Micro Devices X86-64
+  Version:                           0x1
+  Entry point address:               0x0
+  Start of program headers:          64 \(bytes into file\)
+  Start of section headers:          1568 \(bytes into file\)
+  Flags:                             0x0
+  Size of this header:               64 \(bytes\)
+  Size of program headers:           56 \(bytes\)
+  Number of program headers:         4
+  Size of section headers:           64 \(bytes\)
+  Number of section headers:         16
+  Section header string table index: 15
+
+Section Headers:
+  \[Nr\] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
+  \[ 0\]                   NULL            0000000000000000 000000 000000 00      0   0  0
+  \[ 1\] .hash             HASH            0000000000000120 000120 00002c 04   A  2   0  8
+  \[ 2\] .dynsym           DYNSYM          0000000000000150 000150 000090 18   A  3   1  8
+  \[ 3\] .dynstr           STRTAB          00000000000001e0 0001e0 000018 00   A  0   0  1
+  \[ 4\] .rela.dyn         RELA            00000000000001f8 0001f8 000048 18   A  2   0  8
+  \[ 5\] .rela.plt         RELA            0000000000000240 000240 000030 18  AI  2  12  8
+  \[ 6\] .plt              PROGBITS        0000000000000270 000270 000040 10  AX  0   0 16
+  \[ 7\] .plt.got          PROGBITS        00000000000002b0 0002b0 000010 10  AX  0   0 16
+  \[ 8\] .plt.sec          PROGBITS        00000000000002c0 0002c0 000020 10  AX  0   0 16
+  \[ 9\] .text             PROGBITS        00000000000002e0 0002e0 000039 00  AX  0   0  1
+  \[10\] .dynamic          DYNAMIC         0000000000200320 000320 000140 10  WA  3   0  8
+  \[11\] .got              PROGBITS        0000000000200460 000460 000010 08  WA  0   0  8
+  \[12\] .got.plt          PROGBITS        0000000000200470 000470 000048 08  WA  0   0  8
+  \[13\] .symtab           SYMTAB          0000000000000000 0004b8 0000c0 18     14   3  8
+  \[14\] .strtab           STRTAB          0000000000000000 000578 000037 00      0   0  1
+  \[15\] .shstrtab         STRTAB          0000000000000000 0005af 00006f 00      0   0  1
+Key to Flags:
+  W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\), I \(info\),
+  L \(link order\), O \(extra OS processing required\), G \(group\), T \(TLS\),
+  C \(compressed\), x \(unknown\), o \(OS specific\), E \(exclude\),
+  D \(mbind\), l \(large\), p \(processor specific\)
+
+There are no section groups in this file.
+
+Program Headers:
+  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
+  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x000319 0x000319 R E 0x200000
+  LOAD           0x000320 0x0000000000200320 0x0000000000200320 0x000198 0x000198 RW  0x200000
+  DYNAMIC        0x000320 0x0000000000200320 0x0000000000200320 0x000140 0x000140 RW  0x8
+  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10
+
+ Section to Segment mapping:
+  Segment Sections...
+   00     .hash .dynsym .dynstr .rela.dyn .rela.plt .plt .plt.got .plt.sec .text 
+   01     .dynamic .got .got.plt 
+   02     .dynamic 
+   03     
+
+Dynamic section at offset 0x320 contains 15 entries:
+  Tag        Type                         Name/Value
+ 0x0000000000000004 \(HASH\)               0x120
+ 0x0000000000000005 \(STRTAB\)             0x1e0
+ 0x0000000000000006 \(SYMTAB\)             0x150
+ 0x000000000000000a \(STRSZ\)              24 \(bytes\)
+ 0x000000000000000b \(SYMENT\)             24 \(bytes\)
+ 0x0000000000000003 \(PLTGOT\)             0x200470
+ 0x0000000000000002 \(PLTRELSZ\)           48 \(bytes\)
+ 0x0000000000000014 \(PLTREL\)             RELA
+ 0x0000000000000017 \(JMPREL\)             0x240
+ 0x000000006ffffef6 \(TLSDESC_PLT\)        0x2a0
+ 0x000000006ffffef7 \(TLSDESC_GOT\)        0x200468
+ 0x0000000000000007 \(RELA\)               0x1f8
+ 0x0000000000000008 \(RELASZ\)             72 \(bytes\)
+ 0x0000000000000009 \(RELAENT\)            24 \(bytes\)
+ 0x0000000000000000 \(NULL\)               0x0
+
+Relocation section '.rela.dyn' at offset 0x1f8 contains 3 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200460  0000000400000006 R_X86_64_GLOB_DAT      0000000000000000 foo \+ 0
+0+200498  0000000100000024 R_X86_64_TLSDESC       0000000000000000 tls1 \+ 0
+0+2004a8  0000000200000024 R_X86_64_TLSDESC       0000000000000000 tls2 \+ 0
+
+Relocation section '.rela.plt' at offset 0x240 contains 2 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200488  0000000300000007 R_X86_64_JUMP_SLOT     00000000000002e0 func \+ 0
+0+200490  0000000500000007 R_X86_64_JUMP_SLOT     0000000000000000 bar \+ 0
+No processor specific unwind information to decode
+
+Symbol table '.dynsym' contains 6 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000000000     0 TLS     GLOBAL DEFAULT  UND tls1
+     2: 0000000000000000     0 TLS     GLOBAL DEFAULT  UND tls2
+     3: 00000000000002e0     0 FUNC    GLOBAL DEFAULT    9 func
+     4: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     5: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Symbol table '.symtab' contains 8 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000200320     0 OBJECT  LOCAL  DEFAULT   10 _DYNAMIC
+     2: 0000000000200470     0 OBJECT  LOCAL  DEFAULT   12 _GLOBAL_OFFSET_TABLE_
+     3: 0000000000000000     0 TLS     GLOBAL DEFAULT  UND tls1
+     4: 0000000000000000     0 TLS     GLOBAL DEFAULT  UND tls2
+     5: 00000000000002e0     0 FUNC    GLOBAL DEFAULT    9 func
+     6: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     7: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Histogram for bucket list length \(total of 3 buckets\):
+ Length  Number     % of total  Coverage
+      0  0          \(  0.0%\)
+      1  1          \( 33.3%\)     20.0%
+      2  2          \( 66.7%\)    100.0%
+
+No version information found in this file.
+
+Global Offset Table '.got' contains 2 entries:
+   Index:      Address          Reloc             Sym. Name \+ Addend/Value
+       0: 0000000000200460 R_X86_64_GLOB_DAT      foo \+ 0
+       1: 0000000000200468                        0
+
+Global Offset Table '.got.plt' contains 9 entries:
+   Index:      Address          Reloc             Sym. Name \+ Addend/Value
+       0: 0000000000200470                        200320
+       1: 0000000000200478                        0
+       2: 0000000000200480                        0
+       3: 0000000000200488 R_X86_64_JUMP_SLOT     func \+ 0
+       4: 0000000000200490 R_X86_64_JUMP_SLOT     bar \+ 0
+       5: 0000000000200498 R_X86_64_TLSDESC       tls1 \+ 0
+       6: 00000000002004a0                        280
+       7: 00000000002004a8 R_X86_64_TLSDESC       tls2 \+ 0
+       8: 00000000002004b0                        290
+
+'PLT' relocation section at offset 0x240 contains 48 bytes:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200488  0000000300000007 R_X86_64_JUMP_SLOT     00000000000002e0 func \+ 0
+0+200490  0000000500000007 R_X86_64_JUMP_SLOT     0000000000000000 bar \+ 0
+
+There are no dynamic relocations in this file.
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:     Address      GOT Idx   GOT Address    Rel Idx Symbol/Reloc
+     0: 0000000000000270      2: 0000000000200480
+     1: 0000000000000280                               0: func
+     2: 0000000000000290                               1: bar
+     3: 00000000000002a0     -1: 0000000000200468
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:     Address      GOT Idx   GOT Address    Symbol/Reloc
+     0: 00000000000002b0     -2: 0000000000200460 
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:     Address      GOT Idx   GOT Address    Symbol/Reloc
+     0: 00000000000002c0      3: 0000000000200488 
+     1: 00000000000002d0      4: 0000000000200490 
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2a-c.rd b/ld/testsuite/ld-x86-64/libplt-2a-c.rd
new file mode 100644
index 00000000000..e26b741d767
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2a-c.rd
@@ -0,0 +1,17 @@ 
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:    Address   GOT Idx   GOT Addr   Rel Idx Symbol/Reloc
+     0: 000000000270      2: 000000200480
+     1: 000000000280                           0: func
+     2: 000000000290                           1: bar
+     3: 0000000002a0     -1: 000000200468
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:    Address   GOT Idx   GOT Addr   Symbol/Reloc
+     0: 0000000002b0     -2: 000000200460 foo
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:    Address   GOT Idx   GOT Addr   Symbol/Reloc
+     0: 0000000002c0      3: 000000200488 func
+     1: 0000000002d0      4: 000000200490 bar
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2a-d.rd b/ld/testsuite/ld-x86-64/libplt-2a-d.rd
new file mode 100644
index 00000000000..54fbf1bca48
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2a-d.rd
@@ -0,0 +1,17 @@ 
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:     Address      GOT Idx   GOT Address    Rel Idx Symbol/Reloc
+     0: 0000000000000270      2: 0000000000200480
+     1: 0000000000000280                               0: func
+     2: 0000000000000290                               1: bar
+     3: 00000000000002a0     -1: 0000000000200468
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:     Address      GOT Idx   GOT Address    Symbol/Reloc
+     0: 00000000000002b0     -2: 0000000000200460 foo
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:     Address      GOT Idx   GOT Address    Symbol/Reloc
+     0: 00000000000002c0      3: 0000000000200488 func
+     1: 00000000000002d0      4: 0000000000200490 bar
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2a-e.rd b/ld/testsuite/ld-x86-64/libplt-2a-e.rd
new file mode 100644
index 00000000000..c2b931ef437
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2a-e.rd
@@ -0,0 +1,26 @@ 
+
+Symbol table for image contains 6 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000000000     0 TLS     GLOBAL DEFAULT  UND tls1
+     2: 0000000000000000     0 TLS     GLOBAL DEFAULT  UND tls2
+     3: 00000000000002e0     0 FUNC    GLOBAL DEFAULT    9 func
+     4: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     5: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:    Address   GOT Idx   GOT Addr   Rel Idx Symbol/Reloc
+     0: 000000000270      2: 000000200480
+     1: 000000000280                           0: func
+     2: 000000000290                           1: bar
+     3: 0000000002a0     -1: 000000200468
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:    Address   GOT Idx   GOT Addr   Symbol/Reloc
+     0: 0000000002b0     -2: 000000200460 foo
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:    Address   GOT Idx   GOT Addr   Symbol/Reloc
+     0: 0000000002c0      3: 000000200488 func
+     1: 0000000002d0      4: 000000200490 bar
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2a-x32-a.rd b/ld/testsuite/ld-x86-64/libplt-2a-x32-a.rd
new file mode 100644
index 00000000000..1c25cd6c65c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2a-x32-a.rd
@@ -0,0 +1,12 @@ 
+
+Relocation section '.rela.dyn' at offset 0x158 contains 3 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+2002f0  00000406 R_X86_64_GLOB_DAT      00000000   foo \+ 0
+0+200328  00000124 R_X86_64_TLSDESC       00000000   tls1 \+ 0
+0+200338  00000224 R_X86_64_TLSDESC       00000000   tls2 \+ 0
+
+Relocation section '.rela.plt' at offset 0x17c contains 2 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+200318  00000307 R_X86_64_JUMP_SLOT     00000210   func \+ 0
+0+200320  00000507 R_X86_64_JUMP_SLOT     00000000   bar \+ 0
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2a-x32-b.rd b/ld/testsuite/ld-x86-64/libplt-2a-x32-b.rd
new file mode 100644
index 00000000000..46c3a0f608b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2a-x32-b.rd
@@ -0,0 +1,159 @@ 
+ELF Header:
+  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
+  Class:                             ELF32
+  Data:                              2's complement, little endian
+  Version:                           1 \(current\)
+  OS/ABI:                            UNIX - System V
+  ABI Version:                       0
+  Type:                              DYN \(Shared object file\)
+  Machine:                           Advanced Micro Devices X86-64
+  Version:                           0x1
+  Entry point address:               0x0
+  Start of program headers:          52 \(bytes into file\)
+  Start of section headers:          1136 \(bytes into file\)
+  Flags:                             0x0
+  Size of this header:               52 \(bytes\)
+  Size of program headers:           32 \(bytes\)
+  Number of program headers:         4
+  Size of section headers:           40 \(bytes\)
+  Number of section headers:         16
+  Section header string table index: 15
+
+Section Headers:
+  \[Nr\] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
+  \[ 0\]                   NULL            00000000 000000 000000 00      0   0  0
+  \[ 1\] .hash             HASH            000000b4 0000b4 00002c 04   A  2   0  4
+  \[ 2\] .dynsym           DYNSYM          000000e0 0000e0 000060 10   A  3   1  4
+  \[ 3\] .dynstr           STRTAB          00000140 000140 000018 00   A  0   0  1
+  \[ 4\] .rela.dyn         RELA            00000158 000158 000024 0c   A  2   0  4
+  \[ 5\] .rela.plt         RELA            0000017c 00017c 000018 0c  AI  2  12  4
+  \[ 6\] .plt              PROGBITS        000001a0 0001a0 000040 10  AX  0   0 16
+  \[ 7\] .plt.got          PROGBITS        000001e0 0001e0 000010 10  AX  0   0 16
+  \[ 8\] .plt.sec          PROGBITS        000001f0 0001f0 000020 10  AX  0   0 16
+  \[ 9\] .text             PROGBITS        00000210 000210 000039 00  AX  0   0  1
+  \[10\] .dynamic          DYNAMIC         0020024c 00024c 0000a0 08  WA  3   0  4
+  \[11\] .got              PROGBITS        002002f0 0002f0 000010 08  WA  0   0  8
+  \[12\] .got.plt          PROGBITS        00200300 000300 000048 08  WA  0   0  8
+  \[13\] .symtab           SYMTAB          00000000 000348 000080 10     14   3  4
+  \[14\] .strtab           STRTAB          00000000 0003c8 000037 00      0   0  1
+  \[15\] .shstrtab         STRTAB          00000000 0003ff 00006f 00      0   0  1
+Key to Flags:
+  W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\), I \(info\),
+  L \(link order\), O \(extra OS processing required\), G \(group\), T \(TLS\),
+  C \(compressed\), x \(unknown\), o \(OS specific\), E \(exclude\),
+  D \(mbind\), l \(large\), p \(processor specific\)
+
+There are no section groups in this file.
+
+Program Headers:
+  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
+  LOAD           0x000000 0x00000000 0x00000000 0x00249 0x00249 R E 0x200000
+  LOAD           0x00024c 0x0020024c 0x0020024c 0x000fc 0x000fc RW  0x200000
+  DYNAMIC        0x00024c 0x0020024c 0x0020024c 0x000a0 0x000a0 RW  0x4
+  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
+
+ Section to Segment mapping:
+  Segment Sections...
+   00     .hash .dynsym .dynstr .rela.dyn .rela.plt .plt .plt.got .plt.sec .text 
+   01     .dynamic .got .got.plt 
+   02     .dynamic 
+   03     
+
+Dynamic section at offset 0x24c contains 15 entries:
+  Tag        Type                         Name/Value
+ 0x00000004 \(HASH\)                       0xb4
+ 0x00000005 \(STRTAB\)                     0x140
+ 0x00000006 \(SYMTAB\)                     0xe0
+ 0x0000000a \(STRSZ\)                      24 \(bytes\)
+ 0x0000000b \(SYMENT\)                     16 \(bytes\)
+ 0x00000003 \(PLTGOT\)                     0x200300
+ 0x00000002 \(PLTRELSZ\)                   24 \(bytes\)
+ 0x00000014 \(PLTREL\)                     RELA
+ 0x00000017 \(JMPREL\)                     0x17c
+ 0x6ffffef6 \(TLSDESC_PLT\)                0x1d0
+ 0x6ffffef7 \(TLSDESC_GOT\)                0x2002f8
+ 0x00000007 \(RELA\)                       0x158
+ 0x00000008 \(RELASZ\)                     36 \(bytes\)
+ 0x00000009 \(RELAENT\)                    12 \(bytes\)
+ 0x00000000 \(NULL\)                       0x0
+
+Relocation section '.rela.dyn' at offset 0x158 contains 3 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+2002f0  00000406 R_X86_64_GLOB_DAT      00000000   foo \+ 0
+0+200328  00000124 R_X86_64_TLSDESC       00000000   tls1 \+ 0
+0+200338  00000224 R_X86_64_TLSDESC       00000000   tls2 \+ 0
+
+Relocation section '.rela.plt' at offset 0x17c contains 2 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+200318  00000307 R_X86_64_JUMP_SLOT     00000210   func \+ 0
+0+200320  00000507 R_X86_64_JUMP_SLOT     00000000   bar \+ 0
+No processor specific unwind information to decode
+
+Symbol table '.dynsym' contains 6 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 00000000     0 TLS     GLOBAL DEFAULT  UND tls1
+     2: 00000000     0 TLS     GLOBAL DEFAULT  UND tls2
+     3: 00000210     0 FUNC    GLOBAL DEFAULT    9 func
+     4: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     5: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Symbol table '.symtab' contains 8 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0020024c     0 OBJECT  LOCAL  DEFAULT   10 _DYNAMIC
+     2: 00200300     0 OBJECT  LOCAL  DEFAULT   12 _GLOBAL_OFFSET_TABLE_
+     3: 00000000     0 TLS     GLOBAL DEFAULT  UND tls1
+     4: 00000000     0 TLS     GLOBAL DEFAULT  UND tls2
+     5: 00000210     0 FUNC    GLOBAL DEFAULT    9 func
+     6: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     7: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Histogram for bucket list length \(total of 3 buckets\):
+ Length  Number     % of total  Coverage
+      0  0          \(  0.0%\)
+      1  1          \( 33.3%\)     20.0%
+      2  2          \( 66.7%\)    100.0%
+
+No version information found in this file.
+
+Global Offset Table '.got' contains 2 entries:
+   Index:  Address      Reloc             Sym. Name \+ Addend/Value
+       0: 002002f0 R_X86_64_GLOB_DAT      foo \+ 0
+       1: 002002f8                        0
+
+Global Offset Table '.got.plt' contains 9 entries:
+   Index:  Address      Reloc             Sym. Name \+ Addend/Value
+       0: 00200300                        20024c
+       1: 00200308                        0
+       2: 00200310                        0
+       3: 00200318 R_X86_64_JUMP_SLOT     func \+ 0
+       4: 00200320 R_X86_64_JUMP_SLOT     bar \+ 0
+       5: 00200328 R_X86_64_TLSDESC       tls1 \+ 0
+       6: 00200330                        1b0
+       7: 00200338 R_X86_64_TLSDESC       tls2 \+ 0
+       8: 00200340                        1c0
+
+'PLT' relocation section at offset 0x17c contains 24 bytes:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+200318  00000307 R_X86_64_JUMP_SLOT     00000210   func \+ 0
+0+200320  00000507 R_X86_64_JUMP_SLOT     00000000   bar \+ 0
+
+There are no dynamic relocations in this file.
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 000001a0      2: 00200310
+     1: 000001b0                       0: func
+     2: 000001c0                       1: bar
+     3: 000001d0     -1: 002002f8
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 000001e0     -2: 002002f0 
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 000001f0      3: 00200318 
+     1: 00000200      4: 00200320 
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2a-x32-c.rd b/ld/testsuite/ld-x86-64/libplt-2a-x32-c.rd
new file mode 100644
index 00000000000..331ba4162f0
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2a-x32-c.rd
@@ -0,0 +1,17 @@ 
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 000001a0      2: 00200310
+     1: 000001b0                       0: func
+     2: 000001c0                       1: bar
+     3: 000001d0     -1: 002002f8
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 000001e0     -2: 002002f0 foo
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 000001f0      3: 00200318 func
+     1: 00000200      4: 00200320 bar
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2a-x32-d.rd b/ld/testsuite/ld-x86-64/libplt-2a-x32-d.rd
new file mode 100644
index 00000000000..331ba4162f0
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2a-x32-d.rd
@@ -0,0 +1,17 @@ 
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 000001a0      2: 00200310
+     1: 000001b0                       0: func
+     2: 000001c0                       1: bar
+     3: 000001d0     -1: 002002f8
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 000001e0     -2: 002002f0 foo
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 000001f0      3: 00200318 func
+     1: 00000200      4: 00200320 bar
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2a-x32-e.rd b/ld/testsuite/ld-x86-64/libplt-2a-x32-e.rd
new file mode 100644
index 00000000000..f7c3026087f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2a-x32-e.rd
@@ -0,0 +1,26 @@ 
+
+Symbol table for image contains 6 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 00000000     0 TLS     GLOBAL DEFAULT  UND tls1
+     2: 00000000     0 TLS     GLOBAL DEFAULT  UND tls2
+     3: 00000210     0 FUNC    GLOBAL DEFAULT    9 func
+     4: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     5: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 000001a0      2: 00200310
+     1: 000001b0                       0: func
+     2: 000001c0                       1: bar
+     3: 000001d0     -1: 002002f8
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 000001e0     -2: 002002f0 foo
+
+Procedure Linkage Table '.plt.sec' contains 2 entries:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 000001f0      3: 00200318 func
+     1: 00000200      4: 00200320 bar
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2b-a.rd b/ld/testsuite/ld-x86-64/libplt-2b-a.rd
new file mode 100644
index 00000000000..09d8ad30760
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2b-a.rd
@@ -0,0 +1,12 @@ 
+
+Relocation section '.rela.dyn' at offset 0x1f8 contains 3 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200438  0000000400000006 R_X86_64_GLOB_DAT      0000000000000000 foo \+ 0
+0+200470  0000000100000024 R_X86_64_TLSDESC       0000000000000000 tls1 \+ 0
+0+200480  0000000200000024 R_X86_64_TLSDESC       0000000000000000 tls2 \+ 0
+
+Relocation section '.rela.plt' at offset 0x240 contains 2 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200460  0000000300000007 R_X86_64_JUMP_SLOT     00000000000002b8 func \+ 0
+0+200468  0000000500000007 R_X86_64_JUMP_SLOT     0000000000000000 bar \+ 0
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2b-b.rd b/ld/testsuite/ld-x86-64/libplt-2b-b.rd
new file mode 100644
index 00000000000..dc83dcefee6
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2b-b.rd
@@ -0,0 +1,153 @@ 
+ELF Header:
+  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
+  Class:                             ELF64
+  Data:                              2's complement, little endian
+  Version:                           1 \(current\)
+  OS/ABI:                            UNIX - System V
+  ABI Version:                       0
+  Type:                              DYN \(Shared object file\)
+  Machine:                           Advanced Micro Devices X86-64
+  Version:                           0x1
+  Entry point address:               0x0
+  Start of program headers:          64 \(bytes into file\)
+  Start of section headers:          1520 \(bytes into file\)
+  Flags:                             0x0
+  Size of this header:               64 \(bytes\)
+  Size of program headers:           56 \(bytes\)
+  Number of program headers:         4
+  Size of section headers:           64 \(bytes\)
+  Number of section headers:         15
+  Section header string table index: 14
+
+Section Headers:
+  \[Nr\] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
+  \[ 0\]                   NULL            0000000000000000 000000 000000 00      0   0  0
+  \[ 1\] .hash             HASH            0000000000000120 000120 00002c 04   A  2   0  8
+  \[ 2\] .dynsym           DYNSYM          0000000000000150 000150 000090 18   A  3   1  8
+  \[ 3\] .dynstr           STRTAB          00000000000001e0 0001e0 000018 00   A  0   0  1
+  \[ 4\] .rela.dyn         RELA            00000000000001f8 0001f8 000048 18   A  2   0  8
+  \[ 5\] .rela.plt         RELA            0000000000000240 000240 000030 18  AI  2  11  8
+  \[ 6\] .plt              PROGBITS        0000000000000270 000270 000040 10  AX  0   0 16
+  \[ 7\] .plt.got          PROGBITS        00000000000002b0 0002b0 000008 08  AX  0   0  8
+  \[ 8\] .text             PROGBITS        00000000000002b8 0002b8 000039 00  AX  0   0  1
+  \[ 9\] .dynamic          DYNAMIC         00000000002002f8 0002f8 000140 10  WA  3   0  8
+  \[10\] .got              PROGBITS        0000000000200438 000438 000010 08  WA  0   0  8
+  \[11\] .got.plt          PROGBITS        0000000000200448 000448 000048 08  WA  0   0  8
+  \[12\] .symtab           SYMTAB          0000000000000000 000490 0000c0 18     13   3  8
+  \[13\] .strtab           STRTAB          0000000000000000 000550 000037 00      0   0  1
+  \[14\] .shstrtab         STRTAB          0000000000000000 000587 000066 00      0   0  1
+Key to Flags:
+  W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\), I \(info\),
+  L \(link order\), O \(extra OS processing required\), G \(group\), T \(TLS\),
+  C \(compressed\), x \(unknown\), o \(OS specific\), E \(exclude\),
+  D \(mbind\), l \(large\), p \(processor specific\)
+
+There are no section groups in this file.
+
+Program Headers:
+  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
+  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x0002f1 0x0002f1 R E 0x200000
+  LOAD           0x0002f8 0x00000000002002f8 0x00000000002002f8 0x000198 0x000198 RW  0x200000
+  DYNAMIC        0x0002f8 0x00000000002002f8 0x00000000002002f8 0x000140 0x000140 RW  0x8
+  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10
+
+ Section to Segment mapping:
+  Segment Sections...
+   00     .hash .dynsym .dynstr .rela.dyn .rela.plt .plt .plt.got .text 
+   01     .dynamic .got .got.plt 
+   02     .dynamic 
+   03     
+
+Dynamic section at offset 0x2f8 contains 15 entries:
+  Tag        Type                         Name/Value
+ 0x0000000000000004 \(HASH\)               0x120
+ 0x0000000000000005 \(STRTAB\)             0x1e0
+ 0x0000000000000006 \(SYMTAB\)             0x150
+ 0x000000000000000a \(STRSZ\)              24 \(bytes\)
+ 0x000000000000000b \(SYMENT\)             24 \(bytes\)
+ 0x0000000000000003 \(PLTGOT\)             0x200448
+ 0x0000000000000002 \(PLTRELSZ\)           48 \(bytes\)
+ 0x0000000000000014 \(PLTREL\)             RELA
+ 0x0000000000000017 \(JMPREL\)             0x240
+ 0x000000006ffffef6 \(TLSDESC_PLT\)        0x2a0
+ 0x000000006ffffef7 \(TLSDESC_GOT\)        0x200440
+ 0x0000000000000007 \(RELA\)               0x1f8
+ 0x0000000000000008 \(RELASZ\)             72 \(bytes\)
+ 0x0000000000000009 \(RELAENT\)            24 \(bytes\)
+ 0x0000000000000000 \(NULL\)               0x0
+
+Relocation section '.rela.dyn' at offset 0x1f8 contains 3 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200438  0000000400000006 R_X86_64_GLOB_DAT      0000000000000000 foo \+ 0
+0+200470  0000000100000024 R_X86_64_TLSDESC       0000000000000000 tls1 \+ 0
+0+200480  0000000200000024 R_X86_64_TLSDESC       0000000000000000 tls2 \+ 0
+
+Relocation section '.rela.plt' at offset 0x240 contains 2 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200460  0000000300000007 R_X86_64_JUMP_SLOT     00000000000002b8 func \+ 0
+0+200468  0000000500000007 R_X86_64_JUMP_SLOT     0000000000000000 bar \+ 0
+No processor specific unwind information to decode
+
+Symbol table '.dynsym' contains 6 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000000000     0 TLS     GLOBAL DEFAULT  UND tls1
+     2: 0000000000000000     0 TLS     GLOBAL DEFAULT  UND tls2
+     3: 00000000000002b8     0 FUNC    GLOBAL DEFAULT    8 func
+     4: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     5: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Symbol table '.symtab' contains 8 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 00000000002002f8     0 OBJECT  LOCAL  DEFAULT    9 _DYNAMIC
+     2: 0000000000200448     0 OBJECT  LOCAL  DEFAULT   11 _GLOBAL_OFFSET_TABLE_
+     3: 0000000000000000     0 TLS     GLOBAL DEFAULT  UND tls1
+     4: 0000000000000000     0 TLS     GLOBAL DEFAULT  UND tls2
+     5: 00000000000002b8     0 FUNC    GLOBAL DEFAULT    8 func
+     6: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     7: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Histogram for bucket list length \(total of 3 buckets\):
+ Length  Number     % of total  Coverage
+      0  0          \(  0.0%\)
+      1  1          \( 33.3%\)     20.0%
+      2  2          \( 66.7%\)    100.0%
+
+No version information found in this file.
+
+Global Offset Table '.got' contains 2 entries:
+   Index:      Address          Reloc             Sym. Name \+ Addend/Value
+       0: 0000000000200438 R_X86_64_GLOB_DAT      foo \+ 0
+       1: 0000000000200440                        0
+
+Global Offset Table '.got.plt' contains 9 entries:
+   Index:      Address          Reloc             Sym. Name \+ Addend/Value
+       0: 0000000000200448                        2002f8
+       1: 0000000000200450                        0
+       2: 0000000000200458                        0
+       3: 0000000000200460 R_X86_64_JUMP_SLOT     func \+ 0
+       4: 0000000000200468 R_X86_64_JUMP_SLOT     bar \+ 0
+       5: 0000000000200470 R_X86_64_TLSDESC       tls1 \+ 0
+       6: 0000000000200478                        286
+       7: 0000000000200480 R_X86_64_TLSDESC       tls2 \+ 0
+       8: 0000000000200488                        296
+
+'PLT' relocation section at offset 0x240 contains 48 bytes:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0+200460  0000000300000007 R_X86_64_JUMP_SLOT     00000000000002b8 func \+ 0
+0+200468  0000000500000007 R_X86_64_JUMP_SLOT     0000000000000000 bar \+ 0
+
+There are no dynamic relocations in this file.
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:     Address      GOT Idx   GOT Address    Rel Idx Symbol/Reloc
+     0: 0000000000000270      2: 0000000000200458
+     1: 0000000000000280      3: 0000000000200460      0: func
+     2: 0000000000000290      4: 0000000000200468      1: bar
+     3: 00000000000002a0     -1: 0000000000200440
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:     Address      GOT Idx   GOT Address    Symbol/Reloc
+     0: 00000000000002b0     -2: 0000000000200438 
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2b-c.rd b/ld/testsuite/ld-x86-64/libplt-2b-c.rd
new file mode 100644
index 00000000000..8362a36203b
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2b-c.rd
@@ -0,0 +1,12 @@ 
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:    Address   GOT Idx   GOT Addr   Rel Idx Symbol/Reloc
+     0: 000000000270      2: 000000200458
+     1: 000000000280      3: 000000200460      0: func
+     2: 000000000290      4: 000000200468      1: bar
+     3: 0000000002a0     -1: 000000200440
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:    Address   GOT Idx   GOT Addr   Symbol/Reloc
+     0: 0000000002b0     -2: 000000200438 foo
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2b-d.rd b/ld/testsuite/ld-x86-64/libplt-2b-d.rd
new file mode 100644
index 00000000000..9495e894903
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2b-d.rd
@@ -0,0 +1,12 @@ 
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:     Address      GOT Idx   GOT Address    Rel Idx Symbol/Reloc
+     0: 0000000000000270      2: 0000000000200458
+     1: 0000000000000280      3: 0000000000200460      0: func
+     2: 0000000000000290      4: 0000000000200468      1: bar
+     3: 00000000000002a0     -1: 0000000000200440
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:     Address      GOT Idx   GOT Address    Symbol/Reloc
+     0: 00000000000002b0     -2: 0000000000200438 foo
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2b-e.rd b/ld/testsuite/ld-x86-64/libplt-2b-e.rd
new file mode 100644
index 00000000000..29a7e93a615
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2b-e.rd
@@ -0,0 +1,21 @@ 
+
+Symbol table for image contains 6 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000000000     0 TLS     GLOBAL DEFAULT  UND tls1
+     2: 0000000000000000     0 TLS     GLOBAL DEFAULT  UND tls2
+     3: 00000000000002b8     0 FUNC    GLOBAL DEFAULT    8 func
+     4: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     5: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:    Address   GOT Idx   GOT Addr   Rel Idx Symbol/Reloc
+     0: 000000000270      2: 000000200458
+     1: 000000000280      3: 000000200460      0: func
+     2: 000000000290      4: 000000200468      1: bar
+     3: 0000000002a0     -1: 000000200440
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:    Address   GOT Idx   GOT Addr   Symbol/Reloc
+     0: 0000000002b0     -2: 000000200438 foo
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2b-x32-a.rd b/ld/testsuite/ld-x86-64/libplt-2b-x32-a.rd
new file mode 100644
index 00000000000..f9657bd0982
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2b-x32-a.rd
@@ -0,0 +1,12 @@ 
+
+Relocation section '.rela.dyn' at offset 0x158 contains 3 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+2002c8  00000406 R_X86_64_GLOB_DAT      00000000   foo \+ 0
+0+200300  00000124 R_X86_64_TLSDESC       00000000   tls1 \+ 0
+0+200310  00000224 R_X86_64_TLSDESC       00000000   tls2 \+ 0
+
+Relocation section '.rela.plt' at offset 0x17c contains 2 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+2002f0  00000307 R_X86_64_JUMP_SLOT     000001e8   func \+ 0
+0+2002f8  00000507 R_X86_64_JUMP_SLOT     00000000   bar \+ 0
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2b-x32-b.rd b/ld/testsuite/ld-x86-64/libplt-2b-x32-b.rd
new file mode 100644
index 00000000000..edffd0246bf
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2b-x32-b.rd
@@ -0,0 +1,153 @@ 
+ELF Header:
+  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
+  Class:                             ELF32
+  Data:                              2's complement, little endian
+  Version:                           1 \(current\)
+  OS/ABI:                            UNIX - System V
+  ABI Version:                       0
+  Type:                              DYN \(Shared object file\)
+  Machine:                           Advanced Micro Devices X86-64
+  Version:                           0x1
+  Entry point address:               0x0
+  Start of program headers:          52 \(bytes into file\)
+  Start of section headers:          1088 \(bytes into file\)
+  Flags:                             0x0
+  Size of this header:               52 \(bytes\)
+  Size of program headers:           32 \(bytes\)
+  Number of program headers:         4
+  Size of section headers:           40 \(bytes\)
+  Number of section headers:         15
+  Section header string table index: 14
+
+Section Headers:
+  \[Nr\] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
+  \[ 0\]                   NULL            00000000 000000 000000 00      0   0  0
+  \[ 1\] .hash             HASH            000000b4 0000b4 00002c 04   A  2   0  4
+  \[ 2\] .dynsym           DYNSYM          000000e0 0000e0 000060 10   A  3   1  4
+  \[ 3\] .dynstr           STRTAB          00000140 000140 000018 00   A  0   0  1
+  \[ 4\] .rela.dyn         RELA            00000158 000158 000024 0c   A  2   0  4
+  \[ 5\] .rela.plt         RELA            0000017c 00017c 000018 0c  AI  2  11  4
+  \[ 6\] .plt              PROGBITS        000001a0 0001a0 000040 10  AX  0   0 16
+  \[ 7\] .plt.got          PROGBITS        000001e0 0001e0 000008 08  AX  0   0  8
+  \[ 8\] .text             PROGBITS        000001e8 0001e8 000039 00  AX  0   0  1
+  \[ 9\] .dynamic          DYNAMIC         00200224 000224 0000a0 08  WA  3   0  4
+  \[10\] .got              PROGBITS        002002c8 0002c8 000010 08  WA  0   0  8
+  \[11\] .got.plt          PROGBITS        002002d8 0002d8 000048 08  WA  0   0  8
+  \[12\] .symtab           SYMTAB          00000000 000320 000080 10     13   3  4
+  \[13\] .strtab           STRTAB          00000000 0003a0 000037 00      0   0  1
+  \[14\] .shstrtab         STRTAB          00000000 0003d7 000066 00      0   0  1
+Key to Flags:
+  W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\), I \(info\),
+  L \(link order\), O \(extra OS processing required\), G \(group\), T \(TLS\),
+  C \(compressed\), x \(unknown\), o \(OS specific\), E \(exclude\),
+  D \(mbind\), l \(large\), p \(processor specific\)
+
+There are no section groups in this file.
+
+Program Headers:
+  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
+  LOAD           0x000000 0x00000000 0x00000000 0x00221 0x00221 R E 0x200000
+  LOAD           0x000224 0x00200224 0x00200224 0x000fc 0x000fc RW  0x200000
+  DYNAMIC        0x000224 0x00200224 0x00200224 0x000a0 0x000a0 RW  0x4
+  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
+
+ Section to Segment mapping:
+  Segment Sections...
+   00     .hash .dynsym .dynstr .rela.dyn .rela.plt .plt .plt.got .text 
+   01     .dynamic .got .got.plt 
+   02     .dynamic 
+   03     
+
+Dynamic section at offset 0x224 contains 15 entries:
+  Tag        Type                         Name/Value
+ 0x00000004 \(HASH\)                       0xb4
+ 0x00000005 \(STRTAB\)                     0x140
+ 0x00000006 \(SYMTAB\)                     0xe0
+ 0x0000000a \(STRSZ\)                      24 \(bytes\)
+ 0x0000000b \(SYMENT\)                     16 \(bytes\)
+ 0x00000003 \(PLTGOT\)                     0x2002d8
+ 0x00000002 \(PLTRELSZ\)                   24 \(bytes\)
+ 0x00000014 \(PLTREL\)                     RELA
+ 0x00000017 \(JMPREL\)                     0x17c
+ 0x6ffffef6 \(TLSDESC_PLT\)                0x1d0
+ 0x6ffffef7 \(TLSDESC_GOT\)                0x2002d0
+ 0x00000007 \(RELA\)                       0x158
+ 0x00000008 \(RELASZ\)                     36 \(bytes\)
+ 0x00000009 \(RELAENT\)                    12 \(bytes\)
+ 0x00000000 \(NULL\)                       0x0
+
+Relocation section '.rela.dyn' at offset 0x158 contains 3 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+2002c8  00000406 R_X86_64_GLOB_DAT      00000000   foo \+ 0
+0+200300  00000124 R_X86_64_TLSDESC       00000000   tls1 \+ 0
+0+200310  00000224 R_X86_64_TLSDESC       00000000   tls2 \+ 0
+
+Relocation section '.rela.plt' at offset 0x17c contains 2 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+2002f0  00000307 R_X86_64_JUMP_SLOT     000001e8   func \+ 0
+0+2002f8  00000507 R_X86_64_JUMP_SLOT     00000000   bar \+ 0
+No processor specific unwind information to decode
+
+Symbol table '.dynsym' contains 6 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 00000000     0 TLS     GLOBAL DEFAULT  UND tls1
+     2: 00000000     0 TLS     GLOBAL DEFAULT  UND tls2
+     3: 000001e8     0 FUNC    GLOBAL DEFAULT    8 func
+     4: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     5: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Symbol table '.symtab' contains 8 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 00200224     0 OBJECT  LOCAL  DEFAULT    9 _DYNAMIC
+     2: 002002d8     0 OBJECT  LOCAL  DEFAULT   11 _GLOBAL_OFFSET_TABLE_
+     3: 00000000     0 TLS     GLOBAL DEFAULT  UND tls1
+     4: 00000000     0 TLS     GLOBAL DEFAULT  UND tls2
+     5: 000001e8     0 FUNC    GLOBAL DEFAULT    8 func
+     6: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     7: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Histogram for bucket list length \(total of 3 buckets\):
+ Length  Number     % of total  Coverage
+      0  0          \(  0.0%\)
+      1  1          \( 33.3%\)     20.0%
+      2  2          \( 66.7%\)    100.0%
+
+No version information found in this file.
+
+Global Offset Table '.got' contains 2 entries:
+   Index:  Address      Reloc             Sym. Name \+ Addend/Value
+       0: 002002c8 R_X86_64_GLOB_DAT      foo \+ 0
+       1: 002002d0                        0
+
+Global Offset Table '.got.plt' contains 9 entries:
+   Index:  Address      Reloc             Sym. Name \+ Addend/Value
+       0: 002002d8                        200224
+       1: 002002e0                        0
+       2: 002002e8                        0
+       3: 002002f0 R_X86_64_JUMP_SLOT     func \+ 0
+       4: 002002f8 R_X86_64_JUMP_SLOT     bar \+ 0
+       5: 00200300 R_X86_64_TLSDESC       tls1 \+ 0
+       6: 00200308                        1b6
+       7: 00200310 R_X86_64_TLSDESC       tls2 \+ 0
+       8: 00200318                        1c6
+
+'PLT' relocation section at offset 0x17c contains 24 bytes:
+ Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
+0+2002f0  00000307 R_X86_64_JUMP_SLOT     000001e8   func \+ 0
+0+2002f8  00000507 R_X86_64_JUMP_SLOT     00000000   bar \+ 0
+
+There are no dynamic relocations in this file.
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 000001a0      2: 002002e8
+     1: 000001b0      3: 002002f0      0: func
+     2: 000001c0      4: 002002f8      1: bar
+     3: 000001d0     -1: 002002d0
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 000001e0     -2: 002002c8 
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2b-x32-c.rd b/ld/testsuite/ld-x86-64/libplt-2b-x32-c.rd
new file mode 100644
index 00000000000..19bc86b86a4
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2b-x32-c.rd
@@ -0,0 +1,12 @@ 
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 000001a0      2: 002002e8
+     1: 000001b0      3: 002002f0      0: func
+     2: 000001c0      4: 002002f8      1: bar
+     3: 000001d0     -1: 002002d0
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 000001e0     -2: 002002c8 foo
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2b-x32-d.rd b/ld/testsuite/ld-x86-64/libplt-2b-x32-d.rd
new file mode 100644
index 00000000000..19bc86b86a4
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2b-x32-d.rd
@@ -0,0 +1,12 @@ 
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 000001a0      2: 002002e8
+     1: 000001b0      3: 002002f0      0: func
+     2: 000001c0      4: 002002f8      1: bar
+     3: 000001d0     -1: 002002d0
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 000001e0     -2: 002002c8 foo
+#pass
diff --git a/ld/testsuite/ld-x86-64/libplt-2b-x32-e.rd b/ld/testsuite/ld-x86-64/libplt-2b-x32-e.rd
new file mode 100644
index 00000000000..ac33b907d1c
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/libplt-2b-x32-e.rd
@@ -0,0 +1,21 @@ 
+
+Symbol table for image contains 6 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 00000000     0 TLS     GLOBAL DEFAULT  UND tls1
+     2: 00000000     0 TLS     GLOBAL DEFAULT  UND tls2
+     3: 000001e8     0 FUNC    GLOBAL DEFAULT    8 func
+     4: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND foo
+     5: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar
+
+Procedure Linkage Table '.plt' contains 4 entries:
+ Index:  Address GOT Idx GOT Addr Rel Idx Symbol/Reloc
+     0: 000001a0      2: 002002e8
+     1: 000001b0      3: 002002f0      0: func
+     2: 000001c0      4: 002002f8      1: bar
+     3: 000001d0     -1: 002002d0
+
+Procedure Linkage Table '.plt.got' contains 1 entry:
+ Index:  Address GOT Idx GOT Addr Symbol/Reloc
+     0: 000001e0     -2: 002002c8 foo
+#pass
diff --git a/ld/testsuite/ld-x86-64/plt-1.s b/ld/testsuite/ld-x86-64/plt-1.s
new file mode 100644
index 00000000000..a0f6ab7aef0
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/plt-1.s
@@ -0,0 +1,9 @@ 
+	.text
+	.globl	func
+	.type	func, @function
+func:
+	call	func@PLT
+	call	foo@PLT
+	call	*foo@GOTPCREL(%rip)
+	jmp	bar@PLT
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/plt-2.s b/ld/testsuite/ld-x86-64/plt-2.s
new file mode 100644
index 00000000000..774e13e1f68
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/plt-2.s
@@ -0,0 +1,15 @@ 
+	.text
+	.globl	func
+	.type	func, @function
+func:
+	call	func@PLT
+	call	foo@PLT
+	call	*foo@GOTPCREL(%rip)
+	leaq	tls1@TLSDESC(%rip), %rax
+	call	*tls1@TLSCALL(%rax)
+	addq	%fs:0, %rax
+	leaq	tls2@TLSDESC(%rip), %rax
+	call	*tls2@TLSCALL(%rax)
+	addq	%fs:0, %rax
+	jmp	bar@PLT
+	.section	.note.GNU-stack,"",@progbits