public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
@ 2021-02-23 12:15 H.J. Lu
  2021-02-23 13:15 ` Jan Beulich
  0 siblings, 1 reply; 22+ messages in thread
From: H.J. Lu @ 2021-02-23 12:15 UTC (permalink / raw)
  To: binutils

When linking PE/x86-64 inputs to generate ELF executable, we need to
subtract __ImageBase, aka __executable_start, for R_AMD64_IMAGEBASE
relocation.

1. Create an indirect reference to __executable_start for __ImageBase to
support R_AMD64_IMAGEBASE relocation when seeing PE/x86-64 inputs.
2. Pass link_info to bfd_perform_relocation to lookup __ImageBase.
3. Subtract __ImageBase for R_AMD64_IMAGEBASE.

bfd/

	PR ld/27425
	PR ld/27432
	* coff-alpha.c (alpha_ecoff_get_relocated_section_contents): Pass
	link_info to bfd_perform_relocation.
	* elf32-nds32.c (nds32_elf_get_relocated_section_contents):
	Likewise.
	* elfxx-mips.c (_bfd_elf_mips_get_relocated_section_contents):
	Likewise.
	* elf32-mips.c (mips32_64bit_reloc): Pass NULL as link_info to
	bfd_perform_relocation.
	* reloc.c (bfd_perform_relocation): Add a link_info argument.
	Subtract __ImageBase for R_AMD64_IMAGEBASE.
	(bfd_generic_get_relocated_section_contents): Pass link_info to
	bfd_perform_relocation.
	* bfd-in2.h: Regenerated.

ld/

	PR ld/27425
	PR ld/27432
	* ldelf.c (ldelf_load_symbols): Create an indirect reference to
	__executable_start for __ImageBase to support R_AMD64_IMAGEBASE
	relocation when seeing PE/x86-64 inputs.
	* ld-x86-64/pe-x86-64-1.od: Expect __executable_start.
	* testsuite/ld-x86-64/pe-x86-64-2.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-3.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-4.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-5.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-5.rd: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-6.obj.bz2: New file.
	* testsuite/ld-x86-64/pe-x86-64-6.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64.exp: Run ld/27425 test.
---
 bfd/bfd-in2.h                              |   1 +
 bfd/coff-alpha.c                           |  12 +--
 bfd/elf32-mips.c                           |   2 +-
 bfd/elf32-nds32.c                          |   4 +-
 bfd/elfxx-mips.c                           |   1 +
 bfd/reloc.c                                |  40 +++++++--
 ld/ldelf.c                                 |  24 ++++++
 ld/testsuite/ld-x86-64/pe-x86-64-1.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-2.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-3.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-4.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-5.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-5.rd      |   3 +-
 ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2 | Bin 0 -> 1366 bytes
 ld/testsuite/ld-x86-64/pe-x86-64-6.od      |  91 +++++++++++++++++++++
 ld/testsuite/ld-x86-64/pe-x86-64.exp       |   9 ++
 16 files changed, 173 insertions(+), 19 deletions(-)
 create mode 100644 ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2
 create mode 100644 ld/testsuite/ld-x86-64/pe-x86-64-6.od

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index d142bb52213..44d67b44bc4 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2222,6 +2222,7 @@ bfd_boolean bfd_reloc_offset_in_range
 
 bfd_reloc_status_type bfd_perform_relocation
    (bfd *abfd,
+    struct bfd_link_info *link_info,
     arelent *reloc_entry,
     void *data,
     asection *input_section,
diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c
index 8031ab95902..79b95db404b 100644
--- a/bfd/coff-alpha.c
+++ b/bfd/coff-alpha.c
@@ -836,8 +836,8 @@ alpha_ecoff_get_relocated_section_contents (bfd *abfd,
 	      rel->address += input_section->output_offset;
 	      break;
 	    }
-	  r = bfd_perform_relocation (input_bfd, rel, data, input_section,
-				      output_bfd, &err);
+	  r = bfd_perform_relocation (input_bfd, link_info, rel, data,
+				      input_section, output_bfd, &err);
 	  break;
 
 	case ALPHA_R_GPREL32:
@@ -848,8 +848,8 @@ alpha_ecoff_get_relocated_section_contents (bfd *abfd,
 	     addend.  We adjust the addend and let
 	     bfd_perform_relocation finish the job.  */
 	  rel->addend -= gp;
-	  r = bfd_perform_relocation (input_bfd, rel, data, input_section,
-				      output_bfd, &err);
+	  r = bfd_perform_relocation (input_bfd, link_info, rel, data,
+				      input_section, output_bfd, &err);
 	  if (r == bfd_reloc_ok && gp_undefined)
 	    {
 	      r = bfd_reloc_dangerous;
@@ -884,8 +884,8 @@ alpha_ecoff_get_relocated_section_contents (bfd *abfd,
 			|| ((insn >> 26) & 0x3f) == 0x28);
 
 	    rel->addend -= gp;
-	    r = bfd_perform_relocation (input_bfd, rel, data, input_section,
-					output_bfd, &err);
+	    r = bfd_perform_relocation (input_bfd, link_info, rel, data,
+					input_section, output_bfd, &err);
 	    if (r == bfd_reloc_ok && gp_undefined)
 	      {
 		r = bfd_reloc_dangerous;
diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
index 34e61865cd9..9bd30ca95cf 100644
--- a/bfd/elf32-mips.c
+++ b/bfd/elf32-mips.c
@@ -1905,7 +1905,7 @@ mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry,
   if (bfd_big_endian (abfd))
     reloc32.address += 4;
   reloc32.howto = &elf_mips_howto_table_rel[R_MIPS_32];
-  r = bfd_perform_relocation (abfd, &reloc32, data, input_section,
+  r = bfd_perform_relocation (abfd, NULL, &reloc32, data, input_section,
 			      output_bfd, error_message);
 
   /* Sign extend into the upper 32 bits.  */
diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c
index 01d0702255a..215803ea949 100644
--- a/bfd/elf32-nds32.c
+++ b/bfd/elf32-nds32.c
@@ -13098,8 +13098,8 @@ nds32_elf_get_relocated_section_contents (bfd *abfd,
 	      r = bfd_reloc_ok;
 	    }
 	  else
-	    r = bfd_perform_relocation (input_bfd, *parent, data,
-					input_section,
+	    r = bfd_perform_relocation (input_bfd, link_info, *parent,
+					data, input_section,
 					relocatable ? abfd : NULL,
 					&error_message);
 
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 86e15b61edf..325d6d30adf 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -13356,6 +13356,7 @@ _bfd_elf_mips_get_relocated_section_contents
 					       data, gp);
 	  else
 	    r = bfd_perform_relocation (input_bfd,
+					link_info,
 					*parent,
 					data,
 					input_section,
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 4f4b95a0b7f..b22966348d1 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -647,6 +647,7 @@ FUNCTION
 SYNOPSIS
 	bfd_reloc_status_type bfd_perform_relocation
 	  (bfd *abfd,
+	   struct bfd_link_info *link_info,
 	   arelent *reloc_entry,
 	   void *data,
 	   asection *input_section,
@@ -673,6 +674,7 @@ DESCRIPTION
 
 bfd_reloc_status_type
 bfd_perform_relocation (bfd *abfd,
+			struct bfd_link_info *link_info,
 			arelent *reloc_entry,
 			void *data,
 			asection *input_section,
@@ -917,16 +919,35 @@ space consuming.  For each target:
 	 object files to generate ELF output, _bfd_relocate_contents
 	 isn't called and bfd_perform_relocation is used.  We need to
 	 adjust relocation here.  */
-      relocation -= reloc_entry->addend;
-      if (howto->type >= R_AMD64_PCRLONG_1
-	  && howto->type <= R_AMD64_PCRLONG_5)
-	relocation -= (bfd_vma)(howto->type - R_AMD64_PCRLONG);
-      else if (howto->type == R_AMD64_DIR64
-	       || howto->type == R_AMD64_DIR32)
+      if (howto->type == R_AMD64_IMAGEBASE)
+	{
+	  /* Subtract __ImageBase.  */
+	  struct bfd_link_hash_entry *h
+	    = bfd_link_hash_lookup (link_info->hash, "__ImageBase",
+				    FALSE, FALSE, FALSE);
+	  if (h == NULL)
+	    abort ();
+	  while (h->type == bfd_link_hash_indirect)
+	    h = h->u.i.link;
+	  /* ELF symbols in relocatable files are section relative,
+	     but in nonrelocatable files they are virtual addresses.  */
+	  relocation -= (h->u.def.value
+			 + h->u.def.section->output_offset
+			 + h->u.def.section->output_section->vma);
+	}
+      else
 	{
-	  bfd_vma val = read_reloc (abfd, (bfd_byte *) data + octets,
-				    howto);
-	  relocation -= val & howto->src_mask;
+	  relocation -= reloc_entry->addend;
+	  if (howto->type >= R_AMD64_PCRLONG_1
+	      && howto->type <= R_AMD64_PCRLONG_5)
+	    relocation -= (bfd_vma)(howto->type - R_AMD64_PCRLONG);
+	  else if (howto->type == R_AMD64_DIR64
+		   || howto->type == R_AMD64_DIR32)
+	    {
+	      bfd_vma val = read_reloc (abfd, (bfd_byte *) data + octets,
+					howto);
+	      relocation -= val & howto->src_mask;
+	    }
 	}
     }
 
@@ -8457,6 +8478,7 @@ bfd_generic_get_relocated_section_contents (bfd *abfd,
 	    }
 	  else
 	    r = bfd_perform_relocation (input_bfd,
+					link_info,
 					*parent,
 					data,
 					input_section,
diff --git a/ld/ldelf.c b/ld/ldelf.c
index 049992544a2..4693d73d576 100644
--- a/ld/ldelf.c
+++ b/ld/ldelf.c
@@ -81,6 +81,30 @@ ldelf_load_symbols (lang_input_statement_type *entry)
 {
   int link_class = 0;
 
+  if (bfd_link_pde (&link_info)
+      && entry->the_bfd->xvec->flavour == bfd_target_coff_flavour
+      && strcmp (entry->the_bfd->xvec->name, "pe-x86-64") == 0
+      && strcmp (link_info.output_bfd->xvec->name, "elf64-x86-64") == 0)
+    {
+      /* NB: When linking PE/x86-64 inputs to generate ELF executable,
+	 create an indirect reference to __executable_start for
+	 __ImageBase to support R_AMD64_IMAGEBASE relocation which
+	 is relative to __ImageBase.  */
+      struct elf_link_hash_table *htab = elf_hash_table (&link_info);
+      struct elf_link_hash_entry *h, *hi;
+      hi = elf_link_hash_lookup (htab, "__ImageBase", TRUE, FALSE,
+				 FALSE);
+      if (hi->root.type == bfd_link_hash_new
+	  || hi->type == bfd_link_hash_undefined
+	  || hi->type == bfd_link_hash_undefweak)
+	{
+	  h = elf_link_hash_lookup (htab, "__executable_start",
+				    TRUE, FALSE, TRUE);
+	  hi->root.type = bfd_link_hash_indirect;
+	  hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
+	}
+    }
+
   /* Tell the ELF linker that we don't want the output file to have a
      DT_NEEDED entry for this file, unless it is used to resolve
      references in a regular object.  */
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-1.od b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-1.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-2.od b/ld/testsuite/ld-x86-64/pe-x86-64-2.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-2.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-2.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-3.od b/ld/testsuite/ld-x86-64/pe-x86-64-3.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-3.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-3.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-4.od b/ld/testsuite/ld-x86-64/pe-x86-64-4.od
index e0bde11d84e..320c6be5e14 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-4.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-4.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+403038 g       .bss	0000000000000000 c
 0+401000 g       .text\$mn	0000000000000000 begin
 0+403038 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-5.od b/ld/testsuite/ld-x86-64/pe-x86-64-5.od
index 8a4f4a633ac..6ef13abbc94 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-5.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-5.od
@@ -4,6 +4,7 @@
 SYMBOL TABLE:
 0+402014 g       .bss	0000000000000000 non_initdummy
 0+402010 g       .data	0000000000000000 initdummy
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 begin
 0+402012 g       .bss	0000000000000000 __bss_start
 0+402000 g       .data	0000000000000000 Struct
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-5.rd b/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
index 8370665f99f..237052805e9 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
@@ -1,9 +1,10 @@
 
-Symbol table '.symtab' contains 10 entries:
+Symbol table '.symtab' contains 11 entries:
    Num:    Value          Size Type    Bind   Vis      Ndx Name
  +[a-f0-9]+: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
  +[a-f0-9]+: 0000000000402014     0 NOTYPE  GLOBAL DEFAULT    3 non_initdummy
  +[a-f0-9]+: 0000000000402010     0 NOTYPE  GLOBAL DEFAULT    2 initdummy
+ +[a-f0-9]+: 0000000000400000     0 NOTYPE  GLOBAL DEFAULT    1 __executable_start
  +[a-f0-9]+: 0000000000401000     0 NOTYPE  GLOBAL DEFAULT    1 begin
  +[a-f0-9]+: 0000000000402012     0 NOTYPE  GLOBAL DEFAULT    3 __bss_start
  +[a-f0-9]+: 0000000000402000     0 NOTYPE  GLOBAL DEFAULT    2 Struct
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2 b/ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..38255045d45ed918857b2c966400c13a13ea6c07
GIT binary patch
literal 1366
zcmV-c1*!T%T4*^jL0KkKSr(o^9smO9fB*mf|Nh_a|NQ^||Nj5~-}TM^Q*@d9YgPW;
zd+eHR_F&KhxOk{DUEM>1DTr#B8Vxi9QxnNB$qe;OMn*LZjWonG!KBke34qcKG#-Lu
zO+n}oJfkP-n1+}m6BA7tp+8jd3aO!pXvlhuKmni)7)=4727@32A)%%dK*9h3GyobJ
zF#(`ypa1~S&<2Qtn+c+6qtZ`M(<VowN$4g48fl<tXa<3x8X7%78Z>F3218950002c
z8UPw-&;$&OhMHssLqH6JBSwQEplP9@hychk8Z-t#7$DFx0MG!_Kn#r-BS2^XN+L#+
zMDk%qX+0wvnd*n6$Y=o5O#sjXO#o;B000^Q000000BC8T01Y)6t0Ij%1~1Zx-ljTP
zv7~$gP4n@oNq~cfwyu(S%%**p^kz*r4rRAWRcTbfRNzb)2)m)XQMb&4JUVWwY*_%P
z_N_!via~?|2}vgnKR75Sr_AXg#*K-lYBJ6&yOYkj3SvkC7BnqXI+`VjgE9yrmM|#Z
zAcU!thFfPL@ogO(W&_wPR?O<Nl`>0!yz(SMNI$pgD>nP`qq5&di9Y(;<tzfve#7RV
zLQq7sR8<iKE~*d}9#I&mh}9UVJg8-r7@=xZ2NcmYhaEyPiYfpN6hw+h7>GbrM+HPo
z!i9>{yG<#;mMI1E_Jr`*O+8>~P!*e8kP;V5^pWooq=L*qp)SmVWvfu>f>_r&r(rc;
zFlw0LN0dbVEA<6bekiD-s;40s%X>e{Bpb{0V*cpCy@Z%%2(;IT0ltH`?_5}n<UzB5
zf*?Wx?9SUxvoz5xvF*HU!`az<4cefwMgW_uK?W~)_YEp5)<A$@1UQMSt7Vh|X$!8S
zrYkdd%PnrQQ=JI}l%S=Jf?!qja8)kH^@O)sYfeI3m645L`q5BGerN)K?of-0r#>n|
zIJ>G_Jer_3(hAJw3_-j#7s1%O?->CeCR~1-d~uAqlkd=kBse0+P!fP8Gf5HP-!7%i
zY9#t2m+xTN{>23e(7a+I0;{Zo0pKlR8D<0+3~@0q!8UtF@$=vS%Ru|zVD9FpjySx}
zt{H?(&9Uu<p2jzU;|+yP-xYy^SQTmsWFw3b42s1?DxF}&SjcKo)TM}4B<*K1;RKpr
zB9L9W4U0w48Omi$FhV&*nXBTNgK+&nY+(ea!;BBmP6EO12PwtkmC_%#RsA$z@0JaQ
zK;1$!^T@K75<Qv*kCpFrll-gW?LaFYfjkRsvaL~}G=vHfYrg~uZV?6S9IpF-0+5}A
z_)^1T9VRd5A4+zwe~%URaNDw|ovUUIblXiY&aNu_D<Fy>a;O36%A;_CC4P{I;g8Lc
z_oIb1Th5wd#<v-tRhnyBD_BF4(rrdPfGi+1Cj(c?t7>6DvSmSitld-B7DP!ulPV)v
zjtH{yhbV)vqPiypj+2XeCuKWhP+%%5BxPTeR&+A6ME(Spj<8A+AT>of%9IL${b3$W
zT;V{<37R=3O12yjn;D3J_1es%R~rCwc#07V>0~}6Ocbcd(xo^hbFZ_E5g`dK4J43;
zL!(RF%z~VRcxJ6*mWojmVMt69!e|;&A4@D>YChtn2o?5O0qUo}T)OBf@?k*9{q-V&
zj?~DI4x)@7n$%$cCX*@q$)0{8UXMIXT<xV^S2T@qb<#e0E#AcXnZlt{eAv$l(KnN1
zj%}2QO$7taoaiC>k}0dYOV~!Q%X-@vZSVa^tl(<I`&6AfE`zbF1)s_=HB>Bd6H=xt
Y$~B;AV5AHi$*u8sBvXY60cqp`;GR@oQ~&?~

literal 0
HcmV?d00001

diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-6.od b/ld/testsuite/ld-x86-64/pe-x86-64-6.od
new file mode 100644
index 00000000000..cc23658a806
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-6.od
@@ -0,0 +1,91 @@
+
+.*: +file format .*
+
+SYMBOL TABLE:
+0+4010a8 g       .text\$mn	0000000000000000 xfunc
+0+402000 g       .rdata	0000000000000000 \?\?_C@_02LDKJOMJN@AB@
+0+400000 g       .text\$mn	0000000000000000 __executable_start
+0+403058 g       .data	0000000000000000 __bss_start
+0+401000 g       .text\$mn	0000000000000000 main
+0+403038 g       .data	0000000000000000 deadloopvar
+0+4010ac g       .text\$mn	0000000000000000 xstring
+0+403058 g       .data	0000000000000000 _edata
+0+403058 g       .data	0000000000000000 _end
+
+
+
+Disassembly of section .text\$mn:
+
+0+401000 <main>:
+ +[a-f0-9]+:	48 89 5c 24 08       	mov    %rbx,0x8\(%rsp\)
+ +[a-f0-9]+:	48 89 6c 24 10       	mov    %rbp,0x10\(%rsp\)
+ +[a-f0-9]+:	48 89 74 24 20       	mov    %rsi,0x20\(%rsp\)
+ +[a-f0-9]+:	57                   	push   %rdi
+ +[a-f0-9]+:	48 83 ec 20          	sub    \$0x20,%rsp
+ +[a-f0-9]+:	cc                   	int3   
+ +[a-f0-9]+:	8b 05 1d 20 00 00    	mov    0x201d\(%rip\),%eax        # 403038 <deadloopvar>
+ +[a-f0-9]+:	83 f8 01             	cmp    \$0x1,%eax
+ +[a-f0-9]+:	74 f5                	je     401015 <main\+0x15>
+ +[a-f0-9]+:	0f 31                	rdtsc  
+ +[a-f0-9]+:	48 c1 e2 20          	shl    \$0x20,%rdx
+ +[a-f0-9]+:	48 0b c2             	or     %rdx,%rax
+ +[a-f0-9]+:	74 5d                	je     401088 <main\+0x88>
+ +[a-f0-9]+:	33 ff                	xor    %edi,%edi
+ +[a-f0-9]+:	48 8d 2d cc ef ff ff 	lea    -0x1034\(%rip\),%rbp        # 400000 <__executable_start>
+ +[a-f0-9]+:	33 db                	xor    %ebx,%ebx
+ +[a-f0-9]+:	48 8d 35 ff 1f 00 00 	lea    0x1fff\(%rip\),%rsi        # 40303c <deadloopvar\+0x4>
+ +[a-f0-9]+:	48 8b 8c 2b 50 30 00 00 	mov    0x3050\(%rbx,%rbp,1\),%rcx
+ +[a-f0-9]+:	44 8a 01             	mov    \(%rcx\),%r8b
+ +[a-f0-9]+:	45 84 c0             	test   %r8b,%r8b
+ +[a-f0-9]+:	74 28                	je     401075 <main\+0x75>
+ +[a-f0-9]+:	b8 05 00 00 00       	mov    \$0x5,%eax
+ +[a-f0-9]+:	2b 84 2b 48 30 00 00 	sub    0x3048\(%rbx,%rbp,1\),%eax
+ +[a-f0-9]+:	99                   	cltd   
+ +[a-f0-9]+:	2b c2                	sub    %edx,%eax
+ +[a-f0-9]+:	d1 f8                	sar    %eax
+ +[a-f0-9]+:	48 63 d0             	movslq %eax,%rdx
+ +[a-f0-9]+:	48 03 d6             	add    %rsi,%rdx
+ +[a-f0-9]+:	48 ff c1             	inc    %rcx
+ +[a-f0-9]+:	44 88 02             	mov    %r8b,\(%rdx\)
+ +[a-f0-9]+:	48 ff c2             	inc    %rdx
+ +[a-f0-9]+:	44 8a 01             	mov    \(%rcx\),%r8b
+ +[a-f0-9]+:	45 84 c0             	test   %r8b,%r8b
+ +[a-f0-9]+:	75 ef                	jne    401064 <main\+0x64>
+ +[a-f0-9]+:	48 8b ce             	mov    %rsi,%rcx
+ +[a-f0-9]+:	e8 2f 00 00 00       	call   4010ac <xstring>
+ +[a-f0-9]+:	ff c7                	inc    %edi
+ +[a-f0-9]+:	48 83 c3 08          	add    \$0x8,%rbx
+ +[a-f0-9]+:	83 ff 01             	cmp    \$0x1,%edi
+ +[a-f0-9]+:	72 b5                	jb     40103d <main\+0x3d>
+ +[a-f0-9]+:	b1 aa                	mov    \$0xaa,%cl
+ +[a-f0-9]+:	e8 19 00 00 00       	call   4010a8 <xfunc>
+ +[a-f0-9]+:	48 8b 5c 24 30       	mov    0x30\(%rsp\),%rbx
+ +[a-f0-9]+:	33 c0                	xor    %eax,%eax
+ +[a-f0-9]+:	48 8b 6c 24 38       	mov    0x38\(%rsp\),%rbp
+ +[a-f0-9]+:	48 8b 74 24 48       	mov    0x48\(%rsp\),%rsi
+ +[a-f0-9]+:	48 83 c4 20          	add    \$0x20,%rsp
+ +[a-f0-9]+:	5f                   	pop    %rdi
+ +[a-f0-9]+:	c3                   	ret    
+ +[a-f0-9]+:	66 90                	xchg   %ax,%ax
+
+0+4010a8 <xfunc>:
+ +[a-f0-9]+:	66 90                	xchg   %ax,%ax
+ +[a-f0-9]+:	cc                   	int3   
+ +[a-f0-9]+:	c3                   	ret    
+
+0+4010ac <xstring>:
+ +[a-f0-9]+:	40 53                	rex push %rbx
+ +[a-f0-9]+:	48 83 ec 20          	sub    \$0x20,%rsp
+ +[a-f0-9]+:	8a 01                	mov    \(%rcx\),%al
+ +[a-f0-9]+:	48 8b d9             	mov    %rcx,%rbx
+ +[a-f0-9]+:	eb 0c                	jmp    4010c5 <xstring\+0x19>
+ +[a-f0-9]+:	8a c8                	mov    %al,%cl
+ +[a-f0-9]+:	e8 e8 ff ff ff       	call   4010a8 <xfunc>
+ +[a-f0-9]+:	48 ff c3             	inc    %rbx
+ +[a-f0-9]+:	8a 03                	mov    \(%rbx\),%al
+ +[a-f0-9]+:	84 c0                	test   %al,%al
+ +[a-f0-9]+:	75 f0                	jne    4010b9 <xstring\+0xd>
+ +[a-f0-9]+:	48 83 c4 20          	add    \$0x20,%rsp
+ +[a-f0-9]+:	5b                   	pop    %rbx
+ +[a-f0-9]+:	c3                   	ret    
+#pass
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64.exp b/ld/testsuite/ld-x86-64/pe-x86-64.exp
index ccfcdfaddfb..f5d2c84f283 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64.exp
+++ b/ld/testsuite/ld-x86-64/pe-x86-64.exp
@@ -73,4 +73,13 @@ run_ld_link_tests [list \
 	 {readelf {-s -x .data} pe-x86-64-5.rd}} \
 	"pe-x86-64-5" \
     ] \
+    [list \
+	"Build pe-x86-64-6" \
+	"-m elf_x86_64 --entry=main" \
+	"" \
+	"" \
+	{pe-x86-64-6.obj.bz2 } \
+	{{objdump {-dw --sym} pe-x86-64-6.od}} \
+	"pe-x86-64-6" \
+    ] \
 ]
-- 
2.29.2


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-02-23 12:15 [PATCH] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE H.J. Lu
@ 2021-02-23 13:15 ` Jan Beulich
  2021-02-23 13:31   ` H.J. Lu
  0 siblings, 1 reply; 22+ messages in thread
From: Jan Beulich @ 2021-02-23 13:15 UTC (permalink / raw)
  To: H.J. Lu; +Cc: binutils

On 23.02.2021 13:15, H.J. Lu via Binutils wrote:
> When linking PE/x86-64 inputs to generate ELF executable, we need to
> subtract __ImageBase, aka __executable_start, for R_AMD64_IMAGEBASE
> relocation.

Do you really mean PE/x86-64, not the respective COFF objects? In the
description this may not matter much, but since there's at least one
code comment also saying so, which may confuse readers, I'd like to
understand this.

Also, in how far is this x86-64-specific?

> --- a/ld/testsuite/ld-x86-64/pe-x86-64-1.od
> +++ b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
> @@ -2,6 +2,7 @@
>  .*: +file format .*
>  
>  SYMBOL TABLE:
> +0+400000 g       .text\$mn	0000000000000000 __executable_start
>  0+401000 g       .text\$mn	0000000000000000 getaddr1
>  0+401020 g       .text\$mn	0000000000000000 begin
>  0+403014 g       .bss	0000000000000000 __bss_start

I don't think this artifical symbol should appear in the symbol
table. I also wonder what the consequences are if a set of linked
object files specifies a symbol of this name.

Jan

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-02-23 13:15 ` Jan Beulich
@ 2021-02-23 13:31   ` H.J. Lu
  2021-02-23 14:10     ` Jan Beulich
  0 siblings, 1 reply; 22+ messages in thread
From: H.J. Lu @ 2021-02-23 13:31 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Binutils

On Tue, Feb 23, 2021 at 5:15 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 23.02.2021 13:15, H.J. Lu via Binutils wrote:
> > When linking PE/x86-64 inputs to generate ELF executable, we need to
> > subtract __ImageBase, aka __executable_start, for R_AMD64_IMAGEBASE
> > relocation.
>
> Do you really mean PE/x86-64, not the respective COFF objects? In the

What is the difference?  How should I call object files generated by
Microsoft Visual Studio?

> description this may not matter much, but since there's at least one
> code comment also saying so, which may confuse readers, I'd like to
> understand this.
>
> Also, in how far is this x86-64-specific?

I don't know.

> > --- a/ld/testsuite/ld-x86-64/pe-x86-64-1.od
> > +++ b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
> > @@ -2,6 +2,7 @@
> >  .*: +file format .*
> >
> >  SYMBOL TABLE:
> > +0+400000 g       .text\$mn   0000000000000000 __executable_start
> >  0+401000 g       .text\$mn   0000000000000000 getaddr1
> >  0+401020 g       .text\$mn   0000000000000000 begin
> >  0+403014 g       .bss        0000000000000000 __bss_start
>
> I don't think this artifical symbol should appear in the symbol

This symbol is generated by linker.  It should be harmless.

> table. I also wonder what the consequences are if a set of linked
> object files specifies a symbol of this name.

__executable_start is generated by linker.  If __ImageBase is
defined to another value, that value will be used as image base.


