forked from OSchip/llvm-project
				
			Handle symbol assignments before the first section switch.
We now create a dummy section with index 1 before processing the linker script. Thanks to George Rimar for finding the bug and providing the initial testcase. llvm-svn: 294252
This commit is contained in:
		
							parent
							
								
									383c5c228f
								
							
						
					
					
						commit
						06f4743a48
					
				| 
						 | 
					@ -776,6 +776,19 @@ void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
 | 
				
			||||||
  // Assign addresses as instructed by linker script SECTIONS sub-commands.
 | 
					  // Assign addresses as instructed by linker script SECTIONS sub-commands.
 | 
				
			||||||
  Dot = 0;
 | 
					  Dot = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // A symbol can be assigned before any section is mentioned in the linker
 | 
				
			||||||
 | 
					  // script. In an DSO, the symbol values are addresses, so the only important
 | 
				
			||||||
 | 
					  // section values are:
 | 
				
			||||||
 | 
					  // * SHN_UNDEF
 | 
				
			||||||
 | 
					  // * SHN_ABS
 | 
				
			||||||
 | 
					  // * Any value meaning a regular section.
 | 
				
			||||||
 | 
					  // To handle that, create a dummy aether section that fills the void before
 | 
				
			||||||
 | 
					  // the linker scripts switches to another section. It has an index of one
 | 
				
			||||||
 | 
					  // which will map to whatever the first actual section is.
 | 
				
			||||||
 | 
					  auto *Aether = make<OutputSectionBase>("", 0, SHF_ALLOC);
 | 
				
			||||||
 | 
					  Aether->SectionIndex = 1;
 | 
				
			||||||
 | 
					  switchTo(Aether);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
 | 
					  for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
 | 
				
			||||||
    if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) {
 | 
					    if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) {
 | 
				
			||||||
      if (Cmd->Name == ".") {
 | 
					      if (Cmd->Name == ".") {
 | 
				
			||||||
| 
						 | 
					@ -973,14 +986,9 @@ template <class ELFT> bool LinkerScript<ELFT>::isAbsolute(StringRef S) {
 | 
				
			||||||
// to find suitable section for it as well.
 | 
					// to find suitable section for it as well.
 | 
				
			||||||
template <class ELFT>
 | 
					template <class ELFT>
 | 
				
			||||||
const OutputSectionBase *LinkerScript<ELFT>::getSymbolSection(StringRef S) {
 | 
					const OutputSectionBase *LinkerScript<ELFT>::getSymbolSection(StringRef S) {
 | 
				
			||||||
  SymbolBody *Sym = Symtab<ELFT>::X->find(S);
 | 
					  if (SymbolBody *Sym = Symtab<ELFT>::X->find(S))
 | 
				
			||||||
  if (!Sym) {
 | 
					 | 
				
			||||||
    if (OutputSections->empty())
 | 
					 | 
				
			||||||
      return nullptr;
 | 
					 | 
				
			||||||
    return CurOutSec ? CurOutSec : (*OutputSections)[0];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return SymbolTableSection<ELFT>::getOutputSection(Sym);
 | 
					    return SymbolTableSection<ELFT>::getOutputSection(Sym);
 | 
				
			||||||
 | 
					  return CurOutSec;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Returns indices of ELF headers containing specific section, identified
 | 
					// Returns indices of ELF headers containing specific section, identified
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					# REQUIRES: x86
 | 
				
			||||||
 | 
					# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
 | 
				
			||||||
 | 
					# RUN: echo "SECTIONS { A = . + 0x1; . += 0x1000; }" > %t.script
 | 
				
			||||||
 | 
					# RUN: ld.lld -shared %t1.o --script %t.script -o %t
 | 
				
			||||||
 | 
					# RUN: llvm-objdump -section-headers -t %t | FileCheck %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# CHECK:       Sections:
 | 
				
			||||||
 | 
					# CHECK-NEXT:   Idx Name          Size      Address
 | 
				
			||||||
 | 
					# CHECK-NEXT:    0               00000000 0000000000000000
 | 
				
			||||||
 | 
					# CHECK-NEXT:    1 .text         00000000 0000000000001000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# CHECK: 0000000000000001         .text            00000000 A
 | 
				
			||||||
		Loading…
	
		Reference in New Issue