[lld] r274342 - [ELF] Fix first PT_LOAD segment VA calculation, when linker script is used
Eugene Leviant via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 1 03:27:36 PDT 2016
Author: evgeny777
Date: Fri Jul 1 05:27:36 2016
New Revision: 274342
URL: http://llvm.org/viewvc/llvm-project?rev=274342&view=rev
Log:
[ELF] Fix first PT_LOAD segment VA calculation, when linker script is used
Added:
lld/trunk/test/ELF/linkerscript-phdr-check.s
Modified:
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=274342&r1=274341&r2=274342&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Fri Jul 1 05:27:36 2016
@@ -21,6 +21,7 @@
#include "ScriptParser.h"
#include "Strings.h"
#include "SymbolTable.h"
+#include "Target.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/FileSystem.h"
@@ -220,7 +221,8 @@ void LinkerScript<ELFT>::assignAddresses
}
// Assign addresses as instructed by linker script SECTIONS sub-commands.
- Dot = Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
+ Dot = Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
+ uintX_t MinVA = std::numeric_limits<uintX_t>::max();
uintX_t ThreadBssOffset = 0;
for (SectionsCommand &Cmd : Opt.Commands) {
@@ -247,11 +249,20 @@ void LinkerScript<ELFT>::assignAddresses
if (Sec->getFlags() & SHF_ALLOC) {
Dot = alignTo(Dot, Sec->getAlignment());
Sec->setVA(Dot);
+ MinVA = std::min(MinVA, Dot);
Dot += Sec->getSize();
continue;
}
}
}
+
+ // ELF and Program headers need to be right before the first section in memory.
+ // Set their addresses accordingly.
+ MinVA = alignDown(MinVA - Out<ELFT>::ElfHeader->getSize() -
+ Out<ELFT>::ProgramHeaders->getSize(),
+ Target->PageSize);
+ Out<ELFT>::ElfHeader->setVA(MinVA);
+ Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA);
}
template <class ELFT>
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=274342&r1=274341&r2=274342&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Jul 1 05:27:36 2016
@@ -1131,11 +1131,9 @@ template <class ELFT> void Writer<ELFT>:
// list, but have them to simplify the code.
template <class ELFT> void Writer<ELFT>::fixHeaders() {
uintX_t BaseVA = ScriptConfig->DoLayout ? 0 : Target->getVAStart();
- Out<ELFT>::ElfHeader->setVA(BaseVA);
- Out<ELFT>::ElfHeader->setFileOffset(0);
+ Out<ELFT>::ElfHeader->setVA(BaseVA);
uintX_t Off = Out<ELFT>::ElfHeader->getSize();
- Out<ELFT>::ProgramHeaders->setVA(Off + BaseVA);
- Out<ELFT>::ProgramHeaders->setFileOffset(Off);
+ Out<ELFT>::ProgramHeaders->setVA(Off + BaseVA);
}
// Assign VAs (addresses at run-time) to output sections.
@@ -1183,19 +1181,24 @@ static uintX_t getFileAlignment(uintX_t
// Assign file offsets to output sections.
template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
- uintX_t Off =
- Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
+ uintX_t Off = 0;
- for (OutputSectionBase<ELFT> *Sec : OutputSections) {
+ auto Set = [&](OutputSectionBase<ELFT> *Sec) {
if (Sec->getType() == SHT_NOBITS) {
Sec->setFileOffset(Off);
- continue;
+ return;
}
Off = getFileAlignment<ELFT>(Off, Sec);
Sec->setFileOffset(Off);
Off += Sec->getSize();
- }
+ };
+
+ Set(Out<ELFT>::ElfHeader);
+ Set(Out<ELFT>::ProgramHeaders);
+ for (OutputSectionBase<ELFT> *Sec : OutputSections)
+ Set(Sec);
+
SectionHeaderOff = alignTo(Off, sizeof(uintX_t));
FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr);
}
Added: lld/trunk/test/ELF/linkerscript-phdr-check.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript-phdr-check.s?rev=274342&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript-phdr-check.s (added)
+++ lld/trunk/test/ELF/linkerscript-phdr-check.s Fri Jul 1 05:27:36 2016
@@ -0,0 +1,15 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: echo "SECTIONS { . = 0x10000000; .text : {*(.text.*)} }" > %t.script
+# RUN: ld.lld -o %t1 --script %t.script %t
+# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
+# CHECK: ProgramHeaders [
+# CHECK-NEXT: ProgramHeader {
+# CHECK-NEXT: Type: PT_PHDR (0x6)
+# CHECK-NEXT: Offset: 0x40
+# CHECK-NEXT: VirtualAddress: 0xFFFF040
+
+.global _start
+_start:
+ nop
More information about the llvm-commits
mailing list