-- 
H.J.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-02-23 13:31   ` H.J. Lu
@ 2021-02-23 14:10     ` Jan Beulich
  2021-02-23 14:47       ` H.J. Lu
  0 siblings, 1 reply; 22+ messages in thread
From: Jan Beulich @ 2021-02-23 14:10 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

On 23.02.2021 14:31, H.J. Lu wrote:
> On Tue, Feb 23, 2021 at 5:15 AM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 23.02.2021 13:15, H.J. Lu via Binutils wrote:
>>> When linking PE/x86-64 inputs to generate ELF executable, we need to
>>> subtract __ImageBase, aka __executable_start, for R_AMD64_IMAGEBASE
>>> relocation.
>>
>> Do you really mean PE/x86-64, not the respective COFF objects? In the
> 
> What is the difference?  How should I call object files generated by
> Microsoft Visual Studio?

The call them COFF themselves, I believe.

>> description this may not matter much, but since there's at least one
>> code comment also saying so, which may confuse readers, I'd like to
>> understand this.
>>
>> Also, in how far is this x86-64-specific?
> 
> I don't know.
> 
>>> --- a/ld/testsuite/ld-x86-64/pe-x86-64-1.od
>>> +++ b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
>>> @@ -2,6 +2,7 @@
>>>  .*: +file format .*
>>>
>>>  SYMBOL TABLE:
>>> +0+400000 g       .text\$mn   0000000000000000 __executable_start
>>>  0+401000 g       .text\$mn   0000000000000000 getaddr1
>>>  0+401020 g       .text\$mn   0000000000000000 begin
>>>  0+403014 g       .bss        0000000000000000 __bss_start
>>
>> I don't think this artifical symbol should appear in the symbol
> 
> This symbol is generated by linker.  It should be harmless.

According to my experience, stray symbols can be confusing or worse.

>> table. I also wonder what the consequences are if a set of linked
>> object files specifies a symbol of this name.
> 
> __executable_start is generated by linker.  If __ImageBase is
> defined to another value, that value will be used as image base.

So if I have an object defining __executable_start, which of the
two will relocations be resolved against?

Jan

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-02-23 14:10     ` Jan Beulich
@ 2021-02-23 14:47       ` H.J. Lu
  2021-02-23 15:02         ` Jan Beulich
  0 siblings, 1 reply; 22+ messages in thread
From: H.J. Lu @ 2021-02-23 14:47 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Binutils

On Tue, Feb 23, 2021 at 6:10 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 23.02.2021 14:31, H.J. Lu wrote:
> > On Tue, Feb 23, 2021 at 5:15 AM Jan Beulich <jbeulich@suse.com> wrote:
> >>
> >> On 23.02.2021 13:15, H.J. Lu via Binutils wrote:
> >>> When linking PE/x86-64 inputs to generate ELF executable, we need to
> >>> subtract __ImageBase, aka __executable_start, for R_AMD64_IMAGEBASE
> >>> relocation.
> >>
> >> Do you really mean PE/x86-64, not the respective COFF objects? In the
> >
> > What is the difference?  How should I call object files generated by
> > Microsoft Visual Studio?
>
> The call them COFF themselves, I believe.

I have an impression that Windows relocations are different from regular
COFF relocations.  coff-x86_64.c has COFF_WITH_PE in many places.
My patch is only for Windows/PE:

&& strcmp (abfd->xvec->name, "pe-x86-64") == 0

> >> description this may not matter much, but since there's at least one
> >> code comment also saying so, which may confuse readers, I'd like to
> >> understand this.
> >>
> >> Also, in how far is this x86-64-specific?
> >
> > I don't know.
> >
> >>> --- a/ld/testsuite/ld-x86-64/pe-x86-64-1.od
> >>> +++ b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
> >>> @@ -2,6 +2,7 @@
> >>>  .*: +file format .*
> >>>
> >>>  SYMBOL TABLE:
> >>> +0+400000 g       .text\$mn   0000000000000000 __executable_start
> >>>  0+401000 g       .text\$mn   0000000000000000 getaddr1
> >>>  0+401020 g       .text\$mn   0000000000000000 begin
> >>>  0+403014 g       .bss        0000000000000000 __bss_start
> >>
> >> I don't think this artifical symbol should appear in the symbol
> >
> > This symbol is generated by linker.  It should be harmless.
>
> According to my experience, stray symbols can be confusing or worse.

__executable_start is well defined by linker.

> >> table. I also wonder what the consequences are if a set of linked
> >> object files specifies a symbol of this name.
> >
> > __executable_start is generated by linker.  If __ImageBase is
> > defined to another value, that value will be used as image base.
>
> So if I have an object defining __executable_start, which of the
> two will relocations be resolved against?
>

Your __executable_start will be used.

-- 
H.J.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-02-23 14:47       ` H.J. Lu
@ 2021-02-23 15:02         ` Jan Beulich
  2021-02-23 15:07           ` H.J. Lu
  0 siblings, 1 reply; 22+ messages in thread
From: Jan Beulich @ 2021-02-23 15:02 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

On 23.02.2021 15:47, H.J. Lu wrote:
> On Tue, Feb 23, 2021 at 6:10 AM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 23.02.2021 14:31, H.J. Lu wrote:
>>> On Tue, Feb 23, 2021 at 5:15 AM Jan Beulich <jbeulich@suse.com> wrote:
>>>>
>>>> On 23.02.2021 13:15, H.J. Lu via Binutils wrote:
>>>>> When linking PE/x86-64 inputs to generate ELF executable, we need to
>>>>> subtract __ImageBase, aka __executable_start, for R_AMD64_IMAGEBASE
>>>>> relocation.
>>>>
>>>> Do you really mean PE/x86-64, not the respective COFF objects? In the
>>>
>>> What is the difference?  How should I call object files generated by
>>> Microsoft Visual Studio?
>>
>> The call them COFF themselves, I believe.
> 
> I have an impression that Windows relocations are different from regular
> COFF relocations.  coff-x86_64.c has COFF_WITH_PE in many places.

Right - there are differences.

> My patch is only for Windows/PE:
> 
> && strcmp (abfd->xvec->name, "pe-x86-64") == 0

That's (imo) bfd-internal naming that's not helpful to understand what
it really is that talk is about. Comments would hence likely benefit
from naming things like they are called commonly.

Jan

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-02-23 15:02         ` Jan Beulich
@ 2021-02-23 15:07           ` H.J. Lu
  2021-02-23 15:11             ` Jan Beulich
  0 siblings, 1 reply; 22+ messages in thread
From: H.J. Lu @ 2021-02-23 15:07 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Binutils

On Tue, Feb 23, 2021 at 7:02 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 23.02.2021 15:47, H.J. Lu wrote:
> > On Tue, Feb 23, 2021 at 6:10 AM Jan Beulich <jbeulich@suse.com> wrote:
> >>
> >> On 23.02.2021 14:31, H.J. Lu wrote:
> >>> On Tue, Feb 23, 2021 at 5:15 AM Jan Beulich <jbeulich@suse.com> wrote:
> >>>>
> >>>> On 23.02.2021 13:15, H.J. Lu via Binutils wrote:
> >>>>> When linking PE/x86-64 inputs to generate ELF executable, we need to
> >>>>> subtract __ImageBase, aka __executable_start, for R_AMD64_IMAGEBASE
> >>>>> relocation.
> >>>>
> >>>> Do you really mean PE/x86-64, not the respective COFF objects? In the
> >>>
> >>> What is the difference?  How should I call object files generated by
> >>> Microsoft Visual Studio?
> >>
> >> The call them COFF themselves, I believe.
> >
> > I have an impression that Windows relocations are different from regular
> > COFF relocations.  coff-x86_64.c has COFF_WITH_PE in many places.
>
> Right - there are differences.
>
> > My patch is only for Windows/PE:
> >
> > && strcmp (abfd->xvec->name, "pe-x86-64") == 0
>
> That's (imo) bfd-internal naming that's not helpful to understand what
> it really is that talk is about. Comments would hence likely benefit
> from naming things like they are called commonly.

Will "Windows x86-64 relocatable inputs" be better?

-- 
H.J.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-02-23 15:07           ` H.J. Lu
@ 2021-02-23 15:11             ` Jan Beulich
  2021-02-23 17:50               ` [PATCH v2] " H.J. Lu
  0 siblings, 1 reply; 22+ messages in thread
From: Jan Beulich @ 2021-02-23 15:11 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

On 23.02.2021 16:07, H.J. Lu wrote:
> On Tue, Feb 23, 2021 at 7:02 AM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 23.02.2021 15:47, H.J. Lu wrote:
>>> On Tue, Feb 23, 2021 at 6:10 AM Jan Beulich <jbeulich@suse.com> wrote:
>>>>
>>>> On 23.02.2021 14:31, H.J. Lu wrote:
>>>>> On Tue, Feb 23, 2021 at 5:15 AM Jan Beulich <jbeulich@suse.com> wrote:
>>>>>>
>>>>>> On 23.02.2021 13:15, H.J. Lu via Binutils wrote:
>>>>>>> When linking PE/x86-64 inputs to generate ELF executable, we need to
>>>>>>> subtract __ImageBase, aka __executable_start, for R_AMD64_IMAGEBASE
>>>>>>> relocation.
>>>>>>
>>>>>> Do you really mean PE/x86-64, not the respective COFF objects? In the
>>>>>
>>>>> What is the difference?  How should I call object files generated by
>>>>> Microsoft Visual Studio?
>>>>
>>>> The call them COFF themselves, I believe.
>>>
>>> I have an impression that Windows relocations are different from regular
>>> COFF relocations.  coff-x86_64.c has COFF_WITH_PE in many places.
>>
>> Right - there are differences.
>>
>>> My patch is only for Windows/PE:
>>>
>>> && strcmp (abfd->xvec->name, "pe-x86-64") == 0
>>
>> That's (imo) bfd-internal naming that's not helpful to understand what
>> it really is that talk is about. Comments would hence likely benefit
>> from naming things like they are called commonly.
> 
> Will "Windows x86-64 relocatable inputs" be better?

I think so, yes. Of course I continue to be puzzled by the x86-64
special casing here. The concept of image base and image base
relative relocations is architecture independent afaik.

Jan

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v2] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-02-23 15:11             ` Jan Beulich
@ 2021-02-23 17:50               ` H.J. Lu
  2021-02-25  2:09                 ` Alan Modra
  0 siblings, 1 reply; 22+ messages in thread
From: H.J. Lu @ 2021-02-23 17:50 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Binutils

[-- Attachment #1: Type: text/plain, Size: 1802 bytes --]

On Tue, Feb 23, 2021 at 7:11 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 23.02.2021 16:07, H.J. Lu wrote:
> > On Tue, Feb 23, 2021 at 7:02 AM Jan Beulich <jbeulich@suse.com> wrote:
> >>
> >> On 23.02.2021 15:47, H.J. Lu wrote:
> >>> On Tue, Feb 23, 2021 at 6:10 AM Jan Beulich <jbeulich@suse.com> wrote:
> >>>>
> >>>> On 23.02.2021 14:31, H.J. Lu wrote:
> >>>>> On Tue, Feb 23, 2021 at 5:15 AM Jan Beulich <jbeulich@suse.com> wrote:
> >>>>>>
> >>>>>> On 23.02.2021 13:15, H.J. Lu via Binutils wrote:
> >>>>>>> When linking PE/x86-64 inputs to generate ELF executable, we need to
> >>>>>>> subtract __ImageBase, aka __executable_start, for R_AMD64_IMAGEBASE
> >>>>>>> relocation.
> >>>>>>
> >>>>>> Do you really mean PE/x86-64, not the respective COFF objects? In the
> >>>>>
> >>>>> What is the difference?  How should I call object files generated by
> >>>>> Microsoft Visual Studio?
> >>>>
> >>>> The call them COFF themselves, I believe.
> >>>
> >>> I have an impression that Windows relocations are different from regular
> >>> COFF relocations.  coff-x86_64.c has COFF_WITH_PE in many places.
> >>
> >> Right - there are differences.
> >>
> >>> My patch is only for Windows/PE:
> >>>
> >>> && strcmp (abfd->xvec->name, "pe-x86-64") == 0
> >>
> >> That's (imo) bfd-internal naming that's not helpful to understand what
> >> it really is that talk is about. Comments would hence likely benefit
> >> from naming things like they are called commonly.
> >
> > Will "Windows x86-64 relocatable inputs" be better?
>
> I think so, yes. Of course I continue to be puzzled by the x86-64
> special casing here. The concept of image base and image base
> relative relocations is architecture independent afaik.

If there is such a testcase, we can update it.

> Jan

Here is the updated patch.

-- 
H.J.

[-- Attachment #2: v2-0001-elf-x86-64-Subtract-__ImageBase-for-R_AMD64_IMAGE.patch --]
[-- Type: text/x-patch, Size: 21028 bytes --]

From eb2dbfdfb55ad6a27f8311c96a028365c713bbcf Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 15 Feb 2021 18:53:18 -0800
Subject: [PATCH v2] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE

When linking Windows x86-64 relocatable object files to generate ELF
executable, we need to subtract __ImageBase, aka __executable_start,
for R_AMD64_IMAGEBASE relocation.

1. Create an indirect reference to __executable_start for __ImageBase to
support R_AMD64_IMAGEBASE relocation when seeing Windows x86-64 relocatable
object files.
2. Pass link_info to bfd_perform_relocation to lookup __ImageBase.
3. Subtract __ImageBase for R_AMD64_IMAGEBASE.

bfd/

	PR ld/27425
	PR ld/27432
	* coff-alpha.c (alpha_ecoff_get_relocated_section_contents): Pass
	link_info to bfd_perform_relocation.
	* elf32-nds32.c (nds32_elf_get_relocated_section_contents):
	Likewise.
	* elfxx-mips.c (_bfd_elf_mips_get_relocated_section_contents):
	Likewise.
	* elf32-mips.c (mips32_64bit_reloc): Pass NULL as link_info to
	bfd_perform_relocation.
	* reloc.c (bfd_perform_relocation): Add a link_info argument.
	Subtract __ImageBase for R_AMD64_IMAGEBASE.
	(bfd_generic_get_relocated_section_contents): Pass link_info to
	bfd_perform_relocation.
	* bfd-in2.h: Regenerated.

ld/

	PR ld/27425
	PR ld/27432
	* ldelf.c (ldelf_load_symbols): Create an indirect reference to
	__executable_start for __ImageBase to support R_AMD64_IMAGEBASE
	relocation when seeing Windows x86-64 relocatable inputs.
	* ld-x86-64/pe-x86-64-1.od: Expect __executable_start.
	* testsuite/ld-x86-64/pe-x86-64-2.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-3.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-4.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-5.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-5.rd: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-6.obj.bz2: New file.
	* testsuite/ld-x86-64/pe-x86-64-6.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64.exp: Run ld/27425 test.
---
 bfd/bfd-in2.h                              |   1 +
 bfd/coff-alpha.c                           |  12 +--
 bfd/elf32-mips.c                           |   2 +-
 bfd/elf32-nds32.c                          |   4 +-
 bfd/elfxx-mips.c                           |   1 +
 bfd/reloc.c                                |  48 ++++++++---
 ld/ldelf.c                                 |  24 ++++++
 ld/testsuite/ld-x86-64/pe-x86-64-1.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-2.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-3.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-4.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-5.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-5.rd      |   3 +-
 ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2 | Bin 0 -> 1366 bytes
 ld/testsuite/ld-x86-64/pe-x86-64-6.od      |  91 +++++++++++++++++++++
 ld/testsuite/ld-x86-64/pe-x86-64.exp       |   9 ++
 16 files changed, 177 insertions(+), 23 deletions(-)
 create mode 100644 ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2
 create mode 100644 ld/testsuite/ld-x86-64/pe-x86-64-6.od

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index d142bb52213..44d67b44bc4 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2222,6 +2222,7 @@ bfd_boolean bfd_reloc_offset_in_range
 
 bfd_reloc_status_type bfd_perform_relocation
    (bfd *abfd,
+    struct bfd_link_info *link_info,
     arelent *reloc_entry,
     void *data,
     asection *input_section,
diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c
index 8031ab95902..79b95db404b 100644
--- a/bfd/coff-alpha.c
+++ b/bfd/coff-alpha.c
@@ -836,8 +836,8 @@ alpha_ecoff_get_relocated_section_contents (bfd *abfd,
 	      rel->address += input_section->output_offset;
 	      break;
 	    }
-	  r = bfd_perform_relocation (input_bfd, rel, data, input_section,
-				      output_bfd, &err);
+	  r = bfd_perform_relocation (input_bfd, link_info, rel, data,
+				      input_section, output_bfd, &err);
 	  break;
 
 	case ALPHA_R_GPREL32:
@@ -848,8 +848,8 @@ alpha_ecoff_get_relocated_section_contents (bfd *abfd,
 	     addend.  We adjust the addend and let
 	     bfd_perform_relocation finish the job.  */
 	  rel->addend -= gp;
-	  r = bfd_perform_relocation (input_bfd, rel, data, input_section,
-				      output_bfd, &err);
+	  r = bfd_perform_relocation (input_bfd, link_info, rel, data,
+				      input_section, output_bfd, &err);
 	  if (r == bfd_reloc_ok && gp_undefined)
 	    {
 	      r = bfd_reloc_dangerous;
@@ -884,8 +884,8 @@ alpha_ecoff_get_relocated_section_contents (bfd *abfd,
 			|| ((insn >> 26) & 0x3f) == 0x28);
 
 	    rel->addend -= gp;
-	    r = bfd_perform_relocation (input_bfd, rel, data, input_section,
-					output_bfd, &err);
+	    r = bfd_perform_relocation (input_bfd, link_info, rel, data,
+					input_section, output_bfd, &err);
 	    if (r == bfd_reloc_ok && gp_undefined)
 	      {
 		r = bfd_reloc_dangerous;
diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
index 34e61865cd9..9bd30ca95cf 100644
--- a/bfd/elf32-mips.c
+++ b/bfd/elf32-mips.c
@@ -1905,7 +1905,7 @@ mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry,
   if (bfd_big_endian (abfd))
     reloc32.address += 4;
   reloc32.howto = &elf_mips_howto_table_rel[R_MIPS_32];
-  r = bfd_perform_relocation (abfd, &reloc32, data, input_section,
+  r = bfd_perform_relocation (abfd, NULL, &reloc32, data, input_section,
 			      output_bfd, error_message);
 
   /* Sign extend into the upper 32 bits.  */
diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c
index 01d0702255a..215803ea949 100644
--- a/bfd/elf32-nds32.c
+++ b/bfd/elf32-nds32.c
@@ -13098,8 +13098,8 @@ nds32_elf_get_relocated_section_contents (bfd *abfd,
 	      r = bfd_reloc_ok;
 	    }
 	  else
-	    r = bfd_perform_relocation (input_bfd, *parent, data,
-					input_section,
+	    r = bfd_perform_relocation (input_bfd, link_info, *parent,
+					data, input_section,
 					relocatable ? abfd : NULL,
 					&error_message);
 
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 86e15b61edf..325d6d30adf 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -13356,6 +13356,7 @@ _bfd_elf_mips_get_relocated_section_contents
 					       data, gp);
 	  else
 	    r = bfd_perform_relocation (input_bfd,
+					link_info,
 					*parent,
 					data,
 					input_section,
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 4f4b95a0b7f..562cd7804a7 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -647,6 +647,7 @@ FUNCTION
 SYNOPSIS
 	bfd_reloc_status_type bfd_perform_relocation
 	  (bfd *abfd,
+	   struct bfd_link_info *link_info,
 	   arelent *reloc_entry,
 	   void *data,
 	   asection *input_section,
@@ -673,6 +674,7 @@ DESCRIPTION
 
 bfd_reloc_status_type
 bfd_perform_relocation (bfd *abfd,
+			struct bfd_link_info *link_info,
 			arelent *reloc_entry,
 			void *data,
 			asection *input_section,
@@ -913,20 +915,39 @@ space consuming.  For each target:
 		      "elf64-x86-64") == 0)
     {
       /* NB: bfd_perform_relocation isn't called to generate PE binary.
-	 _bfd_relocate_contents is called instead.  When linking PE
-	 object files to generate ELF output, _bfd_relocate_contents
-	 isn't called and bfd_perform_relocation is used.  We need to
-	 adjust relocation here.  */
-      relocation -= reloc_entry->addend;
-      if (howto->type >= R_AMD64_PCRLONG_1
-	  && howto->type <= R_AMD64_PCRLONG_5)
-	relocation -= (bfd_vma)(howto->type - R_AMD64_PCRLONG);
-      else if (howto->type == R_AMD64_DIR64
-	       || howto->type == R_AMD64_DIR32)
+	 _bfd_relocate_contents is called instead.  When linking Windows
+	 x86-64 relocatable object files to generate ELF output,
+	 _bfd_relocate_contents isn't called and bfd_perform_relocation
+	 is used.  We need to adjust relocation here.  */
+      if (howto->type == R_AMD64_IMAGEBASE)
+	{
+	  /* Subtract __ImageBase.  */
+	  struct bfd_link_hash_entry *h
+	    = bfd_link_hash_lookup (link_info->hash, "__ImageBase",
+				    FALSE, FALSE, FALSE);
+	  if (h == NULL)
+	    abort ();
+	  while (h->type == bfd_link_hash_indirect)
+	    h = h->u.i.link;
+	  /* ELF symbols in relocatable files are section relative,
+	     but in nonrelocatable files they are virtual addresses.  */
+	  relocation -= (h->u.def.value
+			 + h->u.def.section->output_offset
+			 + h->u.def.section->output_section->vma);
+	}
+      else
 	{
-	  bfd_vma val = read_reloc (abfd, (bfd_byte *) data + octets,
-				    howto);
-	  relocation -= val & howto->src_mask;
+	  relocation -= reloc_entry->addend;
+	  if (howto->type >= R_AMD64_PCRLONG_1
+	      && howto->type <= R_AMD64_PCRLONG_5)
+	    relocation -= (bfd_vma)(howto->type - R_AMD64_PCRLONG);
+	  else if (howto->type == R_AMD64_DIR64
+		   || howto->type == R_AMD64_DIR32)
+	    {
+	      bfd_vma val = read_reloc (abfd, (bfd_byte *) data + octets,
+					howto);
+	      relocation -= val & howto->src_mask;
+	    }
 	}
     }
 
@@ -8457,6 +8478,7 @@ bfd_generic_get_relocated_section_contents (bfd *abfd,
 	    }
 	  else
 	    r = bfd_perform_relocation (input_bfd,
+					link_info,
 					*parent,
 					data,
 					input_section,
diff --git a/ld/ldelf.c b/ld/ldelf.c
index 049992544a2..c7de958dbdc 100644
--- a/ld/ldelf.c
+++ b/ld/ldelf.c
@@ -81,6 +81,30 @@ ldelf_load_symbols (lang_input_statement_type *entry)
 {
   int link_class = 0;
 
+  if (bfd_link_pde (&link_info)
+      && entry->the_bfd->xvec->flavour == bfd_target_coff_flavour
+      && strcmp (entry->the_bfd->xvec->name, "pe-x86-64") == 0
+      && strcmp (link_info.output_bfd->xvec->name, "elf64-x86-64") == 0)
+    {
+      /* NB: When linking Windows x86-64 relocatable object files to
+	 generate ELF executable, create an indirect reference to
+	 __executable_start for __ImageBase to support R_AMD64_IMAGEBASE
+	 relocation which is relative to __ImageBase.  */
+      struct elf_link_hash_table *htab = elf_hash_table (&link_info);
+      struct elf_link_hash_entry *h, *hi;
+      hi = elf_link_hash_lookup (htab, "__ImageBase", TRUE, FALSE,
+				 FALSE);
+      if (hi->root.type == bfd_link_hash_new
+	  || hi->type == bfd_link_hash_undefined
+	  || hi->type == bfd_link_hash_undefweak)
+	{
+	  h = elf_link_hash_lookup (htab, "__executable_start",
+				    TRUE, FALSE, TRUE);
+	  hi->root.type = bfd_link_hash_indirect;
+	  hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
+	}
+    }
+
   /* Tell the ELF linker that we don't want the output file to have a
      DT_NEEDED entry for this file, unless it is used to resolve
      references in a regular object.  */
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-1.od b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-1.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-2.od b/ld/testsuite/ld-x86-64/pe-x86-64-2.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-2.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-2.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-3.od b/ld/testsuite/ld-x86-64/pe-x86-64-3.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-3.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-3.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-4.od b/ld/testsuite/ld-x86-64/pe-x86-64-4.od
index e0bde11d84e..320c6be5e14 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-4.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-4.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+403038 g       .bss	0000000000000000 c
 0+401000 g       .text\$mn	0000000000000000 begin
 0+403038 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-5.od b/ld/testsuite/ld-x86-64/pe-x86-64-5.od
index 8a4f4a633ac..6ef13abbc94 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-5.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-5.od
@@ -4,6 +4,7 @@
 SYMBOL TABLE:
 0+402014 g       .bss	0000000000000000 non_initdummy
 0+402010 g       .data	0000000000000000 initdummy
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 begin
 0+402012 g       .bss	0000000000000000 __bss_start
 0+402000 g       .data	0000000000000000 Struct
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-5.rd b/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
index 8370665f99f..237052805e9 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
@@ -1,9 +1,10 @@
 
-Symbol table '.symtab' contains 10 entries:
+Symbol table '.symtab' contains 11 entries:
    Num:    Value          Size Type    Bind   Vis      Ndx Name
  +[a-f0-9]+: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
  +[a-f0-9]+: 0000000000402014     0 NOTYPE  GLOBAL DEFAULT    3 non_initdummy
  +[a-f0-9]+: 0000000000402010     0 NOTYPE  GLOBAL DEFAULT    2 initdummy
+ +[a-f0-9]+: 0000000000400000     0 NOTYPE  GLOBAL DEFAULT    1 __executable_start
  +[a-f0-9]+: 0000000000401000     0 NOTYPE  GLOBAL DEFAULT    1 begin
  +[a-f0-9]+: 0000000000402012     0 NOTYPE  GLOBAL DEFAULT    3 __bss_start
  +[a-f0-9]+: 0000000000402000     0 NOTYPE  GLOBAL DEFAULT    2 Struct
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2 b/ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..38255045d45ed918857b2c966400c13a13ea6c07
GIT binary patch
literal 1366
zcmV-c1*!T%T4*^jL0KkKSr(o^9smO9fB*mf|Nh_a|NQ^||Nj5~-}TM^Q*@d9YgPW;
zd+eHR_F&KhxOk{DUEM>1DTr#B8Vxi9QxnNB$qe;OMn*LZjWonG!KBke34qcKG#-Lu
zO+n}oJfkP-n1+}m6BA7tp+8jd3aO!pXvlhuKmni)7)=4727@32A)%%dK*9h3GyobJ
zF#(`ypa1~S&<2Qtn+c+6qtZ`M(<VowN$4g48fl<tXa<3x8X7%78Z>F3218950002c
z8UPw-&;$&OhMHssLqH6JBSwQEplP9@hychk8Z-t#7$DFx0MG!_Kn#r-BS2^XN+L#+
zMDk%qX+0wvnd*n6$Y=o5O#sjXO#o;B000^Q000000BC8T01Y)6t0Ij%1~1Zx-ljTP
zv7~$gP4n@oNq~cfwyu(S%%**p^kz*r4rRAWRcTbfRNzb)2)m)XQMb&4JUVWwY*_%P
z_N_!via~?|2}vgnKR75Sr_AXg#*K-lYBJ6&yOYkj3SvkC7BnqXI+`VjgE9yrmM|#Z
zAcU!thFfPL@ogO(W&_wPR?O<Nl`>0!yz(SMNI$pgD>nP`qq5&di9Y(;<tzfve#7RV
zLQq7sR8<iKE~*d}9#I&mh}9UVJg8-r7@=xZ2NcmYhaEyPiYfpN6hw+h7>GbrM+HPo
z!i9>{yG<#;mMI1E_Jr`*O+8>~P!*e8kP;V5^pWooq=L*qp)SmVWvfu>f>_r&r(rc;
zFlw0LN0dbVEA<6bekiD-s;40s%X>e{Bpb{0V*cpCy@Z%%2(;IT0ltH`?_5}n<UzB5
zf*?Wx?9SUxvoz5xvF*HU!`az<4cefwMgW_uK?W~)_YEp5)<A$@1UQMSt7Vh|X$!8S
zrYkdd%PnrQQ=JI}l%S=Jf?!qja8)kH^@O)sYfeI3m645L`q5BGerN)K?of-0r#>n|
zIJ>G_Jer_3(hAJw3_-j#7s1%O?->CeCR~1-d~uAqlkd=kBse0+P!fP8Gf5HP-!7%i
zY9#t2m+xTN{>23e(7a+I0;{Zo0pKlR8D<0+3~@0q!8UtF@$=vS%Ru|zVD9FpjySx}
zt{H?(&9Uu<p2jzU;|+yP-xYy^SQTmsWFw3b42s1?DxF}&SjcKo)TM}4B<*K1;RKpr
zB9L9W4U0w48Omi$FhV&*nXBTNgK+&nY+(ea!;BBmP6EO12PwtkmC_%#RsA$z@0JaQ
zK;1$!^T@K75<Qv*kCpFrll-gW?LaFYfjkRsvaL~}G=vHfYrg~uZV?6S9IpF-0+5}A
z_)^1T9VRd5A4+zwe~%URaNDw|ovUUIblXiY&aNu_D<Fy>a;O36%A;_CC4P{I;g8Lc
z_oIb1Th5wd#<v-tRhnyBD_BF4(rrdPfGi+1Cj(c?t7>6DvSmSitld-B7DP!ulPV)v
zjtH{yhbV)vqPiypj+2XeCuKWhP+%%5BxPTeR&+A6ME(Spj<8A+AT>of%9IL${b3$W
zT;V{<37R=3O12yjn;D3J_1es%R~rCwc#07V>0~}6Ocbcd(xo^hbFZ_E5g`dK4J43;
zL!(RF%z~VRcxJ6*mWojmVMt69!e|;&A4@D>YChtn2o?5O0qUo}T)OBf@?k*9{q-V&
zj?~DI4x)@7n$%$cCX*@q$)0{8UXMIXT<xV^S2T@qb<#e0E#AcXnZlt{eAv$l(KnN1
zj%}2QO$7taoaiC>k}0dYOV~!Q%X-@vZSVa^tl(<I`&6AfE`zbF1)s_=HB>Bd6H=xt
Y$~B;AV5AHi$*u8sBvXY60cqp`;GR@oQ~&?~

literal 0
HcmV?d00001

diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-6.od b/ld/testsuite/ld-x86-64/pe-x86-64-6.od
new file mode 100644
index 00000000000..cc23658a806
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-6.od
@@ -0,0 +1,91 @@
+
+.*: +file format .*
+
+SYMBOL TABLE:
+0+4010a8 g       .text\$mn	0000000000000000 xfunc
+0+402000 g       .rdata	0000000000000000 \?\?_C@_02LDKJOMJN@AB@
+0+400000 g       .text\$mn	0000000000000000 __executable_start
+0+403058 g       .data	0000000000000000 __bss_start
+0+401000 g       .text\$mn	0000000000000000 main
+0+403038 g       .data	0000000000000000 deadloopvar
+0+4010ac g       .text\$mn	0000000000000000 xstring
+0+403058 g       .data	0000000000000000 _edata
+0+403058 g       .data	0000000000000000 _end
+
+
+
+Disassembly of section .text\$mn:
+
+0+401000 <main>:
+ +[a-f0-9]+:	48 89 5c 24 08       	mov    %rbx,0x8\(%rsp\)
+ +[a-f0-9]+:	48 89 6c 24 10       	mov    %rbp,0x10\(%rsp\)
+ +[a-f0-9]+:	48 89 74 24 20       	mov    %rsi,0x20\(%rsp\)
+ +[a-f0-9]+:	57                   	push   %rdi
+ +[a-f0-9]+:	48 83 ec 20          	sub    \$0x20,%rsp
+ +[a-f0-9]+:	cc                   	int3   
+ +[a-f0-9]+:	8b 05 1d 20 00 00    	mov    0x201d\(%rip\),%eax        # 403038 <deadloopvar>
+ +[a-f0-9]+:	83 f8 01             	cmp    \$0x1,%eax
+ +[a-f0-9]+:	74 f5                	je     401015 <main\+0x15>
+ +[a-f0-9]+:	0f 31                	rdtsc  
+ +[a-f0-9]+:	48 c1 e2 20          	shl    \$0x20,%rdx
+ +[a-f0-9]+:	48 0b c2             	or     %rdx,%rax
+ +[a-f0-9]+:	74 5d                	je     401088 <main\+0x88>
+ +[a-f0-9]+:	33 ff                	xor    %edi,%edi
+ +[a-f0-9]+:	48 8d 2d cc ef ff ff 	lea    -0x1034\(%rip\),%rbp        # 400000 <__executable_start>
+ +[a-f0-9]+:	33 db                	xor    %ebx,%ebx
+ +[a-f0-9]+:	48 8d 35 ff 1f 00 00 	lea    0x1fff\(%rip\),%rsi        # 40303c <deadloopvar\+0x4>
+ +[a-f0-9]+:	48 8b 8c 2b 50 30 00 00 	mov    0x3050\(%rbx,%rbp,1\),%rcx
+ +[a-f0-9]+:	44 8a 01             	mov    \(%rcx\),%r8b
+ +[a-f0-9]+:	45 84 c0             	test   %r8b,%r8b
+ +[a-f0-9]+:	74 28                	je     401075 <main\+0x75>
+ +[a-f0-9]+:	b8 05 00 00 00       	mov    \$0x5,%eax
+ +[a-f0-9]+:	2b 84 2b 48 30 00 00 	sub    0x3048\(%rbx,%rbp,1\),%eax
+ +[a-f0-9]+:	99                   	cltd   
+ +[a-f0-9]+:	2b c2                	sub    %edx,%eax
+ +[a-f0-9]+:	d1 f8                	sar    %eax
+ +[a-f0-9]+:	48 63 d0             	movslq %eax,%rdx
+ +[a-f0-9]+:	48 03 d6             	add    %rsi,%rdx
+ +[a-f0-9]+:	48 ff c1             	inc    %rcx
+ +[a-f0-9]+:	44 88 02             	mov    %r8b,\(%rdx\)
+ +[a-f0-9]+:	48 ff c2             	inc    %rdx
+ +[a-f0-9]+:	44 8a 01             	mov    \(%rcx\),%r8b
+ +[a-f0-9]+:	45 84 c0             	test   %r8b,%r8b
+ +[a-f0-9]+:	75 ef                	jne    401064 <main\+0x64>
+ +[a-f0-9]+:	48 8b ce             	mov    %rsi,%rcx
+ +[a-f0-9]+:	e8 2f 00 00 00       	call   4010ac <xstring>
+ +[a-f0-9]+:	ff c7                	inc    %edi
+ +[a-f0-9]+:	48 83 c3 08          	add    \$0x8,%rbx
+ +[a-f0-9]+:	83 ff 01             	cmp    \$0x1,%edi
+ +[a-f0-9]+:	72 b5                	jb     40103d <main\+0x3d>
+ +[a-f0-9]+:	b1 aa                	mov    \$0xaa,%cl
+ +[a-f0-9]+:	e8 19 00 00 00       	call   4010a8 <xfunc>
+ +[a-f0-9]+:	48 8b 5c 24 30       	mov    0x30\(%rsp\),%rbx
+ +[a-f0-9]+:	33 c0                	xor    %eax,%eax
+ +[a-f0-9]+:	48 8b 6c 24 38       	mov    0x38\(%rsp\),%rbp
+ +[a-f0-9]+:	48 8b 74 24 48       	mov    0x48\(%rsp\),%rsi
+ +[a-f0-9]+:	48 83 c4 20          	add    \$0x20,%rsp
+ +[a-f0-9]+:	5f                   	pop    %rdi
+ +[a-f0-9]+:	c3                   	ret    
+ +[a-f0-9]+:	66 90                	xchg   %ax,%ax
+
+0+4010a8 <xfunc>:
+ +[a-f0-9]+:	66 90                	xchg   %ax,%ax
+ +[a-f0-9]+:	cc                   	int3   
+ +[a-f0-9]+:	c3                   	ret    
+
+0+4010ac <xstring>:
+ +[a-f0-9]+:	40 53                	rex push %rbx
+ +[a-f0-9]+:	48 83 ec 20          	sub    \$0x20,%rsp
+ +[a-f0-9]+:	8a 01                	mov    \(%rcx\),%al
+ +[a-f0-9]+:	48 8b d9             	mov    %rcx,%rbx
+ +[a-f0-9]+:	eb 0c                	jmp    4010c5 <xstring\+0x19>
+ +[a-f0-9]+:	8a c8                	mov    %al,%cl
+ +[a-f0-9]+:	e8 e8 ff ff ff       	call   4010a8 <xfunc>
+ +[a-f0-9]+:	48 ff c3             	inc    %rbx
+ +[a-f0-9]+:	8a 03                	mov    \(%rbx\),%al
+ +[a-f0-9]+:	84 c0                	test   %al,%al
+ +[a-f0-9]+:	75 f0                	jne    4010b9 <xstring\+0xd>
+ +[a-f0-9]+:	48 83 c4 20          	add    \$0x20,%rsp
+ +[a-f0-9]+:	5b                   	pop    %rbx
+ +[a-f0-9]+:	c3                   	ret    
+#pass
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64.exp b/ld/testsuite/ld-x86-64/pe-x86-64.exp
index ccfcdfaddfb..f5d2c84f283 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64.exp
+++ b/ld/testsuite/ld-x86-64/pe-x86-64.exp
@@ -73,4 +73,13 @@ run_ld_link_tests [list \
 	 {readelf {-s -x .data} pe-x86-64-5.rd}} \
 	"pe-x86-64-5" \
     ] \
+    [list \
+	"Build pe-x86-64-6" \
+	"-m elf_x86_64 --entry=main" \
+	"" \
+	"" \
+	{pe-x86-64-6.obj.bz2 } \
+	{{objdump {-dw --sym} pe-x86-64-6.od}} \
+	"pe-x86-64-6" \
+    ] \
 ]
-- 
2.29.2


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v2] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-02-23 17:50               ` [PATCH v2] " H.J. Lu
@ 2021-02-25  2:09                 ` Alan Modra
  2021-02-28  2:38                   ` [PATCH v3] " H.J. Lu
  0 siblings, 1 reply; 22+ messages in thread
