asmjit::CodeHolder Class Reference

Contains basic information about the target architecture and its options.

In addition, it holds assembled code & data (including sections, labels, and relocation information). CodeHolder can store both binary and intermediate representation of assembly, which can be generated by BaseAssembler, BaseBuilder, and BaseCompiler

Note
CodeHolder has an ability to attach an ErrorHandler, however, the error handler is not triggered by CodeHolder itself, it's instead propagated to all emitters that attach to it.

Public Members

Public Types

Member Functions

Construction & Destruction
Attach & Detach
Allocators
Code & Architecture
Emitters
Logging
Error Handling
Code Buffer
Sections
Labels & Symbols
Relocations
Utilities

Member Enumeration Documentation

CodeHolder::CopyOptions : uint32_tenum

Options that can be used with copySectionData() and copyFlattenedData().

ConstantDescription
kCopyPadSectionBuffer 

If virtual size of a section is greater than the size of its CodeBuffer then all bytes between the buffer size and virtual size will be zeroed.

If this option is not set then those bytes would be left as is, which means that if the user didn't initialize them they would have a previous content, which may be unwanted.

kCopyPadTargetBuffer 

Zeroes the target buffer if the flattened data is less than the destination size.

This option works only with copyFlattenedData() as it processes multiple sections. It is ignored by copySectionData().

Constructor & Destructor Documentation

CodeHolder::CodeHolder()noexcept

Creates an uninitialized CodeHolder (you must init() it before it can be used).

CodeHolder::~CodeHolder()noexcept

Destroys the CodeHolder.

Member Function Documentation

bool CodeHolder::isInitialized() constnoexcept

Tests whether the CodeHolder has been initialized.

Emitters can be only attached to initialized CodeHolder instances.

Error CodeHolder::init(const Environment& environment, uint64_t baseAddress = Globals::kNoBaseAddress)noexcept

Initializes CodeHolder to hold code described by code info.

void CodeHolder::reset(uint32_t resetPolicy = Globals::kResetSoft)noexcept

Detaches all code-generators attached and resets the CodeHolder.

Error CodeHolder::attach(BaseEmitter* emitter)noexcept

Attaches an emitter to this CodeHolder.

Error CodeHolder::detach(BaseEmitter* emitter)noexcept

Detaches an emitter from this CodeHolder.

ZoneAllocator* CodeHolder::allocator() constnoexcept

Returns the allocator that the CodeHolder uses.

Note
This should be only used for AsmJit's purposes. Code holder uses arena allocator to allocate everything, so anything allocated through this allocator will be invalidated by CodeHolder::reset() or by CodeHolder's destructor.

const Environment& CodeHolder::environment() constnoexcept

Returns the target environment information, see Environment.

uint32_t CodeHolder::arch() constnoexcept

Returns the target architecture.

uint32_t CodeHolder::subArch() constnoexcept

Returns the target sub-architecture.

bool CodeHolder::hasBaseAddress() constnoexcept

Tests whether a static base-address is set.

uint64_t CodeHolder::baseAddress() constnoexcept

Returns a static base-address or Globals::kNoBaseAddress, if not set.

const ZoneVector<BaseEmitter*>& CodeHolder::emitters() constnoexcept

Returns a vector of attached emitters.

Logger* CodeHolder::logger() constnoexcept

Returns the attached logger, see Logger.

void CodeHolder::setLogger(Logger* logger)noexcept

Attaches a logger to CodeHolder and propagates it to all attached emitters.

void CodeHolder::resetLogger()noexcept

Resets the logger to none.

bool CodeHolder::hasErrorHandler() constnoexcept

Tests whether the CodeHolder has an attached error handler, see ErrorHandler.

ErrorHandler* CodeHolder::errorHandler() constnoexcept

Returns the attached error handler.

void CodeHolder::setErrorHandler(ErrorHandler* errorHandler)noexcept

Attach an error handler to this CodeHolder.

void CodeHolder::resetErrorHandler()noexcept

Resets the error handler to none.

Error CodeHolder::growBuffer(CodeBuffer* cb, size_t n)noexcept

Makes sure that at least n bytes can be added to CodeHolder's buffer cb.

Note
The buffer cb must be managed by CodeHolder - otherwise the behavior of the function is undefined.

Error CodeHolder::reserveBuffer(CodeBuffer* cb, size_t n)noexcept

Reserves the size of cb to at least n bytes.

Note
The buffer cb must be managed by CodeHolder - otherwise the behavior of the function is undefined.

const ZoneVector<Section*>& CodeHolder::sections() constnoexcept

Returns an array of Section* records.

uint32_t CodeHolder::sectionCount() constnoexcept

