mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
Compute A-B if both A and B are in the same comdat section.
Part of pr23272. A small annoyance with the assembly syntax we implement is that given an expression there is no way to know if what is desired is the value of that expression for the symbols in this file or for the final values of those symbols in a link. The first case is useful for use in sections that get discarded or ignored if the section they are describing is discarded. For axample, consider A-B where A and B are in the same comdat section. We can compute the value of the difference in the section that is present in the current .o and if that section survives to the final DSO the value will still will be correct. But the section is in a comdat. Another section from another object file might be used istead. We know that that section will define A and B, but we have no idea what the value of A-B might be. In practice we have to assume that the intention is to compute the value in the current section since otherwise the is no way to create something like the debug aranges section. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235222 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0f0d21e869
commit
560d73a4cc
@ -765,6 +765,9 @@ static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// True if the assembler knows nothing about the final value of the symbol.
|
||||||
|
// This doesn't cover the comdat issues, since in those cases the assembler
|
||||||
|
// can at least know that all symbols in the section will move together.
|
||||||
static bool isWeak(const MCSymbolData &D) {
|
static bool isWeak(const MCSymbolData &D) {
|
||||||
if (MCELF::GetType(D) == ELF::STT_GNU_IFUNC)
|
if (MCELF::GetType(D) == ELF::STT_GNU_IFUNC)
|
||||||
return true;
|
return true;
|
||||||
@ -775,27 +778,11 @@ static bool isWeak(const MCSymbolData &D) {
|
|||||||
case ELF::STB_LOCAL:
|
case ELF::STB_LOCAL:
|
||||||
return false;
|
return false;
|
||||||
case ELF::STB_GLOBAL:
|
case ELF::STB_GLOBAL:
|
||||||
break;
|
return false;
|
||||||
case ELF::STB_WEAK:
|
case ELF::STB_WEAK:
|
||||||
case ELF::STB_GNU_UNIQUE:
|
case ELF::STB_GNU_UNIQUE:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MCSymbol &Sym = D.getSymbol();
|
|
||||||
if (!Sym.isInSection())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const auto &Sec = cast<MCSectionELF>(Sym.getSection());
|
|
||||||
if (!Sec.getGroup())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// It is invalid to replace a reference to a global in a comdat
|
|
||||||
// with a reference to a local since out of comdat references
|
|
||||||
// to a local are forbidden.
|
|
||||||
// We could try to return false for more cases, like the reference
|
|
||||||
// being in the same comdat or Sym being an alias to another global,
|
|
||||||
// but it is not clear if it is worth the effort.
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ELFObjectWriter::RecordRelocation(MCAssembler &Asm,
|
void ELFObjectWriter::RecordRelocation(MCAssembler &Asm,
|
||||||
@ -1692,7 +1679,25 @@ bool ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ELFObjectWriter::isWeak(const MCSymbolData &SD) const {
|
bool ELFObjectWriter::isWeak(const MCSymbolData &SD) const {
|
||||||
return ::isWeak(SD);
|
if (::isWeak(SD))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const MCSymbol &Sym = SD.getSymbol();
|
||||||
|
if (!Sym.isInSection())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto &Sec = cast<MCSectionELF>(Sym.getSection());
|
||||||
|
if (!Sec.getGroup())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// It is invalid to replace a reference to a global in a comdat
|
||||||
|
// with a reference to a local since out of comdat references
|
||||||
|
// to a local are forbidden.
|
||||||
|
// We could try to return false for more cases, like the reference
|
||||||
|
// being in the same comdat or Sym being an alias to another global,
|
||||||
|
// but it is not clear if it is worth the effort.
|
||||||
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
|
MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
|
||||||
|
@ -2,6 +2,13 @@
|
|||||||
|
|
||||||
// Test that we produce the correct relocation.
|
// Test that we produce the correct relocation.
|
||||||
|
|
||||||
|
|
||||||
|
.section .pr23272,"aGw",@progbits,pr23272,comdat
|
||||||
|
.globl pr23272
|
||||||
|
pr23272:
|
||||||
|
pr23272_2:
|
||||||
|
|
||||||
|
.text
|
||||||
bar:
|
bar:
|
||||||
movl $bar, %edx # R_X86_64_32
|
movl $bar, %edx # R_X86_64_32
|
||||||
movq $bar, %rdx # R_X86_64_32S
|
movq $bar, %rdx # R_X86_64_32S
|
||||||
@ -43,6 +50,8 @@ bar:
|
|||||||
|
|
||||||
.long foo@gotpcrel
|
.long foo@gotpcrel
|
||||||
.long foo@plt
|
.long foo@plt
|
||||||
|
|
||||||
|
.quad pr23272_2 - pr23272
|
||||||
// CHECK: Section {
|
// CHECK: Section {
|
||||||
// CHECK: Name: .rela.text
|
// CHECK: Name: .rela.text
|
||||||
// CHECK: Relocations [
|
// CHECK: Relocations [
|
||||||
@ -89,5 +98,5 @@ bar:
|
|||||||
// CHECK-NEXT: Binding: Local
|
// CHECK-NEXT: Binding: Local
|
||||||
// CHECK-NEXT: Type: Section
|
// CHECK-NEXT: Type: Section
|
||||||
// CHECK-NEXT: Other: 0
|
// CHECK-NEXT: Other: 0
|
||||||
// CHECK-NEXT: Section: .text (0x1)
|
// CHECK-NEXT: Section: .text
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
|
Loading…
Reference in New Issue
Block a user