From: Alan Modra @ 2021-02-25  2:09 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Jan Beulich, Binutils

On Tue, Feb 23, 2021 at 09:50:20AM -0800, H.J. Lu via Binutils wrote:
> 	* reloc.c (bfd_perform_relocation): Add a link_info argument.
> 	Subtract __ImageBase for R_AMD64_IMAGEBASE.

H.J., did you consider moving all of this, including the code you
added in git commit 36068e2fa54, to the relevant howto special
functions?  None of it really belongs in bfd_perform_relocation.
You might even be able to do without a link_info parameter, instead
passing the image base value in output_elf_obj_tdata.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-02-25  2:09                 ` Alan Modra
@ 2021-02-28  2:38                   ` H.J. Lu
  2021-03-01 12:19                     ` Alan Modra
  0 siblings, 1 reply; 22+ messages in thread
From: H.J. Lu @ 2021-02-28  2:38 UTC (permalink / raw)
  To: Alan Modra; +Cc: Jan Beulich, Binutils

[-- Attachment #1: Type: text/plain, Size: 1014 bytes --]

On Wed, Feb 24, 2021 at 6:09 PM Alan Modra <amodra@gmail.com> wrote:
>
> On Tue, Feb 23, 2021 at 09:50:20AM -0800, H.J. Lu via Binutils wrote:
> >       * reloc.c (bfd_perform_relocation): Add a link_info argument.
> >       Subtract __ImageBase for R_AMD64_IMAGEBASE.
>
> H.J., did you consider moving all of this, including the code you
> added in git commit 36068e2fa54, to the relevant howto special
> functions?  None of it really belongs in bfd_perform_relocation.

The howto special function, coff_amd64_reloc, isn't changed since

1. Any changes to coff_amd64_reloc may break Windows x86-64 linker.
2. bfd_perform_relocation changes are safe since they are limited to
generating x86-64 ELF executable from Windows x86-64 relocatable object
files.

> You might even be able to do without a link_info parameter, instead
> passing the image base value in output_elf_obj_tdata.

I added "struct bfd_link_info *link_info;" to output_elf_obj_tdata.

Here is the updated patch.  OK for master?

Thanks.

-- 
H.J.

[-- Attachment #2: v3-0001-elf-x86-64-Subtract-__ImageBase-for-R_AMD64_IMAGE.patch --]
[-- Type: text/x-patch, Size: 20346 bytes --]

From 6b5ae13f2f8b5c19617f2352f71425a9772c547b Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 15 Feb 2021 18:53:18 -0800
Subject: [PATCH v3] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE

When linking Windows x86-64 relocatable object files to generate x86-64
ELF executable, we need to subtract __ImageBase, aka __executable_start,
for R_AMD64_IMAGEBASE relocation.

1. Add link_info to struct output_elf_obj_tdata to store optional linker
information and _bfd_get_link_info() to retrieve it.
2. Set link_info up in _bfd_elf_linker_x86_set_options.
3. Create an indirect reference to __executable_start for __ImageBase to
support R_AMD64_IMAGEBASE relocation when seeing Windows x86-64 relocatable
object files.
4. Subtract __ImageBase for R_AMD64_IMAGEBASE in R_AMD64_IMAGEBASE.

The howto special function, coff_amd64_reloc, isn't changed since

1. Any changes to coff_amd64_reloc may break Windows x86-64 linker.
2. bfd_perform_relocation changes are safe since they are limited to
generating x86-64 ELF executable from Windows x86-64 relocatable object
files.

bfd/

	PR ld/27425
	PR ld/27432
	* bfd.c (_bfd_get_link_info): New function.
	* elf-bfd.h (output_elf_obj_tdata): Add link_info.
	(elf_link_info): New.
	* elfxx-x86.c (_bfd_elf_linker_x86_set_options): Set up link_info.
	* libbfd-in.h (_bfd_get_link_info): New prototype.
	* reloc.c (bfd_perform_relocation): Subtract __ImageBase for
	R_AMD64_IMAGEBASE.
	* libbfd.h: Regenerated.

ld/

	PR ld/27425
	PR ld/27432
	* ldelf.c (ldelf_load_symbols): Create an indirect reference to
	__executable_start for __ImageBase to support R_AMD64_IMAGEBASE
	relocation when seeing Windows x86-64 relocatable inputs.
	* ld-x86-64/pe-x86-64-1.od: Expect __executable_start.
	* testsuite/ld-x86-64/pe-x86-64-2.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-3.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-4.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-5.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-5.rd: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-6.obj.bz2: New file.
	* testsuite/ld-x86-64/pe-x86-64-6.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64.exp: Run ld/27425 test.
---
 bfd/bfd.c                                  |  11 +++
 bfd/elf-bfd.h                              |   4 +
 bfd/elfxx-x86.c                            |   2 +
 bfd/libbfd-in.h                            |   2 +
 bfd/libbfd.h                               |   2 +
 bfd/reloc.c                                |  50 ++++++++---
 ld/ldelf.c                                 |  24 ++++++
 ld/testsuite/ld-x86-64/pe-x86-64-1.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-2.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-3.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-4.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-5.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-5.rd      |   3 +-
 ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2 | Bin 0 -> 1366 bytes
 ld/testsuite/ld-x86-64/pe-x86-64-6.od      |  91 +++++++++++++++++++++
 ld/testsuite/ld-x86-64/pe-x86-64.exp       |   9 ++
 16 files changed, 189 insertions(+), 14 deletions(-)
 create mode 100644 ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2
 create mode 100644 ld/testsuite/ld-x86-64/pe-x86-64-6.od

diff --git a/bfd/bfd.c b/bfd/bfd.c
index f1944338838..2cf7b47bca1 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -2808,3 +2808,14 @@ bfd_convert_section_contents (bfd *ibfd, sec_ptr isec, bfd *obfd,
   *ptr_size = size;
   return TRUE;
 }
+
+/* Get the optional linker information.  */
+
+struct bfd_link_info *
+_bfd_get_link_info (bfd *abfd)
+{
+  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+    return NULL;
+
+  return elf_link_info (abfd);
+}
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index dd66d98883e..c2aaab0e5bf 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1887,6 +1887,9 @@ struct output_elf_obj_tdata
   /* Used when laying out sections.  */
   file_ptr next_file_pos;
 
+  /* Optional linker information.  */
+  struct bfd_link_info *link_info;
+
   int num_section_syms;
   unsigned int shstrtab_section, strtab_section;
 
@@ -2064,6 +2067,7 @@ struct elf_obj_tdata
 #define elf_elfsections(bfd)	(elf_tdata(bfd) -> elf_sect_ptr)
 #define elf_numsections(bfd)	(elf_tdata(bfd) -> num_elf_sections)
 #define elf_seg_map(bfd)	(elf_tdata(bfd) -> o->seg_map)
+#define elf_link_info(bfd)	(elf_tdata(bfd) -> o->link_info)
 #define elf_next_file_pos(bfd)	(elf_tdata(bfd) -> o->next_file_pos)
 #define elf_eh_frame_hdr(bfd)	(elf_tdata(bfd) -> o->eh_frame_hdr)
 #define elf_stack_flags(bfd)	(elf_tdata(bfd) -> o->stack_flags)
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 93ad38c5eb0..e60d87ff981 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -3174,6 +3174,8 @@ _bfd_elf_linker_x86_set_options (struct bfd_link_info * info,
     = get_elf_backend_data (info->output_bfd);
   struct elf_x86_link_hash_table *htab
     = elf_x86_hash_table (info, bed->target_id);
+  if (info->output_bfd->xvec->flavour == bfd_target_elf_flavour)
+    elf_link_info (info->output_bfd) = info;
   if (htab != NULL)
     htab->params = params;
 }
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index 2dc20ec1b19..62b1cee0af0 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -899,6 +899,8 @@ extern bfd_vma _bfd_safe_read_leb128
 extern bfd_byte * _bfd_write_unsigned_leb128
   (bfd_byte *, bfd_byte *, bfd_vma) ATTRIBUTE_HIDDEN;
 
+extern struct bfd_link_info *_bfd_get_link_info (bfd *);
+
 #if GCC_VERSION >= 7000
 #define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
 #else
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 7271a2ad5a1..3a481ea468f 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -904,6 +904,8 @@ extern bfd_vma _bfd_safe_read_leb128
 extern bfd_byte * _bfd_write_unsigned_leb128
   (bfd_byte *, bfd_byte *, bfd_vma) ATTRIBUTE_HIDDEN;
 
+extern struct bfd_link_info *_bfd_get_link_info (bfd *);
+
 #if GCC_VERSION >= 7000
 #define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
 #else
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 4f4b95a0b7f..c893fbc2489 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -913,20 +913,44 @@ space consuming.  For each target:
 		      "elf64-x86-64") == 0)
     {
       /* NB: bfd_perform_relocation isn't called to generate PE binary.
-	 _bfd_relocate_contents is called instead.  When linking PE
-	 object files to generate ELF output, _bfd_relocate_contents
-	 isn't called and bfd_perform_relocation is used.  We need to
-	 adjust relocation here.  */
-      relocation -= reloc_entry->addend;
-      if (howto->type >= R_AMD64_PCRLONG_1
-	  && howto->type <= R_AMD64_PCRLONG_5)
-	relocation -= (bfd_vma)(howto->type - R_AMD64_PCRLONG);
-      else if (howto->type == R_AMD64_DIR64
-	       || howto->type == R_AMD64_DIR32)
+	 _bfd_relocate_contents is called instead.  When linking Windows
+	 x86-64 relocatable object files to generate ELF output,
+	 _bfd_relocate_contents isn't called and bfd_perform_relocation
+	 is used.  We need to adjust relocation here.  */
+      if (howto->type == R_AMD64_IMAGEBASE)
 	{
-	  bfd_vma val = read_reloc (abfd, (bfd_byte *) data + octets,
-				    howto);
-	  relocation -= val & howto->src_mask;
+	  /* Subtract __ImageBase.  */
+	  struct bfd_link_info *link_info;
+	  struct bfd_link_hash_entry *h;
+	  link_info
+	    = _bfd_get_link_info (input_section->output_section->owner);
+	  if (link_info == NULL)
+	    abort ();
+	  h = bfd_link_hash_lookup (link_info->hash, "__ImageBase",
+				    FALSE, FALSE, FALSE);
+	  if (h == NULL)
+	    abort ();
+	  while (h->type == bfd_link_hash_indirect)
+	    h = h->u.i.link;
+	  /* ELF symbols in relocatable files are section relative,
+	     but in nonrelocatable files they are virtual addresses.  */
+	  relocation -= (h->u.def.value
+			 + h->u.def.section->output_offset
+			 + h->u.def.section->output_section->vma);
+	}
+      else
+	{
+	  relocation -= reloc_entry->addend;
+	  if (howto->type >= R_AMD64_PCRLONG_1
+	      && howto->type <= R_AMD64_PCRLONG_5)
+	    relocation -= (bfd_vma)(howto->type - R_AMD64_PCRLONG);
+	  else if (howto->type == R_AMD64_DIR64
+		   || howto->type == R_AMD64_DIR32)
+	    {
+	      bfd_vma val = read_reloc (abfd, (bfd_byte *) data + octets,
+					howto);
+	      relocation -= val & howto->src_mask;
+	    }
 	}
     }
 
diff --git a/ld/ldelf.c b/ld/ldelf.c
index 049992544a2..c7de958dbdc 100644
--- a/ld/ldelf.c
+++ b/ld/ldelf.c
@@ -81,6 +81,30 @@ ldelf_load_symbols (lang_input_statement_type *entry)
 {
   int link_class = 0;
 
+  if (bfd_link_pde (&link_info)
+      && entry->the_bfd->xvec->flavour == bfd_target_coff_flavour
+      && strcmp (entry->the_bfd->xvec->name, "pe-x86-64") == 0
+      && strcmp (link_info.output_bfd->xvec->name, "elf64-x86-64") == 0)
+    {
+      /* NB: When linking Windows x86-64 relocatable object files to
+	 generate ELF executable, create an indirect reference to
+	 __executable_start for __ImageBase to support R_AMD64_IMAGEBASE
+	 relocation which is relative to __ImageBase.  */
+      struct elf_link_hash_table *htab = elf_hash_table (&link_info);
+      struct elf_link_hash_entry *h, *hi;
+      hi = elf_link_hash_lookup (htab, "__ImageBase", TRUE, FALSE,
+				 FALSE);
+      if (hi->root.type == bfd_link_hash_new
+	  || hi->type == bfd_link_hash_undefined
+	  || hi->type == bfd_link_hash_undefweak)
+	{
+	  h = elf_link_hash_lookup (htab, "__executable_start",
+				    TRUE, FALSE, TRUE);
+	  hi->root.type = bfd_link_hash_indirect;
+	  hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
+	}
+    }
+
   /* Tell the ELF linker that we don't want the output file to have a
      DT_NEEDED entry for this file, unless it is used to resolve
      references in a regular object.  */
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-1.od b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-1.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-2.od b/ld/testsuite/ld-x86-64/pe-x86-64-2.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-2.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-2.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-3.od b/ld/testsuite/ld-x86-64/pe-x86-64-3.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-3.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-3.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-4.od b/ld/testsuite/ld-x86-64/pe-x86-64-4.od
index e0bde11d84e..320c6be5e14 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-4.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-4.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+403038 g       .bss	0000000000000000 c
 0+401000 g       .text\$mn	0000000000000000 begin
 0+403038 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-5.od b/ld/testsuite/ld-x86-64/pe-x86-64-5.od
index 8a4f4a633ac..6ef13abbc94 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-5.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-5.od
@@ -4,6 +4,7 @@
 SYMBOL TABLE:
 0+402014 g       .bss	0000000000000000 non_initdummy
 0+402010 g       .data	0000000000000000 initdummy
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 begin
 0+402012 g       .bss	0000000000000000 __bss_start
 0+402000 g       .data	0000000000000000 Struct
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-5.rd b/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
index 8370665f99f..237052805e9 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
@@ -1,9 +1,10 @@
 
-Symbol table '.symtab' contains 10 entries:
+Symbol table '.symtab' contains 11 entries:
    Num:    Value          Size Type    Bind   Vis      Ndx Name
  +[a-f0-9]+: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
  +[a-f0-9]+: 0000000000402014     0 NOTYPE  GLOBAL DEFAULT    3 non_initdummy
  +[a-f0-9]+: 0000000000402010     0 NOTYPE  GLOBAL DEFAULT    2 initdummy
+ +[a-f0-9]+: 0000000000400000     0 NOTYPE  GLOBAL DEFAULT    1 __executable_start
  +[a-f0-9]+: 0000000000401000     0 NOTYPE  GLOBAL DEFAULT    1 begin
  +[a-f0-9]+: 0000000000402012     0 NOTYPE  GLOBAL DEFAULT    3 __bss_start
  +[a-f0-9]+: 0000000000402000     0 NOTYPE  GLOBAL DEFAULT    2 Struct
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2 b/ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..38255045d45ed918857b2c966400c13a13ea6c07
GIT binary patch
literal 1366
zcmV-c1*!T%T4*^jL0KkKSr(o^9smO9fB*mf|Nh_a|NQ^||Nj5~-}TM^Q*@d9YgPW;
zd+eHR_F&KhxOk{DUEM>1DTr#B8Vxi9QxnNB$qe;OMn*LZjWonG!KBke34qcKG#-Lu
zO+n}oJfkP-n1+}m6BA7tp+8jd3aO!pXvlhuKmni)7)=4727@32A)%%dK*9h3GyobJ
zF#(`ypa1~S&<2Qtn+c+6qtZ`M(<VowN$4g48fl<tXa<3x8X7%78Z>F3218950002c
z8UPw-&;$&OhMHssLqH6JBSwQEplP9@hychk8Z-t#7$DFx0MG!_Kn#r-BS2^XN+L#+
zMDk%qX+0wvnd*n6$Y=o5O#sjXO#o;B000^Q000000BC8T01Y)6t0Ij%1~1Zx-ljTP
zv7~$gP4n@oNq~cfwyu(S%%**p^kz*r4rRAWRcTbfRNzb)2)m)XQMb&4JUVWwY*_%P
z_N_!via~?|2}vgnKR75Sr_AXg#*K-lYBJ6&yOYkj3SvkC7BnqXI+`VjgE9yrmM|#Z
zAcU!thFfPL@ogO(W&_wPR?O<Nl`>0!yz(SMNI$pgD>nP`qq5&di9Y(;<tzfve#7RV
zLQq7sR8<iKE~*d}9#I&mh}9UVJg8-r7@=xZ2NcmYhaEyPiYfpN6hw+h7>GbrM+HPo
z!i9>{yG<#;mMI1E_Jr`*O+8>~P!*e8kP;V5^pWooq=L*qp)SmVWvfu>f>_r&r(rc;
zFlw0LN0dbVEA<6bekiD-s;40s%X>e{Bpb{0V*cpCy@Z%%2(;IT0ltH`?_5}n<UzB5
zf*?Wx?9SUxvoz5xvF*HU!`az<4cefwMgW_uK?W~)_YEp5)<A$@1UQMSt7Vh|X$!8S
zrYkdd%PnrQQ=JI}l%S=Jf?!qja8)kH^@O)sYfeI3m645L`q5BGerN)K?of-0r#>n|
zIJ>G_Jer_3(hAJw3_-j#7s1%O?->CeCR~1-d~uAqlkd=kBse0+P!fP8Gf5HP-!7%i
zY9#t2m+xTN{>23e(7a+I0;{Zo0pKlR8D<0+3~@0q!8UtF@$=vS%Ru|zVD9FpjySx}
zt{H?(&9Uu<p2jzU;|+yP-xYy^SQTmsWFw3b42s1?DxF}&SjcKo)TM}4B<*K1;RKpr
zB9L9W4U0w48Omi$FhV&*nXBTNgK+&nY+(ea!;BBmP6EO12PwtkmC_%#RsA$z@0JaQ
zK;1$!^T@K75<Qv*kCpFrll-gW?LaFYfjkRsvaL~}G=vHfYrg~uZV?6S9IpF-0+5}A
z_)^1T9VRd5A4+zwe~%URaNDw|ovUUIblXiY&aNu_D<Fy>a;O36%A;_CC4P{I;g8Lc
z_oIb1Th5wd#<v-tRhnyBD_BF4(rrdPfGi+1Cj(c?t7>6DvSmSitld-B7DP!ulPV)v
zjtH{yhbV)vqPiypj+2XeCuKWhP+%%5BxPTeR&+A6ME(Spj<8A+AT>of%9IL${b3$W
zT;V{<37R=3O12yjn;D3J_1es%R~rCwc#07V>0~}6Ocbcd(xo^hbFZ_E5g`dK4J43;
zL!(RF%z~VRcxJ6*mWojmVMt69!e|;&A4@D>YChtn2o?5O0qUo}T)OBf@?k*9{q-V&
zj?~DI4x)@7n$%$cCX*@q$)0{8UXMIXT<xV^S2T@qb<#e0E#AcXnZlt{eAv$l(KnN1
zj%}2QO$7taoaiC>k}0dYOV~!Q%X-@vZSVa^tl(<I`&6AfE`zbF1)s_=HB>Bd6H=xt
Y$~B;AV5AHi$*u8sBvXY60cqp`;GR@oQ~&?~

literal 0
HcmV?d00001

diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-6.od b/ld/testsuite/ld-x86-64/pe-x86-64-6.od
new file mode 100644
index 00000000000..cc23658a806
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-6.od
@@ -0,0 +1,91 @@
+
+.*: +file format .*
+
+SYMBOL TABLE:
+0+4010a8 g       .text\$mn	0000000000000000 xfunc
+0+402000 g       .rdata	0000000000000000 \?\?_C@_02LDKJOMJN@AB@
+0+400000 g       .text\$mn	0000000000000000 __executable_start
+0+403058 g       .data	0000000000000000 __bss_start
+0+401000 g       .text\$mn	0000000000000000 main
+0+403038 g       .data	0000000000000000 deadloopvar
+0+4010ac g       .text\$mn	0000000000000000 xstring
+0+403058 g       .data	0000000000000000 _edata
+0+403058 g       .data	0000000000000000 _end
+
+
+
+Disassembly of section .text\$mn:
+
+0+401000 <main>:
+ +[a-f0-9]+:	48 89 5c 24 08       	mov    %rbx,0x8\(%rsp\)
+ +[a-f0-9]+:	48 89 6c 24 10       	mov    %rbp,0x10\(%rsp\)
+ +[a-f0-9]+:	48 89 74 24 20       	mov    %rsi,0x20\(%rsp\)
+ +[a-f0-9]+:	57                   	push   %rdi
+ +[a-f0-9]+:	48 83 ec 20          	sub    \$0x20,%rsp
+ +[a-f0-9]+:	cc                   	int3   
+ +[a-f0-9]+:	8b 05 1d 20 00 00    	mov    0x201d\(%rip\),%eax        # 403038 <deadloopvar>
+ +[a-f0-9]+:	83 f8 01             	cmp    \$0x1,%eax
+ +[a-f0-9]+:	74 f5                	je     401015 <main\+0x15>
+ +[a-f0-9]+:	0f 31                	rdtsc  
+ +[a-f0-9]+:	48 c1 e2 20          	shl    \$0x20,%rdx
+ +[a-f0-9]+:	48 0b c2             	or     %rdx,%rax
+ +[a-f0-9]+:	74 5d                	je     401088 <main\+0x88>
+ +[a-f0-9]+:	33 ff                	xor    %edi,%edi
+ +[a-f0-9]+:	48 8d 2d cc ef ff ff 	lea    -0x1034\(%rip\),%rbp        # 400000 <__executable_start>
+ +[a-f0-9]+:	33 db                	xor    %ebx,%ebx
+ +[a-f0-9]+:	48 8d 35 ff 1f 00 00 	lea    0x1fff\(%rip\),%rsi        # 40303c <deadloopvar\+0x4>
+ +[a-f0-9]+:	48 8b 8c 2b 50 30 00 00 	mov    0x3050\(%rbx,%rbp,1\),%rcx
+ +[a-f0-9]+:	44 8a 01             	mov    \(%rcx\),%r8b
+ +[a-f0-9]+:	45 84 c0             	test   %r8b,%r8b
+ +[a-f0-9]+:	74 28                	je     401075 <main\+0x75>
+ +[a-f0-9]+:	b8 05 00 00 00       	mov    \$0x5,%eax
+ +[a-f0-9]+:	2b 84 2b 48 30 00 00 	sub    0x3048\(%rbx,%rbp,1\),%eax
+ +[a-f0-9]+:	99                   	cltd   
+ +[a-f0-9]+:	2b c2                	sub    %edx,%eax
+ +[a-f0-9]+:	d1 f8                	sar    %eax
+ +[a-f0-9]+:	48 63 d0             	movslq %eax,%rdx
+ +[a-f0-9]+:	48 03 d6             	add    %rsi,%rdx
+ +[a-f0-9]+:	48 ff c1             	inc    %rcx
+ +[a-f0-9]+:	44 88 02             	mov    %r8b,\(%rdx\)
+ +[a-f0-9]+:	48 ff c2             	inc    %rdx
+ +[a-f0-9]+:	44 8a 01             	mov    \(%rcx\),%r8b
+ +[a-f0-9]+:	45 84 c0             	test   %r8b,%r8b
+ +[a-f0-9]+:	75 ef                	jne    401064 <main\+0x64>
+ +[a-f0-9]+:	48 8b ce             	mov    %rsi,%rcx
+ +[a-f0-9]+:	e8 2f 00 00 00       	call   4010ac <xstring>
+ +[a-f0-9]+:	ff c7                	inc    %edi
+ +[a-f0-9]+:	48 83 c3 08          	add    \$0x8,%rbx
+ +[a-f0-9]+:	83 ff 01             	cmp    \$0x1,%edi
+ +[a-f0-9]+:	72 b5                	jb     40103d <main\+0x3d>
+ +[a-f0-9]+:	b1 aa                	mov    \$0xaa,%cl
+ +[a-f0-9]+:	e8 19 00 00 00       	call   4010a8 <xfunc>
+ +[a-f0-9]+:	48 8b 5c 24 30       	mov    0x30\(%rsp\),%rbx
+ +[a-f0-9]+:	33 c0                	xor    %eax,%eax
+ +[a-f0-9]+:	48 8b 6c 24 38       	mov    0x38\(%rsp\),%rbp
+ +[a-f0-9]+:	48 8b 74 24 48       	mov    0x48\(%rsp\),%rsi
+ +[a-f0-9]+:	48 83 c4 20          	add    \$0x20,%rsp
+ +[a-f0-9]+:	5f                   	pop    %rdi
+ +[a-f0-9]+:	c3                   	ret    
+ +[a-f0-9]+:	66 90                	xchg   %ax,%ax
+
+0+4010a8 <xfunc>:
+ +[a-f0-9]+:	66 90                	xchg   %ax,%ax
+ +[a-f0-9]+:	cc                   	int3   
+ +[a-f0-9]+:	c3                   	ret    
+
+0+4010ac <xstring>:
+ +[a-f0-9]+:	40 53                	rex push %rbx
+ +[a-f0-9]+:	48 83 ec 20          	sub    \$0x20,%rsp
+ +[a-f0-9]+:	8a 01                	mov    \(%rcx\),%al
+ +[a-f0-9]+:	48 8b d9             	mov    %rcx,%rbx
+ +[a-f0-9]+:	eb 0c                	jmp    4010c5 <xstring\+0x19>
+ +[a-f0-9]+:	8a c8                	mov    %al,%cl
+ +[a-f0-9]+:	e8 e8 ff ff ff       	call   4010a8 <xfunc>
+ +[a-f0-9]+:	48 ff c3             	inc    %rbx
+ +[a-f0-9]+:	8a 03                	mov    \(%rbx\),%al
+ +[a-f0-9]+:	84 c0                	test   %al,%al
+ +[a-f0-9]+:	75 f0                	jne    4010b9 <xstring\+0xd>
+ +[a-f0-9]+:	48 83 c4 20          	add    \$0x20,%rsp
+ +[a-f0-9]+:	5b                   	pop    %rbx
+ +[a-f0-9]+:	c3                   	ret    
+#pass
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64.exp b/ld/testsuite/ld-x86-64/pe-x86-64.exp
index ccfcdfaddfb..f5d2c84f283 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64.exp
+++ b/ld/testsuite/ld-x86-64/pe-x86-64.exp
@@ -73,4 +73,13 @@ run_ld_link_tests [list \
 	 {readelf {-s -x .data} pe-x86-64-5.rd}} \
 	"pe-x86-64-5" \
     ] \
+    [list \
+	"Build pe-x86-64-6" \
+	"-m elf_x86_64 --entry=main" \
+	"" \
+	"" \
+	{pe-x86-64-6.obj.bz2 } \
+	{{objdump {-dw --sym} pe-x86-64-6.od}} \
+	"pe-x86-64-6" \
+    ] \
 ]
-- 
2.29.2


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v3] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-02-28  2:38                   ` [PATCH v3] " H.J. Lu
@ 2021-03-01 12:19                     ` Alan Modra
  2021-03-01 13:44                       ` H.J. Lu
  0 siblings, 1 reply; 22+ messages in thread