Returns the number of sections.

bool CodeHolder::isSectionValid(uint32_t sectionId) constnoexcept

Tests whether the given sectionId is valid.

Error CodeHolder::newSection(Section** sectionOut, const char* name, size_t nameSize = SIZE_MAX, uint32_t flags = 0, uint32_t alignment = 1)noexcept

Creates a new section and return its pointer in sectionOut.

Returns Error, does not report a possible error to ErrorHandler.

Section* CodeHolder::sectionById(uint32_t sectionId) constnoexcept

Returns a section entry of the given index.

Section* CodeHolder::sectionByName(const char* name, size_t nameSize = SIZE_MAX) constnoexcept

Returns section-id that matches the given name.

If there is no such section Section::kInvalidId is returned.

Section* CodeHolder::textSection() constnoexcept

Returns '.text' section (section that commonly represents code).

Note
Text section is always the first section in CodeHolder::sections() array.

bool CodeHolder::hasAddressTable() constnoexcept

Tests whether '.addrtab' section exists.

Section* CodeHolder::addressTableSection() constnoexcept

Returns '.addrtab' section.

This section is used exclusively by AsmJit to store absolute 64-bit addresses that cannot be encoded in instructions like 'jmp' or 'call'.

Note
This section is created on demand, the returned pointer can be null.

Section* CodeHolder::ensureAddressTableSection()noexcept

