/// Bindings of names to symbols.
SymbolTable Symbols;
- /// Sections can have a corresponding symbol. This maps one to the
- /// other.
- DenseMap<const MCSection *, MCSymbol *> SectionSymbols;
-
/// A mapping from a local label number and an instance count to a symbol.
/// For example, in the assembly
/// 1:
MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
unsigned Instance);
+ MCSectionELF *createELFSectionImpl(StringRef Section, unsigned Type,
+ unsigned Flags, SectionKind K,
+ unsigned EntrySize,
+ const MCSymbolELF *Group,
+ unsigned UniqueID,
+ const MCSectionELF *Associated);
+
public:
explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI,
const MCObjectFileInfo *MOFI,
/// \param Name - The symbol name, which must be unique across all symbols.
MCSymbol *getOrCreateSymbol(const Twine &Name);
- MCSymbolELF *getOrCreateSectionSymbol(const MCSectionELF &Section);
-
/// Gets a symbol that will be defined to the final stack offset of a local
/// variable after codegen.
///
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags) {
- return getELFSection(Section, Type, Flags, nullptr);
- }
-
- MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
- unsigned Flags, const char *BeginSymName) {
- return getELFSection(Section, Type, Flags, 0, "", BeginSymName);
+ return getELFSection(Section, Type, Flags, 0, "");
}
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const Twine &Group) {
- return getELFSection(Section, Type, Flags, EntrySize, Group, nullptr);
- }
-
- MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
- unsigned Flags, unsigned EntrySize,
- const Twine &Group, const char *BeginSymName) {
- return getELFSection(Section, Type, Flags, EntrySize, Group, ~0,
- BeginSymName);
- }
-
- MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
- unsigned Flags, unsigned EntrySize,
- const Twine &Group, unsigned UniqueID) {
- return getELFSection(Section, Type, Flags, EntrySize, Group, UniqueID,
- nullptr);
+ return getELFSection(Section, Type, Flags, EntrySize, Group, ~0);
}
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
- const Twine &Group, unsigned UniqueID,
- const char *BeginSymName);
+ const Twine &Group, unsigned UniqueID);
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const MCSymbolELF *Group, unsigned UniqueID,
- const char *BeginSymName,
const MCSectionELF *Associated);
/// Get a section with the provided group identifier. This section is
void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) {
- // Section symbols are used as definitions for undefined symbols with matching
- // names. If there are multiple sections with the same name, the first one is
- // used.
- for (const MCSection &Sec : Asm) {
- const MCSymbol *Begin = Sec.getBeginSymbol();
- if (!Begin)
- continue;
-
- const MCSymbol *Alias = Asm.getContext().lookupSymbol(Begin->getName());
- if (!Alias || !Alias->isUndefined())
- continue;
-
- Renames.insert(
- std::make_pair(cast<MCSymbolELF>(Alias), cast<MCSymbolELF>(Begin)));
- }
-
// The presence of symbol versions causes undefined symbols and
// versions declared with @@@ to be renamed.
for (const MCSymbol &A : Asm.symbols()) {
MCSubtargetAllocator.DestroyAll();
UsedNames.clear();
Symbols.clear();
- SectionSymbols.clear();
Allocator.Reset();
Instances.clear();
CompilationDir.clear();
return Sym;
}
-MCSymbolELF *MCContext::getOrCreateSectionSymbol(const MCSectionELF &Section) {
- MCSymbol *&Sym = SectionSymbols[&Section];
- if (Sym)
- return cast<MCSymbolELF>(Sym);
-
- StringRef Name = Section.getSectionName();
- auto NameIter = UsedNames.insert(std::make_pair(Name, false)).first;
- Sym = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false);
-
- return cast<MCSymbolELF>(Sym);
-}
-
MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName,
unsigned Idx) {
return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
const_cast<MCSectionELF *>(Section)->setSectionName(CachedName);
}
+MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
+ unsigned Flags, SectionKind K,
+ unsigned EntrySize,
+ const MCSymbolELF *Group,
+ unsigned UniqueID,
+ const MCSectionELF *Associated) {
+
+ MCSymbolELF *R;
+ MCSymbol *&Sym = Symbols[Section];
+ if (Sym && Sym->isUndefined()) {
+ R = cast<MCSymbolELF>(Sym);
+ } else {
+ auto NameIter = UsedNames.insert(std::make_pair(Section, false)).first;
+ R = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false);
+ if (!Sym)
+ Sym = R;
+ }
+ R->setBinding(ELF::STB_LOCAL);
+ R->setType(ELF::STT_SECTION);
+ R->setRedefinable(true);
+
+ auto *Ret = new (ELFAllocator.Allocate()) MCSectionELF(
+ Section, Type, Flags, K, EntrySize, Group, UniqueID, R, Associated);
+
+ auto *F = new MCDataFragment();
+ Ret->getFragmentList().insert(Ret->begin(), F);
+ F->setParent(Ret);
+ R->setFragment(F);
+
+ return Ret;
+}
+
MCSectionELF *MCContext::createELFRelSection(const Twine &Name, unsigned Type,
unsigned Flags, unsigned EntrySize,
const MCSymbolELF *Group,
std::tie(I, Inserted) =
ELFRelSecNames.insert(std::make_pair(Name.str(), true));
- return new (ELFAllocator.Allocate())
- MCSectionELF(I->getKey(), Type, Flags, SectionKind::getReadOnly(),
- EntrySize, Group, true, nullptr, Associated);
+ return createELFSectionImpl(I->getKey(), Type, Flags,
+ SectionKind::getReadOnly(), EntrySize, Group,
+ true, Associated);
}
MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix,
MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
- const Twine &Group, unsigned UniqueID,
- const char *BeginSymName) {
+ const Twine &Group, unsigned UniqueID) {
MCSymbolELF *GroupSym = nullptr;
if (!Group.isTriviallyEmpty() && !Group.str().empty())
GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group));
return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID,
- BeginSymName, nullptr);
+ nullptr);
}
MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const MCSymbolELF *GroupSym,
unsigned UniqueID,
- const char *BeginSymName,
const MCSectionELF *Associated) {
StringRef Group = "";
if (GroupSym)
else
Kind = SectionKind::getReadOnly();
- MCSymbol *Begin = nullptr;
- if (BeginSymName)
- Begin = createTempSymbol(BeginSymName, false);
-
- MCSectionELF *Result = new (ELFAllocator.Allocate())
- MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID,
- Begin, Associated);
+ MCSectionELF *Result = createELFSectionImpl(
+ CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID, Associated);
Entry.second = Result;
return Result;
}
MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group) {
- MCSectionELF *Result = new (ELFAllocator.Allocate())
- MCSectionELF(".group", ELF::SHT_GROUP, 0, SectionKind::getReadOnly(), 4,
- Group, ~0, nullptr, nullptr);
- return Result;
+ return createELFSectionImpl(".group", ELF::SHT_GROUP, 0,
+ SectionKind::getReadOnly(), 4, Group, ~0,
+ nullptr);
}
MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
Asm.registerSymbol(*Grp);
this->MCObjectStreamer::ChangeSection(Section, Subsection);
- MCContext &Ctx = getContext();
- auto *Begin = cast_or_null<MCSymbolELF>(Section->getBeginSymbol());
- if (!Begin) {
- Begin = Ctx.getOrCreateSectionSymbol(*SectionELF);
- Section->setBeginSymbol(Begin);
- }
- if (Begin->isUndefined()) {
- Asm.registerSymbol(*Begin);
- Begin->setType(ELF::STT_SECTION);
- }
+ Asm.registerSymbol(*Section->getBeginSymbol());
}
void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
COFFDebugTypesSection = nullptr;
// Debug Info Sections.
- DwarfAbbrevSection = Ctx->getELFSection(".debug_abbrev", ELF::SHT_PROGBITS, 0,
- "section_abbrev");
- DwarfInfoSection =
- Ctx->getELFSection(".debug_info", ELF::SHT_PROGBITS, 0, "section_info");
+ DwarfAbbrevSection =
+ Ctx->getELFSection(".debug_abbrev", ELF::SHT_PROGBITS, 0);
+ DwarfInfoSection = Ctx->getELFSection(".debug_info", ELF::SHT_PROGBITS, 0);
DwarfLineSection = Ctx->getELFSection(".debug_line", ELF::SHT_PROGBITS, 0);
DwarfFrameSection = Ctx->getELFSection(".debug_frame", ELF::SHT_PROGBITS, 0);
DwarfPubNamesSection =
DwarfARangesSection =
Ctx->getELFSection(".debug_aranges", ELF::SHT_PROGBITS, 0);
DwarfRangesSection =
- Ctx->getELFSection(".debug_ranges", ELF::SHT_PROGBITS, 0, "debug_range");
- DwarfMacinfoSection = Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS,
- 0, "debug_macinfo");
+ Ctx->getELFSection(".debug_ranges", ELF::SHT_PROGBITS, 0);
+ DwarfMacinfoSection =
+ Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS, 0);
// DWARF5 Experimental Debug Info
// Accelerator Tables
DwarfAccelNamesSection =
- Ctx->getELFSection(".apple_names", ELF::SHT_PROGBITS, 0, "names_begin");
+ Ctx->getELFSection(".apple_names", ELF::SHT_PROGBITS, 0);
DwarfAccelObjCSection =
- Ctx->getELFSection(".apple_objc", ELF::SHT_PROGBITS, 0, "objc_begin");
- DwarfAccelNamespaceSection = Ctx->getELFSection(
- ".apple_namespaces", ELF::SHT_PROGBITS, 0, "namespac_begin");
+ Ctx->getELFSection(".apple_objc", ELF::SHT_PROGBITS, 0);
+ DwarfAccelNamespaceSection =
+ Ctx->getELFSection(".apple_namespaces", ELF::SHT_PROGBITS, 0);
DwarfAccelTypesSection =
- Ctx->getELFSection(".apple_types", ELF::SHT_PROGBITS, 0, "types_begin");
+ Ctx->getELFSection(".apple_types", ELF::SHT_PROGBITS, 0);
// Fission Sections
DwarfInfoDWOSection =
DwarfLineDWOSection =
Ctx->getELFSection(".debug_line.dwo", ELF::SHT_PROGBITS, 0);
DwarfLocDWOSection =
- Ctx->getELFSection(".debug_loc.dwo", ELF::SHT_PROGBITS, 0, "skel_loc");
+ Ctx->getELFSection(".debug_loc.dwo", ELF::SHT_PROGBITS, 0);
DwarfStrOffDWOSection =
Ctx->getELFSection(".debug_str_offsets.dwo", ELF::SHT_PROGBITS, 0);
- DwarfAddrSection =
- Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0, "addr_sec");
+ DwarfAddrSection = Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0);
// DWP Sections
DwarfCUIndexSection =
return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
"alignment, can't be less than zero");
+ Sym->redefineIfPossible();
if (!Sym->isUndefined())
return Error(IDLoc, "invalid symbol redefinition");
void MCSymbolELF::setBinding(unsigned Binding) const {
setIsBindingSet();
+ if (getType() == ELF::STT_SECTION && Binding != ELF::STB_LOCAL)
+ setType(ELF::STT_NOTYPE);
unsigned Val;
switch (Binding) {
default:
void MCSymbolELF::setType(unsigned Type) const {
unsigned Val;
+ if (Type == ELF::STT_SECTION && getBinding() != ELF::STB_LOCAL)
+ return;
switch (Type) {
default:
llvm_unreachable("Unsupported Binding");
const MCSymbolELF *Group = FnSection.getGroup();
if (Group)
Flags |= ELF::SHF_GROUP;
- MCSectionELF *EHSection =
- getContext().getELFSection(EHSecName, Type, Flags, 0, Group,
- FnSection.getUniqueID(), nullptr, &FnSection);
+ MCSectionELF *EHSection = getContext().getELFSection(
+ EHSecName, Type, Flags, 0, Group, FnSection.getUniqueID(), &FnSection);
assert(EHSection && "Failed to get the required EH section");
; RUN: %llc_dwarf -O2 %s -o - | FileCheck %s
; Check struct X for dead variable xyz from inlined function foo.
-; CHECK: section_info
+; CHECK: .section .debug_info,"",@progbits
; CHECK: DW_TAG_structure_type
; CHECK-NEXT: DW_AT_name
!7 = distinct !DILexicalBlock(line: 3, column: 12, file: !14, scope: !0)
!8 = !DICompositeType(tag: DW_TAG_array_type, align: 32, file: !14, scope: !2, baseType: !5, elements: !9)
!9 = !{!10}
-;CHECK: section_info:
+;CHECK: .section .debug_info,"",@progbits
;CHECK: DW_TAG_subrange_type
;CHECK-NEXT: DW_AT_type
;CHECK-NOT: DW_AT_lower_bound
; RUN: llc -mtriple mips-linux-gnu -O2 %s -o - | FileCheck %s
; Check struct X for dead variable xyz from inlined function foo.
-; CHECK: section_info
+; CHECK: .section .debug_info,"",@progbits
; CHECK: DW_TAG_structure_type
; CHECK-NEXT: info_string
; DW_OP_GNU_push_tls_address
; CHECK-NEXT: .byte 224
; check that the expected TLS address description is the first thing in the debug_addr section
-; CHECK: debug_addr
-; CHECK-NEXT: .Laddr_sec:
+; CHECK: .section .debug_addr,"",@progbits
; CHECK-NEXT: .quad tls@DTPREL+32768
source_filename = "test/DebugInfo/PowerPC/tls-fission.ll"
; CHECK: DW_TAG_variable
; Make sure this is relocatable.
; and test that we don't create the labels to emit a correct COFF relocation
-; ELF-ASM: .quad .Lsection_info+[[TYPE]] # DW_AT_type
+; ELF-ASM: .quad .debug_info+[[TYPE]] # DW_AT_type
; COFF-ASM: .secrel32 .Lsection_info+[[TYPE]] # DW_AT_type
; DARWIN-ASM2: .quad [[TYPE]] ## DW_AT_type
; DARWIN-ASM4: .long [[TYPE]] ## DW_AT_type
; check that the expected TLS address description is the first thing in the debug_addr section
; FISSION: .section .debug_addr
-; FISSION: addr_sec:
; FISSION-NEXT: .quad tls@DTPOFF
; FISSION-NEXT: .quad glbl
; FISSION-NOT: .quad glbl
add w0, w1, #(sec_y - sec_x)
cmp w0, #(sec_y - sec_x)
- // CHECK: error: symbol 'sec_x' can not be undefined in a subtraction expression
+ // CHECK: error: Cannot represent a difference across sections
// CHECK-NEXT: add w0, w1, #(sec_y - sec_x)
// CHECK-NEXT: ^
- // CHECK: error: symbol 'sec_x' can not be undefined in a subtraction expression
+ // CHECK: error: Cannot represent a difference across sections
// CHECK-NEXT: cmp w0, #(sec_y - sec_x)
// CHECK-NEXT: ^
// ASM: .section .debug_info
// ASM: .section .debug_abbrev
-// ASM-NEXT: .Lsection_abbrev:
// ASM-NEXT: [[ABBREV_LABEL:.Ltmp[0-9]+]]
// Second instance of the section has the CU
# MICRO: b .text # encoding: [0x94,0x00,A,A]
# MICRO: # fixup A - offset: 0, value: .text, kind: fixup_MICROMIPS_PC16_S1
-# ELF-O32: 10 00 ff ff b 0
-# ELF-O32-NEXT: 00000018: R_MIPS_PC16 .text
+# ELF-O32: 10 00 ff f9 b -24 <local_label>
+# ELF-O32-NEXT: 00 00 00 00 nop
-# ELF-NXX: 10 00 00 00 b 4
-# ELF-NXX-NEXT: R_MIPS_PC16/R_MIPS_NONE/R_MIPS_NONE .text
+# ELF-NXX: 10 00 ff f9 b -24 <local_label>
+# ELF-NXX-NEXT: 00 00 00 00 nop
j 1f
nop
jal .text
nop
-# FIXME: The .text section MCSymbol isn't created when printing assembly. However,
-# it is created when generating an ELF object file.
# Expanding "jal .text":
-# O32-FIXME: lw $25, %call16(.text)($gp) # encoding: [0x8f,0x99,A,A]
-# O32-FIXME: # fixup A - offset: 0, value: %got(.text), kind: fixup_Mips_GOT_CALL
+# O32: lw $25, %got(.text)($gp) # encoding: [0x8f,0x99,A,A]
+# O32-NEXT: # fixup A - offset: 0, value: %got(.text), kind: fixup_Mips_GOT
# ELF-O32: 8f 99 00 00 lw $25, 0($gp)
-# ELF-O32-NEXT: R_MIPS_CALL16 .text
+# ELF-O32-NEXT: R_MIPS_GOT16 .text
-# N32-FIXME: lw $25, %call16(.text)($gp) # encoding: [0x8f,0x99,A,A]
-# N32-FIXME: # fixup A - offset: 0, value: %call16(.text), kind: fixup_Mips_GOT_DISP
+# N32: lw $25, %got_disp(.text)($gp) # encoding: [0x8f,0x99,A,A]
+# N32-NEXT: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_Mips_GOT_DISP
# ELF-N32: 8f 99 00 00 lw $25, 0($gp)
-# ELF-N32-NEXT: R_MIPS_CALL16/R_MIPS_NONE/R_MIPS_NONE .text
+# ELF-N32-NEXT: R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE .text
-# N64-FIXME: ld $25, %call16(.text)($gp) # encoding: [0xdf,0x99,A,A]
-# N64-FIXME: # fixup A - offset: 0, value: %call16(.text), kind: fixup_Mips_GOT_DISP
+# N64: ld $25, %got_disp(.text)($gp) # encoding: [0xdf,0x99,A,A]
+# N64-NEXT: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_Mips_GOT_DISP
# ELF-N64: df 99 00 00 ld $25, 0($gp)
-# ELF-N64-NEXT: R_MIPS_CALL16/R_MIPS_NONE/R_MIPS_NONE .text
+# ELF-N64-NEXT: R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE .text
-# O32-MM-FIXME: lw $25, %got(.text)($gp) # encoding: [0xff,0x3c,A,A]
-# O32-MM-FIXME: # fixup A - offset: 0, value: %got(.text), kind: fixup_MICROMIPS_GOT16
-# O32-MM-FIXME: addiu $25, $25, %lo(.text) # encoding: [0x33,0x39,A,A]
-# O32-MM-FIXME: # fixup A - offset: 0, value: %lo(.text), kind: fixup_MICROMIPS_LO16
+# O32-MM: lw $25, %got(.text)($gp) # encoding: [0xff,0x3c,A,A]
+# O32-MM-NEXT: # fixup A - offset: 0, value: %got(.text), kind: fixup_MICROMIPS_GOT16
+# O32-MM-NEXT: addiu $25, $25, %lo(.text) # encoding: [0x33,0x39,A,A]
+# O32-MM-NEXT: # fixup A - offset: 0, value: %lo(.text), kind: fixup_MICROMIPS_LO16
-# N32-MM-FIXME: lw $25, %got_disp(.text)($gp) # encoding: [0xff,0x3c,A,A]
-# N32-MM-FIXME: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_MICROMIPS_GOT_DISP
+# N32-MM: lw $25, %got_disp(.text)($gp) # encoding: [0xff,0x3c,A,A]
+# N32-MM-NEXT: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_MICROMIPS_GOT_DISP
-# N64-MM-FIXME: ld $25, %got_disp(.text)($gp) # encoding: [0xdf,0x99,A,A]
-# N64-MM-FIXME: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_MICROMIPS_GOT_DISP
+# N64-MM: ld $25, %got_disp(.text)($gp) # encoding: [0xdf,0x99,A,A]
+# N64-MM-NEXT: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_MICROMIPS_GOT_DISP
# MIPS: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
# MM: jalr $ra, $25 # encoding: [0x03,0xf9,0x0f,0x3c]
# ELF-O32: 8f 99 00 00 lw $25, 0($gp)
# ELF-O32-NEXT: R_MIPS_GOT16 .text
-# ELF-O32-NEXT: 27 39 00 54 addiu $25, $25, 84
+# ELF-O32-NEXT: 27 39 00 58 addiu $25, $25, 88
# ELF-O32-NEXT: R_MIPS_LO16 .text
# N32: lw $25, %got_disp($tmp0)($gp) # encoding: [0x8f,0x99,A,A]
# ELF-O32: 8f 99 00 00 lw $25, 0($gp)
# ELF-O32-NEXT: R_MIPS_GOT16 .text
-# ELF-O32-NEXT: 27 39 00 60 addiu $25, $25, 96
+# ELF-O32-NEXT: 27 39 00 64 addiu $25, $25, 100
# ELF-O32-NEXT: R_MIPS_LO16 .text
# N32-FIXME: lw $25, %got_disp(forward_local)($gp) # encoding: [0x8f,0x99,A,A]