From: Alan Modra @ 2021-03-01 12:19 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Jan Beulich, Binutils

On Sat, Feb 27, 2021 at 06:38:24PM -0800, H.J. Lu wrote:
> On Wed, Feb 24, 2021 at 6:09 PM Alan Modra <amodra@gmail.com> wrote:
> >
> > On Tue, Feb 23, 2021 at 09:50:20AM -0800, H.J. Lu via Binutils wrote:
> > >       * reloc.c (bfd_perform_relocation): Add a link_info argument.
> > >       Subtract __ImageBase for R_AMD64_IMAGEBASE.
> >
> > H.J., did you consider moving all of this, including the code you
> > added in git commit 36068e2fa54, to the relevant howto special
> > functions?  None of it really belongs in bfd_perform_relocation.
> 
> The howto special function, coff_amd64_reloc, isn't changed since
> 
> 1. Any changes to coff_amd64_reloc may break Windows x86-64 linker.

I am sure you are capable of making those changes without breaking
windows.

> 2. bfd_perform_relocation changes are safe since they are limited to
> generating x86-64 ELF executable from Windows x86-64 relocatable object
> files.

It is the wrong place.  Every time bfd_perform_relocation is called
with a coff input it now needs to test for output to ELF.  If you did
this properly in a howto function then the extra tests would only be
done for x86_64 coff.  Besides the performance impact, nobody
maintaining reloc.c wants to deal with code specially for pe-x86-64
and elf64-x84-64.  The special case for coff there is already
horrible.  It shouldn't be made worse.

Did anyone review your commit 36068e2fa54?

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v3] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-03-01 12:19                     ` Alan Modra
@ 2021-03-01 13:44                       ` H.J. Lu
  2021-03-04 13:14                         ` Alan Modra
  0 siblings, 1 reply; 22+ messages in thread
From: H.J. Lu @ 2021-03-01 13:44 UTC (permalink / raw)
  To: Alan Modra; +Cc: Jan Beulich, Binutils

On Mon, Mar 1, 2021 at 4:19 AM Alan Modra <amodra@gmail.com> wrote:
>
> On Sat, Feb 27, 2021 at 06:38:24PM -0800, H.J. Lu wrote:
> > On Wed, Feb 24, 2021 at 6:09 PM Alan Modra <amodra@gmail.com> wrote:
> > >
> > > On Tue, Feb 23, 2021 at 09:50:20AM -0800, H.J. Lu via Binutils wrote:
> > > >       * reloc.c (bfd_perform_relocation): Add a link_info argument.
> > > >       Subtract __ImageBase for R_AMD64_IMAGEBASE.
> > >
> > > H.J., did you consider moving all of this, including the code you
> > > added in git commit 36068e2fa54, to the relevant howto special
> > > functions?  None of it really belongs in bfd_perform_relocation.
> >
> > The howto special function, coff_amd64_reloc, isn't changed since
> >
> > 1. Any changes to coff_amd64_reloc may break Windows x86-64 linker.
>
> I am sure you are capable of making those changes without breaking
> windows.

The difficult part is I can't test it.

> > 2. bfd_perform_relocation changes are safe since they are limited to
> > generating x86-64 ELF executable from Windows x86-64 relocatable object
> > files.
>
> It is the wrong place.  Every time bfd_perform_relocation is called
> with a coff input it now needs to test for output to ELF.  If you did
> this properly in a howto function then the extra tests would only be

bfd_perform_relocation is called with

           r = bfd_perform_relocation (input_bfd,
                                        *parent,
                                        data,
                                        input_section,
                                        relocatable ? abfd : NULL,
<<< output_bfd
                                        &error_message);

and coff_amd64_reloc is very hard to understand.

> done for x86_64 coff.  Besides the performance impact, nobody
> maintaining reloc.c wants to deal with code specially for pe-x86-64
> and elf64-x84-64.  The special case for coff there is already
> horrible.  It shouldn't be made worse.

 I made the change in bfd_perform_relocation since the COFF
linker is very delicate.

> Did anyone review your commit 36068e2fa54?

No.  My change is limited to a very special case of ELF/x86-64.

bfd_perform_relocation has

      /* WTF?? */
      if (abfd->xvec->flavour == bfd_target_coff_flavour
          && strcmp (abfd->xvec->name, "coff-Intel-little") != 0
          && strcmp (abfd->xvec->name, "coff-Intel-big") != 0)
        {

with a long comment.   I added:

 else if (abfd->xvec->flavour == bfd_target_coff_flavour
           && (input_section->output_section->owner->xvec->flavour
               == bfd_target_elf_flavour)
           && strcmp (abfd->xvec->name, "pe-x86-64") == 0
           && strcmp (input_section->output_section->owner->xvec->name,
                      "elf64-x86-64") == 0)

Its performance impact should be low.

-- 
H.J.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v3] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-03-01 13:44                       ` H.J. Lu
@ 2021-03-04 13:14                         ` Alan Modra
  2021-03-04 13:54                           ` [PATCH v4] " H.J. Lu
  0 siblings, 1 reply; 22+ messages in thread
From: Alan Modra @ 2021-03-04 13:14 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Jan Beulich, Binutils

On Mon, Mar 01, 2021 at 05:44:48AM -0800, H.J. Lu wrote:
> On Mon, Mar 1, 2021 at 4:19 AM Alan Modra <amodra@gmail.com> wrote:
> >
> > On Sat, Feb 27, 2021 at 06:38:24PM -0800, H.J. Lu wrote:
> > > On Wed, Feb 24, 2021 at 6:09 PM Alan Modra <amodra@gmail.com> wrote:
> > > >
> > > > On Tue, Feb 23, 2021 at 09:50:20AM -0800, H.J. Lu via Binutils wrote:
> > > > >       * reloc.c (bfd_perform_relocation): Add a link_info argument.
> > > > >       Subtract __ImageBase for R_AMD64_IMAGEBASE.
> > > >
> > > > H.J., did you consider moving all of this, including the code you
> > > > added in git commit 36068e2fa54, to the relevant howto special
> > > > functions?  None of it really belongs in bfd_perform_relocation.
> > >
> > > The howto special function, coff_amd64_reloc, isn't changed since
> > >
> > > 1. Any changes to coff_amd64_reloc may break Windows x86-64 linker.
> >
> > I am sure you are capable of making those changes without breaking
> > windows.
> 
> The difficult part is I can't test it.

Which says that you also can't test your bfd_perform_relocation
changes on windows.

> > > 2. bfd_perform_relocation changes are safe since they are limited to
> > > generating x86-64 ELF executable from Windows x86-64 relocatable object
> > > files.
> >
> > It is the wrong place.  Every time bfd_perform_relocation is called
> > with a coff input it now needs to test for output to ELF.  If you did
> > this properly in a howto function then the extra tests would only be
> 
> bfd_perform_relocation is called with
> 
>            r = bfd_perform_relocation (input_bfd,
>                                         *parent,
>                                         data,
>                                         input_section,
>                                         relocatable ? abfd : NULL,
> <<< output_bfd
>                                         &error_message);
> 
> and coff_amd64_reloc is very hard to understand.

Yes, it surely is.  You do realize that coff_amd64_reloc has already
made changes to the section contents before you again make changes in
bfd_perform_relocation.  Arguing that it is easier to support ELF
output in bfd_perform_relocation doesn't make much sense.  To do it
correctly there you need to understand coff_amd64_reloc anyway.

Are your bfd_perform_relocation changes correct for every x86_64 PE
reloc, and for weak and common symbols?

