References:
This section is mostly from: llvm-mc, with partial info from LLVM CodeGen.
Assembly Parser.
MCStreamer. an assembler API.
EmitLable
,EmtSymbolAttribute
,SwitchSection
,EmitValue
, for .byte
, .word
EmitInstruction
, output an MCInst
to the streamer.MCAsmStreamer
assembly printer.
Instruction Printer
to format the MCInsts
.MCObjectStreamer
(or `)
MCStreamer
has a MCTargetStreamer
class instance.
FooTargetStreamer
that inherits from this MCTargetStreamer
and is a lot like MCStreamer
itself.FooTargetStreamer
:
FooTargetAsmStreamer : public FooTargetStreamer
: a target asm streamer just prints it (emitFnStart -> .fnstart), andFooTargetELFStreamer : public FooTargetStreamer
: the object streamer implements the assembler logic for it.Assembler Backend.
Compiler Integration.
Classes: MCInst, MCSymbol (a label in .s), MCSection, MCExpr.
Usage 01: disassembler library
Usage 02: standalone assembler
Usage 03: Compiler-integrated assembler
AsmPrinter
for your target, converting MachineFunction
s into MC label constructs.
TargetLoweringObjectFile
class.MCInst
to your ISA instruction as raw_ostream
text.
.td
file (when you specify something like add $dst, $src1, $src2
in the file), but you need to implement routines to print operands.MachineInstr
to an MCInst
.
<Target>MCInstLower.cpp
.MCLabels
from:
MCInst
then is fed into the instruction printer or encoder.MCCodeEmitter
, to lower MCInst
s into machine code bytes and relocations.
.o
file emission, or would like to implement an assembler for your target.A section containing metadata on functino stack sizes will be emitted when TargetLoweringObjectFile::StackSizeSection
is not null and TargetOptions::EmitSstackSizeSection
is set (via -stack-size-section
).
The section will contain an array of pairs of function symbol values (pointer size) and stack size (unsigned LEB128). The stack size values only include the space allocated in the function prologue. Functions with dynamic stack allocations are not included.
Reference: The LLVM Target-Independent Code Generator
MCStreamer
API that can be implemented to output an ELF .o file (or .s file, etc). Its API correspond directly to what you see in a .s file.
The MCContext
class: the owener of a variety of uniqued data structures at the MC Layer, including symbols, sections, etc.
The MCSymbol
class: represents a symbol (aka label) in the assembly file. Created by MCContext
and uniqued there. Can be compared for pointer equivalence to find out if they are the same symbol. (But pointer equivalence does not mean two label will end up in two differen address; since two different label can be used to point to the same address). Two kinds of symbols:
L
labels in MachO.The MCSection
class. It represents an object-file specific section.
MCSectionMachO
, MCSectionCOFF
, MCSectionELF
) and these are created and uniqued by MCContext
.MCStreamer
has a notion of current section SectionStack.back().first
or MCSectionSubPair()
, which can be changed via SwitchToSection()
method (which corresponds to a .section
directive in a .s file). See more .section directiveThe MCInst
class. A target-independent representation of an instruction.
References: reference // class .member struct ELFWriter{ ELFObjectWriter &OWriter; } // parent --> child MCObjectWriter -> ELFObjectWriter States: ELFObjectWriter &OWriter support::endian::Writer W. An adapter to write values to a stream in a particular byte order. unsigned LastLocalSymbolIndex. This holds the symbol table index of the last local symbol. unsigned StringTableIndex. This holds the .strtab section index. unsigned SymbolTableIndex. This holds the .symtabl section index. std::vector<const MCSectionELF *> SectionTable.
Reference reference To emit a new section, e.g. .newsection, to an object (ELF) file: add an option to clang to enable options. need to pass option from clang frontend to backend. Option finally goes to TargetOptions::EmitNewSection Option access in different classes: via TargetMachine instance: TM.Options.EmitNewSection Can be used in AsmPrinter, etc. via MachineFunction instance: MF.getTarget().Options.EmitNewSection update AsmPrinter class in LLVM CodeGen to emit the new section.
Reference reference llvm/include/llvm/CodeGen/AsmPrinter.h llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp AsmPrinter is a pass at MachineFunction level: class AsmPrinter : public MachineFunctionPass. It acts as a driver for the MC layer streamers. It defines the MachineFunction pass that calls OutStreamer->emitXXX() to emit all the stuff to the binary or assembly files. The (misnamed) target-independent AsmPrinter class implements the general lowering process converting MachineFunction’s into MC label constructs. target-specific subclasses of AsmPrinter, such as SparcAsmPrinter, MipsAsmPrinter target specific functions such as emitFunctionBodyStart()/End() Additionally, for other code generation other than MachineFunction labels:
Reference reference // lib/MC/MCAssembler.cpp bool MCAssembler::registerSection(MCSection &Section) { if (Section.isRegistered()) return false; Sections.push_back(&Section); Section.setIsRegistered(true); return true; } // include/llvm/MC/MCAssembler.h /// \name Section List Access /// @{ iterator begin() { return Sections.begin(); } const_iterator begin() const { return Sections.begin(); } iterator end() { return Sections.end(); } const_iterator end() const { return Sections.end(); } size_t size() const { return Sections.size(); }
Reference include/llvm/MC/MCContext.h lib/MC/MCContext.cpp Context object for machine code objects. This class owns all the sections that it creates. MCSectionELF *MCContext::getELFSection() Search ELFUniquingMap return if hit create new section using createELFSectionImp() if miss. MCSectionELF *MCContext::createELFSectionImpl() get existing or create a new MCSymbolELF *R set binding ELF::STB_LOCAL set type ELF::STT_SECTION create a new MCSectionELF *Ret create new MCDataFragment() *F insert F to Ret->getFragmentList() F->setParent(Ret) R->setFragment(F) return R, the MCSectionELF
Reference LLVM Source code Parent -> Child: MCObjectFileInfo -> TargetLoweringObjectFile -> TargetLoweringObjectFileELF -> MipsTargetObjectFile MCObjectFileInfo 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. DWARF sections DwarfLineSection DwarfLineStrSection DwarfStrSection … Sections Initialization Initialized in function MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large). code // lib/MC/MCObjectFileInfo.
References: LLVM MCStreamer Class Reference llvm/include/llvm/MCStreamer.h llvm/lib/MC/MCStreamer.cpp MCStreamer class is an abstract API that is implemented in different ways (e.g. to output a .s file, output an ELF .o file, etc). It is effectively an “assembler API”. MCStreamer has one method per directive, such as EmitLabel, EmitSymbolAttribute, SwitchSection, etc, which directly correspond to assembly level directives. Two implementations of MCStreamer: MCAsmStreamer is a straightforward impl that prints out a directive for each method.
ELF Basics llvm-objcopy: object copy and editing tool Relocation wiki Object File Editing llvm-objcopy [options] input [output]: --add-section <section=file>, add a section named <section> with the content of <file> to the output. --dump-section <section>=<file>, dump the content of section <section> into the file <file> --discard-all, -x, remove most local symbols from the output. ELF Section Flags // include/llvm/BinaryFormat/ELF.h // Section flags. enum : unsigned { // Section data should be writable during execution.
If you could revise
the fundmental principles of
computer system design
to improve security...
... what would you change?