Reference LLVM Source code
Parent -> Child: MCObjectFileInfo
-> TargetLoweringObjectFile
-> TargetLoweringObjectFileELF
-> MipsTargetObjectFile
SourceCode of class MCObjectFileInfo
llvm/MC/MCObjectFileInfo.h
llvm/lib/MC/MCObjectFileInfo.cpp
States:
MCSection *TextSection, *DataSection, *BSSSection
MCSection *ReadOnlySection
. Not required.MCSection *LSDASection
. Section of Language Specific Data Area (LSDA). To support languages with exception handling.DwarfLineSection
DwarfLineStrSection
DwarfStrSection
Initialized in function MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large)
.
// lib/MC/MCObjectFileInfo.cpp
void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
switch (T.getArch()) {
case Triple::mips:
case Triple::mipsel:
case Triple::mips64:
case Triple::mips64el:
case Triple::cheri:
FDECFIEncoding = Ctx->getAsmInfo()->getCodePointerSize() == 4
? dwarf::DW_EH_PE_sdata4
: dwarf::DW_EH_PE_sdata8;
break;
case Triple::ppc64:
case Triple::ppc64le:
case Triple::x86_64:
FDECFIEncoding = dwarf::DW_EH_PE_pcrel |
(Large ? dwarf::DW_EH_PE_sdata8 : dwarf::DW_EH_PE_sdata4);
break;
case Triple::bpfel:
case Triple::bpfeb:
FDECFIEncoding = dwarf::DW_EH_PE_sdata8;
break;
case Triple::hexagon:
FDECFIEncoding =
PositionIndependent ? dwarf::DW_EH_PE_pcrel : dwarf::DW_EH_PE_absptr;
break;
default:
FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
break;
}
unsigned EHSectionType = T.getArch() == Triple::x86_64
? ELF::SHT_X86_64_UNWIND
: ELF::SHT_PROGBITS;
// Solaris requires different flags for .eh_frame to seemingly every other
// platform.
unsigned EHSectionFlags = ELF::SHF_ALLOC;
if (T.isOSSolaris() && T.getArch() != Triple::x86_64)
EHSectionFlags |= ELF::SHF_WRITE;
// This is (currently) also true for MIPS
// TODO: add a T.isMIPS()?
switch (T.getArch()) {
case Triple::mips:
case Triple::mipsel:
case Triple::mips64:
case Triple::mips64el:
case Triple::cheri:
if (PositionIndependent) {
EHSectionFlags |= ELF::SHF_WRITE;
}
break;
default:
break;
}
// ELF
BSSSection = Ctx->getELFSection(".bss", ELF::SHT_NOBITS,
ELF::SHF_WRITE | ELF::SHF_ALLOC);
TextSection = Ctx->getELFSection(".text", ELF::SHT_PROGBITS,
ELF::SHF_EXECINSTR | ELF::SHF_ALLOC);
DataSection = Ctx->getELFSection(".data", ELF::SHT_PROGBITS,
ELF::SHF_WRITE | ELF::SHF_ALLOC);
ReadOnlySection =
Ctx->getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
TLSDataSection =
Ctx->getELFSection(".tdata", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_TLS | ELF::SHF_WRITE);
TLSBSSSection = Ctx->getELFSection(
".tbss", ELF::SHT_NOBITS, ELF::SHF_ALLOC | ELF::SHF_TLS | ELF::SHF_WRITE);
DataRelROSection = Ctx->getELFSection(".data.rel.ro", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_WRITE);
MergeableConst4Section =
Ctx->getELFSection(".rodata.cst4", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_MERGE, 4, "");
MergeableConst8Section =
Ctx->getELFSection(".rodata.cst8", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_MERGE, 8, "");
MergeableConst16Section =
Ctx->getELFSection(".rodata.cst16", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_MERGE, 16, "");
MergeableConst32Section =
Ctx->getELFSection(".rodata.cst32", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHF_MERGE, 32, "");
// Exception Handling Sections.
// FIXME: We're emitting LSDA info into a readonly section on ELF, even though
// it contains relocatable pointers. In PIC mode, this is probably a big
// runtime hit for C++ apps. Either the contents of the LSDA need to be
// adjusted or this should be a data section.
LSDASection = Ctx->getELFSection(".gcc_except_table", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC);
COFFDebugSymbolsSection = nullptr;
COFFDebugTypesSection = nullptr;
unsigned DebugSecType = ELF::SHT_PROGBITS;
// MIPS .debug_* sections should have SHT_MIPS_DWARF section type
// to distinguish among sections contain DWARF and ECOFF debug formats.
// Sections with ECOFF debug format are obsoleted and marked by SHT_PROGBITS.
if (T.isMIPS())
DebugSecType = ELF::SHT_MIPS_DWARF;
// Debug Info Sections.
DwarfAbbrevSection =
Ctx->getELFSection(".debug_abbrev", DebugSecType, 0);
DwarfInfoSection = Ctx->getELFSection(".debug_info", DebugSecType, 0);
DwarfLineSection = Ctx->getELFSection(".debug_line", DebugSecType, 0);
DwarfLineStrSection =
Ctx->getELFSection(".debug_line_str", DebugSecType,
ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, "");
DwarfFrameSection = Ctx->getELFSection(".debug_frame", DebugSecType, 0);
DwarfPubNamesSection =
Ctx->getELFSection(".debug_pubnames", DebugSecType, 0);
DwarfPubTypesSection =
Ctx->getELFSection(".debug_pubtypes", DebugSecType, 0);
DwarfGnuPubNamesSection =
Ctx->getELFSection(".debug_gnu_pubnames", DebugSecType, 0);
DwarfGnuPubTypesSection =
Ctx->getELFSection(".debug_gnu_pubtypes", DebugSecType, 0);
DwarfStrSection =
Ctx->getELFSection(".debug_str", DebugSecType,
ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, "");
DwarfLocSection = Ctx->getELFSection(".debug_loc", DebugSecType, 0);
DwarfARangesSection =
Ctx->getELFSection(".debug_aranges", DebugSecType, 0);
DwarfRangesSection =
Ctx->getELFSection(".debug_ranges", DebugSecType, 0);
DwarfMacinfoSection =
Ctx->getELFSection(".debug_macinfo", DebugSecType, 0);
// DWARF5 Experimental Debug Info
// Accelerator Tables
DwarfDebugNamesSection =
Ctx->getELFSection(".debug_names", ELF::SHT_PROGBITS, 0);
DwarfAccelNamesSection =
Ctx->getELFSection(".apple_names", ELF::SHT_PROGBITS, 0);
DwarfAccelObjCSection =
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);
// String Offset and Address Sections
DwarfStrOffSection =
Ctx->getELFSection(".debug_str_offsets", DebugSecType, 0);
DwarfAddrSection = Ctx->getELFSection(".debug_addr", DebugSecType, 0);
DwarfRnglistsSection = Ctx->getELFSection(".debug_rnglists", DebugSecType, 0);
DwarfLoclistsSection = Ctx->getELFSection(".debug_loclists", DebugSecType, 0);
// Fission Sections
DwarfInfoDWOSection =
Ctx->getELFSection(".debug_info.dwo", DebugSecType, ELF::SHF_EXCLUDE);
DwarfTypesDWOSection =
Ctx->getELFSection(".debug_types.dwo", DebugSecType, ELF::SHF_EXCLUDE);
DwarfAbbrevDWOSection =
Ctx->getELFSection(".debug_abbrev.dwo", DebugSecType, ELF::SHF_EXCLUDE);
DwarfStrDWOSection = Ctx->getELFSection(
".debug_str.dwo", DebugSecType,
ELF::SHF_MERGE | ELF::SHF_STRINGS | ELF::SHF_EXCLUDE, 1, "");
DwarfLineDWOSection =
Ctx->getELFSection(".debug_line.dwo", DebugSecType, ELF::SHF_EXCLUDE);
DwarfLocDWOSection =
Ctx->getELFSection(".debug_loc.dwo", DebugSecType, ELF::SHF_EXCLUDE);
DwarfStrOffDWOSection = Ctx->getELFSection(".debug_str_offsets.dwo",
DebugSecType, ELF::SHF_EXCLUDE);
DwarfRnglistsDWOSection =
Ctx->getELFSection(".debug_rnglists.dwo", DebugSecType, ELF::SHF_EXCLUDE);
// DWP Sections
DwarfCUIndexSection =
Ctx->getELFSection(".debug_cu_index", DebugSecType, 0);
DwarfTUIndexSection =
Ctx->getELFSection(".debug_tu_index", DebugSecType, 0);
StackMapSection =
Ctx->getELFSection(".llvm_stackmaps", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
FaultMapSection =
Ctx->getELFSection(".llvm_faultmaps", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
EHFrameSection =
Ctx->getELFSection(".eh_frame", EHSectionType, EHSectionFlags);
StackSizesSection = Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, 0);
RemarksSection =
Ctx->getELFSection(".remarks", ELF::SHT_PROGBITS, ELF::SHF_EXCLUDE);
}
getDataSection() const { return DataSection; }
getTLSExtraDataSection() const { return TLSExtraDataSection; }
getTLSDataSection() const { return TLSDataSection; }
getConstDataSection() const { return ConstDataSection; }
Called in:
MipsTargetStreamer.cpp: MipsTargetELFStreamer::finish()
.bss, .text, .data
are always at least 16-byte aligned.This class handles lowerings for common ELF object file formats
Source code:
It will return a section for the input global address.
MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal
It will use getDataSections()
to check whether different variables should use separate sections.
TargetMachine.h: the -fdata-sections
and -ffunction-sections
option: put every variable or function into different section:
//llvm/include/llvm/Target/TargetMachine.h
/// Return true if data objects should be emitted into their own section,
/// corresponds to -fdata-sections.
bool getDataSections() const {
return Options.DataSections;
}
/// Return true if functions should be emitted into their own section,
/// corresponding to -ffunction-sections.
bool getFunctionSections() const {
return Options.FunctionSections;
}
Source: llvm/lib/Target/Mips/
MipsTargetObjectFile.h/cpp
Parent class: TargetLoweringObjectFileELF
About Small Data/BSS Sections:
TargetLoweringObjectFileELF
gp_rel
operator. Data can be
SelectSectionForGlobal()
)SelectSectionForConstant()
)MipsTargetObjectFile::IsGlobalInSmallSection()
IsGlobalInSmallSectionImpl()
and global Kind.isData() || Kind.isBSS() || Kind.isCommon() || Kind.isReadOnly()
, then the global should be placed into small data/bss section.-mlocal-sdata
is given, and global variable ->hasLocalLinkage()
-extern-sdata
is given, and global variable (GVA->hasExternalLinkage() && GVA->isDeclaration() ) || GVA-> hasCommonLinkage()
-membedded-data
is given, and global variable GVA->isConstant()
.(No constructor method.)
MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM)
MCContext &Ctx
const TargetMachine &TM
SmallDataSection
: .sdata
in ELF. Init via getContext().getELFSection()
SmallBSSSection
: .sbss
in ELF. Init via getContext().getELFSection()
this->TM = &static_cast<const MipsTargetMachine &> (TM)
To distinguish a global variable from functions in a GlobalObject
const GlobalObject GO; // passed in as parameter.
const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GO);
if (!GVA)
return false;
// source: llvm/lib/Target/Mips/MipsTargetObjectFile.cpp: `IsGlobalInSmallSectionImpl()`
To reconginze the subtarget of the Mips Arch: use getSubtargetImpl()
from TargetMacine
class.
TailPaddingAmount
MipsTargetObjectFile::getTailPaddingForPreciseBounds(uint64_t Size) const {
const MipsSubtarget &Subtarget =
*static_cast<const MipsTargetMachine &>(*TM).getSubtargetImpl();
if (!Subtarget.isCheri())
return TailPaddingAmount::None;
if (Subtarget.isCheri128()) {
return static_cast<TailPaddingAmount>(
llvm::alignTo(Size, cc128_get_required_alignment(Size)) - Size);
}
assert(Subtarget.isCheri256());
// No padding required for CHERI256
return TailPaddingAmount::None;
}
// source: llvm/lib/Target/Mips/MipsTargetObjectFile.cpp
If you could revise
the fundmental principles of
computer system design
to improve security...
... what would you change?