> 
> > done for x86_64 coff.  Besides the performance impact, nobody
> > maintaining reloc.c wants to deal with code specially for pe-x86-64
> > and elf64-x84-64.  The special case for coff there is already
> > horrible.  It shouldn't be made worse.
> 
>  I made the change in bfd_perform_relocation since the COFF
> linker is very delicate.
> 
> > Did anyone review your commit 36068e2fa54?
> 
> No.  My change is limited to a very special case of ELF/x86-64.
> 
> bfd_perform_relocation has
> 
>       /* WTF?? */
>       if (abfd->xvec->flavour == bfd_target_coff_flavour
>           && strcmp (abfd->xvec->name, "coff-Intel-little") != 0
>           && strcmp (abfd->xvec->name, "coff-Intel-big") != 0)
>         {
> 
> with a long comment.   I added:

Right, and the "WTF??" is exclaiming that this sort of thing should
not be done in bfd_perform_relocation.  The long comment is trying to
explain why it is there anyway, and reinforcing what I'm saying says
this: "The first obvious point is that bfd_perform_relocation should
not have any tests that depend upon the flavour."

I'm going to revert your bfd_perform_relocation changes, and possibly
apply a much simpler coff_amd64_reloc change that happens to make
things work for the testcases you added.  I have no confidence that
the coff_amd64_reloc patch is correct in all cases, but it looks more
reasonable to me.  I'd appreciate you checking it.

	* reloc.c (bfd_perform_relocation): Revert 2021-01-12 and
	2020-09-16 changes.
	* coff-x86_64.c (coff_amd64_reloc): Do more or less the same
	adjustments here instead.  Tidy comments and formatting.

diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
index adab60cd11..63a7f06f9b 100644
--- a/bfd/coff-x86_64.c
+++ b/bfd/coff-x86_64.c
@@ -75,14 +75,14 @@ coff_amd64_reloc (bfd *abfd,
 {
   symvalue diff;
 
-#if !defined(COFF_WITH_PE)
+#if !defined (COFF_WITH_PE)
   if (output_bfd == NULL)
     return bfd_reloc_continue;
 #endif
 
   if (bfd_is_com_section (symbol->section))
     {
-#if !defined(COFF_WITH_PE)
+#if !defined (COFF_WITH_PE)
       /* We are relocating a common symbol.  The current value in the
 	 object file is ORIG + OFFSET, where ORIG is the value of the
 	 common symbol as seen by the object file when it was compiled
@@ -113,14 +113,14 @@ coff_amd64_reloc (bfd *abfd,
 
 	  /* Although PC relative relocations are very similar between
 	     PE and non-PE formats, but they are off by 1 << howto->size
-	     bytes. For the external relocation, PE is very different
-	     from others. See md_apply_fix3 () in gas/config/tc-amd64.c.
+	     bytes.  For the external relocation, PE is very different
+	     from others.  See md_apply_fix in gas/config/tc-i386.c.
 	     When we link PE and non-PE object files together to
 	     generate a non-PE executable, we have to compensate it
 	     here.  */
-	  if(howto->pc_relative && howto->pcrel_offset)
+	  if (howto->pc_relative && howto->pcrel_offset)
 	    diff = -(1 << howto->size);
-	  else if(symbol->flags & BSF_WEAK)
+	  else if (symbol->flags & BSF_WEAK)
 	    diff = reloc_entry->addend - symbol->value;
 	  else
 	    diff = -reloc_entry->addend;
@@ -130,7 +130,20 @@ coff_amd64_reloc (bfd *abfd,
 	diff = reloc_entry->addend;
     }
 
-#if defined(COFF_WITH_PE)
+#if defined (COFF_WITH_PE)
+  if (output_bfd == NULL
+      && (bfd_get_flavour (input_section->output_section->owner)
+	  == bfd_target_elf_flavour))
+    {
+      if (reloc_entry->howto->pc_relative)
+	{
+	  diff -= reloc_entry->addend;
+	  if (reloc_entry->howto->type >= R_AMD64_PCRLONG_1
+	      && reloc_entry->howto->type <= R_AMD64_PCRLONG_5)
+	    diff -= (bfd_vma) (reloc_entry->howto->type - R_AMD64_PCRLONG);
+	}
+    }
+
   /* FIXME: How should this case be handled?  */
   if (reloc_entry->howto->type == R_AMD64_IMAGEBASE
       && output_bfd != NULL
diff --git a/bfd/reloc.c b/bfd/reloc.c
index a7547187eb..5ed7bb8e59 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -51,7 +51,7 @@ SECTION
 #include "bfdlink.h"
 #include "libbfd.h"
 #include "bfdver.h"
-#include "coff/x86_64.h"
+
 /*
 DOCDD
 INODE
@@ -905,30 +905,6 @@ space consuming.  For each target:
 	    }
 	}
     }
-  else if (abfd->xvec->flavour == bfd_target_coff_flavour
-	   && (input_section->output_section->owner->xvec->flavour
-	       == bfd_target_elf_flavour)
-	   && strcmp (abfd->xvec->name, "pe-x86-64") == 0
-	   && strcmp (input_section->output_section->owner->xvec->name,
-		      "elf64-x86-64") == 0)
-    {
-      /* NB: bfd_perform_relocation isn't called to generate PE binary.
-	 _bfd_relocate_contents is called instead.  When linking PE
-	 object files to generate ELF output, _bfd_relocate_contents
-	 isn't called and bfd_perform_relocation is used.  We need to
-	 adjust relocation here.  */
-      relocation -= reloc_entry->addend;
-      if (howto->type >= R_AMD64_PCRLONG_1
-	  && howto->type <= R_AMD64_PCRLONG_5)
-	relocation -= (bfd_vma)(howto->type - R_AMD64_PCRLONG);
-      else if (howto->type == R_AMD64_DIR64
-	       || howto->type == R_AMD64_DIR32)
-	{
-	  bfd_vma val = read_reloc (abfd, (bfd_byte *) data + octets,
-				    howto);
-	  relocation -= val & howto->src_mask;
-	}
-    }
 
   /* FIXME: This overflow checking is incomplete, because the value
      might have overflowed before we get here.  For a correct check we

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v4] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-03-04 13:14                         ` Alan Modra
@ 2021-03-04 13:54                           ` H.J. Lu
  2021-03-05  5:17                             ` Alan Modra
  0 siblings, 1 reply; 22+ messages in thread
From: H.J. Lu @ 2021-03-04 13:54 UTC (permalink / raw)
  To: Alan Modra; +Cc: Jan Beulich, Binutils

On Thu, Mar 4, 2021 at 5:14 AM Alan Modra <amodra@gmail.com> wrote:
>
> On Mon, Mar 01, 2021 at 05:44:48AM -0800, H.J. Lu wrote:
> > On Mon, Mar 1, 2021 at 4:19 AM Alan Modra <amodra@gmail.com> wrote:
> > >
> > > On Sat, Feb 27, 2021 at 06:38:24PM -0800, H.J. Lu wrote:
> > > > On Wed, Feb 24, 2021 at 6:09 PM Alan Modra <amodra@gmail.com> wrote:
> > > > >
> > > > > On Tue, Feb 23, 2021 at 09:50:20AM -0800, H.J. Lu via Binutils wrote:
> > > > > >       * reloc.c (bfd_perform_relocation): Add a link_info argument.
> > > > > >       Subtract __ImageBase for R_AMD64_IMAGEBASE.
> > > > >
> > > > > H.J., did you consider moving all of this, including the code you
> > > > > added in git commit 36068e2fa54, to the relevant howto special
> > > > > functions?  None of it really belongs in bfd_perform_relocation.
> > > >
> > > > The howto special function, coff_amd64_reloc, isn't changed since
> > > >
> > > > 1. Any changes to coff_amd64_reloc may break Windows x86-64 linker.
> > >
> > > I am sure you are capable of making those changes without breaking
> > > windows.
> >
> > The difficult part is I can't test it.
>
> Which says that you also can't test your bfd_perform_relocation
> changes on windows.
>
> > > > 2. bfd_perform_relocation changes are safe since they are limited to
> > > > generating x86-64 ELF executable from Windows x86-64 relocatable object
> > > > files.
> > >
> > > It is the wrong place.  Every time bfd_perform_relocation is called
> > > with a coff input it now needs to test for output to ELF.  If you did
> > > this properly in a howto function then the extra tests would only be
> >
> > bfd_perform_relocation is called with
> >
> >            r = bfd_perform_relocation (input_bfd,
> >                                         *parent,
> >                                         data,
> >                                         input_section,
> >                                         relocatable ? abfd : NULL,
> > <<< output_bfd
> >                                         &error_message);
> >
> > and coff_amd64_reloc is very hard to understand.
>
> Yes, it surely is.  You do realize that coff_amd64_reloc has already
> made changes to the section contents before you again make changes in
> bfd_perform_relocation.  Arguing that it is easier to support ELF
> output in bfd_perform_relocation doesn't make much sense.  To do it
> correctly there you need to understand coff_amd64_reloc anyway.
>
> Are your bfd_perform_relocation changes correct for every x86_64 PE
> reloc, and for weak and common symbols?
>
> >
> > > done for x86_64 coff.  Besides the performance impact, nobody
> > > maintaining reloc.c wants to deal with code specially for pe-x86-64
> > > and elf64-x84-64.  The special case for coff there is already
> > > horrible.  It shouldn't be made worse.
> >
> >  I made the change in bfd_perform_relocation since the COFF
> > linker is very delicate.
> >
> > > Did anyone review your commit 36068e2fa54?
> >
> > No.  My change is limited to a very special case of ELF/x86-64.
> >
> > bfd_perform_relocation has
> >
> >       /* WTF?? */
> >       if (abfd->xvec->flavour == bfd_target_coff_flavour
> >           && strcmp (abfd->xvec->name, "coff-Intel-little") != 0
> >           && strcmp (abfd->xvec->name, "coff-Intel-big") != 0)
> >         {
> >
> > with a long comment.   I added:
>
> Right, and the "WTF??" is exclaiming that this sort of thing should
> not be done in bfd_perform_relocation.  The long comment is trying to
> explain why it is there anyway, and reinforcing what I'm saying says
> this: "The first obvious point is that bfd_perform_relocation should
> not have any tests that depend upon the flavour."
>
> I'm going to revert your bfd_perform_relocation changes, and possibly
> apply a much simpler coff_amd64_reloc change that happens to make
> things work for the testcases you added.  I have no confidence that
> the coff_amd64_reloc patch is correct in all cases, but it looks more
> reasonable to me.  I'd appreciate you checking it.
>
>         * reloc.c (bfd_perform_relocation): Revert 2021-01-12 and
>         2020-09-16 changes.
>         * coff-x86_64.c (coff_amd64_reloc): Do more or less the same
>         adjustments here instead.  Tidy comments and formatting.
>

Here is the v4 patch on top of yours.

Thanks.

-- 
H.J.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-03-04 13:54                           ` [PATCH v4] " H.J. Lu
@ 2021-03-05  5:17                             ` Alan Modra
  2021-03-05  5:29                               ` H.J. Lu
  0 siblings, 1 reply; 22+ messages in thread
From: Alan Modra @ 2021-03-05  5:17 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Jan Beulich, Binutils

On Thu, Mar 04, 2021 at 05:54:20AM -0800, H.J. Lu wrote:
> Here is the v4 patch on top of yours.

No patch?

This is what I'm about to commit, now rather than in a week's time
since you seem happy with it.  Changes from the previous patch are:
 - removed test of ELF output, the fixes are generic
 - untangled and corrected pc-relative adjustment to use
   bfd_get_reloc_size

There are some further obvious fixes to make as noted in the commit
log, but I'll leave that to someone with better access to PE
compilers.

----
Subject: Move x86_64 PE changes out of bfd_perform_relocation

bfd_perform_relocation should not have special case target code.  This
patch moves the code that was there for x86_64 PE linking to ELF
output into the x86_64 PE howto special function, correcting that
function for linking to targets other than ELF too.  The fixes in
bfd_perform_relocation were over-complicated due to needing to
compensate for things that had already gone wrong in coff_amd64_reloc.
In particular, an adjustment for pc-relative relocs was done in a way
that meant adjustment for things related to symbol offsets was lost.
I think those two things are orthogonal, but who knows with COFF where
addends and symbol values are found randomly in the section contents.

Note that linking natively to an x86_64 PE output relocates by
coff_pe_amd64_relocate_section, which does not use arelent relocs or
bfd_perform_relocation, but be aware of coff_amd64_rtype_to_howto
hacking addends for relocations.  The adjustments for a particular
relocation type there and in coff_amd64_reloc ought to match after
taking into consideration CALC_ADDEND.  They don't.  For example,
the pc-relative adjustment for R_PCRWORD is 2 bytes in
coff_amd64_reloc and 4 bytes in coff_amd64_rtype_to_howto.

	* reloc.c (bfd_perform_relocation): Revert 2021-01-12 and
	2020-09-16 changes.
	* coff-x86_64.c (coff_amd64_reloc): Do more or less the same
	adjustments here instead.  Separate pc-relative adjustments
	from symbol related adjustments.  Tidy comments and formatting.

diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
index adab60cd11..5b09023f3c 100644
--- a/bfd/coff-x86_64.c
+++ b/bfd/coff-x86_64.c
@@ -75,14 +75,14 @@ coff_amd64_reloc (bfd *abfd,
 {
   symvalue diff;
 
-#if !defined(COFF_WITH_PE)
+#if !defined (COFF_WITH_PE)
   if (output_bfd == NULL)
     return bfd_reloc_continue;
 #endif
 
   if (bfd_is_com_section (symbol->section))
     {
-#if !defined(COFF_WITH_PE)
+#if !defined (COFF_WITH_PE)
       /* We are relocating a common symbol.  The current value in the
 	 object file is ORIG + OFFSET, where ORIG is the value of the
 	 common symbol as seen by the object file when it was compiled
@@ -106,21 +106,10 @@ coff_amd64_reloc (bfd *abfd,
 	 ignores the addend for a COFF target when producing
 	 relocatable output.  This seems to be always wrong for 386
 	 COFF, so we handle the addend here instead.  */
-#if defined(COFF_WITH_PE)
+#if defined (COFF_WITH_PE)
       if (output_bfd == NULL)
 	{
-	  reloc_howto_type *howto = reloc_entry->howto;
-
-	  /* Although PC relative relocations are very similar between
-	     PE and non-PE formats, but they are off by 1 << howto->size
-	     bytes. For the external relocation, PE is very different
-	     from others. See md_apply_fix3 () in gas/config/tc-amd64.c.
-	     When we link PE and non-PE object files together to
-	     generate a non-PE executable, we have to compensate it
-	     here.  */
-	  if(howto->pc_relative && howto->pcrel_offset)
-	    diff = -(1 << howto->size);
-	  else if(symbol->flags & BSF_WEAK)
+	  if (symbol->flags & BSF_WEAK)
 	    diff = reloc_entry->addend - symbol->value;
 	  else
 	    diff = -reloc_entry->addend;
@@ -130,7 +119,18 @@ coff_amd64_reloc (bfd *abfd,
 	diff = reloc_entry->addend;
     }
 
-#if defined(COFF_WITH_PE)
+#if defined (COFF_WITH_PE)
+  if (output_bfd == NULL)
+    {
+      /* PC relative relocations are off by their size.  */
+      if (reloc_entry->howto->pc_relative)
+	diff -= bfd_get_reloc_size (reloc_entry->howto);
+
+      if (reloc_entry->howto->type >= R_AMD64_PCRLONG_1
+	  && reloc_entry->howto->type <= R_AMD64_PCRLONG_5)
+	diff -= reloc_entry->howto->type - R_AMD64_PCRLONG;
+    }
+
   /* FIXME: How should this case be handled?  */
   if (reloc_entry->howto->type == R_AMD64_IMAGEBASE
       && output_bfd != NULL
diff --git a/bfd/reloc.c b/bfd/reloc.c
index a7547187eb..5ed7bb8e59 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -51,7 +51,7 @@ SECTION
 #include "bfdlink.h"
 #include "libbfd.h"
 #include "bfdver.h"
-#include "coff/x86_64.h"
+
 /*
 DOCDD
 INODE
@@ -905,30 +905,6 @@ space consuming.  For each target:
 	    }
 	}
     }
-  else if (abfd->xvec->flavour == bfd_target_coff_flavour
-	   && (input_section->output_section->owner->xvec->flavour
-	       == bfd_target_elf_flavour)
-	   && strcmp (abfd->xvec->name, "pe-x86-64") == 0
-	   && strcmp (input_section->output_section->owner->xvec->name,
-		      "elf64-x86-64") == 0)
-    {
-      /* NB: bfd_perform_relocation isn't called to generate PE binary.
-	 _bfd_relocate_contents is called instead.  When linking PE
-	 object files to generate ELF output, _bfd_relocate_contents
-	 isn't called and bfd_perform_relocation is used.  We need to
-	 adjust relocation here.  */
-      relocation -= reloc_entry->addend;
-      if (howto->type >= R_AMD64_PCRLONG_1
-	  && howto->type <= R_AMD64_PCRLONG_5)
-	relocation -= (bfd_vma)(howto->type - R_AMD64_PCRLONG);
-      else if (howto->type == R_AMD64_DIR64
-	       || howto->type == R_AMD64_DIR32)
-	{
-	  bfd_vma val = read_reloc (abfd, (bfd_byte *) data + octets,
-				    howto);
-	  relocation -= val & howto->src_mask;
-	}
-    }
 
   /* FIXME: This overflow checking is incomplete, because the value
      might have overflowed before we get here.  For a correct check we


-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-03-05  5:17                             ` Alan Modra
@ 2021-03-05  5:29                               ` H.J. Lu
  2021-03-05 13:57                                 ` Alan Modra
  0 siblings, 1 reply; 22+ messages in thread
From: H.J. Lu @ 2021-03-05  5:29 UTC (permalink / raw)
  To: Alan Modra; +Cc: Jan Beulich, Binutils

[-- Attachment #1: Type: text/plain, Size: 6573 bytes --]

On Thu, Mar 4, 2021 at 9:17 PM Alan Modra <amodra@gmail.com> wrote:
>
> On Thu, Mar 04, 2021 at 05:54:20AM -0800, H.J. Lu wrote:
> > Here is the v4 patch on top of yours.
>
> No patch?
>
> This is what I'm about to commit, now rather than in a week's time
> since you seem happy with it.  Changes from the previous patch are:
>  - removed test of ELF output, the fixes are generic
>  - untangled and corrected pc-relative adjustment to use
>    bfd_get_reloc_size
>
> There are some further obvious fixes to make as noted in the commit
> log, but I'll leave that to someone with better access to PE
> compilers.
>
> ----
> Subject: Move x86_64 PE changes out of bfd_perform_relocation
>
> bfd_perform_relocation should not have special case target code.  This
> patch moves the code that was there for x86_64 PE linking to ELF
> output into the x86_64 PE howto special function, correcting that
> function for linking to targets other than ELF too.  The fixes in
> bfd_perform_relocation were over-complicated due to needing to
> compensate for things that had already gone wrong in coff_amd64_reloc.
> In particular, an adjustment for pc-relative relocs was done in a way
> that meant adjustment for things related to symbol offsets was lost.
> I think those two things are orthogonal, but who knows with COFF where
> addends and symbol values are found randomly in the section contents.
>
> Note that linking natively to an x86_64 PE output relocates by
> coff_pe_amd64_relocate_section, which does not use arelent relocs or
> bfd_perform_relocation, but be aware of coff_amd64_rtype_to_howto
> hacking addends for relocations.  The adjustments for a particular
> relocation type there and in coff_amd64_reloc ought to match after
> taking into consideration CALC_ADDEND.  They don't.  For example,
> the pc-relative adjustment for R_PCRWORD is 2 bytes in
> coff_amd64_reloc and 4 bytes in coff_amd64_rtype_to_howto.
>
>         * reloc.c (bfd_perform_relocation): Revert 2021-01-12 and
>         2020-09-16 changes.
>         * coff-x86_64.c (coff_amd64_reloc): Do more or less the same
>         adjustments here instead.  Separate pc-relative adjustments
>         from symbol related adjustments.  Tidy comments and formatting.
>
> diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
> index adab60cd11..5b09023f3c 100644
> --- a/bfd/coff-x86_64.c
> +++ b/bfd/coff-x86_64.c
> @@ -75,14 +75,14 @@ coff_amd64_reloc (bfd *abfd,
>  {
>    symvalue diff;
>
> -#if !defined(COFF_WITH_PE)
> +#if !defined (COFF_WITH_PE)
>    if (output_bfd == NULL)
>      return bfd_reloc_continue;
>  #endif
>
>    if (bfd_is_com_section (symbol->section))
>      {
> -#if !defined(COFF_WITH_PE)
> +#if !defined (COFF_WITH_PE)
>        /* We are relocating a common symbol.  The current value in the
>          object file is ORIG + OFFSET, where ORIG is the value of the
>          common symbol as seen by the object file when it was compiled
> @@ -106,21 +106,10 @@ coff_amd64_reloc (bfd *abfd,
>          ignores the addend for a COFF target when producing
>          relocatable output.  This seems to be always wrong for 386
>          COFF, so we handle the addend here instead.  */
> -#if defined(COFF_WITH_PE)
> +#if defined (COFF_WITH_PE)
>        if (output_bfd == NULL)
>         {
> -         reloc_howto_type *howto = reloc_entry->howto;
> -
> -         /* Although PC relative relocations are very similar between
> -            PE and non-PE formats, but they are off by 1 << howto->size
> -            bytes. For the external relocation, PE is very different
> -            from others. See md_apply_fix3 () in gas/config/tc-amd64.c.
> -            When we link PE and non-PE object files together to
> -            generate a non-PE executable, we have to compensate it
> -            here.  */
> -         if(howto->pc_relative && howto->pcrel_offset)
> -           diff = -(1 << howto->size);
> -         else if(symbol->flags & BSF_WEAK)
> +         if (symbol->flags & BSF_WEAK)
>             diff = reloc_entry->addend - symbol->value;
>           else
>             diff = -reloc_entry->addend;
> @@ -130,7 +119,18 @@ coff_amd64_reloc (bfd *abfd,
>         diff = reloc_entry->addend;
>      }
>
> -#if defined(COFF_WITH_PE)
> +#if defined (COFF_WITH_PE)
> +  if (output_bfd == NULL)
> +    {
> +      /* PC relative relocations are off by their size.  */
> +      if (reloc_entry->howto->pc_relative)
> +       diff -= bfd_get_reloc_size (reloc_entry->howto);
> +
> +      if (reloc_entry->howto->type >= R_AMD64_PCRLONG_1
> +         && reloc_entry->howto->type <= R_AMD64_PCRLONG_5)
> +       diff -= reloc_entry->howto->type - R_AMD64_PCRLONG;
> +    }
> +
>    /* FIXME: How should this case be handled?  */
>    if (reloc_entry->howto->type == R_AMD64_IMAGEBASE
>        && output_bfd != NULL
> diff --git a/bfd/reloc.c b/bfd/reloc.c
> index a7547187eb..5ed7bb8e59 100644
> --- a/bfd/reloc.c
> +++ b/bfd/reloc.c
> @@ -51,7 +51,7 @@ SECTION
>  #include "bfdlink.h"
>  #include "libbfd.h"
>  #include "bfdver.h"
> -#include "coff/x86_64.h"
> +
>  /*
>  DOCDD
>  INODE
> @@ -905,30 +905,6 @@ space consuming.  For each target:
>             }
>         }
>      }
> -  else if (abfd->xvec->flavour == bfd_target_coff_flavour
> -          && (input_section->output_section->owner->xvec->flavour
> -              == bfd_target_elf_flavour)
> -          && strcmp (abfd->xvec->name, "pe-x86-64") == 0
> -          && strcmp (input_section->output_section->owner->xvec->name,
> -                     "elf64-x86-64") == 0)
> -    {
> -      /* NB: bfd_perform_relocation isn't called to generate PE binary.
> -        _bfd_relocate_contents is called instead.  When linking PE
> -        object files to generate ELF output, _bfd_relocate_contents
> -        isn't called and bfd_perform_relocation is used.  We need to
> -        adjust relocation here.  */
> -      relocation -= reloc_entry->addend;
> -      if (howto->type >= R_AMD64_PCRLONG_1
> -         && howto->type <= R_AMD64_PCRLONG_5)
> -       relocation -= (bfd_vma)(howto->type - R_AMD64_PCRLONG);
> -      else if (howto->type == R_AMD64_DIR64
> -              || howto->type == R_AMD64_DIR32)
> -       {
> -         bfd_vma val = read_reloc (abfd, (bfd_byte *) data + octets,
> -                                   howto);
> -         relocation -= val & howto->src_mask;
> -       }
> -    }
>
>    /* FIXME: This overflow checking is incomplete, because the value
>       might have overflowed before we get here.  For a correct check we
>

Here is the v4 patch.  OK for master?

Thanks.

-- 
H.J.

[-- Attachment #2: v4-0001-elf-x86-64-Subtract-__ImageBase-for-R_AMD64_IMAGE.patch --]
[-- Type: text/x-patch, Size: 19560 bytes --]

From 5d2172fe937794079721186041538d3bdb0e3ac2 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 15 Feb 2021 18:53:18 -0800
Subject: [PATCH v4] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE

When linking Windows x86-64 relocatable object files to generate x86-64
ELF executable, we need to subtract __ImageBase, aka __executable_start,
for R_AMD64_IMAGEBASE relocation.

1. Add link_info to struct output_elf_obj_tdata to store optional linker
information and _bfd_get_link_info() to retrieve it.
2. Set link_info up in _bfd_elf_linker_x86_set_options.
3. Create an indirect reference to __executable_start for __ImageBase to
support R_AMD64_IMAGEBASE relocation when seeing Windows x86-64 relocatable
object files.
4. Subtract __ImageBase for R_AMD64_IMAGEBASE in R_AMD64_IMAGEBASE.

bfd/

	PR ld/27425
	PR ld/27432
	* bfd.c (_bfd_get_link_info): New function.
	* elf-bfd.h (output_elf_obj_tdata): Add link_info.
	(elf_link_info): New.
	* elfxx-x86.c (_bfd_elf_linker_x86_set_options): Set up link_info.
	* libbfd-in.h (_bfd_get_link_info): New prototype.
	* coff-x86_64.c (coff_amd64_reloc): Subtract __ImageBase for
	R_AMD64_IMAGEBASE.
	* libbfd.h: Regenerated.

ld/

	PR ld/27425
	PR ld/27432
	* ldelf.c (ldelf_load_symbols): Create an indirect reference to
	__executable_start for __ImageBase to support R_AMD64_IMAGEBASE
	relocation when seeing Windows x86-64 relocatable inputs.
	* ld-x86-64/pe-x86-64-1.od: Expect __executable_start.
	* testsuite/ld-x86-64/pe-x86-64-2.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-3.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-4.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-5.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-5.rd: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-6.obj.bz2: New file.
	* testsuite/ld-x86-64/pe-x86-64-6.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64.exp: Run ld/27425 test.
---
 bfd/bfd.c                                  |  11 +++
 bfd/coff-x86_64.c                          |  38 +++++++--
 bfd/elf-bfd.h                              |   4 +
 bfd/elfxx-x86.c                            |   2 +
 bfd/libbfd-in.h                            |   2 +
 bfd/libbfd.h                               |   2 +
 ld/ldelf.c                                 |  24 ++++++
 ld/testsuite/ld-x86-64/pe-x86-64-1.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-2.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-3.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-4.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-5.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-5.rd      |   3 +-
 ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2 | Bin 0 -> 1366 bytes
 ld/testsuite/ld-x86-64/pe-x86-64-6.od      |  91 +++++++++++++++++++++
 ld/testsuite/ld-x86-64/pe-x86-64.exp       |   9 ++
 16 files changed, 184 insertions(+), 7 deletions(-)
 create mode 100644 ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2
 create mode 100644 ld/testsuite/ld-x86-64/pe-x86-64-6.od

diff --git a/bfd/bfd.c b/bfd/bfd.c
index f1944338838..2cf7b47bca1 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -2808,3 +2808,14 @@ bfd_convert_section_contents (bfd *ibfd, sec_ptr isec, bfd *obfd,
   *ptr_size = size;
   return TRUE;
 }
+
+/* Get the optional linker information.  */
+
+struct bfd_link_info *
+_bfd_get_link_info (bfd *abfd)
+{
+  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+    return NULL;
+
+  return elf_link_info (abfd);
+}
diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
index 5b09023f3c2..be20da165d9 100644
--- a/bfd/coff-x86_64.c
+++ b/bfd/coff-x86_64.c
@@ -122,13 +122,39 @@ coff_amd64_reloc (bfd *abfd,
 #if defined (COFF_WITH_PE)
   if (output_bfd == NULL)
     {
-      /* PC relative relocations are off by their size.  */
-      if (reloc_entry->howto->pc_relative)
-	diff -= bfd_get_reloc_size (reloc_entry->howto);
+      if ((bfd_get_flavour (input_section->output_section->owner)
+	   == bfd_target_elf_flavour)
+	  && reloc_entry->howto->type == R_AMD64_IMAGEBASE)
+	{
+	  /* Subtract __ImageBase.  */
+	  struct bfd_link_info *link_info;
+	  struct bfd_link_hash_entry *h;
+	  link_info
+	    = _bfd_get_link_info (input_section->output_section->owner);
+	  if (link_info == NULL)
+	    abort ();
+	  h = bfd_link_hash_lookup (link_info->hash, "__ImageBase",
+				    FALSE, FALSE, FALSE);
+	  if (h == NULL)
+	    abort ();
+	  while (h->type == bfd_link_hash_indirect)
+	    h = h->u.i.link;
+	  /* ELF symbols in relocatable files are section relative,
+	     but in nonrelocatable files they are virtual addresses.  */
+	  diff -= (h->u.def.value
+		   + h->u.def.section->output_offset
+		   + h->u.def.section->output_section->vma);
+	}
+      else
+	{
+	  /* PC relative relocations are off by their size.  */
+	  if (reloc_entry->howto->pc_relative)
+	    diff -= bfd_get_reloc_size (reloc_entry->howto);
 
-      if (reloc_entry->howto->type >= R_AMD64_PCRLONG_1
-	  && reloc_entry->howto->type <= R_AMD64_PCRLONG_5)
-	diff -= reloc_entry->howto->type - R_AMD64_PCRLONG;
+	  if (reloc_entry->howto->type >= R_AMD64_PCRLONG_1
+	      && reloc_entry->howto->type <= R_AMD64_PCRLONG_5)
+	    diff -= reloc_entry->howto->type - R_AMD64_PCRLONG;
+	}
     }
 
   /* FIXME: How should this case be handled?  */
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index dd66d98883e..c2aaab0e5bf 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1887,6 +1887,9 @@ struct output_elf_obj_tdata
   /* Used when laying out sections.  */
   file_ptr next_file_pos;
 
+  /* Optional linker information.  */
+  struct bfd_link_info *link_info;
+
   int num_section_syms;
   unsigned int shstrtab_section, strtab_section;
 
@@ -2064,6 +2067,7 @@ struct elf_obj_tdata
 #define elf_elfsections(bfd)	(elf_tdata(bfd) -> elf_sect_ptr)
 #define elf_numsections(bfd)	(elf_tdata(bfd) -> num_elf_sections)
 #define elf_seg_map(bfd)	(elf_tdata(bfd) -> o->seg_map)
+#define elf_link_info(bfd)	(elf_tdata(bfd) -> o->link_info)
 #define elf_next_file_pos(bfd)	(elf_tdata(bfd) -> o->next_file_pos)
 #define elf_eh_frame_hdr(bfd)	(elf_tdata(bfd) -> o->eh_frame_hdr)
 #define elf_stack_flags(bfd)	(elf_tdata(bfd) -> o->stack_flags)
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 93ad38c5eb0..e60d87ff981 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -3174,6 +3174,8 @@ _bfd_elf_linker_x86_set_options (struct bfd_link_info * info,
     = get_elf_backend_data (info->output_bfd);
   struct elf_x86_link_hash_table *htab
     = elf_x86_hash_table (info, bed->target_id);
+  if (info->output_bfd->xvec->flavour == bfd_target_elf_flavour)
+    elf_link_info (info->output_bfd) = info;
   if (htab != NULL)
     htab->params = params;
 }
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index 2dc20ec1b19..62b1cee0af0 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -899,6 +899,8 @@ extern bfd_vma _bfd_safe_read_leb128
 extern bfd_byte * _bfd_write_unsigned_leb128
   (bfd_byte *, bfd_byte *, bfd_vma) ATTRIBUTE_HIDDEN;
 
+extern struct bfd_link_info *_bfd_get_link_info (bfd *);
+
 #if GCC_VERSION >= 7000
 #define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
 #else
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 7271a2ad5a1..3a481ea468f 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -904,6 +904,8 @@ extern bfd_vma _bfd_safe_read_leb128
 extern bfd_byte * _bfd_write_unsigned_leb128
   (bfd_byte *, bfd_byte *, bfd_vma) ATTRIBUTE_HIDDEN;
 
+extern struct bfd_link_info *_bfd_get_link_info (bfd *);
+
 #if GCC_VERSION >= 7000
 #define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
 #else
diff --git a/ld/ldelf.c b/ld/ldelf.c
index 049992544a2..c7de958dbdc 100644
--- a/ld/ldelf.c
+++ b/ld/ldelf.c
@@ -81,6 +81,30 @@ ldelf_load_symbols (lang_input_statement_type *entry)
 {
   int link_class = 0;
 
+  if (bfd_link_pde (&link_info)
+      && entry->the_bfd->xvec->flavour == bfd_target_coff_flavour
+      && strcmp (entry->the_bfd->xvec->name, "pe-x86-64") == 0
+      && strcmp (link_info.output_bfd->xvec->name, "elf64-x86-64") == 0)
+    {
+      /* NB: When linking Windows x86-64 relocatable object files to
+	 generate ELF executable, create an indirect reference to
+	 __executable_start for __ImageBase to support R_AMD64_IMAGEBASE
+	 relocation which is relative to __ImageBase.  */
+      struct elf_link_hash_table *htab = elf_hash_table (&link_info);
+      struct elf_link_hash_entry *h, *hi;
+      hi = elf_link_hash_lookup (htab, "__ImageBase", TRUE, FALSE,
+				 FALSE);
+      if (hi->root.type == bfd_link_hash_new
+	  || hi->type == bfd_link_hash_undefined
+	  || hi->type == bfd_link_hash_undefweak)
+	{
+	  h = elf_link_hash_lookup (htab, "__executable_start",
+				    TRUE, FALSE, TRUE);
+	  hi->root.type = bfd_link_hash_indirect;
+	  hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
+	}
+    }
+
   /* Tell the ELF linker that we don't want the output file to have a
      DT_NEEDED entry for this file, unless it is used to resolve
      references in a regular object.  */
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-1.od b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-1.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-2.od b/ld/testsuite/ld-x86-64/pe-x86-64-2.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-2.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-2.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-3.od b/ld/testsuite/ld-x86-64/pe-x86-64-3.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-3.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-3.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-4.od b/ld/testsuite/ld-x86-64/pe-x86-64-4.od
index e0bde11d84e..320c6be5e14 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-4.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-4.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+403038 g       .bss	0000000000000000 c
 0+401000 g       .text\$mn	0000000000000000 begin
 0+403038 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-5.od b/ld/testsuite/ld-x86-64/pe-x86-64-5.od
index 8a4f4a633ac..6ef13abbc94 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-5.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-5.od
@@ -4,6 +4,7 @@
 SYMBOL TABLE:
 0+402014 g       .bss	0000000000000000 non_initdummy
 0+402010 g       .data	0000000000000000 initdummy
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 begin
 0+402012 g       .bss	0000000000000000 __bss_start
 0+402000 g       .data	0000000000000000 Struct
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-5.rd b/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
index 8370665f99f..237052805e9 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
@@ -1,9 +1,10 @@
 
-Symbol table '.symtab' contains 10 entries:
+Symbol table '.symtab' contains 11 entries:
    Num:    Value          Size Type    Bind   Vis      Ndx Name
  +[a-f0-9]+: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
  +[a-f0-9]+: 0000000000402014     0 NOTYPE  GLOBAL DEFAULT    3 non_initdummy
  +[a-f0-9]+: 0000000000402010     0 NOTYPE  GLOBAL DEFAULT    2 initdummy
+ +[a-f0-9]+: 0000000000400000     0 NOTYPE  GLOBAL DEFAULT    1 __executable_start
  +[a-f0-9]+: 0000000000401000     0 NOTYPE  GLOBAL DEFAULT    1 begin
  +[a-f0-9]+: 0000000000402012     0 NOTYPE  GLOBAL DEFAULT    3 __bss_start
  +[a-f0-9]+: 0000000000402000     0 NOTYPE  GLOBAL DEFAULT    2 Struct
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2 b/ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..38255045d45ed918857b2c966400c13a13ea6c07
GIT binary patch
literal 1366
zcmV-c1*!T%T4*^jL0KkKSr(o^9smO9fB*mf|Nh_a|NQ^||Nj5~-}TM^Q*@d9YgPW;
zd+eHR_F&KhxOk{DUEM>1DTr#B8Vxi9QxnNB$qe;OMn*LZjWonG!KBke34qcKG#-Lu
zO+n}oJfkP-n1+}m6BA7tp+8jd3aO!pXvlhuKmni)7)=4727@32A)%%dK*9h3GyobJ
zF#(`ypa1~S&<2Qtn+c+6qtZ`M(<VowN$4g48fl<tXa<3x8X7%78Z>F3218950002c
z8UPw-&;$&OhMHssLqH6JBSwQEplP9@hychk8Z-t#7$DFx0MG!_Kn#r-BS2^XN+L#+
zMDk%qX+0wvnd*n6$Y=o5O#sjXO#o;B000^Q000000BC8T01Y)6t0Ij%1~1Zx-ljTP
zv7~$gP4n@oNq~cfwyu(S%%**p^kz*r4rRAWRcTbfRNzb)2)m)XQMb&4JUVWwY*_%P
z_N_!via~?|2}vgnKR75Sr_AXg#*K-lYBJ6&yOYkj3SvkC7BnqXI+`VjgE9yrmM|#Z
zAcU!thFfPL@ogO(W&_wPR?O<Nl`>0!yz(SMNI$pgD>nP`qq5&di9Y(;<tzfve#7RV
zLQq7sR8<iKE~*d}9#I&mh}9UVJg8-r7@=xZ2NcmYhaEyPiYfpN6hw+h7>GbrM+HPo
z!i9>{yG<#;mMI1E_Jr`*O+8>~P!*e8kP;V5^pWooq=L*qp)SmVWvfu>f>_r&r(rc;
zFlw0LN0dbVEA<6bekiD-s;40s%X>e{Bpb{0V*cpCy@Z%%2(;IT0ltH`?_5}n<UzB5
zf*?Wx?9SUxvoz5xvF*HU!`az<4cefwMgW_uK?W~)_YEp5)<A$@1UQMSt7Vh|X$!8S
zrYkdd%PnrQQ=JI}l%S=Jf?!qja8)kH^@O)sYfeI3m645L`q5BGerN)K?of-0r#>n|
zIJ>G_Jer_3(hAJw3_-j#7s1%O?->CeCR~1-d~uAqlkd=kBse0+P!fP8Gf5HP-!7%i
zY9#t2m+xTN{>23e(7a+I0;{Zo0pKlR8D<0+3~@0q!8UtF@$=vS%Ru|zVD9FpjySx}
zt{H?(&9Uu<p2jzU;|+yP-xYy^SQTmsWFw3b42s1?DxF}&SjcKo)TM}4B<*K1;RKpr
zB9L9W4U0w48Omi$FhV&*nXBTNgK+&nY+(ea!;BBmP6EO12PwtkmC_%#RsA$z@0JaQ
zK;1$!^T@K75<Qv*kCpFrll-gW?LaFYfjkRsvaL~}G=vHfYrg~uZV?6S9IpF-0+5}A
z_)^1T9VRd5A4+zwe~%URaNDw|ovUUIblXiY&aNu_D<Fy>a;O36%A;_CC4P{I;g8Lc
z_oIb1Th5wd#<v-tRhnyBD_BF4(rrdPfGi+1Cj(c?t7>6DvSmSitld-B7DP!ulPV)v
zjtH{yhbV)vqPiypj+2XeCuKWhP+%%5BxPTeR&+A6ME(Spj<8A+AT>of%9IL${b3$W
zT;V{<37R=3O12yjn;D3J_1es%R~rCwc#07V>0~}6Ocbcd(xo^hbFZ_E5g`dK4J43;
zL!(RF%z~VRcxJ6*mWojmVMt69!e|;&A4@D>YChtn2o?5O0qUo}T)OBf@?k*9{q-V&
zj?~DI4x)@7n$%$cCX*@q$)0{8UXMIXT<xV^S2T@qb<#e0E#AcXnZlt{eAv$l(KnN1
zj%}2QO$7taoaiC>k}0dYOV~!Q%X-@vZSVa^tl(<I`&6AfE`zbF1)s_=HB>Bd6H=xt
Y$~B;AV5AHi$*u8sBvXY60cqp`;GR@oQ~&?~

literal 0
HcmV?d00001

diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-6.od b/ld/testsuite/ld-x86-64/pe-x86-64-6.od
new file mode 100644
index 00000000000..cc23658a806
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-6.od
@@ -0,0 +1,91 @@
+
+.*: +file format .*
+
+SYMBOL TABLE:
+0+4010a8 g       .text\$mn	0000000000000000 xfunc
+0+402000 g       .rdata	0000000000000000 \?\?_C@_02LDKJOMJN@AB@
+0+400000 g       .text\$mn	0000000000000000 __executable_start
+0+403058 g       .data	0000000000000000 __bss_start
+0+401000 g       .text\$mn	0000000000000000 main
+0+403038 g       .data	0000000000000000 deadloopvar
+0+4010ac g       .text\$mn	0000000000000000 xstring
+0+403058 g       .data	0000000000000000 _edata
+0+403058 g       .data	0000000000000000 _end
+
+
+
+Disassembly of section .text\$mn:
+
+0+401000 <main>:
+ +[a-f0-9]+:	48 89 5c 24 08       	mov    %rbx,0x8\(%rsp\)
+ +[a-f0-9]+:	48 89 6c 24 10       	mov    %rbp,0x10\(%rsp\)
+ +[a-f0-9]+:	48 89 74 24 20       	mov    %rsi,0x20\(%rsp\)
+ +[a-f0-9]+:	57                   	push   %rdi
+ +[a-f0-9]+:	48 83 ec 20          	sub    \$0x20,%rsp
+ +[a-f0-9]+:	cc                   	int3   
+ +[a-f0-9]+:	8b 05 1d 20 00 00    	mov    0x201d\(%rip\),%eax        # 403038 <deadloopvar>
+ +[a-f0-9]+:	83 f8 01             	cmp    \$0x1,%eax
+ +[a-f0-9]+:	74 f5                	je     401015 <main\+0x15>
+ +[a-f0-9]+:	0f 31                	rdtsc  
+ +[a-f0-9]+:	48 c1 e2 20          	shl    \$0x20,%rdx
+ +[a-f0-9]+:	48 0b c2             	or     %rdx,%rax
+ +[a-f0-9]+:	74 5d                	je     401088 <main\+0x88>
+ +[a-f0-9]+:	33 ff                	xor    %edi,%edi
+ +[a-f0-9]+:	48 8d 2d cc ef ff ff 	lea    -0x1034\(%rip\),%rbp        # 400000 <__executable_start>
+ +[a-f0-9]+:	33 db                	xor    %ebx,%ebx
+ +[a-f0-9]+:	48 8d 35 ff 1f 00 00 	lea    0x1fff\(%rip\),%rsi        # 40303c <deadloopvar\+0x4>
+ +[a-f0-9]+:	48 8b 8c 2b 50 30 00 00 	mov    0x3050\(%rbx,%rbp,1\),%rcx
+ +[a-f0-9]+:	44 8a 01             	mov    \(%rcx\),%r8b
+ +[a-f0-9]+:	45 84 c0             	test   %r8b,%r8b
+ +[a-f0-9]+:	74 28                	je     401075 <main\+0x75>
+ +[a-f0-9]+:	b8 05 00 00 00       	mov    \$0x5,%eax
+ +[a-f0-9]+:	2b 84 2b 48 30 00 00 	sub    0x3048\(%rbx,%rbp,1\),%eax
+ +[a-f0-9]+:	99                   	cltd   
+ +[a-f0-9]+:	2b c2                	sub    %edx,%eax
+ +[a-f0-9]+:	d1 f8                	sar    %eax
+ +[a-f0-9]+:	48 63 d0             	movslq %eax,%rdx
+ +[a-f0-9]+:	48 03 d6             	add    %rsi,%rdx
+ +[a-f0-9]+:	48 ff c1             	inc    %rcx
+ +[a-f0-9]+:	44 88 02             	mov    %r8b,\(%rdx\)
+ +[a-f0-9]+:	48 ff c2             	inc    %rdx
+ +[a-f0-9]+:	44 8a 01             	mov    \(%rcx\),%r8b
+ +[a-f0-9]+:	45 84 c0             	test   %r8b,%r8b
+ +[a-f0-9]+:	75 ef                	jne    401064 <main\+0x64>
+ +[a-f0-9]+:	48 8b ce             	mov    %rsi,%rcx
+ +[a-f0-9]+:	e8 2f 00 00 00       	call   4010ac <xstring>
+ +[a-f0-9]+:	ff c7                	inc    %edi
+ +[a-f0-9]+:	48 83 c3 08          	add    \$0x8,%rbx
+ +[a-f0-9]+:	83 ff 01             	cmp    \$0x1,%edi
+ +[a-f0-9]+:	72 b5                	jb     40103d <main\+0x3d>
+ +[a-f0-9]+:	b1 aa                	mov    \$0xaa,%cl
+ +[a-f0-9]+:	e8 19 00 00 00       	call   4010a8 <xfunc>
+ +[a-f0-9]+:	48 8b 5c 24 30       	mov    0x30\(%rsp\),%rbx
+ +[a-f0-9]+:	33 c0                	xor    %eax,%eax
+ +[a-f0-9]+:	48 8b 6c 24 38       	mov    0x38\(%rsp\),%rbp
+ +[a-f0-9]+:	48 8b 74 24 48       	mov    0x48\(%rsp\),%rsi
+ +[a-f0-9]+:	48 83 c4 20          	add    \$0x20,%rsp
+ +[a-f0-9]+:	5f                   	pop    %rdi
+ +[a-f0-9]+:	c3                   	ret    
+ +[a-f0-9]+:	66 90                	xchg   %ax,%ax
+
+0+4010a8 <xfunc>:
+ +[a-f0-9]+:	66 90                	xchg   %ax,%ax
+ +[a-f0-9]+:	cc                   	int3   
+ +[a-f0-9]+:	c3                   	ret    
+
+0+4010ac <xstring>:
+ +[a-f0-9]+:	40 53                	rex push %rbx
+ +[a-f0-9]+:	48 83 ec 20          	sub    \$0x20,%rsp
+ +[a-f0-9]+:	8a 01                	mov    \(%rcx\),%al
+ +[a-f0-9]+:	48 8b d9             	mov    %rcx,%rbx
+ +[a-f0-9]+:	eb 0c                	jmp    4010c5 <xstring\+0x19>
+ +[a-f0-9]+:	8a c8                	mov    %al,%cl
+ +[a-f0-9]+:	e8 e8 ff ff ff       	call   4010a8 <xfunc>
+ +[a-f0-9]+:	48 ff c3             	inc    %rbx
+ +[a-f0-9]+:	8a 03                	mov    \(%rbx\),%al
+ +[a-f0-9]+:	84 c0                	test   %al,%al
+ +[a-f0-9]+:	75 f0                	jne    4010b9 <xstring\+0xd>
+ +[a-f0-9]+:	48 83 c4 20          	add    \$0x20,%rsp
+ +[a-f0-9]+:	5b                   	pop    %rbx
+ +[a-f0-9]+:	c3                   	ret    
+#pass
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64.exp b/ld/testsuite/ld-x86-64/pe-x86-64.exp
index ccfcdfaddfb..f5d2c84f283 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64.exp
+++ b/ld/testsuite/ld-x86-64/pe-x86-64.exp
@@ -73,4 +73,13 @@ run_ld_link_tests [list \
 	 {readelf {-s -x .data} pe-x86-64-5.rd}} \
 	"pe-x86-64-5" \
     ] \
+    [list \
+	"Build pe-x86-64-6" \
+	"-m elf_x86_64 --entry=main" \
+	"" \
+	"" \
+	{pe-x86-64-6.obj.bz2 } \
+	{{objdump {-dw --sym} pe-x86-64-6.od}} \
+	"pe-x86-64-6" \
+    ] \
 ]
-- 
2.29.2


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-03-05  5:29                               ` H.J. Lu
@ 2021-03-05 13:57                                 ` Alan Modra
  2021-03-05 18:26                                   ` [PATCH v5] " H.J. Lu
  0 siblings, 1 reply; 22+ messages in thread
From: Alan Modra @ 2021-03-05 13:57 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Jan Beulich, Binutils

On Thu, Mar 04, 2021 at 09:29:48PM -0800, H.J. Lu wrote:
> --- a/bfd/coff-x86_64.c
> +++ b/bfd/coff-x86_64.c
> @@ -122,13 +122,39 @@ coff_amd64_reloc (bfd *abfd,
>  #if defined (COFF_WITH_PE)
>    if (output_bfd == NULL)
>      {
> -      /* PC relative relocations are off by their size.  */
> -      if (reloc_entry->howto->pc_relative)
> -	diff -= bfd_get_reloc_size (reloc_entry->howto);
> +      if ((bfd_get_flavour (input_section->output_section->owner)
> +	   == bfd_target_elf_flavour)
> +	  && reloc_entry->howto->type == R_AMD64_IMAGEBASE)
> +	{
> +	  /* Subtract __ImageBase.  */
> +	  struct bfd_link_info *link_info;
> +	  struct bfd_link_hash_entry *h;
> +	  link_info
> +	    = _bfd_get_link_info (input_section->output_section->owner);
> +	  if (link_info == NULL)
> +	    abort ();
> +	  h = bfd_link_hash_lookup (link_info->hash, "__ImageBase",
> +				    FALSE, FALSE, FALSE);
> +	  if (h == NULL)
> +	    abort ();
> +	  while (h->type == bfd_link_hash_indirect)
> +	    h = h->u.i.link;
> +	  /* ELF symbols in relocatable files are section relative,
> +	     but in nonrelocatable files they are virtual addresses.  */
> +	  diff -= (h->u.def.value
> +		   + h->u.def.section->output_offset
> +		   + h->u.def.section->output_section->vma);
> +	}
> +      else
> +	{
> +	  /* PC relative relocations are off by their size.  */
> +	  if (reloc_entry->howto->pc_relative)
> +	    diff -= bfd_get_reloc_size (reloc_entry->howto);
>  
> -      if (reloc_entry->howto->type >= R_AMD64_PCRLONG_1
> -	  && reloc_entry->howto->type <= R_AMD64_PCRLONG_5)
> -	diff -= reloc_entry->howto->type - R_AMD64_PCRLONG;
> +	  if (reloc_entry->howto->type >= R_AMD64_PCRLONG_1
> +	      && reloc_entry->howto->type <= R_AMD64_PCRLONG_5)
> +	    diff -= reloc_entry->howto->type - R_AMD64_PCRLONG;
> +	}
>      }

I think this would be better style if the pc_relative and PCRLONG
adjustments were left as they were, and then write

    if (reloc_entry->howto->type == R_AMD64_IMAGEBASE)
      {
	bfd *obfd = input_section->output_section->owner;

	switch (bfd_get_flavour (obfd))
	  {
	  case bfd_target_coff_flavour:
	    diff -= pe_data (obfd)->pe_opthdr.ImageBase;
	    break;

	  case bfd_target_elf_flavour:
	    {
	      your new code
	    }
	    break;
	  }
      }

That should get rid of the FIXME.

>  
>    /* FIXME: How should this case be handled?  */


> diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
> index dd66d98883e..c2aaab0e5bf 100644
> --- a/bfd/elf-bfd.h
> +++ b/bfd/elf-bfd.h
> @@ -1887,6 +1887,9 @@ struct output_elf_obj_tdata
>    /* Used when laying out sections.  */
>    file_ptr next_file_pos;
>  
> +  /* Optional linker information.  */
> +  struct bfd_link_info *link_info;
> +

That's a nice trick that might be handy elsewhere, if you always set
it rather than making it optional.

>    int num_section_syms;
>    unsigned int shstrtab_section, strtab_section;
>  
> @@ -2064,6 +2067,7 @@ struct elf_obj_tdata
>  #define elf_elfsections(bfd)	(elf_tdata(bfd) -> elf_sect_ptr)
>  #define elf_numsections(bfd)	(elf_tdata(bfd) -> num_elf_sections)
>  #define elf_seg_map(bfd)	(elf_tdata(bfd) -> o->seg_map)
> +#define elf_link_info(bfd)	(elf_tdata(bfd) -> o->link_info)
>  #define elf_next_file_pos(bfd)	(elf_tdata(bfd) -> o->next_file_pos)
>  #define elf_eh_frame_hdr(bfd)	(elf_tdata(bfd) -> o->eh_frame_hdr)
>  #define elf_stack_flags(bfd)	(elf_tdata(bfd) -> o->stack_flags)
> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
> index 93ad38c5eb0..e60d87ff981 100644
> --- a/bfd/elfxx-x86.c
> +++ b/bfd/elfxx-x86.c
> @@ -3174,6 +3174,8 @@ _bfd_elf_linker_x86_set_options (struct bfd_link_info * info,
>      = get_elf_backend_data (info->output_bfd);
>    struct elf_x86_link_hash_table *htab
>      = elf_x86_hash_table (info, bed->target_id);
> +  if (info->output_bfd->xvec->flavour == bfd_target_elf_flavour)
> +    elf_link_info (info->output_bfd) = info;

Move this to somewhere all ELF targets will have elf_link_info, a new
ldelf.c:elf_set_output_arch perhaps?

>    if (htab != NULL)
>      htab->params = params;
>  }
> diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
> index 2dc20ec1b19..62b1cee0af0 100644
> --- a/bfd/libbfd-in.h
> +++ b/bfd/libbfd-in.h
> @@ -899,6 +899,8 @@ extern bfd_vma _bfd_safe_read_leb128
>  extern bfd_byte * _bfd_write_unsigned_leb128
>    (bfd_byte *, bfd_byte *, bfd_vma) ATTRIBUTE_HIDDEN;
>  
> +extern struct bfd_link_info *_bfd_get_link_info (bfd *);
> +
>  #if GCC_VERSION >= 7000
>  #define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
>  #else
> diff --git a/bfd/libbfd.h b/bfd/libbfd.h
> index 7271a2ad5a1..3a481ea468f 100644
> --- a/bfd/libbfd.h
> +++ b/bfd/libbfd.h
> @@ -904,6 +904,8 @@ extern bfd_vma _bfd_safe_read_leb128
>  extern bfd_byte * _bfd_write_unsigned_leb128
>    (bfd_byte *, bfd_byte *, bfd_vma) ATTRIBUTE_HIDDEN;
>  
> +extern struct bfd_link_info *_bfd_get_link_info (bfd *);
> +
>  #if GCC_VERSION >= 7000
>  #define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
>  #else
> diff --git a/ld/ldelf.c b/ld/ldelf.c
> index 049992544a2..c7de958dbdc 100644
> --- a/ld/ldelf.c
> +++ b/ld/ldelf.c
> @@ -81,6 +81,30 @@ ldelf_load_symbols (lang_input_statement_type *entry)
>  {
>    int link_class = 0;
>  
> +  if (bfd_link_pde (&link_info)
> +      && entry->the_bfd->xvec->flavour == bfd_target_coff_flavour
> +      && strcmp (entry->the_bfd->xvec->name, "pe-x86-64") == 0
> +      && strcmp (link_info.output_bfd->xvec->name, "elf64-x86-64") == 0)
> +    {
> +      /* NB: When linking Windows x86-64 relocatable object files to
> +	 generate ELF executable, create an indirect reference to
> +	 __executable_start for __ImageBase to support R_AMD64_IMAGEBASE
> +	 relocation which is relative to __ImageBase.  */
> +      struct elf_link_hash_table *htab = elf_hash_table (&link_info);
> +      struct elf_link_hash_entry *h, *hi;
> +      hi = elf_link_hash_lookup (htab, "__ImageBase", TRUE, FALSE,
> +				 FALSE);
> +      if (hi->root.type == bfd_link_hash_new
> +	  || hi->type == bfd_link_hash_undefined
> +	  || hi->type == bfd_link_hash_undefweak)
> +	{
> +	  h = elf_link_hash_lookup (htab, "__executable_start",
> +				    TRUE, FALSE, TRUE);
> +	  hi->root.type = bfd_link_hash_indirect;
> +	  hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
> +	}
> +    }
> +
>    /* Tell the ELF linker that we don't want the output file to have a
>       DT_NEEDED entry for this file, unless it is used to resolve
>       references in a regular object.  */

This doesn't look like the right place to set up a reference to
__executable_start.  Doing so in a new check_relocs in pei-x86_64.c
that tests for an ELF output would be better.  I'm not suggesting that
you run over relocs looking for R_AMD64_IMAGEBASE, that could be done
but seems unnecessary.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v5] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-03-05 13:57                                 ` Alan Modra
@ 2021-03-05 18:26                                   ` H.J. Lu
  2021-03-06  0:11                                     ` Alan Modra
  0 siblings, 1 reply; 22+ messages in thread
From: H.J. Lu @ 2021-03-05 18:26 UTC (permalink / raw)
  To: Alan Modra; +Cc: Jan Beulich, Binutils

[-- Attachment #1: Type: text/plain, Size: 7820 bytes --]

On Fri, Mar 5, 2021 at 5:57 AM Alan Modra <amodra@gmail.com> wrote:
>
> On Thu, Mar 04, 2021 at 09:29:48PM -0800, H.J. Lu wrote:
> > --- a/bfd/coff-x86_64.c
> > +++ b/bfd/coff-x86_64.c
> > @@ -122,13 +122,39 @@ coff_amd64_reloc (bfd *abfd,
> >  #if defined (COFF_WITH_PE)
> >    if (output_bfd == NULL)
> >      {
> > -      /* PC relative relocations are off by their size.  */
> > -      if (reloc_entry->howto->pc_relative)
> > -     diff -= bfd_get_reloc_size (reloc_entry->howto);
> > +      if ((bfd_get_flavour (input_section->output_section->owner)
> > +        == bfd_target_elf_flavour)
> > +       && reloc_entry->howto->type == R_AMD64_IMAGEBASE)
> > +     {
> > +       /* Subtract __ImageBase.  */
> > +       struct bfd_link_info *link_info;
> > +       struct bfd_link_hash_entry *h;
> > +       link_info
> > +         = _bfd_get_link_info (input_section->output_section->owner);
> > +       if (link_info == NULL)
> > +         abort ();
> > +       h = bfd_link_hash_lookup (link_info->hash, "__ImageBase",
> > +                                 FALSE, FALSE, FALSE);
> > +       if (h == NULL)
> > +         abort ();
> > +       while (h->type == bfd_link_hash_indirect)
> > +         h = h->u.i.link;
> > +       /* ELF symbols in relocatable files are section relative,
> > +          but in nonrelocatable files they are virtual addresses.  */
> > +       diff -= (h->u.def.value
> > +                + h->u.def.section->output_offset
> > +                + h->u.def.section->output_section->vma);
> > +     }
> > +      else
> > +     {
> > +       /* PC relative relocations are off by their size.  */
> > +       if (reloc_entry->howto->pc_relative)
> > +         diff -= bfd_get_reloc_size (reloc_entry->howto);
> >
> > -      if (reloc_entry->howto->type >= R_AMD64_PCRLONG_1
> > -       && reloc_entry->howto->type <= R_AMD64_PCRLONG_5)
> > -     diff -= reloc_entry->howto->type - R_AMD64_PCRLONG;
> > +       if (reloc_entry->howto->type >= R_AMD64_PCRLONG_1
> > +           && reloc_entry->howto->type <= R_AMD64_PCRLONG_5)
> > +         diff -= reloc_entry->howto->type - R_AMD64_PCRLONG;
> > +     }
> >      }
>
> I think this would be better style if the pc_relative and PCRLONG
> adjustments were left as they were, and then write
>
>     if (reloc_entry->howto->type == R_AMD64_IMAGEBASE)
>       {
>         bfd *obfd = input_section->output_section->owner;
>
>         switch (bfd_get_flavour (obfd))
>           {
>           case bfd_target_coff_flavour:
>             diff -= pe_data (obfd)->pe_opthdr.ImageBase;
>             break;
>
>           case bfd_target_elf_flavour:
>             {
>               your new code
>             }
>             break;
>           }
>       }
>
> That should get rid of the FIXME.

Fixed.

> >
> >    /* FIXME: How should this case be handled?  */
>
>
> > diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
> > index dd66d98883e..c2aaab0e5bf 100644
> > --- a/bfd/elf-bfd.h
> > +++ b/bfd/elf-bfd.h
> > @@ -1887,6 +1887,9 @@ struct output_elf_obj_tdata
> >    /* Used when laying out sections.  */
> >    file_ptr next_file_pos;
> >
> > +  /* Optional linker information.  */
> > +  struct bfd_link_info *link_info;
> > +
>
> That's a nice trick that might be handy elsewhere, if you always set
> it rather than making it optional.

Fixed.

> >    int num_section_syms;
> >    unsigned int shstrtab_section, strtab_section;
> >
> > @@ -2064,6 +2067,7 @@ struct elf_obj_tdata
> >  #define elf_elfsections(bfd) (elf_tdata(bfd) -> elf_sect_ptr)
> >  #define elf_numsections(bfd) (elf_tdata(bfd) -> num_elf_sections)
> >  #define elf_seg_map(bfd)     (elf_tdata(bfd) -> o->seg_map)
> > +#define elf_link_info(bfd)   (elf_tdata(bfd) -> o->link_info)
> >  #define elf_next_file_pos(bfd)       (elf_tdata(bfd) -> o->next_file_pos)
> >  #define elf_eh_frame_hdr(bfd)        (elf_tdata(bfd) -> o->eh_frame_hdr)
> >  #define elf_stack_flags(bfd) (elf_tdata(bfd) -> o->stack_flags)
> > diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
> > index 93ad38c5eb0..e60d87ff981 100644
> > --- a/bfd/elfxx-x86.c
> > +++ b/bfd/elfxx-x86.c
> > @@ -3174,6 +3174,8 @@ _bfd_elf_linker_x86_set_options (struct bfd_link_info * info,
> >      = get_elf_backend_data (info->output_bfd);
> >    struct elf_x86_link_hash_table *htab
> >      = elf_x86_hash_table (info, bed->target_id);
> > +  if (info->output_bfd->xvec->flavour == bfd_target_elf_flavour)
> > +    elf_link_info (info->output_bfd) = info;
>
> Move this to somewhere all ELF targets will have elf_link_info, a new
> ldelf.c:elf_set_output_arch perhaps?

Added ldelf_set_output_arch.

> >    if (htab != NULL)
> >      htab->params = params;
> >  }
> > diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
> > index 2dc20ec1b19..62b1cee0af0 100644
> > --- a/bfd/libbfd-in.h
> > +++ b/bfd/libbfd-in.h
> > @@ -899,6 +899,8 @@ extern bfd_vma _bfd_safe_read_leb128
> >  extern bfd_byte * _bfd_write_unsigned_leb128
> >    (bfd_byte *, bfd_byte *, bfd_vma) ATTRIBUTE_HIDDEN;
> >
> > +extern struct bfd_link_info *_bfd_get_link_info (bfd *);
> > +
> >  #if GCC_VERSION >= 7000
> >  #define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
> >  #else
> > diff --git a/bfd/libbfd.h b/bfd/libbfd.h
> > index 7271a2ad5a1..3a481ea468f 100644
> > --- a/bfd/libbfd.h
> > +++ b/bfd/libbfd.h
> > @@ -904,6 +904,8 @@ extern bfd_vma _bfd_safe_read_leb128
> >  extern bfd_byte * _bfd_write_unsigned_leb128
> >    (bfd_byte *, bfd_byte *, bfd_vma) ATTRIBUTE_HIDDEN;
> >
> > +extern struct bfd_link_info *_bfd_get_link_info (bfd *);
> > +
> >  #if GCC_VERSION >= 7000
> >  #define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
> >  #else
> > diff --git a/ld/ldelf.c b/ld/ldelf.c
> > index 049992544a2..c7de958dbdc 100644
> > --- a/ld/ldelf.c
> > +++ b/ld/ldelf.c
> > @@ -81,6 +81,30 @@ ldelf_load_symbols (lang_input_statement_type *entry)
> >  {
> >    int link_class = 0;
> >
> > +  if (bfd_link_pde (&link_info)
> > +      && entry->the_bfd->xvec->flavour == bfd_target_coff_flavour
> > +      && strcmp (entry->the_bfd->xvec->name, "pe-x86-64") == 0
> > +      && strcmp (link_info.output_bfd->xvec->name, "elf64-x86-64") == 0)
> > +    {
> > +      /* NB: When linking Windows x86-64 relocatable object files to
> > +      generate ELF executable, create an indirect reference to
> > +      __executable_start for __ImageBase to support R_AMD64_IMAGEBASE
> > +      relocation which is relative to __ImageBase.  */
> > +      struct elf_link_hash_table *htab = elf_hash_table (&link_info);
> > +      struct elf_link_hash_entry *h, *hi;
> > +      hi = elf_link_hash_lookup (htab, "__ImageBase", TRUE, FALSE,
> > +                              FALSE);
> > +      if (hi->root.type == bfd_link_hash_new
> > +       || hi->type == bfd_link_hash_undefined
> > +       || hi->type == bfd_link_hash_undefweak)
> > +     {
> > +       h = elf_link_hash_lookup (htab, "__executable_start",
> > +                                 TRUE, FALSE, TRUE);
> > +       hi->root.type = bfd_link_hash_indirect;
> > +       hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
> > +     }
> > +    }
> > +
> >    /* Tell the ELF linker that we don't want the output file to have a
> >       DT_NEEDED entry for this file, unless it is used to resolve
> >       references in a regular object.  */
>
> This doesn't look like the right place to set up a reference to
> __executable_start.  Doing so in a new check_relocs in pei-x86_64.c
> that tests for an ELF output would be better.  I'm not suggesting that
> you run over relocs looking for R_AMD64_IMAGEBASE, that could be done
> but seems unnecessary.

check_relocs is too late.  We need to do it in load_symbols ().  Otherwise,
__executable_start won't be defined.  I added pex64_link_add_symbols to
do it.

Here is the v5 patch.  OK for master?

Thanks.

-- 
H.J.

[-- Attachment #2: v5-0001-elf-x86-64-Subtract-__ImageBase-for-R_AMD64_IMAGE.patch --]
[-- Type: text/x-patch, Size: 20616 bytes --]

From 242301311a4face0f4c0b3d3673606d17adc05c5 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 15 Feb 2021 18:53:18 -0800
Subject: [PATCH v5] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE

When linking Windows x86-64 relocatable object files to generate x86-64
ELF executable, we need to subtract __ImageBase, aka __executable_start,
for R_AMD64_IMAGEBASE relocation:

1. Add link_info to struct output_elf_obj_tdata to store linker info and
_bfd_get_link_info() to retrieve it.
2. Add ldelf_set_output_arch to set up link_info.
3. Add pex64_link_add_symbols to create an indirect reference to
__executable_start for __ImageBase to support R_AMD64_IMAGEBASE relocation
when adding symbols from Windows x86-64 relocatable object files to
generate x86-64 ELF executable.
4. Also subtract __ImageBase for R_AMD64_IMAGEBASE when generating x86-64
ELF executable.

bfd/

	PR ld/27425
	PR ld/27432
	* bfd.c (_bfd_get_link_info): New function.
	* elf-bfd.h (output_elf_obj_tdata): Add link_info.
	(elf_link_info): New.
	* libbfd-in.h (_bfd_get_link_info): New prototype.
	* coff-x86_64.c (coff_amd64_reloc): Also subtract __ImageBase for
	R_AMD64_IMAGEBASE when generating x86-64 ELF executable.
	* pe-x86_64.c (pex64_link_add_symbols): New function.
	(coff_bfd_link_add_symbols): New macro.
	* libbfd.h: Regenerated.

ld/

	PR ld/27425
	PR ld/27432
	* ldelf.c (ldelf_set_output_arch): New function.
	* ldelf.h (ldelf_set_output_arch): New prototype.
	* emultempl/elf.em (LDEMUL_SET_OUTPUT_ARCH): Default to
	ldelf_set_output_arch.
	* ld-x86-64/pe-x86-64-1.od: Expect __executable_start.
	* testsuite/ld-x86-64/pe-x86-64-2.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-3.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-4.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-5.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-5.rd: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-6.obj.bz2: New file.
	* testsuite/ld-x86-64/pe-x86-64-6.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64.exp: Run ld/27425 test.
---
 bfd/bfd.c                                  |  11 +++
 bfd/coff-x86_64.c                          |  36 ++++++--
 bfd/elf-bfd.h                              |   4 +
 bfd/libbfd-in.h                            |   2 +
 bfd/libbfd.h                               |   2 +
 bfd/pe-x86_64.c                            |  34 +++++++-
 ld/emultempl/elf.em                        |   2 +-
 ld/ldelf.c                                 |   8 ++
 ld/ldelf.h                                 |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-1.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-2.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-3.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-4.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-5.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-5.rd      |   3 +-
 ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2 | Bin 0 -> 1366 bytes
 ld/testsuite/ld-x86-64/pe-x86-64-6.od      |  91 +++++++++++++++++++++
 ld/testsuite/ld-x86-64/pe-x86-64.exp       |   9 ++
 18 files changed, 200 insertions(+), 8 deletions(-)
 create mode 100644 ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2
 create mode 100644 ld/testsuite/ld-x86-64/pe-x86-64-6.od

diff --git a/bfd/bfd.c b/bfd/bfd.c
index f1944338838..2cf7b47bca1 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -2808,3 +2808,14 @@ bfd_convert_section_contents (bfd *ibfd, sec_ptr isec, bfd *obfd,
   *ptr_size = size;
   return TRUE;
 }
+
+/* Get the optional linker information.  */
+
+struct bfd_link_info *
+_bfd_get_link_info (bfd *abfd)
+{
+  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+    return NULL;
+
+  return elf_link_info (abfd);
+}
diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
index 5b09023f3c2..0b98b434422 100644
--- a/bfd/coff-x86_64.c
+++ b/bfd/coff-x86_64.c
@@ -131,11 +131,37 @@ coff_amd64_reloc (bfd *abfd,
 	diff -= reloc_entry->howto->type - R_AMD64_PCRLONG;
     }
 
-  /* FIXME: How should this case be handled?  */
-  if (reloc_entry->howto->type == R_AMD64_IMAGEBASE
-      && output_bfd != NULL
-      && bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
-    diff -= pe_data (output_bfd)->pe_opthdr.ImageBase;
+  if (reloc_entry->howto->type == R_AMD64_IMAGEBASE)
+    {
+      bfd *obfd = input_section->output_section->owner;
+      struct bfd_link_info *link_info;
+      struct bfd_link_hash_entry *h;
+      switch (bfd_get_flavour (obfd))
+	{
+	case bfd_target_coff_flavour:
+	  diff -= pe_data (obfd)->pe_opthdr.ImageBase;
+	  break;
+	case bfd_target_elf_flavour:
+	  /* Subtract __ImageBase.  */
+	  link_info = _bfd_get_link_info (obfd);
+	  if (link_info == NULL)
+	    abort ();
+	  h = bfd_link_hash_lookup (link_info->hash, "__ImageBase",
+				    FALSE, FALSE, FALSE);
+	  if (h == NULL)
+	    abort ();
+	  while (h->type == bfd_link_hash_indirect)
+	    h = h->u.i.link;
+	  /* ELF symbols in relocatable files are section relative,
+	     but in nonrelocatable files they are virtual addresses.  */
+	  diff -= (h->u.def.value
+		   + h->u.def.section->output_offset
+		   + h->u.def.section->output_section->vma);
+	  break;
+	default:
+	  break;
+	}
+    }
 #endif
 
 #define DOIT(x) \
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index c40030bdca6..04785a814e8 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1887,6 +1887,9 @@ struct output_elf_obj_tdata
   /* Used when laying out sections.  */
   file_ptr next_file_pos;
 
+  /* Linker information.  */
+  struct bfd_link_info *link_info;
+
   int num_section_syms;
   unsigned int shstrtab_section, strtab_section;
 
@@ -2064,6 +2067,7 @@ struct elf_obj_tdata
 #define elf_elfsections(bfd)	(elf_tdata(bfd) -> elf_sect_ptr)
 #define elf_numsections(bfd)	(elf_tdata(bfd) -> num_elf_sections)
 #define elf_seg_map(bfd)	(elf_tdata(bfd) -> o->seg_map)
+#define elf_link_info(bfd)	(elf_tdata(bfd) -> o->link_info)
 #define elf_next_file_pos(bfd)	(elf_tdata(bfd) -> o->next_file_pos)
 #define elf_eh_frame_hdr(bfd)	(elf_tdata(bfd) -> o->eh_frame_hdr)
 #define elf_stack_flags(bfd)	(elf_tdata(bfd) -> o->stack_flags)
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index 2dc20ec1b19..62b1cee0af0 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -899,6 +899,8 @@ extern bfd_vma _bfd_safe_read_leb128
 extern bfd_byte * _bfd_write_unsigned_leb128
   (bfd_byte *, bfd_byte *, bfd_vma) ATTRIBUTE_HIDDEN;
 
+extern struct bfd_link_info *_bfd_get_link_info (bfd *);
+
 #if GCC_VERSION >= 7000
 #define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
 #else
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 7271a2ad5a1..3a481ea468f 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -904,6 +904,8 @@ extern bfd_vma _bfd_safe_read_leb128
 extern bfd_byte * _bfd_write_unsigned_leb128
   (bfd_byte *, bfd_byte *, bfd_vma) ATTRIBUTE_HIDDEN;
 
+extern struct bfd_link_info *_bfd_get_link_info (bfd *);
+
 #if GCC_VERSION >= 7000
 #define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
 #else
diff --git a/bfd/pe-x86_64.c b/bfd/pe-x86_64.c
index 5b734442e3b..e2fc471cd34 100644
--- a/bfd/pe-x86_64.c
+++ b/bfd/pe-x86_64.c
@@ -22,6 +22,9 @@
 
 #include "sysdep.h"
 #include "bfd.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+#include "elf-bfd.h"
 
 #define TARGET_SYM		x86_64_pe_vec
 #define TARGET_NAME		"pe-x86-64"
@@ -66,5 +69,34 @@ extern bfd_boolean pex64_bfd_print_pdata (bfd *, void *);
 
 #define bfd_pe_print_pdata   pex64_bfd_print_pdata
 
-#include "coff-x86_64.c"
+static bfd_boolean
+pex64_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+  if (bfd_link_pde (info)
+      && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
+    {
+      /* NB: When linking Windows x86-64 relocatable object files to
+	 generate ELF executable, create an indirect reference to
+	 __executable_start for __ImageBase to support R_AMD64_IMAGEBASE
+	 relocation which is relative to __ImageBase.  */
+      struct elf_link_hash_table *htab = elf_hash_table (info);
+      struct elf_link_hash_entry *h, *hi;
+      hi = elf_link_hash_lookup (htab, "__ImageBase", TRUE, FALSE,
+				 FALSE);
+      if (hi->root.type == bfd_link_hash_new
+	  || hi->type == bfd_link_hash_undefined
+	  || hi->type == bfd_link_hash_undefweak)
+	{
+	  h = elf_link_hash_lookup (htab, "__executable_start",
+				    TRUE, FALSE, TRUE);
+	  hi->root.type = bfd_link_hash_indirect;
+	  hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
+	}
+    }
+
+  return _bfd_coff_link_add_symbols (abfd, info);
+}
 
+#define coff_bfd_link_add_symbols pex64_link_add_symbols
+
+#include "coff-x86_64.c"
diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em
index cea89e57e25..9e7c3d86a9e 100644
--- a/ld/emultempl/elf.em
+++ b/ld/emultempl/elf.em
@@ -919,7 +919,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
   ${LDEMUL_AFTER_CHECK_RELOCS-after_check_relocs_default},
   ${LDEMUL_BEFORE_PLACE_ORPHANS-ldelf_before_place_orphans},
   ${LDEMUL_AFTER_ALLOCATION-gld${EMULATION_NAME}_after_allocation},
-  ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
+  ${LDEMUL_SET_OUTPUT_ARCH-ldelf_set_output_arch},
   ${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
   ${LDEMUL_BEFORE_ALLOCATION-gld${EMULATION_NAME}_before_allocation},
   ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script},
diff --git a/ld/ldelf.c b/ld/ldelf.c
index 049992544a2..a733131e51c 100644
--- a/ld/ldelf.c
+++ b/ld/ldelf.c
@@ -2206,3 +2206,11 @@ ldelf_before_place_orphans (void)
 	  }
       }
 }
+
+void
+ldelf_set_output_arch (void)
+{
+  set_output_arch_default ();
+  if (link_info.output_bfd->xvec->flavour == bfd_target_elf_flavour)
+    elf_link_info (link_info.output_bfd) = &link_info;
+}
diff --git a/ld/ldelf.h b/ld/ldelf.h
index 629e7c1543a..aaf264ae239 100644
--- a/ld/ldelf.h
+++ b/ld/ldelf.h
@@ -31,3 +31,4 @@ extern bfd_boolean ldelf_open_dynamic_archive
 extern lang_output_section_statement_type *ldelf_place_orphan
   (asection *, const char *, int);
 extern void ldelf_before_place_orphans (void);
+extern void ldelf_set_output_arch (void);
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-1.od b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-1.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-2.od b/ld/testsuite/ld-x86-64/pe-x86-64-2.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-2.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-2.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-3.od b/ld/testsuite/ld-x86-64/pe-x86-64-3.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-3.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-3.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-4.od b/ld/testsuite/ld-x86-64/pe-x86-64-4.od
index e0bde11d84e..320c6be5e14 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-4.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-4.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+403038 g       .bss	0000000000000000 c
 0+401000 g       .text\$mn	0000000000000000 begin
 0+403038 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-5.od b/ld/testsuite/ld-x86-64/pe-x86-64-5.od
index 8a4f4a633ac..6ef13abbc94 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-5.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-5.od
@@ -4,6 +4,7 @@
 SYMBOL TABLE:
 0+402014 g       .bss	0000000000000000 non_initdummy
 0+402010 g       .data	0000000000000000 initdummy
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 begin
 0+402012 g       .bss	0000000000000000 __bss_start
 0+402000 g       .data	0000000000000000 Struct
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-5.rd b/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
index 8370665f99f..237052805e9 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
@@ -1,9 +1,10 @@
 
-Symbol table '.symtab' contains 10 entries:
+Symbol table '.symtab' contains 11 entries:
    Num:    Value          Size Type    Bind   Vis      Ndx Name
  +[a-f0-9]+: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
  +[a-f0-9]+: 0000000000402014     0 NOTYPE  GLOBAL DEFAULT    3 non_initdummy
  +[a-f0-9]+: 0000000000402010     0 NOTYPE  GLOBAL DEFAULT    2 initdummy
+ +[a-f0-9]+: 0000000000400000     0 NOTYPE  GLOBAL DEFAULT    1 __executable_start
  +[a-f0-9]+: 0000000000401000     0 NOTYPE  GLOBAL DEFAULT    1 begin
  +[a-f0-9]+: 0000000000402012     0 NOTYPE  GLOBAL DEFAULT    3 __bss_start
  +[a-f0-9]+: 0000000000402000     0 NOTYPE  GLOBAL DEFAULT    2 Struct
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2 b/ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..38255045d45ed918857b2c966400c13a13ea6c07
GIT binary patch
literal 1366
zcmV-c1*!T%T4*^jL0KkKSr(o^9smO9fB*mf|Nh_a|NQ^||Nj5~-}TM^Q*@d9YgPW;
zd+eHR_F&KhxOk{DUEM>1DTr#B8Vxi9QxnNB$qe;OMn*LZjWonG!KBke34qcKG#-Lu
zO+n}oJfkP-n1+}m6BA7tp+8jd3aO!pXvlhuKmni)7)=4727@32A)%%dK*9h3GyobJ
zF#(`ypa1~S&<2Qtn+c+6qtZ`M(<VowN$4g48fl<tXa<3x8X7%78Z>F3218950002c
z8UPw-&;$&OhMHssLqH6JBSwQEplP9@hychk8Z-t#7$DFx0MG!_Kn#r-BS2^XN+L#+
zMDk%qX+0wvnd*n6$Y=o5O#sjXO#o;B000^Q000000BC8T01Y)6t0Ij%1~1Zx-ljTP
zv7~$gP4n@oNq~cfwyu(S%%**p^kz*r4rRAWRcTbfRNzb)2)m)XQMb&4JUVWwY*_%P
z_N_!via~?|2}vgnKR75Sr_AXg#*K-lYBJ6&yOYkj3SvkC7BnqXI+`VjgE9yrmM|#Z
zAcU!thFfPL@ogO(W&_wPR?O<Nl`>0!yz(SMNI$pgD>nP`qq5&di9Y(;<tzfve#7RV
zLQq7sR8<iKE~*d}9#I&mh}9UVJg8-r7@=xZ2NcmYhaEyPiYfpN6hw+h7>GbrM+HPo
z!i9>{yG<#;mMI1E_Jr`*O+8>~P!*e8kP;V5^pWooq=L*qp)SmVWvfu>f>_r&r(rc;
zFlw0LN0dbVEA<6bekiD-s;40s%X>e{Bpb{0V*cpCy@Z%%2(;IT0ltH`?_5}n<UzB5
zf*?Wx?9SUxvoz5xvF*HU!`az<4cefwMgW_uK?W~)_YEp5)<A$@1UQMSt7Vh|X$!8S
zrYkdd%PnrQQ=JI}l%S=Jf?!qja8)kH^@O)sYfeI3m645L`q5BGerN)K?of-0r#>n|
zIJ>G_Jer_3(hAJw3_-j#7s1%O?->CeCR~1-d~uAqlkd=kBse0+P!fP8Gf5HP-!7%i
zY9#t2m+xTN{>23e(7a+I0;{Zo0pKlR8D<0+3~@0q!8UtF@$=vS%Ru|zVD9FpjySx}
zt{H?(&9Uu<p2jzU;|+yP-xYy^SQTmsWFw3b42s1?DxF}&SjcKo)TM}4B<*K1;RKpr
zB9L9W4U0w48Omi$FhV&*nXBTNgK+&nY+(ea!;BBmP6EO12PwtkmC_%#RsA$z@0JaQ
zK;1$!^T@K75<Qv*kCpFrll-gW?LaFYfjkRsvaL~}G=vHfYrg~uZV?6S9IpF-0+5}A
z_)^1T9VRd5A4+zwe~%URaNDw|ovUUIblXiY&aNu_D<Fy>a;O36%A;_CC4P{I;g8Lc
z_oIb1Th5wd#<v-tRhnyBD_BF4(rrdPfGi+1Cj(c?t7>6DvSmSitld-B7DP!ulPV)v
zjtH{yhbV)vqPiypj+2XeCuKWhP+%%5BxPTeR&+A6ME(Spj<8A+AT>of%9IL${b3$W
zT;V{<37R=3O12yjn;D3J_1es%R~rCwc#07V>0~}6Ocbcd(xo^hbFZ_E5g`dK4J43;
zL!(RF%z~VRcxJ6*mWojmVMt69!e|;&A4@D>YChtn2o?5O0qUo}T)OBf@?k*9{q-V&
zj?~DI4x)@7n$%$cCX*@q$)0{8UXMIXT<xV^S2T@qb<#e0E#AcXnZlt{eAv$l(KnN1
zj%}2QO$7taoaiC>k}0dYOV~!Q%X-@vZSVa^tl(<I`&6AfE`zbF1)s_=HB>Bd6H=xt
Y$~B;AV5AHi$*u8sBvXY60cqp`;GR@oQ~&?~

literal 0
HcmV?d00001

diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-6.od b/ld/testsuite/ld-x86-64/pe-x86-64-6.od
new file mode 100644
index 00000000000..cc23658a806
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-6.od
@@ -0,0 +1,91 @@
+
+.*: +file format .*
+
+SYMBOL TABLE:
+0+4010a8 g       .text\$mn	0000000000000000 xfunc
+0+402000 g       .rdata	0000000000000000 \?\?_C@_02LDKJOMJN@AB@
+0+400000 g       .text\$mn	0000000000000000 __executable_start
+0+403058 g       .data	0000000000000000 __bss_start
+0+401000 g       .text\$mn	0000000000000000 main
+0+403038 g       .data	0000000000000000 deadloopvar
+0+4010ac g       .text\$mn	0000000000000000 xstring
+0+403058 g       .data	0000000000000000 _edata
+0+403058 g       .data	0000000000000000 _end
+
+
+
+Disassembly of section .text\$mn:
+
+0+401000 <main>:
+ +[a-f0-9]+:	48 89 5c 24 08       	mov    %rbx,0x8\(%rsp\)
+ +[a-f0-9]+:	48 89 6c 24 10       	mov    %rbp,0x10\(%rsp\)
+ +[a-f0-9]+:	48 89 74 24 20       	mov    %rsi,0x20\(%rsp\)
+ +[a-f0-9]+:	57                   	push   %rdi
+ +[a-f0-9]+:	48 83 ec 20          	sub    \$0x20,%rsp
+ +[a-f0-9]+:	cc                   	int3   
+ +[a-f0-9]+:	8b 05 1d 20 00 00    	mov    0x201d\(%rip\),%eax        # 403038 <deadloopvar>
+ +[a-f0-9]+:	83 f8 01             	cmp    \$0x1,%eax
+ +[a-f0-9]+:	74 f5                	je     401015 <main\+0x15>
+ +[a-f0-9]+:	0f 31                	rdtsc  
+ +[a-f0-9]+:	48 c1 e2 20          	shl    \$0x20,%rdx
+ +[a-f0-9]+:	48 0b c2             	or     %rdx,%rax
+ +[a-f0-9]+:	74 5d                	je     401088 <main\+0x88>
+ +[a-f0-9]+:	33 ff                	xor    %edi,%edi
+ +[a-f0-9]+:	48 8d 2d cc ef ff ff 	lea    -0x1034\(%rip\),%rbp        # 400000 <__executable_start>
+ +[a-f0-9]+:	33 db                	xor    %ebx,%ebx
+ +[a-f0-9]+:	48 8d 35 ff 1f 00 00 	lea    0x1fff\(%rip\),%rsi        # 40303c <deadloopvar\+0x4>
+ +[a-f0-9]+:	48 8b 8c 2b 50 30 00 00 	mov    0x3050\(%rbx,%rbp,1\),%rcx
+ +[a-f0-9]+:	44 8a 01             	mov    \(%rcx\),%r8b
+ +[a-f0-9]+:	45 84 c0             	test   %r8b,%r8b
+ +[a-f0-9]+:	74 28                	je     401075 <main\+0x75>
+ +[a-f0-9]+:	b8 05 00 00 00       	mov    \$0x5,%eax
+ +[a-f0-9]+:	2b 84 2b 48 30 00 00 	sub    0x3048\(%rbx,%rbp,1\),%eax
+ +[a-f0-9]+:	99                   	cltd   
+ +[a-f0-9]+:	2b c2                	sub    %edx,%eax
+ +[a-f0-9]+:	d1 f8                	sar    %eax
+ +[a-f0-9]+:	48 63 d0             	movslq %eax,%rdx
+ +[a-f0-9]+:	48 03 d6             	add    %rsi,%rdx
+ +[a-f0-9]+:	48 ff c1             	inc    %rcx
+ +[a-f0-9]+:	44 88 02             	mov    %r8b,\(%rdx\)
+ +[a-f0-9]+:	48 ff c2             	inc    %rdx
+ +[a-f0-9]+:	44 8a 01             	mov    \(%rcx\),%r8b
+ +[a-f0-9]+:	45 84 c0             	test   %r8b,%r8b
+ +[a-f0-9]+:	75 ef                	jne    401064 <main\+0x64>
+ +[a-f0-9]+:	48 8b ce             	mov    %rsi,%rcx
+ +[a-f0-9]+:	e8 2f 00 00 00       	call   4010ac <xstring>
+ +[a-f0-9]+:	ff c7                	inc    %edi
+ +[a-f0-9]+:	48 83 c3 08          	add    \$0x8,%rbx
+ +[a-f0-9]+:	83 ff 01             	cmp    \$0x1,%edi
+ +[a-f0-9]+:	72 b5                	jb     40103d <main\+0x3d>
+ +[a-f0-9]+:	b1 aa                	mov    \$0xaa,%cl
+ +[a-f0-9]+:	e8 19 00 00 00       	call   4010a8 <xfunc>
+ +[a-f0-9]+:	48 8b 5c 24 30       	mov    0x30\(%rsp\),%rbx
+ +[a-f0-9]+:	33 c0                	xor    %eax,%eax
+ +[a-f0-9]+:	48 8b 6c 24 38       	mov    0x38\(%rsp\),%rbp
+ +[a-f0-9]+:	48 8b 74 24 48       	mov    0x48\(%rsp\),%rsi
+ +[a-f0-9]+:	48 83 c4 20          	add    \$0x20,%rsp
+ +[a-f0-9]+:	5f                   	pop    %rdi
+ +[a-f0-9]+:	c3                   	ret    
+ +[a-f0-9]+:	66 90                	xchg   %ax,%ax
+
+0+4010a8 <xfunc>:
+ +[a-f0-9]+:	66 90                	xchg   %ax,%ax
+ +[a-f0-9]+:	cc                   	int3   
+ +[a-f0-9]+:	c3                   	ret    
+
+0+4010ac <xstring>:
+ +[a-f0-9]+:	40 53                	rex push %rbx
+ +[a-f0-9]+:	48 83 ec 20          	sub    \$0x20,%rsp
+ +[a-f0-9]+:	8a 01                	mov    \(%rcx\),%al
+ +[a-f0-9]+:	48 8b d9             	mov    %rcx,%rbx
+ +[a-f0-9]+:	eb 0c                	jmp    4010c5 <xstring\+0x19>
+ +[a-f0-9]+:	8a c8                	mov    %al,%cl
+ +[a-f0-9]+:	e8 e8 ff ff ff       	call   4010a8 <xfunc>
+ +[a-f0-9]+:	48 ff c3             	inc    %rbx
+ +[a-f0-9]+:	8a 03                	mov    \(%rbx\),%al
+ +[a-f0-9]+:	84 c0                	test   %al,%al
+ +[a-f0-9]+:	75 f0                	jne    4010b9 <xstring\+0xd>
+ +[a-f0-9]+:	48 83 c4 20          	add    \$0x20,%rsp
+ +[a-f0-9]+:	5b                   	pop    %rbx
+ +[a-f0-9]+:	c3                   	ret    
+#pass
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64.exp b/ld/testsuite/ld-x86-64/pe-x86-64.exp
index ccfcdfaddfb..f5d2c84f283 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64.exp
+++ b/ld/testsuite/ld-x86-64/pe-x86-64.exp
@@ -73,4 +73,13 @@ run_ld_link_tests [list \
 	 {readelf {-s -x .data} pe-x86-64-5.rd}} \
 	"pe-x86-64-5" \
     ] \
+    [list \
+	"Build pe-x86-64-6" \
+	"-m elf_x86_64 --entry=main" \
+	"" \
+	"" \
+	{pe-x86-64-6.obj.bz2 } \
+	{{objdump {-dw --sym} pe-x86-64-6.od}} \
+	"pe-x86-64-6" \
+    ] \
 ]
-- 
2.29.2


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v5] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-03-05 18:26                                   ` [PATCH v5] " H.J. Lu
@ 2021-03-06  0:11                                     ` Alan Modra
  2021-03-06  1:00                                       ` [PATCH v6] " H.J. Lu
  0 siblings, 1 reply; 22+ messages in thread
