[lld] r322421 - Fix incorrect physical address on self-referencing AT command.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 12 15:26:25 PST 2018


Author: rafael
Date: Fri Jan 12 15:26:25 2018
New Revision: 322421

URL: http://llvm.org/viewvc/llvm-project?rev=322421&view=rev
Log:
Fix incorrect physical address on self-referencing AT command.

When a section placement (AT) command references the section itself,
the physical address of the section in the ELF header was calculated
incorrectly due to alignment happening right after the location
pointer's value was captured.

The problem was diagnosed and the first version of the patch written
by Erick Reyes.

Added:
    lld/trunk/test/ELF/linkerscript/at-self-reference.s
Modified:
    lld/trunk/ELF/LinkerScript.cpp

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=322421&r1=322420&r2=322421&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Fri Jan 12 15:26:25 2018
@@ -608,13 +608,6 @@ void LinkerScript::switchTo(OutputSectio
 
   Ctx->OutSec = Sec;
   Ctx->OutSec->Addr = advance(0, Ctx->OutSec->Alignment);
-
-  // If neither AT nor AT> is specified for an allocatable section, the linker
-  // will set the LMA such that the difference between VMA and LMA for the
-  // section is the same as the preceding output section in the same region
-  // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
-  if (Ctx->LMAOffset)
-    Ctx->OutSec->LMAOffset = Ctx->LMAOffset();
 }
 
 // This function searches for a memory region to place the given output
@@ -662,6 +655,8 @@ void LinkerScript::assignOffsets(OutputS
   if (Ctx->MemRegion)
     Dot = Ctx->MemRegionOffset[Ctx->MemRegion];
 
+  switchTo(Sec);
+
   if (Sec->LMAExpr) {
     uint64_t D = Dot;
     Ctx->LMAOffset = [=] { return Sec->LMAExpr().getValue() - D; };
@@ -676,7 +671,12 @@ void LinkerScript::assignOffsets(OutputS
     }
   }
 
-  switchTo(Sec);
+  // If neither AT nor AT> is specified for an allocatable section, the linker
+  // will set the LMA such that the difference between VMA and LMA for the
+  // section is the same as the preceding output section in the same region
+  // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
+  if (Ctx->LMAOffset)
+    Ctx->OutSec->LMAOffset = Ctx->LMAOffset();
 
   // The Size previously denoted how many InputSections had been added to this
   // section, and was used for sorting SHF_LINK_ORDER sections. Reset it to

Added: lld/trunk/test/ELF/linkerscript/at-self-reference.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/at-self-reference.s?rev=322421&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/at-self-reference.s (added)
+++ lld/trunk/test/ELF/linkerscript/at-self-reference.s Fri Jan 12 15:26:25 2018
@@ -0,0 +1,63 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: echo "SECTIONS { \
+# RUN:  . = 0x1000; \
+# RUN:  .aaa : AT(ADDR(.aaa)) { *(.aaa) } \
+# RUN:  .bbb : AT(ADDR(.bbb)) { *(.bbb) } \
+# RUN: }" > %t.script
+# RUN: ld.lld %t --script %t.script -o %t2
+# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
+
+# CHECK:      ProgramHeaders [
+# CHECK-NEXT:  ProgramHeader {
+# CHECK-NEXT:    Type: PT_LOAD (0x1)
+# CHECK-NEXT:    Offset: 0x1000
+# CHECK-NEXT:    VirtualAddress: 0x1000
+# CHECK-NEXT:    PhysicalAddress: 0x1000
+# CHECK-NEXT:    FileSize: 3
+# CHECK-NEXT:    MemSize: 3
+# CHECK-NEXT:    Flags [ (0x5)
+# CHECK-NEXT:      PF_R (0x4)
+# CHECK-NEXT:      PF_X (0x1)
+# CHECK-NEXT:    ]
+# CHECK-NEXT:    Alignment: 4096
+# CHECK-NEXT:  }
+# CHECK-NEXT:  ProgramHeader {
+# CHECK-NEXT:    Type: PT_LOAD (0x1)
+# CHECK-NEXT:    Offset: 0x1008
+# CHECK-NEXT:    VirtualAddress: 0x1008
+# CHECK-NEXT:    PhysicalAddress: 0x1008
+# CHECK-NEXT:    FileSize: 9
+# CHECK-NEXT:    MemSize: 9
+# CHECK-NEXT:    Flags [ (0x5)
+# CHECK-NEXT:      PF_R (0x4)
+# CHECK-NEXT:      PF_X (0x1)
+# CHECK-NEXT:    ]
+# CHECK-NEXT:    Alignment: 4096
+# CHECK-NEXT:  }
+# CHECK-NEXT:  ProgramHeader {
+# CHECK-NEXT:    Type: PT_GNU_STACK (0x6474E551)
+# CHECK-NEXT:    Offset: 0x0
+# CHECK-NEXT:    VirtualAddress: 0x0
+# CHECK-NEXT:    PhysicalAddress: 0x0
+# CHECK-NEXT:    FileSize: 0
+# CHECK-NEXT:    MemSize: 0
+# CHECK-NEXT:    Flags [ (0x6)
+# CHECK-NEXT:      PF_R (0x4)
+# CHECK-NEXT:      PF_W (0x2)
+# CHECK-NEXT:    ]
+# CHECK-NEXT:    Alignment: 0
+# CHECK-NEXT:  }
+# CHECK-NEXT:]
+
+.global _start
+_start:
+ nop
+
+
+.section .aaa, "a"
+.asciz "aa"
+
+.section .bbb, "a"
+.align 8
+.quad 0




More information about the llvm-commits mailing list