in rts/linker/MachO.c [65:157]
int64_t decodeAddend(ObjectCode * oc, Section * section,
MachORelocationInfo * ri);
void encodeAddend(ObjectCode * oc, Section * section,
MachORelocationInfo * ri, int64_t addend);
/* finding and making stubs. We don't need to care about the symbol they
* represent. As long as two stubs point to the same address, they are identical
*/
bool findStub(Section * section, void ** addr);
bool makeStub(Section * section, void ** addr);
void freeStubs(Section * section);
/* Global Offset Table logic */
bool isGotLoad(MachORelocationInfo * ri);
bool needGotSlot(MachONList * symbol);
bool makeGot(ObjectCode * oc);
void freeGot(ObjectCode * oc);
#endif /* aarch64_HOST_ARCH */
#if defined(ios_HOST_OS)
/* on iOS we need to ensure we only have r+w or r+x pages hence we need to mmap
* pages r+w and r+x mprotect them later on.
*/
bool ocMprotect_MachO( ObjectCode *oc );
#endif /* ios_HOST_OS */
/*
* Initialize some common data in the object code so we don't have to
* continuously look up the addresses.
*/
void
ocInit_MachO(ObjectCode * oc)
{
ocDeinit_MachO(oc);
oc->info = (struct ObjectCodeFormatInfo*)stgCallocBytes(
1, sizeof *oc->info,
"ocInit_MachO(ObjectCodeFormatInfo)");
oc->info->header = (MachOHeader *) oc->image;
oc->info->symCmd = NULL;
oc->info->segCmd = NULL;
oc->info->dsymCmd = NULL;
MachOLoadCommand *lc = (MachOLoadCommand*)(oc->image + sizeof(MachOHeader));
for(size_t i = 0; i < oc->info->header->ncmds; i++) {
if (lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64) {
oc->info->segCmd = (MachOSegmentCommand*) lc;
}
else if (lc->cmd == LC_SYMTAB) {
oc->info->symCmd = (MachOSymtabCommand*) lc;
}
else if (lc->cmd == LC_DYSYMTAB) {
oc->info->dsymCmd = (MachODsymtabCommand*) lc;
}
lc = (MachOLoadCommand *) ( ((char*)lc) + lc->cmdsize );
}
if (NULL == oc->info->segCmd) {
barf("ocGetNames_MachO: no segment load command");
}
oc->info->macho_sections = (MachOSection*) (oc->info->segCmd+1);
oc->n_sections = oc->info->segCmd->nsects;
oc->info->nlist = oc->info->symCmd == NULL
? NULL
: (MachONList *)(oc->image + oc->info->symCmd->symoff);
oc->info->names = oc->info->symCmd == NULL
? NULL
: (oc->image + oc->info->symCmd->stroff);
/* If we have symbols, allocate and fill the macho_symbols
* This will make relocation easier.
*/
oc->info->n_macho_symbols = 0;
oc->info->macho_symbols = NULL;
if(NULL != oc->info->nlist) {
oc->info->n_macho_symbols = oc->info->symCmd->nsyms;
oc->info->macho_symbols = (MachOSymbol*)stgCallocBytes(
oc->info->symCmd->nsyms,
sizeof(MachOSymbol),
"ocInit_MachO(MachOSymbol)");
for(uint32_t i = 0; i < oc->info->symCmd->nsyms; i++) {
oc->info->macho_symbols[i].name = oc->info->names
+ oc->info->nlist[i].n_un.n_strx;
oc->info->macho_symbols[i].nlist = &oc->info->nlist[i];
/* we don't have an address for this symbol yet; this will be
* populated during ocGetNames_MachO. hence addr = NULL
*/
oc->info->macho_symbols[i].addr = NULL;
}
}
}