From: Alan Modra @ 2021-03-06  0:11 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Jan Beulich, Binutils

On Fri, Mar 05, 2021 at 10:26:35AM -0800, H.J. Lu wrote:
> On Fri, Mar 5, 2021 at 5:57 AM Alan Modra <amodra@gmail.com> wrote:
> > This doesn't look like the right place to set up a reference to
> > __executable_start.  Doing so in a new check_relocs in pei-x86_64.c
> > that tests for an ELF output would be better.  I'm not suggesting that
> > you run over relocs looking for R_AMD64_IMAGEBASE, that could be done
> > but seems unnecessary.
> 
> check_relocs is too late.  We need to do it in load_symbols ().  Otherwise,
> __executable_start won't be defined.  I added pex64_link_add_symbols to
> do it.

Ah, I was forgetting that check_relocs now runs much later.  Even so,
I would have thought that the PROVIDE would define the symbol?  The
question is academic, I'm happy with pex64_link_add_symbols.

> Here is the v5 patch.  OK for master?

OK with three further changes.
1) The R_AMD64_IMAGEBASE handling should to be inside the
   output_bfd == NULL block.  It is wrong to apply the image base
   adjustment to the section for relocatable linking.  Doing so would
   effectively change the reloc addend.
2) I worry about the abort, which I think you might hit if trying to
   link PE objects into a pie.  One possible fix would be to change
   the bfd_link_pde in pex64_link_add_symbols to !bfd_link_relocatable.
   That might just be sweeping a problem under the rug, so an
   alternative fix would be to remove the abort and instead return
   with bfd_reloc_dangerous.  Either fix is fine with me.