Ensures that '.addrtab' section exists (creates it if it doesn't) and returns it.

Can return nullptr on out of memory condition.

Error CodeHolder::addAddressToAddressTable(uint64_t address)noexcept

Used to add an address to an address table.

This implicitly calls ensureAddressTableSection() and then creates AddressTableEntry that is inserted to _addressTableEntries. If the address already exists this operation does nothing as the same addresses use the same slot.

This function should be considered internal as it's used by assemblers to insert an absolute address into the address table. Inserting address into address table without creating a particula relocation entry makes no sense.

const ZoneVector<LabelEntry*>& CodeHolder::labelEntries() constnoexcept

Returns array of LabelEntry* records.

uint32_t CodeHolder::labelCount() constnoexcept

Returns number of labels created.

bool CodeHolder::isLabelValid(uint32_t labelId) constnoexcept[1/2]

Tests whether the label having id is valid (i.e. created by newLabelEntry()).

bool CodeHolder::isLabelValid(const Label& label) constnoexcept[2/2]

Tests whether the label is valid (i.e. created by newLabelEntry()).

bool CodeHolder::isLabelBound(uint32_t labelId) constnoexcept[1/2]

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

bool CodeHolder::isLabelBound(const Label& label) constnoexcept[2/2]

Tests whether the label is already bound.

Returns false if the label is not valid.

LabelEntry* CodeHolder::labelEntry(uint32_t labelId) constnoexcept[1/2]

Returns LabelEntry of the given label id.

LabelEntry* CodeHolder::labelEntry(const Label& label) constnoexcept[2/2]

Returns LabelEntry of the given label.

uint64_t CodeHolder::labelOffset(uint32_t labelId) constnoexcept[1/2]

Returns offset of a Label by its labelId.

The offset returned is relative to the start of the section. Zero offset is returned for unbound labels, which is their initial offset value.

uint64_t CodeHolder::labelOffset(const Label& label) constnoexcept[2/2]

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

uint64_t CodeHolder::labelOffsetFromBase(uint32_t labelId) constnoexcept[1/2]

Returns offset of a label by it's labelId relative to the base offset.

Remarks
The offset of the section where the label is bound must be valid in order to use this function, otherwise the value returned will not be reliable.

uint64_t CodeHolder::labelOffsetFromBase(const Label& label) constnoexcept[2/2]

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Error CodeHolder::newLabelEntry(LabelEntry** entryOut)noexcept

Creates a new anonymous label and return its id in idOut.

Returns Error, does not report error to ErrorHandler.

Error CodeHolder::newNamedLabelEntry(LabelEntry** entryOut, const char* name, size_t nameSize, uint32_t type, uint32_t parentId = Globals::kInvalidId)noexcept

Creates a new named LabelEntry of the given label type.

Parameters
entryOutWhere to store the created LabelEntry.
nameThe name of the label.
nameSizeThe length of name argument, or SIZE_MAX if name is a null terminated string, which means that the CodeHolder will use strlen() to determine the length.
typeThe type of the label to create, see Label::LabelType.
parentIdParent id of a local label, otherwise it must be Globals::kInvalidId.
Return values
Alwaysreturns Error, does not report a possible error to the attached ErrorHandler.

AsmJit has a support for local labels (Label::kTypeLocal) which require a parent label id (parentId). The names of local labels can conflict with names of other local labels that have a different parent.

Label CodeHolder::labelByName(const char* name, size_t nameSize = SIZE_MAX, uint32_t parentId = Globals::kInvalidId)noexcept

Returns a label by name.

If the named label doesn't a default constructed Label is returned, which has its id set to Globals::kInvalidId.

uint32_t CodeHolder::labelIdByName(const char* name, size_t nameSize = SIZE_MAX, uint32_t parentId = Globals::kInvalidId)noexcept

Returns a label id by name.

If the named label doesn't exist Globals::kInvalidId is returned.

bool CodeHolder::hasUnresolvedLinks() constnoexcept

Tests whether there are any unresolved label links.

size_t CodeHolder::unresolvedLinkCount() constnoexcept

Returns the number of label links, which are unresolved.

LabelLink* CodeHolder::newLabelLink(LabelEntry* le, uint32_t sectionId, size_t offset, intptr_t rel)noexcept

Creates a new label-link used to store information about yet unbound labels.

Returns null if the allocation failed.

Error CodeHolder::resolveUnresolvedLinks()noexcept

Resolves cross-section links (LabelLink) associated with each label that was used as a destination in code of a different section.

It's only useful to people that use multiple sections as it will do nothing if the code only contains a single section in which cross-section links are not possible.

Error CodeHolder::bindLabel(const Label& label, uint32_t sectionId, uint64_t offset)noexcept

Binds a label to a given sectionId and offset (relative to start of the section).

This function is generally used by BaseAssembler::bind() to do the heavy lifting.

bool CodeHolder::hasRelocEntries() constnoexcept

Tests whether the code contains relocation entries.

const ZoneVector<RelocEntry*>& CodeHolder::relocEntries() constnoexcept

Returns array of RelocEntry* records.

RelocEntry* CodeHolder::relocEntry(uint32_t id) constnoexcept

Returns a RelocEntry of the given id.

Error CodeHolder::newRelocEntry(RelocEntry** dst, uint32_t relocType, uint32_t valueSize)noexcept

Creates a new relocation entry of type relocType and size valueSize.

Additional fields can be set after the relocation entry was created.

Error CodeHolder::flatten()noexcept

Flattens all sections by recalculating their offsets, starting at 0.

Note
This should never be called more than once.

size_t CodeHolder::codeSize() constnoexcept

Returns computed the size of code & data of all sections.

Note
All sections will be iterated over and the code size returned would represent the minimum code size of all combined sections after applying minimum alignment. Code size may decrease after calling flatten() and relocateToBase().

Error CodeHolder::relocateToBase(uint64_t baseAddress)noexcept

Relocates the code to the given baseAddress.

Parameters
baseAddressAbsolute base address where the code will be relocated to. Please note that nothing is copied to such base address, it's just an absolute value used by the relocator to resolve all stored relocations.
Note
This should never be called more than once.

Error CodeHolder::copySectionData(void* dst, size_t dstSize, uint32_t sectionId, uint32_t copyOptions = 0)noexcept

Copies a single section into dst.

Error CodeHolder::copyFlattenedData(void* dst, size_t dstSize, uint32_t copyOptions = 0)noexcept

Copies all sections into dst.

This should only be used if the data was flattened and there are no gaps between the sections. The dstSize is always checked and the copy will never write anything outside the provided buffer.

Member Data Documentation

Environment CodeHolder::_environment

Environment information.

uint64_t CodeHolder::_baseAddress

Base address or Globals::kNoBaseAddress.

Logger* CodeHolder::_logger

Attached Logger, used by all consumers.

ErrorHandler* CodeHolder::_errorHandler

Attached ErrorHandler.

Zone CodeHolder::_zone

Code zone (used to allocate core structures).

ZoneAllocator CodeHolder::_allocator

Zone allocator, used to manage internal containers.

ZoneVector<BaseEmitter*>CodeHolder::_emitters

Attached emitters.

ZoneVector<Section*>CodeHolder::_sections

Section entries.

ZoneVector<LabelEntry*>CodeHolder::_labelEntries

Label entries.

ZoneVector<RelocEntry*>CodeHolder::_relocations

Relocation entries.

ZoneHash<LabelEntry>CodeHolder::_namedLabels

Label name -> LabelEntry (only named labels).

size_t CodeHolder::_unresolvedLinkCount

Count of label links, which are not resolved.

Section* CodeHolder::_addressTableSection

Pointer to an address table section (or null if this section doesn't exist).

ZoneTree<AddressTableEntry>CodeHolder::_addressTableEntries

Address table entries.