3) No need to check for bfd_target_elf_flavour in set_output_arch.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v6] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-03-06  0:11                                     ` Alan Modra
@ 2021-03-06  1:00                                       ` H.J. Lu
  2021-03-07  4:16                                         ` Alan Modra
  0 siblings, 1 reply; 22+ messages in thread
From: H.J. Lu @ 2021-03-06  1:00 UTC (permalink / raw)
  To: Alan Modra; +Cc: Jan Beulich, Binutils

[-- Attachment #1: Type: text/plain, Size: 2704 bytes --]

On Fri, Mar 5, 2021 at 4:11 PM Alan Modra <amodra@gmail.com> wrote:
>
> On Fri, Mar 05, 2021 at 10:26:35AM -0800, H.J. Lu wrote:
> > On Fri, Mar 5, 2021 at 5:57 AM Alan Modra <amodra@gmail.com> wrote:
> > > This doesn't look like the right place to set up a reference to
> > > __executable_start.  Doing so in a new check_relocs in pei-x86_64.c
> > > that tests for an ELF output would be better.  I'm not suggesting that
> > > you run over relocs looking for R_AMD64_IMAGEBASE, that could be done
> > > but seems unnecessary.
> >
> > check_relocs is too late.  We need to do it in load_symbols ().  Otherwise,
> > __executable_start won't be defined.  I added pex64_link_add_symbols to
> > do it.
>
> Ah, I was forgetting that check_relocs now runs much later.  Even so,
> I would have thought that the PROVIDE would define the symbol?  The
> question is academic, I'm happy with pex64_link_add_symbols.
>
> > Here is the v5 patch.  OK for master?
>
> OK with three further changes.
> 1) The R_AMD64_IMAGEBASE handling should to be inside the
>    output_bfd == NULL block.  It is wrong to apply the image base
>    adjustment to the section for relocatable linking.  Doing so would
>    effectively change the reloc addend.

Fixed.

> 2) I worry about the abort, which I think you might hit if trying to
>    link PE objects into a pie.  One possible fix would be to change
>    the bfd_link_pde in pex64_link_add_symbols to !bfd_link_relocatable.
>    That might just be sweeping a problem under the rug, so an
>    alternative fix would be to remove the abort and instead return
>    with bfd_reloc_dangerous.  Either fix is fine with me.

Changed to return bfd_reloc_dangerous.

> 3) No need to check for bfd_target_elf_flavour in set_output_arch.
>

The check is needed for

./ld-new -z norelro
-L/export/gnu/import/git/gitlab/x86-binutils/ld/testsuite/ld-elf  -T
pr21884.t -o tmpdir/dump tmpdir/pr21884a.o tmpdir/pr21884b.o
Executing on host: sh -c {./ld-new -z norelro
-L/export/gnu/import/git/gitlab/x86-binutils/ld/testsuite/ld-elf  -T
pr21884.t -o tmpdir/dump tmpdir/pr21884a.o tmpdir/pr21884b.o  2>&1}
/dev/null dump.tmp (timeout = 300)
spawn [open ...]^M
sh: line 1: 1894243 Segmentation fault      (core dumped) ./ld-new -z
norelro -L/export/gnu/import/git/gitlab/x86-binutils/ld/testsuite/ld-elf
-T pr21884.t -o tmpdir/dump tmpdir/pr21884a.o tmpdir/pr21884b.o 2>&1
failed with: <sh: line 1: 1894243 Segmentation fault      (core
dumped) ./ld-new -z norelro
-L/export/gnu/import/git/gitlab/x86-binutils/ld/testsuite/ld-elf -T
pr21884.t -o tmpdir/dump tmpdir/pr21884a.o tmpdir/pr21884b.o 2>&1>, no
expected output
FAIL: ld-elf/pr21884

This is the patch I am checking in.

Thanks.

-- 
H.J.

[-- Attachment #2: v6-0001-elf-x86-64-Subtract-__ImageBase-for-R_AMD64_IMAGE.patch --]
[-- Type: text/x-patch, Size: 20543 bytes --]

From 1d4a687b2651ce8de36c4e7cf1d92ed3a007e09a Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 15 Feb 2021 18:53:18 -0800
Subject: [PATCH v6] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE

When linking Windows x86-64 relocatable object files to generate x86-64
ELF executable, we need to subtract __ImageBase, aka __executable_start,
for R_AMD64_IMAGEBASE relocation:

1. Add link_info to struct output_elf_obj_tdata to store linker info and
_bfd_get_link_info() to retrieve it.
2. Add ldelf_set_output_arch to set up link_info.
3. Add pex64_link_add_symbols to create an indirect reference to
__executable_start for __ImageBase to support R_AMD64_IMAGEBASE relocation
when adding symbols from Windows x86-64 relocatable object files to
generate x86-64 ELF executable.
4. Also subtract __ImageBase for R_AMD64_IMAGEBASE when generating x86-64
ELF executable.

bfd/

	PR ld/27425
	PR ld/27432
	* bfd.c (_bfd_get_link_info): New function.
	* elf-bfd.h (output_elf_obj_tdata): Add link_info.
	(elf_link_info): New.
	* libbfd-in.h (_bfd_get_link_info): New prototype.
	* coff-x86_64.c (coff_amd64_reloc): Also subtract __ImageBase for
	R_AMD64_IMAGEBASE when generating x86-64 ELF executable.
	* pe-x86_64.c: Include "coff/internal.h" and "libcoff.h".
	(pex64_link_add_symbols): New function.
	(coff_bfd_link_add_symbols): New macro.
	* libbfd.h: Regenerated.

ld/

	PR ld/27425
	PR ld/27432
	* ldelf.c (ldelf_set_output_arch): New function.
	* ldelf.h (ldelf_set_output_arch): New prototype.
	* emultempl/elf.em (LDEMUL_SET_OUTPUT_ARCH): Default to
	ldelf_set_output_arch.
	* ld-x86-64/pe-x86-64-1.od: Expect __executable_start.
	* testsuite/ld-x86-64/pe-x86-64-2.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-3.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-4.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-5.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-5.rd: Likewise.
	* testsuite/ld-x86-64/pe-x86-64-6.obj.bz2: New file.
	* testsuite/ld-x86-64/pe-x86-64-6.od: Likewise.
	* testsuite/ld-x86-64/pe-x86-64.exp: Run ld/27425 test.
---
 bfd/bfd.c                                  |  11 +++
 bfd/coff-x86_64.c                          |  35 +++++++-
 bfd/elf-bfd.h                              |   4 +
 bfd/libbfd-in.h                            |   2 +
 bfd/libbfd.h                               |   2 +
 bfd/pe-x86_64.c                            |  32 +++++++-
 ld/emultempl/elf.em                        |   2 +-
 ld/ldelf.c                                 |   8 ++
 ld/ldelf.h                                 |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-1.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-2.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-3.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-4.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-5.od      |   1 +
 ld/testsuite/ld-x86-64/pe-x86-64-5.rd      |   3 +-
 ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2 | Bin 0 -> 1366 bytes
 ld/testsuite/ld-x86-64/pe-x86-64-6.od      |  91 +++++++++++++++++++++
 ld/testsuite/ld-x86-64/pe-x86-64.exp       |   9 ++
 18 files changed, 198 insertions(+), 7 deletions(-)
 create mode 100644 ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2
 create mode 100644 ld/testsuite/ld-x86-64/pe-x86-64-6.od

diff --git a/bfd/bfd.c b/bfd/bfd.c
index f1944338838..2c620857863 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -2808,3 +2808,14 @@ bfd_convert_section_contents (bfd *ibfd, sec_ptr isec, bfd *obfd,
   *ptr_size = size;
   return TRUE;
 }
+
+/* Get the linker information.  */
+
+struct bfd_link_info *
+_bfd_get_link_info (bfd *abfd)
+{
+  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+    return NULL;
+
+  return elf_link_info (abfd);
+}
diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
index 5b09023f3c2..870df2b2b7a 100644
--- a/bfd/coff-x86_64.c
+++ b/bfd/coff-x86_64.c
@@ -131,11 +131,38 @@ coff_amd64_reloc (bfd *abfd,
 	diff -= reloc_entry->howto->type - R_AMD64_PCRLONG;
     }
 
-  /* FIXME: How should this case be handled?  */
   if (reloc_entry->howto->type == R_AMD64_IMAGEBASE
-      && output_bfd != NULL
-      && bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
-    diff -= pe_data (output_bfd)->pe_opthdr.ImageBase;
+      && output_bfd == NULL)
+    {
+      bfd *obfd = input_section->output_section->owner;
+      struct bfd_link_info *link_info;
+      struct bfd_link_hash_entry *h;
+      switch (bfd_get_flavour (obfd))
+	{
+	case bfd_target_coff_flavour:
+	  diff -= pe_data (obfd)->pe_opthdr.ImageBase;
+	  break;
+	case bfd_target_elf_flavour:
+	  /* Subtract __ImageBase.  */
+	  link_info = _bfd_get_link_info (obfd);
+	  if (link_info == NULL)
+	    return bfd_reloc_dangerous;
+	  h = bfd_link_hash_lookup (link_info->hash, "__ImageBase",
+				    FALSE, FALSE, FALSE);
+	  if (h == NULL)
+	    return bfd_reloc_dangerous;
+	  while (h->type == bfd_link_hash_indirect)
+	    h = h->u.i.link;
+	  /* ELF symbols in relocatable files are section relative,
+	     but in nonrelocatable files they are virtual addresses.  */
+	  diff -= (h->u.def.value
+		   + h->u.def.section->output_offset
+		   + h->u.def.section->output_section->vma);
+	  break;
+	default:
+	  break;
+	}
+    }
 #endif
 
 #define DOIT(x) \
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index c40030bdca6..04785a814e8 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1887,6 +1887,9 @@ struct output_elf_obj_tdata
   /* Used when laying out sections.  */
   file_ptr next_file_pos;
 
+  /* Linker information.  */
+  struct bfd_link_info *link_info;
+
   int num_section_syms;
   unsigned int shstrtab_section, strtab_section;
 
@@ -2064,6 +2067,7 @@ struct elf_obj_tdata
 #define elf_elfsections(bfd)	(elf_tdata(bfd) -> elf_sect_ptr)
 #define elf_numsections(bfd)	(elf_tdata(bfd) -> num_elf_sections)
 #define elf_seg_map(bfd)	(elf_tdata(bfd) -> o->seg_map)
+#define elf_link_info(bfd)	(elf_tdata(bfd) -> o->link_info)
 #define elf_next_file_pos(bfd)	(elf_tdata(bfd) -> o->next_file_pos)
 #define elf_eh_frame_hdr(bfd)	(elf_tdata(bfd) -> o->eh_frame_hdr)
 #define elf_stack_flags(bfd)	(elf_tdata(bfd) -> o->stack_flags)
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index 2dc20ec1b19..62b1cee0af0 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -899,6 +899,8 @@ extern bfd_vma _bfd_safe_read_leb128
 extern bfd_byte * _bfd_write_unsigned_leb128
   (bfd_byte *, bfd_byte *, bfd_vma) ATTRIBUTE_HIDDEN;
 
+extern struct bfd_link_info *_bfd_get_link_info (bfd *);
+
 #if GCC_VERSION >= 7000
 #define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
 #else
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 7271a2ad5a1..3a481ea468f 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -904,6 +904,8 @@ extern bfd_vma _bfd_safe_read_leb128
 extern bfd_byte * _bfd_write_unsigned_leb128
   (bfd_byte *, bfd_byte *, bfd_vma) ATTRIBUTE_HIDDEN;
 
+extern struct bfd_link_info *_bfd_get_link_info (bfd *);
+
 #if GCC_VERSION >= 7000
 #define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
 #else
diff --git a/bfd/pe-x86_64.c b/bfd/pe-x86_64.c
index 5b734442e3b..771651aba89 100644
--- a/bfd/pe-x86_64.c
+++ b/bfd/pe-x86_64.c
@@ -22,6 +22,8 @@
 
 #include "sysdep.h"
 #include "bfd.h"
+#include "coff/internal.h"
+#include "libcoff.h"
 
 #define TARGET_SYM		x86_64_pe_vec
 #define TARGET_NAME		"pe-x86-64"
@@ -66,5 +68,33 @@ extern bfd_boolean pex64_bfd_print_pdata (bfd *, void *);
 
 #define bfd_pe_print_pdata   pex64_bfd_print_pdata
 
-#include "coff-x86_64.c"
+static bfd_boolean
+pex64_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+  if (bfd_link_pde (info)
+      && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
+    {
+      /* NB: When linking Windows x86-64 relocatable object files to
+	 generate ELF executable, create an indirect reference to
+	 __executable_start for __ImageBase to support R_AMD64_IMAGEBASE
+	 relocation which is relative to __ImageBase.  */
+      struct bfd_link_hash_entry *h, *hi;
+      hi = bfd_link_hash_lookup (info->hash, "__ImageBase", TRUE, FALSE,
+				 FALSE);
+      if (hi->type == bfd_link_hash_new
+	  || hi->type == bfd_link_hash_undefined
+	  || hi->type == bfd_link_hash_undefweak)
+	{
+	  h = bfd_link_hash_lookup (info->hash, "__executable_start",
+				    TRUE, FALSE, TRUE);
+	  hi->type = bfd_link_hash_indirect;
+	  hi->u.i.link = h;
+	}
+    }
+
+  return _bfd_coff_link_add_symbols (abfd, info);
+}
 
+#define coff_bfd_link_add_symbols pex64_link_add_symbols
+
+#include "coff-x86_64.c"
diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em
index cea89e57e25..9e7c3d86a9e 100644
--- a/ld/emultempl/elf.em
+++ b/ld/emultempl/elf.em
@@ -919,7 +919,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
   ${LDEMUL_AFTER_CHECK_RELOCS-after_check_relocs_default},
   ${LDEMUL_BEFORE_PLACE_ORPHANS-ldelf_before_place_orphans},
   ${LDEMUL_AFTER_ALLOCATION-gld${EMULATION_NAME}_after_allocation},
-  ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
+  ${LDEMUL_SET_OUTPUT_ARCH-ldelf_set_output_arch},
   ${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
   ${LDEMUL_BEFORE_ALLOCATION-gld${EMULATION_NAME}_before_allocation},
   ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script},
diff --git a/ld/ldelf.c b/ld/ldelf.c
index 049992544a2..a733131e51c 100644
--- a/ld/ldelf.c
+++ b/ld/ldelf.c
@@ -2206,3 +2206,11 @@ ldelf_before_place_orphans (void)
 	  }
       }
 }
+
+void
+ldelf_set_output_arch (void)
+{
+  set_output_arch_default ();
+  if (link_info.output_bfd->xvec->flavour == bfd_target_elf_flavour)
+    elf_link_info (link_info.output_bfd) = &link_info;
+}
diff --git a/ld/ldelf.h b/ld/ldelf.h
index 629e7c1543a..aaf264ae239 100644
--- a/ld/ldelf.h
+++ b/ld/ldelf.h
@@ -31,3 +31,4 @@ extern bfd_boolean ldelf_open_dynamic_archive
 extern lang_output_section_statement_type *ldelf_place_orphan
   (asection *, const char *, int);
 extern void ldelf_before_place_orphans (void);
+extern void ldelf_set_output_arch (void);
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-1.od b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-1.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-1.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-2.od b/ld/testsuite/ld-x86-64/pe-x86-64-2.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-2.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-2.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-3.od b/ld/testsuite/ld-x86-64/pe-x86-64-3.od
index 4966d55fb5a..227875f82dc 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-3.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-3.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 getaddr1
 0+401020 g       .text\$mn	0000000000000000 begin
 0+403014 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-4.od b/ld/testsuite/ld-x86-64/pe-x86-64-4.od
index e0bde11d84e..320c6be5e14 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-4.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-4.od
@@ -2,6 +2,7 @@
 .*: +file format .*
 
 SYMBOL TABLE:
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+403038 g       .bss	0000000000000000 c
 0+401000 g       .text\$mn	0000000000000000 begin
 0+403038 g       .bss	0000000000000000 __bss_start
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-5.od b/ld/testsuite/ld-x86-64/pe-x86-64-5.od
index 8a4f4a633ac..6ef13abbc94 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-5.od
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-5.od
@@ -4,6 +4,7 @@
 SYMBOL TABLE:
 0+402014 g       .bss	0000000000000000 non_initdummy
 0+402010 g       .data	0000000000000000 initdummy
+0+400000 g       .text\$mn	0000000000000000 __executable_start
 0+401000 g       .text\$mn	0000000000000000 begin
 0+402012 g       .bss	0000000000000000 __bss_start
 0+402000 g       .data	0000000000000000 Struct
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-5.rd b/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
index 8370665f99f..237052805e9 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-5.rd
@@ -1,9 +1,10 @@
 
-Symbol table '.symtab' contains 10 entries:
+Symbol table '.symtab' contains 11 entries:
    Num:    Value          Size Type    Bind   Vis      Ndx Name
  +[a-f0-9]+: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
  +[a-f0-9]+: 0000000000402014     0 NOTYPE  GLOBAL DEFAULT    3 non_initdummy
  +[a-f0-9]+: 0000000000402010     0 NOTYPE  GLOBAL DEFAULT    2 initdummy
+ +[a-f0-9]+: 0000000000400000     0 NOTYPE  GLOBAL DEFAULT    1 __executable_start
  +[a-f0-9]+: 0000000000401000     0 NOTYPE  GLOBAL DEFAULT    1 begin
  +[a-f0-9]+: 0000000000402012     0 NOTYPE  GLOBAL DEFAULT    3 __bss_start
  +[a-f0-9]+: 0000000000402000     0 NOTYPE  GLOBAL DEFAULT    2 Struct
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2 b/ld/testsuite/ld-x86-64/pe-x86-64-6.obj.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..38255045d45ed918857b2c966400c13a13ea6c07
GIT binary patch
literal 1366
zcmV-c1*!T%T4*^jL0KkKSr(o^9smO9fB*mf|Nh_a|NQ^||Nj5~-}TM^Q*@d9YgPW;
zd+eHR_F&KhxOk{DUEM>1DTr#B8Vxi9QxnNB$qe;OMn*LZjWonG!KBke34qcKG#-Lu
zO+n}oJfkP-n1+}m6BA7tp+8jd3aO!pXvlhuKmni)7)=4727@32A)%%dK*9h3GyobJ
zF#(`ypa1~S&<2Qtn+c+6qtZ`M(<VowN$4g48fl<tXa<3x8X7%78Z>F3218950002c
z8UPw-&;$&OhMHssLqH6JBSwQEplP9@hychk8Z-t#7$DFx0MG!_Kn#r-BS2^XN+L#+
zMDk%qX+0wvnd*n6$Y=o5O#sjXO#o;B000^Q000000BC8T01Y)6t0Ij%1~1Zx-ljTP
zv7~$gP4n@oNq~cfwyu(S%%**p^kz*r4rRAWRcTbfRNzb)2)m)XQMb&4JUVWwY*_%P
z_N_!via~?|2}vgnKR75Sr_AXg#*K-lYBJ6&yOYkj3SvkC7BnqXI+`VjgE9yrmM|#Z
zAcU!thFfPL@ogO(W&_wPR?O<Nl`>0!yz(SMNI$pgD>nP`qq5&di9Y(;<tzfve#7RV
zLQq7sR8<iKE~*d}9#I&mh}9UVJg8-r7@=xZ2NcmYhaEyPiYfpN6hw+h7>GbrM+HPo
z!i9>{yG<#;mMI1E_Jr`*O+8>~P!*e8kP;V5^pWooq=L*qp)SmVWvfu>f>_r&r(rc;
zFlw0LN0dbVEA<6bekiD-s;40s%X>e{Bpb{0V*cpCy@Z%%2(;IT0ltH`?_5}n<UzB5
zf*?Wx?9SUxvoz5xvF*HU!`az<4cefwMgW_uK?W~)_YEp5)<A$@1UQMSt7Vh|X$!8S
zrYkdd%PnrQQ=JI}l%S=Jf?!qja8)kH^@O)sYfeI3m645L`q5BGerN)K?of-0r#>n|
zIJ>G_Jer_3(hAJw3_-j#7s1%O?->CeCR~1-d~uAqlkd=kBse0+P!fP8Gf5HP-!7%i
zY9#t2m+xTN{>23e(7a+I0;{Zo0pKlR8D<0+3~@0q!8UtF@$=vS%Ru|zVD9FpjySx}
zt{H?(&9Uu<p2jzU;|+yP-xYy^SQTmsWFw3b42s1?DxF}&SjcKo)TM}4B<*K1;RKpr
zB9L9W4U0w48Omi$FhV&*nXBTNgK+&nY+(ea!;BBmP6EO12PwtkmC_%#RsA$z@0JaQ
zK;1$!^T@K75<Qv*kCpFrll-gW?LaFYfjkRsvaL~}G=vHfYrg~uZV?6S9IpF-0+5}A
z_)^1T9VRd5A4+zwe~%URaNDw|ovUUIblXiY&aNu_D<Fy>a;O36%A;_CC4P{I;g8Lc
z_oIb1Th5wd#<v-tRhnyBD_BF4(rrdPfGi+1Cj(c?t7>6DvSmSitld-B7DP!ulPV)v
zjtH{yhbV)vqPiypj+2XeCuKWhP+%%5BxPTeR&+A6ME(Spj<8A+AT>of%9IL${b3$W
zT;V{<37R=3O12yjn;D3J_1es%R~rCwc#07V>0~}6Ocbcd(xo^hbFZ_E5g`dK4J43;
zL!(RF%z~VRcxJ6*mWojmVMt69!e|;&A4@D>YChtn2o?5O0qUo}T)OBf@?k*9{q-V&
zj?~DI4x)@7n$%$cCX*@q$)0{8UXMIXT<xV^S2T@qb<#e0E#AcXnZlt{eAv$l(KnN1
zj%}2QO$7taoaiC>k}0dYOV~!Q%X-@vZSVa^tl(<I`&6AfE`zbF1)s_=HB>Bd6H=xt
Y$~B;AV5AHi$*u8sBvXY60cqp`;GR@oQ~&?~

literal 0
HcmV?d00001

diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-6.od b/ld/testsuite/ld-x86-64/pe-x86-64-6.od
new file mode 100644
index 00000000000..cc23658a806
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pe-x86-64-6.od
@@ -0,0 +1,91 @@
+
+.*: +file format .*
+
+SYMBOL TABLE:
+0+4010a8 g       .text\$mn	0000000000000000 xfunc
+0+402000 g       .rdata	0000000000000000 \?\?_C@_02LDKJOMJN@AB@
+0+400000 g       .text\$mn	0000000000000000 __executable_start
+0+403058 g       .data	0000000000000000 __bss_start
+0+401000 g       .text\$mn	0000000000000000 main
+0+403038 g       .data	0000000000000000 deadloopvar
+0+4010ac g       .text\$mn	0000000000000000 xstring
+0+403058 g       .data	0000000000000000 _edata
+0+403058 g       .data	0000000000000000 _end
+
+
+
+Disassembly of section .text\$mn:
+
+0+401000 <main>:
+ +[a-f0-9]+:	48 89 5c 24 08       	mov    %rbx,0x8\(%rsp\)
+ +[a-f0-9]+:	48 89 6c 24 10       	mov    %rbp,0x10\(%rsp\)
+ +[a-f0-9]+:	48 89 74 24 20       	mov    %rsi,0x20\(%rsp\)
+ +[a-f0-9]+:	57                   	push   %rdi
+ +[a-f0-9]+:	48 83 ec 20          	sub    \$0x20,%rsp
+ +[a-f0-9]+:	cc                   	int3   
+ +[a-f0-9]+:	8b 05 1d 20 00 00    	mov    0x201d\(%rip\),%eax        # 403038 <deadloopvar>
+ +[a-f0-9]+:	83 f8 01             	cmp    \$0x1,%eax
+ +[a-f0-9]+:	74 f5                	je     401015 <main\+0x15>
+ +[a-f0-9]+:	0f 31                	rdtsc  
+ +[a-f0-9]+:	48 c1 e2 20          	shl    \$0x20,%rdx
+ +[a-f0-9]+:	48 0b c2             	or     %rdx,%rax
+ +[a-f0-9]+:	74 5d                	je     401088 <main\+0x88>
+ +[a-f0-9]+:	33 ff                	xor    %edi,%edi
+ +[a-f0-9]+:	48 8d 2d cc ef ff ff 	lea    -0x1034\(%rip\),%rbp        # 400000 <__executable_start>
+ +[a-f0-9]+:	33 db                	xor    %ebx,%ebx
+ +[a-f0-9]+:	48 8d 35 ff 1f 00 00 	lea    0x1fff\(%rip\),%rsi        # 40303c <deadloopvar\+0x4>
+ +[a-f0-9]+:	48 8b 8c 2b 50 30 00 00 	mov    0x3050\(%rbx,%rbp,1\),%rcx
+ +[a-f0-9]+:	44 8a 01             	mov    \(%rcx\),%r8b
+ +[a-f0-9]+:	45 84 c0             	test   %r8b,%r8b
+ +[a-f0-9]+:	74 28                	je     401075 <main\+0x75>
+ +[a-f0-9]+:	b8 05 00 00 00       	mov    \$0x5,%eax
+ +[a-f0-9]+:	2b 84 2b 48 30 00 00 	sub    0x3048\(%rbx,%rbp,1\),%eax
+ +[a-f0-9]+:	99                   	cltd   
+ +[a-f0-9]+:	2b c2                	sub    %edx,%eax
+ +[a-f0-9]+:	d1 f8                	sar    %eax
+ +[a-f0-9]+:	48 63 d0             	movslq %eax,%rdx
+ +[a-f0-9]+:	48 03 d6             	add    %rsi,%rdx
+ +[a-f0-9]+:	48 ff c1             	inc    %rcx
+ +[a-f0-9]+:	44 88 02             	mov    %r8b,\(%rdx\)
+ +[a-f0-9]+:	48 ff c2             	inc    %rdx
+ +[a-f0-9]+:	44 8a 01             	mov    \(%rcx\),%r8b
+ +[a-f0-9]+:	45 84 c0             	test   %r8b,%r8b
+ +[a-f0-9]+:	75 ef                	jne    401064 <main\+0x64>
+ +[a-f0-9]+:	48 8b ce             	mov    %rsi,%rcx
+ +[a-f0-9]+:	e8 2f 00 00 00       	call   4010ac <xstring>
+ +[a-f0-9]+:	ff c7                	inc    %edi
+ +[a-f0-9]+:	48 83 c3 08          	add    \$0x8,%rbx
+ +[a-f0-9]+:	83 ff 01             	cmp    \$0x1,%edi
+ +[a-f0-9]+:	72 b5                	jb     40103d <main\+0x3d>
+ +[a-f0-9]+:	b1 aa                	mov    \$0xaa,%cl
+ +[a-f0-9]+:	e8 19 00 00 00       	call   4010a8 <xfunc>
+ +[a-f0-9]+:	48 8b 5c 24 30       	mov    0x30\(%rsp\),%rbx
+ +[a-f0-9]+:	33 c0                	xor    %eax,%eax
+ +[a-f0-9]+:	48 8b 6c 24 38       	mov    0x38\(%rsp\),%rbp
+ +[a-f0-9]+:	48 8b 74 24 48       	mov    0x48\(%rsp\),%rsi
+ +[a-f0-9]+:	48 83 c4 20          	add    \$0x20,%rsp
+ +[a-f0-9]+:	5f                   	pop    %rdi
+ +[a-f0-9]+:	c3                   	ret    
+ +[a-f0-9]+:	66 90                	xchg   %ax,%ax
+
+0+4010a8 <xfunc>:
+ +[a-f0-9]+:	66 90                	xchg   %ax,%ax
+ +[a-f0-9]+:	cc                   	int3   
+ +[a-f0-9]+:	c3                   	ret    
+
+0+4010ac <xstring>:
+ +[a-f0-9]+:	40 53                	rex push %rbx
+ +[a-f0-9]+:	48 83 ec 20          	sub    \$0x20,%rsp
+ +[a-f0-9]+:	8a 01                	mov    \(%rcx\),%al
+ +[a-f0-9]+:	48 8b d9             	mov    %rcx,%rbx
+ +[a-f0-9]+:	eb 0c                	jmp    4010c5 <xstring\+0x19>
+ +[a-f0-9]+:	8a c8                	mov    %al,%cl
+ +[a-f0-9]+:	e8 e8 ff ff ff       	call   4010a8 <xfunc>
+ +[a-f0-9]+:	48 ff c3             	inc    %rbx
+ +[a-f0-9]+:	8a 03                	mov    \(%rbx\),%al
+ +[a-f0-9]+:	84 c0                	test   %al,%al
+ +[a-f0-9]+:	75 f0                	jne    4010b9 <xstring\+0xd>
+ +[a-f0-9]+:	48 83 c4 20          	add    \$0x20,%rsp
+ +[a-f0-9]+:	5b                   	pop    %rbx
+ +[a-f0-9]+:	c3                   	ret    
+#pass
diff --git a/ld/testsuite/ld-x86-64/pe-x86-64.exp b/ld/testsuite/ld-x86-64/pe-x86-64.exp
index ccfcdfaddfb..f5d2c84f283 100644
--- a/ld/testsuite/ld-x86-64/pe-x86-64.exp
+++ b/ld/testsuite/ld-x86-64/pe-x86-64.exp
@@ -73,4 +73,13 @@ run_ld_link_tests [list \
 	 {readelf {-s -x .data} pe-x86-64-5.rd}} \
 	"pe-x86-64-5" \
     ] \
+    [list \
+	"Build pe-x86-64-6" \
+	"-m elf_x86_64 --entry=main" \
+	"" \
+	"" \
+	{pe-x86-64-6.obj.bz2 } \
+	{{objdump {-dw --sym} pe-x86-64-6.od}} \
+	"pe-x86-64-6" \
+    ] \
 ]
-- 
2.29.2


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v6] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE
  2021-03-06  1:00                                       ` [PATCH v6] " H.J. Lu
@ 2021-03-07  4:16                                         ` Alan Modra
  0 siblings, 0 replies; 22+ messages in thread
From: Alan Modra @ 2021-03-07  4:16 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Jan Beulich, Binutils

On Fri, Mar 05, 2021 at 05:00:23PM -0800, H.J. Lu wrote:
> > 3) No need to check for bfd_target_elf_flavour in set_output_arch.
> 
> The check is needed for
[cases where the output format is non-ELF]

Yes indeed, my mental gears slipped a cog.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2021-03-07  4:16 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-23 12:15 [PATCH] elf/x86-64: Subtract __ImageBase for R_AMD64_IMAGEBASE H.J. Lu
2021-02-23 13:15 ` Jan Beulich
2021-02-23 13:31   ` H.J. Lu
2021-02-23 14:10     ` Jan Beulich
2021-02-23 14:47       ` H.J. Lu
2021-02-23 15:02         ` Jan Beulich
2021-02-23 15:07           ` H.J. Lu
2021-02-23 15:11             ` Jan Beulich
2021-02-23 17:50               ` [PATCH v2] " H.J. Lu
2021-02-25  2:09                 ` Alan Modra
2021-02-28  2:38                   ` [PATCH v3] " H.J. Lu
2021-03-01 12:19                     ` Alan Modra
2021-03-01 13:44                       ` H.J. Lu
2021-03-04 13:14                         ` Alan Modra
2021-03-04 13:54                           ` [PATCH v4] " H.J. Lu
2021-03-05  5:17                             ` Alan Modra
2021-03-05  5:29                               ` H.J. Lu
2021-03-05 13:57                                 ` Alan Modra
2021-03-05 18:26                                   ` [PATCH v5] " H.J. Lu
2021-03-06  0:11                                     ` Alan Modra
2021-03-06  1:00                                       ` [PATCH v6] " H.J. Lu
2021-03-07  4:16                                         ` Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).