2022-12-29 12:32:55 +00:00
|
|
|
#include "compiler/ObjGenMachO.h"
|
|
|
|
#include "compiler/CError.h"
|
|
|
|
#include "compiler/CInit.h"
|
|
|
|
#include "compiler/CFunc.h"
|
|
|
|
#include "compiler/CMachine.h"
|
|
|
|
#include "compiler/CMangler.h"
|
|
|
|
#include "compiler/CParser.h"
|
|
|
|
#include "compiler/CodeGen.h"
|
|
|
|
#include "compiler/CompilerTools.h"
|
|
|
|
#include "compiler/uDump.h"
|
|
|
|
#include "compiler/GenStabs.h"
|
|
|
|
#include "compiler/IrOptimizer.h"
|
|
|
|
#include "compiler/MachO.h"
|
|
|
|
#include "compiler/PCodeListing.h"
|
|
|
|
#include "compiler/TOC.h"
|
|
|
|
#include "compiler/objects.h"
|
|
|
|
#include "cos.h"
|
|
|
|
|
|
|
|
#ifdef __MWERKS__
|
|
|
|
#pragma options align=mac68k
|
|
|
|
#endif
|
|
|
|
typedef struct Reloc {
|
|
|
|
MachOSection *section;
|
|
|
|
SInt32 offset;
|
|
|
|
SInt32 relocID;
|
|
|
|
SInt32 picOffset;
|
|
|
|
struct Reloc *next;
|
|
|
|
RelocType relocType;
|
|
|
|
MWReloc mwRelType;
|
|
|
|
} Reloc;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
Section x0;
|
|
|
|
Section x1;
|
|
|
|
char *segname;
|
|
|
|
char *sectname;
|
|
|
|
UInt32 align;
|
|
|
|
UInt32 flags;
|
|
|
|
} DefSectionInfo;
|
|
|
|
|
|
|
|
static DefSectionInfo def_section_info[] = {
|
|
|
|
SECT_DEFAULT, SECT_DEFAULT, "", "", 1, S_REGULAR,
|
|
|
|
SECT_TEXT, SECT_TEXT_COALESCE, "__TEXT", "__text", 4, S_ATTR_SOME_INSTRUCTIONS,
|
|
|
|
SECT_DATA, SECT_DATA_COALESCE, "__DATA", "__data", 8, S_REGULAR,
|
|
|
|
SECT_UDATA, SECT_UDATA_COALESCE, "__DATA", "__bss", 8, S_ZEROFILL,
|
|
|
|
SECT_DATA_FAR, 0, "__DATA", "__fdata", 8, S_REGULAR,
|
|
|
|
SECT_DATA_NEAR, 0, "__DATA", "__ndata", 8, S_REGULAR,
|
|
|
|
SECT_INIT, 0, "__INIT", "__init", 4, S_REGULAR,
|
|
|
|
SECT_OBJC_CAT_CLS_METH, 0, "__OBJC", "__cat_cls_meth", 4, S_REGULAR,
|
|
|
|
SECT_OBJC_CAT_INST_METH, 0, "__OBJC", "__cat_inst_meth", 4, S_REGULAR,
|
|
|
|
SECT_OBJC_STRING_OBJECT, 0, "__OBJC", "__string_object", 1, S_REGULAR,
|
|
|
|
SECT_OBJC_CSTRING_OBJECT, 0, "__OBJC", "__cstring_object", 1, S_REGULAR,
|
|
|
|
SECT_OBJC_MESSAGE_REFS, 0, "__OBJC", "__message_refs", 4, S_LITERAL_POINTERS,
|
|
|
|
SECT_OBJC_SEL_FIXUP, 0, "__OBJC", "__sel_fixup", 4, S_REGULAR,
|
|
|
|
SECT_OBJC_CLS_REFS, 0, "__OBJC", "__cls_refs", 4, S_LITERAL_POINTERS,
|
|
|
|
SECT_OBJC_CLASS, 0, "__OBJC", "__class", 4, S_REGULAR,
|
|
|
|
SECT_OBJC_META_CLASS, 0, "__OBJC", "__meta_class", 4, S_REGULAR,
|
|
|
|
SECT_OBJC_CLS_METH, 0, "__OBJC", "__cls_meth", 4, S_REGULAR,
|
|
|
|
SECT_OBJC_INST_METH, 0, "__OBJC", "__inst_meth", 4, S_REGULAR,
|
|
|
|
SECT_OBJC_PROTOCOL, 0, "__OBJC", "__protocol", 4, S_REGULAR,
|
|
|
|
SECT_OBJC_CLASS_NAMES, 0, "__OBJC", "__class_names", 4, S_CSTRING_LITERALS,
|
|
|
|
SECT_OBJC_METH_VAR_TYPES, 0, "__OBJC", "__meth_var_types", 4, S_CSTRING_LITERALS,
|
|
|
|
SECT_OBJC_METH_VAR_NAMES, 0, "__OBJC", "__meth_var_names", 4, S_CSTRING_LITERALS,
|
|
|
|
SECT_OBJC_CATEGORY, 0, "__OBJC", "__category", 4, S_REGULAR,
|
|
|
|
SECT_OBJC_CLASS_VARS, 0, "__OBJC", "__class_vars", 4, S_REGULAR,
|
|
|
|
SECT_OBJC_INSTANCE_VARS, 0, "__OBJC", "__instance_vars", 4, S_REGULAR,
|
|
|
|
SECT_OBJC_MODULE_INFO, 0, "__OBJC", "__module_info", 4, S_REGULAR,
|
|
|
|
SECT_OBJC_MSYMBOLS, 0, "__OBJC", "__symbols", 4, S_REGULAR,
|
|
|
|
SECT_TEXT_CSTRING, SECT_TEXT_CSTRING, "__TEXT", "__cstring", 4, S_CSTRING_LITERALS,
|
|
|
|
SECT_MW_EX_TABLE, SECT_MW_EX_TABLE, "__DATA", "__coalsc_MXCPTTB", 4, S_COALESCED | S_ATTR_NO_TOC,
|
|
|
|
SECT_MW_EX_TABLE_INDEX, SECT_MW_EX_TABLE_INDEX, "__DATA", "__mwexceptionidx", 4, S_COALESCED | S_ATTR_NO_TOC,
|
|
|
|
SECT_MW_SWITCH, SECT_MW_SWITCH, "__DATA", "__mwswitch", 4, S_REGULAR,
|
|
|
|
SECT_8BYTE_LITERALS, SECT_8BYTE_LITERALS, "__TEXT", "__literal8", 8, S_8BYTE_LITERALS,
|
|
|
|
SECT_4BYTE_LITERALS, SECT_4BYTE_LITERALS, "__TEXT", "__literal4", 4, S_4BYTE_LITERALS,
|
|
|
|
SECT_MOD_INIT_FUNC, SECT_MOD_INIT_FUNC, "__DATA", "__mod_init_func", 4, S_MOD_INIT_FUNC_POINTERS,
|
|
|
|
SECT_CONST, SECT_CONST, "__TEXT", "__const", 4, S_REGULAR,
|
2023-01-14 13:20:48 +00:00
|
|
|
SECT_CONST_PTR, SECT_CONST_PTR, "__DATA", "__const", 4, S_REGULAR,
|
2022-12-29 12:32:55 +00:00
|
|
|
SECT_NONLAZY_PTRS, SECT_NONLAZY_PTRS, "__DATA", "__nl_symbol_ptr", 4, S_NON_LAZY_SYMBOL_POINTERS,
|
|
|
|
SECT_COMMON_VARS, SECT_COMMON_VARS, NULL, NULL, 0, S_REGULAR,
|
|
|
|
SECT_16BYTE_LITERALS, SECT_16BYTE_LITERALS, "__DATA", "__literal16", 16, S_REGULAR,
|
|
|
|
SECT_TEXT_COALESCE, SECT_TEXT_COALESCE, "__TEXT", "__coalesced_text", 4, S_COALESCED | S_ATTR_SOME_INSTRUCTIONS,
|
|
|
|
SECT_DATA_COALESCE, SECT_DATA_COALESCE, "__DATA", "__coalesced_data", 8, S_COALESCED,
|
|
|
|
SECT_UDATA_COALESCE, SECT_UDATA_COALESCE, "__DATA", "__coalesced_bss", 8, S_COALESCED,
|
|
|
|
SECT_CONST_COALESCE, SECT_CONST_COALESCE, "__TEXT", "__coalesce_const", 4, S_COALESCED,
|
|
|
|
SECT_CONST_PTR_COALESCE, SECT_CONST_PTR_COALESCE, "__DATA", "__coalesce_const", 4, S_COALESCED
|
|
|
|
};
|
|
|
|
#ifdef __MWERKS__
|
|
|
|
#pragma options align=reset
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Boolean declare_readonly;
|
|
|
|
SInt32 symdeclend;
|
|
|
|
SInt32 symdecloffset;
|
|
|
|
SInt32 nexttypeid;
|
|
|
|
GList symtypemodule;
|
|
|
|
SInt32 last_base_offset[N_SECTIONS];
|
|
|
|
static SInt32 RelocIndex;
|
|
|
|
static MachOSegment *TheSegment;
|
|
|
|
MachOSection *Sections[N_SECTIONS];
|
|
|
|
static MachOSection *StubSect;
|
|
|
|
static MachOSection *LazySymbolSect;
|
|
|
|
static MachOSection *NonLazySymbolSect;
|
|
|
|
static GList RelocData;
|
|
|
|
static Reloc *FirstReloc;
|
|
|
|
static Reloc *LastReloc;
|
|
|
|
Section last_function_sect_id;
|
|
|
|
MachOSection *last_function_sect;
|
|
|
|
SInt32 pic_base_offset;
|
|
|
|
|
|
|
|
#define RELOC_DATA(_id) (((RelocDataT *) (*RelocData.data))[(_id)])
|
|
|
|
|
|
|
|
static Section SegmentForceCreate = SECT_TEXT;
|
|
|
|
|
|
|
|
// forward decls
|
|
|
|
static void CreateTheSegment(void);
|
|
|
|
static void SymContainedVars(void);
|
|
|
|
static void AppendGListZeros(GList *glist, SInt32 size);
|
|
|
|
|
|
|
|
static Section ObjGen_CheckCoalesceSection(Object *object) {
|
|
|
|
Section s;
|
|
|
|
|
|
|
|
if (
|
|
|
|
!CParser_HasInternalLinkage(object) &&
|
|
|
|
(object->qual & (Q_20000 | Q_OVERLOAD)) &&
|
|
|
|
(s = def_section_info[object->section].x1) != SECT_DEFAULT
|
|
|
|
)
|
|
|
|
return s;
|
|
|
|
else
|
|
|
|
return object->section;
|
|
|
|
}
|
|
|
|
|
|
|
|
static MachOSection *ObjGen_GetSection(Section section) {
|
|
|
|
CError_ASSERT(360, section != SECT_COMMON_VARS);
|
|
|
|
|
|
|
|
if (!Sections[section]) {
|
|
|
|
DefSectionInfo *info = def_section_info + section;
|
|
|
|
Sections[section] = MachO_CreateSection(
|
|
|
|
TheSegment,
|
|
|
|
info->segname,
|
|
|
|
info->sectname,
|
|
|
|
info->align,
|
|
|
|
info->flags,
|
|
|
|
section);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Sections[section];
|
|
|
|
}
|
|
|
|
|
|
|
|
static UInt32 AlignTo_Section(MachOSection *section, UInt32 value) {
|
|
|
|
UInt32 conv;
|
|
|
|
UInt32 work;
|
|
|
|
|
|
|
|
if (value < (1 << section->section.align))
|
|
|
|
return 1 << section->section.align;
|
|
|
|
|
|
|
|
conv = 0;
|
|
|
|
work = 1;
|
|
|
|
while (work < value) {
|
|
|
|
work = work * 2;
|
|
|
|
conv++;
|
|
|
|
}
|
|
|
|
|
|
|
|
section->section.align = conv;
|
|
|
|
return work;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void updatesectreloc(RelocDataT *r, MachOSection *section, UInt32 a) {
|
|
|
|
CError_ASSERT(396, r->x3 == 0);
|
|
|
|
|
|
|
|
r->type = RT_0;
|
|
|
|
r->section = section;
|
|
|
|
r->x4 = a;
|
|
|
|
}
|
|
|
|
|
|
|
|
SInt32 ObjGen_MakeSectReloc(MachOSection *section) {
|
|
|
|
RelocDataT r = {0};
|
|
|
|
r.x18 = -1;
|
|
|
|
updatesectreloc(&r, section, section->glist.data ? section->glist.size : section->section.size);
|
|
|
|
AppendGListData(&RelocData, &r, sizeof(r));
|
|
|
|
|
|
|
|
return RelocIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char ObjGen_ComputePrivFlag(UInt8 objectFlags) {
|
|
|
|
switch (copts.x06) {
|
|
|
|
case 0:
|
|
|
|
case 1:
|
|
|
|
if (
|
2023-01-11 22:29:53 +00:00
|
|
|
(objectFlags & OBJECT_FLAGS_1) &&
|
2022-12-29 12:32:55 +00:00
|
|
|
(objectFlags & OBJECT_FLAGS_2) &&
|
|
|
|
!(objectFlags & OBJECT_FLAGS_4)
|
|
|
|
)
|
|
|
|
return 0;
|
|
|
|
return 1;
|
|
|
|
case 3:
|
|
|
|
case 4:
|
|
|
|
if ((objectFlags & OBJECT_FLAGS_10) == OBJECT_FLAGS_10)
|
|
|
|
return 1;
|
|
|
|
if ((objectFlags & OBJECT_FLAGS_40) == OBJECT_FLAGS_40)
|
|
|
|
return 0;
|
|
|
|
if (
|
2023-01-11 22:29:53 +00:00
|
|
|
(objectFlags & OBJECT_FLAGS_1) &&
|
2022-12-29 12:32:55 +00:00
|
|
|
(objectFlags & OBJECT_FLAGS_2) &&
|
|
|
|
!(objectFlags & OBJECT_FLAGS_4)
|
|
|
|
)
|
|
|
|
return 0;
|
|
|
|
return 1;
|
|
|
|
case 2:
|
|
|
|
return 0;
|
|
|
|
default:
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SInt32 ObjGen_GetHashNodeRelocID(Object *object, MachOSection *section, SInt32 value) {
|
|
|
|
HashNameNode *name;
|
|
|
|
HashNameNode *name2;
|
|
|
|
RelocDataT r;
|
|
|
|
RelocDataT *other_rd;
|
|
|
|
ObjectList *list;
|
|
|
|
SInt32 tmp;
|
|
|
|
|
|
|
|
memclrw(&r, sizeof(r));
|
|
|
|
r.x18 = -1;
|
|
|
|
|
|
|
|
if (object->datatype == DNONLAZYPTR)
|
|
|
|
name = object->name;
|
|
|
|
else
|
|
|
|
name = CMangler_GetLinkName(object);
|
|
|
|
|
|
|
|
if (value < 0)
|
|
|
|
return name->id;
|
|
|
|
|
|
|
|
if (name->id < 0) {
|
|
|
|
if (section) {
|
|
|
|
if (Sections[SECT_COMMON_VARS] && section == Sections[SECT_COMMON_VARS]) {
|
|
|
|
CError_FATAL(489);
|
|
|
|
} else {
|
|
|
|
name->id = ObjGen_MakeSectReloc(section);
|
|
|
|
}
|
|
|
|
} else if (object->datatype == DNONLAZYPTR) {
|
|
|
|
CError_ASSERT(497, object->u.var.realObj != NULL);
|
|
|
|
name->id = RelocIndex;
|
|
|
|
|
|
|
|
r.type = RT_3;
|
|
|
|
r.privFlag = ObjGen_ComputePrivFlag(object->flags);
|
|
|
|
r.name = name->name;
|
|
|
|
|
|
|
|
AppendGListData(&RelocData, &r, sizeof(r));
|
|
|
|
RelocIndex++;
|
|
|
|
ObjGen_GetHashNodeRelocID(object->u.var.realObj, NULL, 0);
|
|
|
|
} else if (value) {
|
|
|
|
object->section = SECT_COMMON_VARS;
|
|
|
|
name->id = RelocIndex;
|
|
|
|
|
|
|
|
r.type = RT_4;
|
|
|
|
r.privFlag = ObjGen_ComputePrivFlag(object->flags);
|
|
|
|
r.name = name->name;
|
|
|
|
r.x4 = value;
|
|
|
|
|
|
|
|
AppendGListData(&RelocData, &r, sizeof(r));
|
|
|
|
RelocIndex++;
|
|
|
|
} else {
|
|
|
|
name->id = RelocIndex;
|
|
|
|
|
|
|
|
r.type = (object->datatype == DFUNC || object->datatype == DVFUNC) ? RT_1 : RT_2;
|
|
|
|
r.x2 = 1;
|
|
|
|
r.privFlag = ObjGen_ComputePrivFlag(object->flags);
|
|
|
|
if (!CParser_HasInternalLinkage(object))
|
|
|
|
r.x3 = (object->qual & (Q_20000 | Q_OVERLOAD)) > 0;
|
|
|
|
r.name = name->name;
|
|
|
|
r.x4 = value;
|
|
|
|
|
|
|
|
AppendGListData(&RelocData, &r, sizeof(r));
|
|
|
|
RelocIndex++;
|
|
|
|
}
|
|
|
|
} else if (section) {
|
|
|
|
other_rd = &RELOC_DATA(name->id);
|
|
|
|
other_rd->privFlag = ObjGen_ComputePrivFlag(object->flags);
|
|
|
|
if (!CParser_HasInternalLinkage(object) && (object->qual & (Q_20000 | Q_OVERLOAD))) {
|
|
|
|
other_rd->x3 = 1;
|
|
|
|
switch (other_rd->type) {
|
|
|
|
case RT_0:
|
|
|
|
CError_FATAL(548);
|
|
|
|
|
|
|
|
other_rd->type = (object->datatype == DFUNC || object->datatype == DVFUNC) ? RT_1 : RT_2;
|
|
|
|
other_rd->x2 = 1;
|
|
|
|
other_rd->privFlag = ObjGen_ComputePrivFlag(object->flags);
|
|
|
|
other_rd->x18 = -1;
|
|
|
|
other_rd->name = name->name;
|
|
|
|
break;
|
|
|
|
case RT_1:
|
|
|
|
case RT_2:
|
|
|
|
case RT_5:
|
|
|
|
tmp = ObjGen_GetSectSize(section);
|
|
|
|
other_rd = &RELOC_DATA(name->id);
|
|
|
|
other_rd->section = section;
|
|
|
|
other_rd->x4 = tmp;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
CError_FATAL(571);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (other_rd->type) {
|
|
|
|
case RT_0:
|
|
|
|
CError_ASSERT(577, other_rd->section == section);
|
|
|
|
break;
|
|
|
|
case RT_2:
|
|
|
|
name2 = CMangler_GetLinkName(object);
|
|
|
|
for (list = toclist; list; list = list->next) {
|
|
|
|
if (name2->id == CMangler_GetLinkName(list->object)->id) {
|
|
|
|
SInt32 id = list->object->name->id;
|
|
|
|
list->object->section = SECT_CONST_PTR;
|
|
|
|
list->object->u.var.realObj = object;
|
|
|
|
other_rd = &RELOC_DATA(id);
|
|
|
|
if (other_rd->type == RT_3) {
|
|
|
|
other_rd->type = RT_6;
|
|
|
|
other_rd->x18 = name2->id;
|
|
|
|
} else if (other_rd->type != RT_6) {
|
|
|
|
CError_FATAL(602);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (tmp = 0; tmp < RelocIndex; tmp++) {
|
|
|
|
other_rd = &RELOC_DATA(tmp);
|
|
|
|
if (other_rd->type == RT_2 && !strcmp(name->name, other_rd->name)) {
|
|
|
|
name->id = tmp;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
case RT_1:
|
|
|
|
case RT_5:
|
|
|
|
tmp = ObjGen_GetSectSize(section);
|
|
|
|
other_rd = &RELOC_DATA(name->id);
|
|
|
|
updatesectreloc(other_rd, section, tmp);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
CError_FATAL(626);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (value) {
|
|
|
|
other_rd = &RELOC_DATA(name->id);
|
|
|
|
other_rd->privFlag = ObjGen_ComputePrivFlag(object->flags);
|
|
|
|
if (other_rd->type == RT_4) {
|
|
|
|
CError_ASSERT(635, value == other_rd->x4);
|
|
|
|
} else {
|
|
|
|
CError_ASSERT(639, other_rd->type == RT_2);
|
|
|
|
other_rd->type = RT_4;
|
|
|
|
other_rd->x4 = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return name->id;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Boolean ObjGen_DeclareSymbol(Object *object, MachOSection *section, SInt32 value) {
|
|
|
|
HashNameNode *name;
|
|
|
|
RelocDataT r;
|
|
|
|
|
|
|
|
if (object->name->name[0] == '@')
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (object->sclass == TK_STATIC) {
|
|
|
|
if (!strncmp(object->name->name, "L_OBJC_", 7) || !strncmp(object->name->name, "L_NSConst", 9))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
name = CMangler_GetLinkName(object);
|
|
|
|
memclrw(&r, sizeof(r));
|
|
|
|
r.x18 = -1;
|
|
|
|
r.type = RT_7;
|
|
|
|
|
|
|
|
if (!CParser_HasInternalLinkage(object)) {
|
|
|
|
if (object->datatype == DFUNC || object->datatype == DVFUNC) {
|
|
|
|
if (ObjGen_ComputePrivFlag(object->flags)) {
|
|
|
|
r.privFlag = 1;
|
|
|
|
r.x2 = 1;
|
|
|
|
} else {
|
|
|
|
r.privFlag = 0;
|
|
|
|
r.x2 = 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (object->qual & Q_INLINE) {
|
|
|
|
r.privFlag = 1;
|
|
|
|
r.x2 = 1;
|
|
|
|
} else {
|
|
|
|
r.privFlag = 0;
|
|
|
|
r.x2 = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!CParser_HasInternalLinkage(object) && (object->qual & (Q_20000 | Q_OVERLOAD)))
|
|
|
|
r.x3 = 1;
|
|
|
|
|
|
|
|
r.x4 = value;
|
|
|
|
r.section = section;
|
|
|
|
r.name = name->name;
|
|
|
|
|
|
|
|
if (r.x3) {
|
|
|
|
r.type = (object->datatype == DFUNC || object->datatype == DVFUNC) ? RT_1 : RT_2;
|
|
|
|
if (name->id >= 0) {
|
|
|
|
RELOC_DATA(name->id) = r;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (r.type == RT_7) {
|
|
|
|
AppendGListData(&RelocData, &r, sizeof(r));
|
|
|
|
RelocIndex++;
|
|
|
|
r.type = RT_0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (name->id < 0)
|
|
|
|
name->id = RelocIndex;
|
|
|
|
|
|
|
|
AppendGListData(&RelocData, &r, sizeof(r));
|
|
|
|
RelocIndex++;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_Setup(void) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
MachO_Setup();
|
|
|
|
GenStab_Setup();
|
|
|
|
declare_readonly = 0;
|
|
|
|
symtypemodule.data = NULL;
|
|
|
|
if (InitGList(&symtypemodule, 5000))
|
|
|
|
CError_NoMem();
|
|
|
|
|
|
|
|
nexttypeid = -1;
|
|
|
|
pic_base_offset = 0;
|
|
|
|
last_function_sect = 0;
|
|
|
|
last_function_sect_id = SECT_DEFAULT;
|
|
|
|
|
|
|
|
setupaddressing();
|
|
|
|
|
|
|
|
TheSegment = NULL;
|
|
|
|
|
|
|
|
for (i = 0; i < N_SECTIONS; i++) {
|
|
|
|
Sections[i] = NULL;
|
|
|
|
last_base_offset[i] = 0;
|
|
|
|
CError_ASSERT(769, i == def_section_info[i].x0);
|
|
|
|
}
|
|
|
|
|
|
|
|
RelocIndex = 0;
|
|
|
|
FirstReloc = NULL;
|
|
|
|
StubSect = NULL;
|
|
|
|
LazySymbolSect = NULL;
|
|
|
|
NonLazySymbolSect = NULL;
|
|
|
|
LastReloc = NULL;
|
|
|
|
|
|
|
|
InitGList(&RelocData, 2800);
|
|
|
|
|
|
|
|
CreateTheSegment();
|
|
|
|
ObjGen_SrcBreakName(NULL, 0, 1);
|
|
|
|
IRO_Setup();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void GenStubs(void) {
|
|
|
|
SInt32 i;
|
|
|
|
SInt32 rdCount;
|
|
|
|
SInt32 offset;
|
|
|
|
RelocDataT *rd;
|
|
|
|
|
|
|
|
rdCount = RelocData.size / sizeof(RelocDataT);
|
|
|
|
for (i = 0; i < rdCount; i++) {
|
|
|
|
if (RELOC_DATA(i).type == RT_1 && RELOC_DATA(i).x3) {
|
|
|
|
if (StubSect == NULL) {
|
|
|
|
StubSect = MachO_CreateSection(
|
|
|
|
TheSegment,
|
|
|
|
"__TEXT",
|
|
|
|
copts.codegen_pic ? "__picsymbol_stub" : "__symbol_stub",
|
|
|
|
4,
|
|
|
|
S_SYMBOL_STUBS | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS,
|
|
|
|
-1);
|
|
|
|
MachO_GetGList(StubSect);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LazySymbolSect == NULL) {
|
|
|
|
LazySymbolSect = MachO_CreateSection(
|
|
|
|
TheSegment,
|
|
|
|
"__DATA",
|
|
|
|
"__la_symbol_ptr",
|
|
|
|
4,
|
|
|
|
S_LAZY_SYMBOL_POINTERS,
|
|
|
|
-2);
|
|
|
|
}
|
|
|
|
|
|
|
|
offset = StubSect->glist.size;
|
|
|
|
rd = &RELOC_DATA(i);
|
|
|
|
rd->gapC = offset;
|
|
|
|
rd->sect10 = StubSect;
|
|
|
|
CodeGen_GenDynLinkStub(StubSect, LazySymbolSect, ObjGen_MakeSectReloc(LazySymbolSect));
|
|
|
|
StubSect->section.reserved2 = StubSect->glist.size - offset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < rdCount; i++) {
|
|
|
|
if (RELOC_DATA(i).type == RT_1 && !RELOC_DATA(i).x3) {
|
|
|
|
if (StubSect == NULL) {
|
|
|
|
StubSect = MachO_CreateSection(
|
|
|
|
TheSegment,
|
|
|
|
"__TEXT",
|
|
|
|
copts.codegen_pic ? "__picsymbol_stub" : "__symbol_stub",
|
|
|
|
4,
|
|
|
|
S_SYMBOL_STUBS | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS,
|
|
|
|
-1);
|
|
|
|
MachO_GetGList(StubSect);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LazySymbolSect == NULL) {
|
|
|
|
LazySymbolSect = MachO_CreateSection(
|
|
|
|
TheSegment,
|
|
|
|
"__DATA",
|
|
|
|
"__la_symbol_ptr",
|
|
|
|
4,
|
|
|
|
S_LAZY_SYMBOL_POINTERS,
|
|
|
|
-2);
|
|
|
|
}
|
|
|
|
|
|
|
|
offset = StubSect->glist.size;
|
|
|
|
rd = &RELOC_DATA(i);
|
|
|
|
rd->gapC = offset;
|
|
|
|
rd->sect10 = StubSect;
|
|
|
|
CodeGen_GenDynLinkStub(StubSect, LazySymbolSect, ObjGen_MakeSectReloc(LazySymbolSect));
|
|
|
|
StubSect->section.reserved2 = StubSect->glist.size - offset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void GenNonLazyPointers(void) {
|
|
|
|
ObjectList *list; // r31
|
|
|
|
Object *object; // r30
|
|
|
|
MachOSection *section; // r29
|
|
|
|
SInt32 id; // r29, r27?
|
|
|
|
UInt32 offset; // r26
|
|
|
|
RelocDataT *rd; // r26
|
|
|
|
GList *gl; // r25
|
|
|
|
SInt32 align;
|
|
|
|
SInt32 i;
|
|
|
|
|
|
|
|
for (list = toclist; list; list = list->next) {
|
|
|
|
object = list->object;
|
|
|
|
|
|
|
|
if (object->section == SECT_NONLAZY_PTRS) {
|
|
|
|
id = ObjGen_GetHashNodeRelocID(object, NULL, 0);
|
|
|
|
|
|
|
|
CError_ASSERT(877, RELOC_DATA(id).type == RT_3);
|
|
|
|
|
|
|
|
if (NonLazySymbolSect == NULL) {
|
|
|
|
NonLazySymbolSect = ObjGen_GetSection(SECT_NONLAZY_PTRS);
|
|
|
|
MachO_GetGList(NonLazySymbolSect);
|
|
|
|
}
|
|
|
|
|
|
|
|
updatesectreloc(&RELOC_DATA(id), NonLazySymbolSect, NonLazySymbolSect->glist.size);
|
|
|
|
AppendGListLong(&NonLazySymbolSect->glist, 0);
|
|
|
|
} else if (object->section == SECT_CONST_PTR) {
|
|
|
|
id = ObjGen_GetHashNodeRelocID(object, NULL, 0);
|
|
|
|
|
|
|
|
CError_ASSERT(901, RELOC_DATA(id).type == RT_6 || RELOC_DATA(id).type == RT_3);
|
|
|
|
|
|
|
|
section = ObjGen_GetSection(object->section);
|
|
|
|
gl = MachO_GetGList(section);
|
|
|
|
offset = gl->size;
|
|
|
|
|
|
|
|
align = AlignTo_Section(section, 4);
|
|
|
|
if ((offset % align) != 0) {
|
|
|
|
for (i = 0; i < (align - (offset % align)); i++)
|
|
|
|
AppendGListByte(gl, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
rd = &RELOC_DATA(id);
|
|
|
|
updatesectreloc(rd, section, section->glist.size);
|
|
|
|
AppendGListLong(§ion->glist, 0);
|
|
|
|
|
|
|
|
id = CMangler_GetLinkName(object)->id;
|
|
|
|
CError_ASSERT(940, RELOC_DATA(id).type == RT_0);
|
|
|
|
|
|
|
|
ObjGen_Relocate(section, rd->x4, id, RT_4, MW_RELOC_0);
|
|
|
|
} else {
|
|
|
|
CError_FATAL(944);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_DeclareFloatConst(Object *object) {
|
|
|
|
Section sectionID;
|
|
|
|
GList *gl;
|
|
|
|
|
|
|
|
if (!TheSegment)
|
|
|
|
CreateTheSegment();
|
|
|
|
|
|
|
|
sectionID = object->section;
|
|
|
|
if (sectionID == SECT_DEFAULT) {
|
|
|
|
if (object->type->size == 4)
|
|
|
|
sectionID = SECT_4BYTE_LITERALS;
|
|
|
|
else
|
|
|
|
sectionID = SECT_8BYTE_LITERALS;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjGen_GetHashNodeRelocID(object, ObjGen_GetSection(sectionID), 0);
|
|
|
|
|
|
|
|
gl = MachO_GetGList(Sections[sectionID]);
|
|
|
|
if (object->type->size == 4) {
|
|
|
|
float f = object->u.data.u.floatconst->value;
|
2023-01-14 18:58:26 +00:00
|
|
|
CTool_EndianConvertMem(&f, 4);
|
2022-12-29 12:32:55 +00:00
|
|
|
AppendGListData(gl, &f, 4);
|
|
|
|
} else if (object->type->size == 8) {
|
|
|
|
double f = object->u.data.u.floatconst->value;
|
2023-01-14 18:58:26 +00:00
|
|
|
CTool_EndianConvertMem(&f, 8);
|
2022-12-29 12:32:55 +00:00
|
|
|
AppendGListData(gl, &f, 8);
|
|
|
|
} else {
|
|
|
|
CError_FATAL(998);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_DeclareVectorConst(Object *object) {
|
|
|
|
Section sectionID;
|
|
|
|
GList *gl;
|
|
|
|
|
|
|
|
if (!TheSegment)
|
|
|
|
CreateTheSegment();
|
|
|
|
|
|
|
|
sectionID = SECT_16BYTE_LITERALS;
|
|
|
|
ObjGen_GetHashNodeRelocID(object, ObjGen_GetSection(sectionID), 0);
|
|
|
|
|
|
|
|
gl = MachO_GetGList(Sections[sectionID]);
|
|
|
|
if (object->type->size == 16) {
|
|
|
|
MWVector128 vec = *object->u.data.u.vector128const;
|
|
|
|
AppendGListData(gl, &vec, 16);
|
|
|
|
} else {
|
|
|
|
CError_FATAL(1034);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_Finish(void) {
|
|
|
|
UInt32 symIndex;
|
|
|
|
SInt32 rdCount;
|
|
|
|
RelocDataT *rdArray;
|
|
|
|
SInt32 rdIndex;
|
|
|
|
RelocDataT *rd;
|
|
|
|
Reloc *reloc;
|
|
|
|
ObjectList *objlist;
|
|
|
|
SInt32 value;
|
|
|
|
int flags;
|
|
|
|
int desc;
|
|
|
|
enum reloc_type_ppc nextRelType;
|
|
|
|
UInt32 opMask;
|
|
|
|
UInt32 argMask;
|
|
|
|
|
2023-01-15 12:14:05 +00:00
|
|
|
if (copts.filesyminfo)
|
2022-12-29 12:32:55 +00:00
|
|
|
GenStab_SourceFile("");
|
|
|
|
|
|
|
|
CInit_DeclarePooledStrings();
|
|
|
|
DeclarePooledConstants();
|
|
|
|
|
|
|
|
if (copts.codegen_dynamic) {
|
|
|
|
GenStubs();
|
|
|
|
GenNonLazyPointers();
|
|
|
|
}
|
|
|
|
|
|
|
|
MachO_ReOrderSections();
|
|
|
|
COS_LockHandle(RelocData.data);
|
|
|
|
|
|
|
|
rdCount = RelocData.size / sizeof(RelocDataT);
|
|
|
|
|
|
|
|
rdArray = &RELOC_DATA(0);
|
|
|
|
for (rdIndex = 0; rdIndex < (RelocData.size / sizeof(RelocDataT)); rdIndex++) {
|
|
|
|
rd = rdArray + rdIndex;
|
|
|
|
if (rd->type == RT_7 && rd->x2 == 0) {
|
|
|
|
symIndex = MachO_DeclareSymbol(rd->name, rd->section, rd->x4, 0, 0, 0);
|
|
|
|
rd->type = RT_5;
|
|
|
|
rd->x18 = symIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rdArray = &RELOC_DATA(0);
|
|
|
|
for (rdIndex = 0; rdIndex < rdCount; rdIndex++) {
|
|
|
|
rd = rdArray + rdIndex;
|
|
|
|
if (rd->type == RT_7 && rd->x2 != 0) {
|
|
|
|
flags = N_EXT;
|
|
|
|
desc = 0;
|
|
|
|
if (rd->privFlag != 0) {
|
|
|
|
flags |= N_PEXT;
|
|
|
|
desc = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
symIndex = MachO_DeclareSymbol(rd->name, rd->section, rd->x4, 0, flags, desc);
|
|
|
|
rd->type = RT_5;
|
|
|
|
rd->x18 = symIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (copts.codegen_dynamic && StubSect)
|
|
|
|
StubSect->section.reserved1 = MachO_NumIndirectSym();
|
|
|
|
|
|
|
|
for (rdIndex = 0; rdIndex < rdCount; rdIndex++) {
|
|
|
|
rd = &RELOC_DATA(rdIndex);
|
|
|
|
if (rd->type == RT_1 && rd->x3 != 0) {
|
|
|
|
flags = N_EXT;
|
|
|
|
desc = 0;
|
|
|
|
if (rd->privFlag != 0) {
|
|
|
|
flags |= N_PEXT;
|
|
|
|
desc = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
symIndex = MachO_DeclareSymbol(rd->name, rd->section, rd->x4, 0, flags, desc);
|
|
|
|
rd->x18 = symIndex;
|
|
|
|
|
|
|
|
if (copts.codegen_dynamic && rd->sect10 == StubSect) {
|
|
|
|
MachOSection *tmpSection;
|
|
|
|
UInt32 tmpValue;
|
|
|
|
|
|
|
|
MachO_AddIndirectSymbol(symIndex);
|
|
|
|
|
|
|
|
tmpSection = rd->section;
|
|
|
|
tmpValue = rd->x4;
|
|
|
|
rd->section = rd->sect10;
|
|
|
|
rd->x4 = rd->gapC;
|
|
|
|
rd->sect10 = tmpSection;
|
|
|
|
rd->gapC = tmpValue;
|
|
|
|
} else {
|
|
|
|
rd->x2 = 1;
|
|
|
|
rd->type = RT_5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (rdIndex = 0; rdIndex < rdCount; rdIndex++) {
|
|
|
|
rd = rdArray + rdIndex;
|
|
|
|
if (rd->type == RT_2 && rd->x3 != 0) {
|
|
|
|
flags = N_EXT;
|
|
|
|
desc = 0;
|
|
|
|
if (rd->privFlag != 0) {
|
|
|
|
flags |= N_PEXT;
|
|
|
|
desc = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
symIndex = MachO_DeclareSymbol(rd->name, rd->section, rd->x4, 0, flags, desc);
|
|
|
|
rd->type = RT_5;
|
|
|
|
rd->x18 = symIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (rdIndex = 0; rdIndex < rdCount; rdIndex++) {
|
|
|
|
rd = rdArray + rdIndex;
|
|
|
|
if (rd->type == RT_4) {
|
|
|
|
flags = N_EXT;
|
|
|
|
desc = 0;
|
|
|
|
if (rd->privFlag != 0) {
|
|
|
|
flags |= N_PEXT;
|
|
|
|
desc = 4; // REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY?
|
|
|
|
}
|
|
|
|
|
|
|
|
symIndex = MachO_DeclareSymbol(rd->name, NULL, rd->x4, 0, flags, desc);
|
|
|
|
rd->type = RT_5;
|
|
|
|
rd->x18 = symIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (rdIndex = 0; rdIndex < rdCount; rdIndex++) {
|
|
|
|
rd = rdArray + rdIndex;
|
|
|
|
if (rd->type == RT_2 & rd->x3 == 0) { // typo alert
|
|
|
|
flags = N_EXT;
|
|
|
|
desc = 0;
|
|
|
|
if (rd->privFlag != 0) {
|
|
|
|
flags |= N_PEXT;
|
|
|
|
desc = 4; // REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY?
|
|
|
|
}
|
|
|
|
|
|
|
|
symIndex = MachO_DeclareSymbol(rd->name, NULL, rd->x4, 0, flags, desc);
|
|
|
|
rd->type = RT_5;
|
|
|
|
rd->x18 = symIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (rdIndex = 0; rdIndex < rdCount; rdIndex++) {
|
|
|
|
rd = &RELOC_DATA(rdIndex);
|
|
|
|
if (rd->type == RT_1 && rd->x3 == 0) {
|
|
|
|
flags = N_EXT;
|
|
|
|
desc = 1; // REFERENCE_FLAG_UNDEFINED_LAZY?
|
|
|
|
if (rd->privFlag != 0) {
|
|
|
|
flags |= N_PEXT;
|
|
|
|
desc = 5; // REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY?
|
|
|
|
}
|
|
|
|
|
|
|
|
symIndex = MachO_DeclareSymbol(rd->name, NULL, 0, 0, flags, desc);
|
|
|
|
rd = &RELOC_DATA(rdIndex);
|
|
|
|
rd->x18 = symIndex;
|
|
|
|
|
|
|
|
if (copts.codegen_dynamic && rd->sect10 == StubSect) {
|
|
|
|
MachO_AddIndirectSymbol(symIndex);
|
|
|
|
rd->section = rd->sect10;
|
|
|
|
rd->x4 = rd->gapC;
|
|
|
|
} else {
|
|
|
|
rd->x2 = 1;
|
|
|
|
rd->type = RT_5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (copts.codegen_dynamic) {
|
|
|
|
if (LazySymbolSect)
|
|
|
|
LazySymbolSect->section.reserved1 = MachO_NumIndirectSym();
|
|
|
|
|
|
|
|
for (rdIndex = 0; rdIndex < rdCount; rdIndex++) {
|
|
|
|
rd = &RELOC_DATA(rdIndex);
|
|
|
|
if (rd->type == RT_1 && rd->x3 != 0 && rd->section == StubSect) {
|
|
|
|
MachO_AddIndirectSymbol(rd->x18);
|
|
|
|
|
|
|
|
rd = &RELOC_DATA(rdIndex);
|
|
|
|
rd->x3 = 0;
|
|
|
|
updatesectreloc(rd, rd->section, rd->x4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (rdIndex = 0; rdIndex < rdCount; rdIndex++) {
|
|
|
|
rd = &RELOC_DATA(rdIndex);
|
|
|
|
if (rd->type == RT_1 && rd->x3 == 0 && rd->section == StubSect) {
|
|
|
|
MachO_AddIndirectSymbol(rd->x18);
|
|
|
|
|
|
|
|
rd = &RELOC_DATA(rdIndex);
|
|
|
|
rd->x3 = 0;
|
|
|
|
updatesectreloc(rd, rd->section, rd->x4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (copts.codegen_dynamic) {
|
|
|
|
if (NonLazySymbolSect)
|
|
|
|
NonLazySymbolSect->section.reserved1 = MachO_NumIndirectSym();
|
|
|
|
|
|
|
|
for (objlist = toclist; objlist; objlist = objlist->next) {
|
|
|
|
if (objlist->object->section == SECT_NONLAZY_PTRS) {
|
|
|
|
SInt32 id = CMangler_GetLinkName(objlist->object)->id;
|
|
|
|
MachO_AddIndirectSymbol(RELOC_DATA(id).x18);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (reloc = FirstReloc; reloc; reloc = reloc->next) {
|
|
|
|
rd = rdArray + reloc->relocID;
|
|
|
|
value = 0;
|
|
|
|
switch (rd->type) {
|
|
|
|
case RT_0:
|
|
|
|
if (rd->section == StubSect && reloc->mwRelType == MW_RELOC_9) {
|
|
|
|
symIndex = rd->sect10->num;
|
|
|
|
value = rd->gapC;
|
|
|
|
} else {
|
|
|
|
symIndex = rd->section->num;
|
|
|
|
value = rd->x4;
|
|
|
|
flags = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RT_5:
|
|
|
|
symIndex = rd->x18;
|
|
|
|
flags = N_EXT;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
CError_FATAL(1341);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (copts.codegen_pic) {
|
|
|
|
switch (reloc->mwRelType) {
|
|
|
|
case MW_RELOC_5_LO16:
|
|
|
|
opMask = 0xFFFF0000;
|
|
|
|
argMask = 0xFFFF;
|
|
|
|
value = value & 0xFFFF;
|
|
|
|
nextRelType = PPC_RELOC_LO16_SECTDIFF;
|
|
|
|
break;
|
|
|
|
case MW_RELOC_7_HA16:
|
|
|
|
opMask = 0xFFFF0000;
|
|
|
|
argMask = 0xFFFF;
|
|
|
|
if (value & 0x8000)
|
|
|
|
value += 0x10000;
|
|
|
|
value = (value >> 16) & 0xFFFF;
|
|
|
|
nextRelType = PPC_RELOC_HA16_SECTDIFF;
|
|
|
|
break;
|
|
|
|
case MW_RELOC_6_HI16:
|
|
|
|
opMask = 0xFFFF0000;
|
|
|
|
argMask = 0xFFFF;
|
|
|
|
value = (value >> 16) & 0xFFFF;
|
|
|
|
nextRelType = PPC_RELOC_HI16_SECTDIFF;
|
|
|
|
break;
|
|
|
|
case MW_RELOC_8:
|
|
|
|
CError_FATAL(1367);
|
|
|
|
nextRelType = PPC_RELOC_HI16_SECTDIFF;
|
|
|
|
break;
|
|
|
|
case MW_RELOC_0:
|
|
|
|
case MW_RELOC_9:
|
|
|
|
opMask = 0;
|
|
|
|
argMask = 0xFFFFFFFF;
|
|
|
|
nextRelType = PPC_RELOC_VANILLA;
|
|
|
|
break;
|
|
|
|
case MW_RELOC_2_BR24:
|
|
|
|
opMask = 0xFC000003;
|
|
|
|
argMask = 0x3FFFFFC;
|
|
|
|
value = value & 0x3FFFFFC;
|
|
|
|
nextRelType = PPC_RELOC_BR24;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
CError_FATAL(1383);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nextRelType == PPC_RELOC_BR24) {
|
|
|
|
MachO_Relocate(reloc->section, reloc->offset, symIndex, 4, 1, flags, nextRelType);
|
|
|
|
} else if (nextRelType == PPC_RELOC_VANILLA) {
|
|
|
|
MachO_Relocate(reloc->section, reloc->offset, symIndex, 4, 0, flags, nextRelType);
|
|
|
|
} else {
|
|
|
|
CError_ASSERT(1391, rd->type == RT_0);
|
|
|
|
|
|
|
|
MachO_Relocate(reloc->section, reloc->offset, symIndex, 4, 0, flags, nextRelType);
|
|
|
|
MachO_Relocate(reloc->section, rd->x4, reloc->picOffset, 4, 0, flags, PPC_RELOC_PAIR);
|
|
|
|
value = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (value) {
|
|
|
|
UInt32 *ptr = (UInt32 *) (*reloc->section->glist.data + reloc->offset);
|
2023-01-13 01:36:56 +00:00
|
|
|
*ptr = CTool_EndianConvertWord32(
|
|
|
|
(CTool_EndianConvertWord32(*ptr) & opMask) |
|
|
|
|
(argMask & (value + (CTool_EndianConvertWord32(*ptr) & argMask)))
|
|
|
|
);
|
2022-12-29 12:32:55 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (reloc->mwRelType) {
|
|
|
|
case MW_RELOC_5_LO16:
|
|
|
|
opMask = 0xFFFF0000;
|
|
|
|
argMask = 0xFFFF;
|
|
|
|
value = value & 0xFFFF;
|
|
|
|
nextRelType = PPC_RELOC_LO16;
|
|
|
|
break;
|
|
|
|
case MW_RELOC_7_HA16:
|
|
|
|
opMask = 0xFFFF0000;
|
|
|
|
argMask = 0xFFFF;
|
|
|
|
if (value & 0x8000)
|
|
|
|
value += 0x10000;
|
|
|
|
value = (value >> 16) & 0xFFFF;
|
|
|
|
nextRelType = PPC_RELOC_HA16;
|
|
|
|
break;
|
|
|
|
case MW_RELOC_6_HI16:
|
|
|
|
opMask = 0xFFFF0000;
|
|
|
|
argMask = 0xFFFF;
|
|
|
|
value = (value >> 16) & 0xFFFF;
|
|
|
|
nextRelType = PPC_RELOC_HI16;
|
|
|
|
break;
|
|
|
|
case MW_RELOC_8:
|
|
|
|
CError_FATAL(1434);
|
|
|
|
opMask = 0xFFFF0000;
|
|
|
|
argMask = 0xFFFF;
|
|
|
|
nextRelType = PPC_RELOC_HI16;
|
|
|
|
break;
|
|
|
|
case MW_RELOC_2_BR24:
|
|
|
|
opMask = 0xFC000003;
|
|
|
|
argMask = 0x3FFFFFC;
|
|
|
|
value = value & 0x3FFFFFC;
|
|
|
|
nextRelType = PPC_RELOC_BR24;
|
|
|
|
break;
|
|
|
|
case MW_RELOC_0:
|
|
|
|
case MW_RELOC_9:
|
|
|
|
opMask = 0;
|
|
|
|
argMask = 0xFFFFFFFF;
|
|
|
|
nextRelType = PPC_RELOC_VANILLA;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
CError_FATAL(1452);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (value != 0) {
|
|
|
|
UInt32 *ptr = (UInt32 *) (*reloc->section->glist.data + reloc->offset);
|
2023-01-13 01:36:56 +00:00
|
|
|
*ptr = CTool_EndianConvertWord32(
|
|
|
|
(CTool_EndianConvertWord32(*ptr) & opMask) |
|
|
|
|
(argMask & (value + (CTool_EndianConvertWord32(*ptr) & argMask)))
|
|
|
|
);
|
2022-12-29 12:32:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (nextRelType == PPC_RELOC_BR24) {
|
|
|
|
MachO_Relocate(reloc->section, reloc->offset, symIndex, 4, 1, flags, nextRelType);
|
|
|
|
} else {
|
|
|
|
MachO_Relocate(reloc->section, reloc->offset, symIndex, 4, 0, flags, nextRelType);
|
|
|
|
if (nextRelType == PPC_RELOC_HI16 || nextRelType == PPC_RELOC_HA16 || nextRelType == PPC_RELOC_LO16)
|
|
|
|
MachO_Relocate(reloc->section, rd->x4, 0xFFFFFF, 4, 0, 0, PPC_RELOC_PAIR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
COS_UnlockHandle(RelocData.data);
|
|
|
|
MachO_Finish();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_Cleanup(void) {
|
|
|
|
MachO_Cleanup();
|
|
|
|
if (RelocData.data)
|
|
|
|
FreeGList(&RelocData);
|
|
|
|
|
|
|
|
CleanupDumpIR();
|
|
|
|
pccleanuplisting();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_SetupSym(void) {
|
|
|
|
}
|
|
|
|
|
|
|
|
static void CreateTheSegment(void) {
|
|
|
|
TheSegment = MachO_CreateSegment("", 7, 7, 0);
|
|
|
|
Sections[SegmentForceCreate] = ObjGen_GetSection(SegmentForceCreate);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void patchuplazyptr(Object *object) {
|
|
|
|
RelocDataT *rd;
|
|
|
|
Object *toc;
|
|
|
|
|
|
|
|
if (CParser_HasInternalLinkage(object) || !(object->qual & (Q_20000 | Q_OVERLOAD))) {
|
|
|
|
toc = object->toc;
|
|
|
|
if (toc->section == SECT_NONLAZY_PTRS) {
|
|
|
|
toc->section = SECT_CONST_PTR;
|
|
|
|
rd = &RELOC_DATA(ObjGen_GetHashNodeRelocID(toc, NULL, 0));
|
|
|
|
if (rd->type == RT_3) {
|
|
|
|
rd->type = RT_6;
|
|
|
|
rd->x18 = ObjGen_GetHashNodeRelocID(object, NULL, 0);
|
|
|
|
} else {
|
|
|
|
CError_FATAL(1592);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void definedatasymbol(Object *object, MachOSection *section, SInt32 value) {
|
|
|
|
Boolean flag;
|
|
|
|
|
|
|
|
flag = ObjGen_DeclareSymbol(object, section, value);
|
|
|
|
ObjGen_GetHashNodeRelocID(object, section, 0);
|
|
|
|
|
2023-01-15 12:14:05 +00:00
|
|
|
if (flag && copts.filesyminfo)
|
2022-12-29 12:32:55 +00:00
|
|
|
GenStab_Var(object);
|
|
|
|
if (object->toc)
|
|
|
|
patchuplazyptr(object);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void declaredata(Object *object, char *data, OLinkList *olinklist, UInt32 size, Boolean isConst) {
|
|
|
|
Section sectionID; // r30
|
|
|
|
MachOSection *section; // r24
|
|
|
|
SInt32 offset; // r23
|
|
|
|
GList *gl; // r22
|
|
|
|
UInt32 align;
|
|
|
|
OLinkList *scan;
|
|
|
|
|
|
|
|
if (!TheSegment)
|
|
|
|
CreateTheSegment();
|
|
|
|
|
|
|
|
if (data) {
|
|
|
|
if (object->section == SECT_COMMON_VARS)
|
|
|
|
object->section = SECT_DEFAULT;
|
|
|
|
|
|
|
|
if (object->section == SECT_DEFAULT) {
|
|
|
|
if (isConst)
|
|
|
|
object->section = SECT_CONST;
|
|
|
|
else
|
|
|
|
object->section = SECT_DATA;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (object->section == SECT_CONST && olinklist)
|
|
|
|
object->section = SECT_CONST_PTR;
|
|
|
|
|
|
|
|
object->section = ObjGen_CheckCoalesceSection(object);
|
|
|
|
|
|
|
|
sectionID = object->section;
|
|
|
|
section = Sections[sectionID];
|
|
|
|
if (!section)
|
|
|
|
section = ObjGen_GetSection(sectionID);
|
|
|
|
|
|
|
|
gl = MachO_GetGList(section);
|
|
|
|
offset = gl->size;
|
|
|
|
|
|
|
|
align = CMach_AllocationAlignment(object->type, object->qual);
|
|
|
|
if (!align)
|
|
|
|
align = 1;
|
|
|
|
align = AlignTo_Section(section, align);
|
|
|
|
|
|
|
|
if (offset % align) {
|
|
|
|
SInt32 adjust = align - (offset % align);
|
|
|
|
AppendGListZeros(gl, adjust);
|
|
|
|
offset += adjust;
|
|
|
|
}
|
|
|
|
|
|
|
|
definedatasymbol(object, Sections[sectionID], offset);
|
|
|
|
|
|
|
|
for (scan = olinklist; scan; scan = scan->next) {
|
|
|
|
if (scan->somevalue)
|
2023-01-14 13:20:48 +00:00
|
|
|
*((SInt32 *) (data + scan->offset)) = CTool_EndianConvertWord32(scan->somevalue);
|
2022-12-29 12:32:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (sectionID == SECT_8BYTE_LITERALS)
|
|
|
|
AppendGListData(gl, data, 8);
|
|
|
|
else if (sectionID == SECT_4BYTE_LITERALS)
|
|
|
|
AppendGListData(gl, data, 4);
|
|
|
|
else
|
|
|
|
AppendGListData(gl, data, size);
|
|
|
|
|
|
|
|
while (olinklist) {
|
|
|
|
SInt32 extflag;
|
|
|
|
SInt32 id;
|
|
|
|
|
2023-01-13 01:36:56 +00:00
|
|
|
extflag = ObjGen_IsExternalVar(ObjGen_GetHashNodeRelocID(olinklist->obj, NULL, 0));
|
|
|
|
id = CMangler_GetLinkName(olinklist->obj)->id;
|
|
|
|
ObjGen_Relocate(Sections[sectionID], offset + olinklist->offset, extflag + id, RT_4, MW_RELOC_0);
|
2022-12-29 12:32:55 +00:00
|
|
|
olinklist = olinklist->next;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (
|
|
|
|
CParser_HasInternalLinkage(object) ||
|
|
|
|
(copts.no_common && !(object->qual & Q_20000)) ||
|
|
|
|
!object->qual & Q_1000000 // typo alert
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (object->section == SECT_DEFAULT) {
|
|
|
|
if (isConst)
|
|
|
|
object->section = SECT_CONST;
|
|
|
|
else
|
|
|
|
object->section = SECT_UDATA;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (object->section == SECT_CONST && olinklist)
|
|
|
|
object->section = SECT_CONST_PTR;
|
|
|
|
|
|
|
|
object->section = ObjGen_CheckCoalesceSection(object);
|
|
|
|
section = ObjGen_GetSection(object->section);
|
|
|
|
sectionID = object->section;
|
|
|
|
|
|
|
|
if (sectionID == SECT_UDATA) {
|
|
|
|
align = CMach_AllocationAlignment(object->type, object->qual);
|
|
|
|
AlignTo_Section(section, align);
|
|
|
|
offset = section->section.size;
|
|
|
|
if (!align)
|
|
|
|
align = 1;
|
|
|
|
|
|
|
|
if (offset % align) {
|
|
|
|
// issue here
|
|
|
|
SInt32 adjust = align - (offset % align);
|
|
|
|
offset = offset + adjust;
|
|
|
|
}
|
|
|
|
|
|
|
|
section->section.size = offset;
|
|
|
|
|
|
|
|
definedatasymbol(object, Sections[sectionID], offset);
|
|
|
|
|
|
|
|
offset += size;
|
|
|
|
section->section.size = offset;
|
|
|
|
} else {
|
|
|
|
gl = MachO_GetGList(section);
|
|
|
|
offset = gl->size;
|
|
|
|
|
|
|
|
align = CMach_AllocationAlignment(object->type, object->qual);
|
|
|
|
if (!align)
|
|
|
|
align = 1;
|
|
|
|
align = AlignTo_Section(section, align);
|
|
|
|
|
|
|
|
if (offset % align) {
|
|
|
|
SInt32 adjust = align - (offset % align);
|
|
|
|
AppendGListZeros(gl, adjust);
|
|
|
|
offset += adjust;
|
|
|
|
}
|
|
|
|
|
|
|
|
definedatasymbol(object, Sections[sectionID], offset);
|
|
|
|
AppendGListZeros(gl, size);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
object->qual |= Q_1000000;
|
|
|
|
object->section = SECT_COMMON_VARS;
|
|
|
|
ObjGen_GetHashNodeRelocID(object, NULL, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_DeclareData(Object *object, char *data, OLinkList *olinklist, UInt32 size) {
|
|
|
|
declaredata(object, data, olinklist, size, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_DeclareReadOnlyData(Object *object, char *data, OLinkList *olinklist, UInt32 size) {
|
|
|
|
declaredata(object, data, olinklist, size, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_SegmentName(void) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_SymFunc(Object *function) {
|
|
|
|
GenStab_Function(function, ObjGen_GetHashNodeRelocID(function, NULL, 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGenMach_SymFuncEnd(Object *function, UInt32 offset) {
|
|
|
|
GenStab_FunctionEnd(function, ObjGen_GetHashNodeRelocID(function, NULL, 0), offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_CodeSetup(void) {
|
|
|
|
// empty/unknown args
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_CodeCleanup(void) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_SrcBreakName(HashNameNode *name, SInt32 fileModDate, Boolean flag) {
|
|
|
|
char *ptr;
|
|
|
|
char *ptr2;
|
|
|
|
char *ptr3;
|
|
|
|
char buf1[1024];
|
|
|
|
char buf2[1024];
|
|
|
|
|
2023-01-15 12:14:05 +00:00
|
|
|
if (copts.filesyminfo) {
|
2022-12-29 12:32:55 +00:00
|
|
|
if (name)
|
|
|
|
strncpy(buf1, name->name, sizeof(buf1));
|
|
|
|
else
|
2023-01-15 12:14:05 +00:00
|
|
|
COS_FileGetPathName(buf1, &cparamblkptr->sourcefile, &fileModDate);
|
2022-12-29 12:32:55 +00:00
|
|
|
|
|
|
|
if (name && copts.absolutepath)
|
|
|
|
ptr = buf1 + strlen(buf1);
|
|
|
|
else
|
|
|
|
ptr = strrchr(buf1, '/');
|
|
|
|
|
|
|
|
if ((flag || name) && ptr && copts.absolutepath) {
|
|
|
|
if (!strncmp(buf1, "Mac OS X:", strlen("Mac OS X:"))) {
|
|
|
|
strcpy(buf2, "/");
|
|
|
|
ptr2 = buf2 + 1;
|
|
|
|
ptr3 = buf1 + strlen("Mac OS X:");
|
|
|
|
} else {
|
|
|
|
strcpy(buf2, "/Volumes/");
|
|
|
|
ptr2 = buf2 + strlen("/Volumes/");
|
|
|
|
ptr3 = buf1;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (ptr3 <= ptr)
|
|
|
|
*(ptr2++) = *(ptr3++);
|
|
|
|
*ptr2 = 0;
|
|
|
|
|
|
|
|
if (flag && !name) {
|
|
|
|
GenStab_SourceFile(buf2);
|
|
|
|
} else {
|
|
|
|
GenStab_IncludeFile(buf2);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ptr)
|
|
|
|
ptr++;
|
|
|
|
else
|
|
|
|
ptr = buf1;
|
|
|
|
|
|
|
|
if (flag && !name)
|
|
|
|
GenStab_SourceFile(ptr);
|
|
|
|
else
|
|
|
|
GenStab_IncludeFile(ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GList *ObjGen_GetSectionGList(MachOSection *section) {
|
|
|
|
return MachO_GetGList(section);
|
|
|
|
}
|
|
|
|
|
|
|
|
MachOSection *ObjGen_DeclareFunction(Object *object) {
|
|
|
|
MachOSection *section;
|
|
|
|
|
|
|
|
if (!TheSegment)
|
|
|
|
CreateTheSegment();
|
|
|
|
|
|
|
|
if (object->section == SECT_DEFAULT)
|
|
|
|
object->section = SECT_TEXT;
|
|
|
|
|
|
|
|
object->section = ObjGen_CheckCoalesceSection(object);
|
|
|
|
section = ObjGen_GetSection(object->section);
|
|
|
|
|
|
|
|
if (object) {
|
|
|
|
ObjGen_DeclareSymbol(object, section, section->glist.size);
|
|
|
|
if (CMangler_GetLinkName(object)->id == -1) {
|
|
|
|
CMangler_GetLinkName(object)->id = ObjGen_MakeSectReloc(section);
|
|
|
|
} else {
|
|
|
|
RelocDataT *rd = &RELOC_DATA(CMangler_GetLinkName(object)->id);
|
|
|
|
if (rd->x3 == 0) {
|
|
|
|
updatesectreloc(rd, section, section->glist.size);
|
|
|
|
} else {
|
|
|
|
rd->section = section;
|
|
|
|
rd->x4 = section->glist.size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return section;
|
|
|
|
}
|
|
|
|
|
|
|
|
MachOSection *ObjGen_DeclareCode(Object *object) {
|
|
|
|
MachOSection *section;
|
|
|
|
|
|
|
|
section = ObjGen_DeclareFunction(object);
|
|
|
|
last_base_offset[object->section] = ObjGen_GetSectionGList(section)->size;
|
|
|
|
last_function_sect = section;
|
|
|
|
last_function_sect_id = object->section;
|
|
|
|
|
|
|
|
return section;
|
|
|
|
}
|
|
|
|
|
|
|
|
MachOSection *ObjGen_DeclareMachSection() {
|
|
|
|
// unknown args
|
|
|
|
CError_FATAL(2020);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_Relocate(MachOSection *section, SInt32 offset, SInt32 relocID, RelocType relocType, MWReloc mwRelType) {
|
|
|
|
Reloc *reloc;
|
|
|
|
|
|
|
|
reloc = galloc(sizeof(Reloc));
|
|
|
|
reloc->section = section;
|
|
|
|
reloc->offset = offset;
|
|
|
|
reloc->relocID = relocID;
|
|
|
|
reloc->relocType = relocType;
|
|
|
|
reloc->mwRelType = mwRelType;
|
|
|
|
if (copts.codegen_pic)
|
|
|
|
reloc->picOffset = pic_base_offset;
|
|
|
|
else
|
|
|
|
reloc->picOffset = 0;
|
|
|
|
|
|
|
|
reloc->next = NULL;
|
|
|
|
if (FirstReloc == NULL)
|
|
|
|
FirstReloc = reloc;
|
|
|
|
else
|
|
|
|
LastReloc->next = reloc;
|
|
|
|
LastReloc = reloc;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_RelocateObj(MachOSection *section, SInt32 offset, Object *object, MWReloc mwRelType) {
|
|
|
|
Reloc *reloc;
|
|
|
|
|
|
|
|
if (section == last_function_sect)
|
|
|
|
offset += last_base_offset[last_function_sect_id];
|
|
|
|
|
|
|
|
if (object) {
|
|
|
|
reloc = galloc(sizeof(Reloc));
|
|
|
|
reloc->section = section;
|
|
|
|
reloc->offset = offset;
|
|
|
|
reloc->relocID = ObjGen_GetHashNodeRelocID(object, NULL, 0);
|
|
|
|
switch (mwRelType) {
|
|
|
|
case MW_RELOC_0:
|
|
|
|
case MW_RELOC_2_BR24:
|
|
|
|
case MW_RELOC_9:
|
|
|
|
reloc->picOffset = 0;
|
|
|
|
break;
|
|
|
|
case MW_RELOC_5_LO16:
|
|
|
|
case MW_RELOC_6_HI16:
|
|
|
|
case MW_RELOC_7_HA16:
|
|
|
|
reloc->picOffset = pic_base_offset;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
CError_FATAL(2115);
|
|
|
|
}
|
|
|
|
reloc->relocType = RT_4;
|
|
|
|
reloc->mwRelType = mwRelType;
|
|
|
|
|
|
|
|
reloc->next = NULL;
|
|
|
|
if (FirstReloc == NULL)
|
|
|
|
FirstReloc = reloc;
|
|
|
|
else
|
|
|
|
LastReloc->next = reloc;
|
|
|
|
LastReloc = reloc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SInt32 ObjGen_DeclareLiteralString(UInt32 len, char *data, SInt32 align) {
|
|
|
|
SInt32 offset;
|
|
|
|
SInt32 relocID;
|
|
|
|
GList *gl;
|
|
|
|
MachOSection *section;
|
|
|
|
UInt32 align2;
|
|
|
|
SInt32 pad;
|
|
|
|
SInt32 i;
|
|
|
|
|
|
|
|
if (!TheSegment)
|
|
|
|
CreateTheSegment();
|
|
|
|
|
|
|
|
section = ObjGen_GetSection(SECT_TEXT_CSTRING);
|
|
|
|
gl = MachO_GetGList(section);
|
|
|
|
offset = gl->size;
|
|
|
|
if (!align)
|
|
|
|
align = 1;
|
|
|
|
|
|
|
|
align2 = AlignTo_Section(section, align);
|
|
|
|
if (offset % align2) {
|
|
|
|
pad = align2 - (offset % align2);
|
|
|
|
for (i = 0; i < pad; i++)
|
|
|
|
AppendGListByte(gl, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
relocID = ObjGen_MakeSectReloc(section);
|
|
|
|
AppendGListData(gl, data, len);
|
|
|
|
return relocID;
|
|
|
|
}
|
|
|
|
|
|
|
|
UInt32 ObjGen_GetSectSize(MachOSection *section) {
|
|
|
|
if (section->glist.data)
|
|
|
|
return section->glist.size;
|
|
|
|
else
|
|
|
|
return section->section.size;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_GetExtName(SInt32 id, char *buf) {
|
|
|
|
switch (RELOC_DATA(id).type) {
|
|
|
|
case RT_0:
|
|
|
|
sprintf(buf, "%s+%08x", RELOC_DATA(id).section->section.sectname, RELOC_DATA(id).x4);
|
|
|
|
break;
|
|
|
|
case RT_1:
|
|
|
|
case RT_2:
|
|
|
|
case RT_3:
|
|
|
|
case RT_4:
|
|
|
|
strcpy(buf, RELOC_DATA(id).name);
|
|
|
|
break;
|
|
|
|
case RT_5:
|
|
|
|
sprintf(buf, "id(%d)", RELOC_DATA(id).x18);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_PicRelocate(MachOSection *section, SInt32 offset, SInt32 relocID, SInt32 picOffset) {
|
|
|
|
Reloc *reloc;
|
|
|
|
|
|
|
|
reloc = galloc(sizeof(Reloc));
|
|
|
|
reloc->section = section;
|
|
|
|
reloc->offset = offset;
|
|
|
|
reloc->relocID = relocID;
|
|
|
|
reloc->relocType = RT_4;
|
|
|
|
reloc->mwRelType = MW_RELOC_0;
|
|
|
|
reloc->picOffset = picOffset;
|
|
|
|
|
|
|
|
reloc->next = NULL;
|
|
|
|
if (FirstReloc == NULL)
|
|
|
|
FirstReloc = reloc;
|
|
|
|
else
|
|
|
|
LastReloc->next = reloc;
|
|
|
|
LastReloc = reloc;
|
|
|
|
}
|
|
|
|
|
|
|
|
SInt32 ObjGen_GetRelocOffset(SInt32 id) {
|
|
|
|
switch (RELOC_DATA(id).type) {
|
|
|
|
case RT_0:
|
|
|
|
break;
|
|
|
|
case RT_1:
|
|
|
|
case RT_2:
|
|
|
|
if (RELOC_DATA(id).x3)
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return RELOC_DATA(id).x4;
|
|
|
|
}
|
|
|
|
|
|
|
|
Boolean ObjGen_IsExternalVar(SInt32 id) {
|
|
|
|
return RELOC_DATA(id).type == RT_3;
|
|
|
|
}
|
|
|
|
|
|
|
|
SInt32 ObjGen_DeclareInit(UInt32 len, char *data, SInt32 align) {
|
|
|
|
SInt32 offset;
|
|
|
|
SInt32 relocID;
|
|
|
|
GList *gl;
|
|
|
|
MachOSection *section;
|
|
|
|
UInt32 align2;
|
|
|
|
SInt32 pad;
|
|
|
|
SInt32 i;
|
|
|
|
|
|
|
|
section = ObjGen_GetSection(SECT_DATA);
|
|
|
|
gl = MachO_GetGList(section);
|
|
|
|
offset = gl->size;
|
|
|
|
if (!align)
|
|
|
|
align = 1;
|
|
|
|
|
|
|
|
align2 = AlignTo_Section(section, align);
|
|
|
|
if (offset % align2) {
|
|
|
|
pad = align2 - (offset % align2);
|
|
|
|
for (i = 0; i < pad; i++)
|
|
|
|
AppendGListByte(gl, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
relocID = ObjGen_MakeSectReloc(section);
|
|
|
|
AppendGListData(gl, data, len);
|
|
|
|
return relocID;
|
|
|
|
}
|
|
|
|
|
|
|
|
static UInt32 pic_stub[] = {
|
|
|
|
0x7C0802A6,
|
|
|
|
0x429F0005,
|
|
|
|
0x7D6802A6,
|
|
|
|
0x7C0803A6,
|
|
|
|
0x3D6B0000,
|
|
|
|
0x818B0000,
|
|
|
|
0x7D8903A6,
|
|
|
|
0x396B0000,
|
|
|
|
0x4E800420,
|
|
|
|
0
|
|
|
|
};
|
|
|
|
static UInt32 abs_stub[] = {
|
|
|
|
0x3D600000,
|
|
|
|
0x818B0000,
|
|
|
|
0x7D8903A6,
|
|
|
|
0x396B0000,
|
|
|
|
0x4E800420,
|
|
|
|
0
|
|
|
|
};
|
|
|
|
|
|
|
|
void CodeGen_GenDynLinkStub(MachOSection *a, MachOSection *b, SInt32 relocID) {
|
|
|
|
SInt32 offset;
|
|
|
|
GList *gl;
|
|
|
|
SInt32 id;
|
|
|
|
|
|
|
|
id = ObjGen_GetHashNodeRelocID(dyld_stub_binding_helper, NULL, 0);
|
|
|
|
|
|
|
|
offset = ObjGen_GetSectSize(a);
|
|
|
|
gl = ObjGen_GetSectionGList(a);
|
|
|
|
|
|
|
|
if (copts.codegen_pic) {
|
|
|
|
UInt32 i;
|
|
|
|
for (i = 0; i < 9; i++)
|
2023-01-13 13:40:30 +00:00
|
|
|
AppendGListLong(gl, CTool_EndianConvertWord32(pic_stub[i]));
|
2022-12-29 12:32:55 +00:00
|
|
|
pic_base_offset = offset + 8;
|
|
|
|
ObjGen_Relocate(a, offset + 16, relocID, RT_4, MW_RELOC_7_HA16);
|
|
|
|
ObjGen_Relocate(a, offset + 20, relocID, RT_4, MW_RELOC_5_LO16);
|
|
|
|
ObjGen_Relocate(a, offset + 28, relocID, RT_4, MW_RELOC_5_LO16);
|
|
|
|
} else {
|
|
|
|
UInt32 i;
|
|
|
|
for (i = 0; i < 5; i++)
|
2023-01-13 13:40:30 +00:00
|
|
|
AppendGListLong(gl, CTool_EndianConvertWord32(abs_stub[i]));
|
2022-12-29 12:32:55 +00:00
|
|
|
ObjGen_Relocate(a, offset, relocID, RT_4, MW_RELOC_7_HA16);
|
|
|
|
ObjGen_Relocate(a, offset + 4, relocID, RT_4, MW_RELOC_5_LO16);
|
|
|
|
ObjGen_Relocate(a, offset + 12, relocID, RT_4, MW_RELOC_5_LO16);
|
|
|
|
}
|
|
|
|
|
|
|
|
offset = ObjGen_GetSectSize(b);
|
|
|
|
gl = ObjGen_GetSectionGList(b);
|
|
|
|
AppendGListLong(gl, 0);
|
|
|
|
|
|
|
|
ObjGen_Relocate(b, offset, id, RT_4, MW_RELOC_0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_DeclarePICBase(Object *object, SInt32 offset) {
|
|
|
|
pic_base_offset = offset + ObjGen_GetRelocOffset(CMangler_GetLinkName(object)->id);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_DeclareEntry(Object *object, SInt32 offset) {
|
|
|
|
RelocDataT r = {0};
|
|
|
|
|
|
|
|
CError_ASSERT(2415, last_function_sect_id != SECT_DEFAULT);
|
|
|
|
|
|
|
|
ObjGen_DeclareSymbol(
|
|
|
|
object,
|
|
|
|
Sections[last_function_sect_id],
|
|
|
|
offset + last_base_offset[last_function_sect_id]);
|
|
|
|
|
|
|
|
r.privFlag = ObjGen_ComputePrivFlag(object->flags);
|
|
|
|
|
|
|
|
updatesectreloc(
|
|
|
|
&r,
|
|
|
|
Sections[last_function_sect_id],
|
|
|
|
offset + last_base_offset[last_function_sect_id]);
|
|
|
|
|
|
|
|
AppendGListData(&RelocData, &r, sizeof(r));
|
|
|
|
CMangler_GetLinkName(object)->id = RelocIndex;
|
|
|
|
RelocIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_DeclareExceptionTables(Object *object, SInt32 codesize, char *data, SInt32 len, OLinkList *refs) {
|
|
|
|
UInt32 offset;
|
|
|
|
MachOSection *section;
|
|
|
|
GList *gl;
|
|
|
|
SInt32 relocID;
|
|
|
|
Boolean flag22;
|
|
|
|
char *buf;
|
|
|
|
char *tmp;
|
|
|
|
|
|
|
|
UInt32 zero;
|
|
|
|
RelocDataT rd;
|
|
|
|
UInt32 stuff[3];
|
|
|
|
|
|
|
|
zero = 0;
|
|
|
|
flag22 = 1;
|
|
|
|
if (CParser_HasInternalLinkage(object))
|
|
|
|
flag22 = 0;
|
|
|
|
|
|
|
|
if (len == 8) {
|
2023-01-14 13:20:48 +00:00
|
|
|
if (CTool_EndianConvertWord16(*((UInt16 *) data) & 8) >> 3) {
|
|
|
|
*((UInt16 *) data) = CTool_EndianConvertWord16(CTool_EndianConvertWord16(*((UInt16 *) data)) & ~8);
|
2022-12-29 12:32:55 +00:00
|
|
|
len = 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len != 4) {
|
|
|
|
section = ObjGen_GetSection(SECT_MW_EX_TABLE);
|
|
|
|
offset = ObjGen_GetSectSize(section);
|
|
|
|
|
|
|
|
memclrw(&rd, sizeof(rd));
|
|
|
|
rd.type = RT_7;
|
|
|
|
rd.x2 = flag22;
|
|
|
|
rd.privFlag = 1;
|
|
|
|
rd.x3 = 1;
|
|
|
|
rd.x4 = offset;
|
|
|
|
rd.section = section;
|
|
|
|
|
|
|
|
tmp = CMangler_GetLinkName(object)->name;
|
|
|
|
buf = galloc(1 + strlen(tmp) + strlen("mwEXTBL@"));
|
|
|
|
sprintf(buf, "mwEXTBL.%s", tmp);
|
|
|
|
rd.name = buf;
|
|
|
|
rd.x18 = -1;
|
|
|
|
|
|
|
|
AppendGListData(&RelocData, &rd, sizeof(rd));
|
|
|
|
RelocIndex++;
|
|
|
|
|
|
|
|
gl = ObjGen_GetSectionGList(section);
|
|
|
|
relocID = ObjGen_MakeSectReloc(section);
|
|
|
|
AppendGListData(gl, data, len);
|
|
|
|
if ((len & 3) != 0)
|
|
|
|
AppendGListData(gl, &zero, 4 - (len & 3));
|
|
|
|
|
|
|
|
while (refs) {
|
|
|
|
ObjGen_RelocateObj(section, offset + refs->offset, refs->obj, MW_RELOC_9);
|
|
|
|
refs = refs->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
section = ObjGen_GetSection(SECT_MW_EX_TABLE_INDEX);
|
|
|
|
gl = ObjGen_GetSectionGList(section);
|
|
|
|
offset = ObjGen_GetSectSize(section);
|
|
|
|
|
|
|
|
memclrw(&rd, sizeof(rd));
|
|
|
|
rd.type = RT_7;
|
|
|
|
rd.x2 = flag22;
|
|
|
|
rd.privFlag = 1;
|
|
|
|
rd.x3 = 1;
|
|
|
|
rd.x4 = offset;
|
|
|
|
rd.section = section;
|
|
|
|
|
|
|
|
tmp = CMangler_GetLinkName(object)->name;
|
|
|
|
buf = galloc(1 + strlen(tmp) + strlen("mwEXTBL@"));
|
|
|
|
sprintf(buf, "mwEXIDX.%s", tmp);
|
|
|
|
rd.name = buf;
|
|
|
|
rd.x18 = -1;
|
|
|
|
|
|
|
|
AppendGListData(&RelocData, &rd, sizeof(rd));
|
|
|
|
RelocIndex++;
|
|
|
|
|
|
|
|
stuff[0] = 0;
|
2023-01-14 13:20:48 +00:00
|
|
|
stuff[1] = CTool_EndianConvertWord32(((len == 4) << 31) | (codesize & 0x7FFFFFFF));
|
|
|
|
stuff[2] = CTool_EndianConvertWord32((len == 4) ? CTool_EndianConvertWord32(*((UInt32 *) data)) : 0);
|
2022-12-29 12:32:55 +00:00
|
|
|
AppendGListData(gl, stuff, sizeof(stuff));
|
|
|
|
|
|
|
|
ObjGen_RelocateObj(section, offset, object, MW_RELOC_9);
|
|
|
|
if (len != 4)
|
|
|
|
ObjGen_Relocate(section, offset + 8, relocID, RT_4, MW_RELOC_9);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_DeclareCodeLabel(Object *labelobj, SInt32 offset, Object *funcobj) {
|
|
|
|
SInt32 relocOffset;
|
|
|
|
GList *gl;
|
|
|
|
MachOSection *section;
|
|
|
|
|
|
|
|
section = ObjGen_GetSection(SECT_DATA);
|
|
|
|
gl = MachO_GetGList(section);
|
|
|
|
relocOffset = ObjGen_GetSectSize(section);
|
|
|
|
|
|
|
|
ObjGen_GetHashNodeRelocID(labelobj, section, 0);
|
|
|
|
AppendGListData(gl, &offset, 4);
|
|
|
|
ObjGen_RelocateObj(section, relocOffset, funcobj, MW_RELOC_9);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_DeclareSwitchTable(Object *tableobj, Object *funcobj) {
|
|
|
|
SInt32 relocOffset;
|
|
|
|
GList *gl;
|
|
|
|
int i;
|
|
|
|
MachOSection *section;
|
|
|
|
|
|
|
|
section = ObjGen_GetSection(SECT_MW_SWITCH);
|
|
|
|
gl = MachO_GetGList(section);
|
|
|
|
relocOffset = ObjGen_GetSectSize(section);
|
|
|
|
|
|
|
|
ObjGen_GetHashNodeRelocID(tableobj, section, 0);
|
|
|
|
AppendGListData(gl, tableobj->u.data.u.switchtable.data, 4 * tableobj->u.data.u.switchtable.size);
|
|
|
|
for (i = tableobj->u.data.u.switchtable.size; i; i--) {
|
|
|
|
ObjGen_RelocateObj(section, relocOffset, funcobj, MW_RELOC_9);
|
|
|
|
relocOffset += 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_DeclareTracebackTable(Object *tableobj, void *data, SInt32 size) {
|
|
|
|
MachOSection *section;
|
|
|
|
GList *gl;
|
|
|
|
|
|
|
|
section = ObjGen_GetSection(SECT_MW_SWITCH);
|
|
|
|
gl = MachO_GetGList(section);
|
|
|
|
|
|
|
|
ObjGen_GetHashNodeRelocID(tableobj, section, 0);
|
|
|
|
if (CMangler_GetLinkName(tableobj)->id < 0) {
|
|
|
|
CMangler_GetLinkName(tableobj)->id = ObjGen_MakeSectReloc(section);
|
|
|
|
} else {
|
|
|
|
RelocDataT *rd = &RELOC_DATA(CMangler_GetLinkName(tableobj)->id);
|
|
|
|
switch (rd->type) {
|
|
|
|
case RT_2:
|
|
|
|
updatesectreloc(rd, section, section->glist.size);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
CError_FATAL(2628);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AppendGListData(gl, data, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_DeclareSymInfo(void) {
|
2023-01-15 12:14:05 +00:00
|
|
|
if (copts.filesyminfo)
|
2022-12-29 12:32:55 +00:00
|
|
|
SymContainedVars();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_Line(UInt32 line, UInt32 offset) {
|
2023-01-15 12:14:05 +00:00
|
|
|
if (copts.filesyminfo && line)
|
2022-12-29 12:32:55 +00:00
|
|
|
GenStab_Line(line, offset + last_base_offset[last_function_sect_id]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_OutputDebugInfo(Object *funcobj) {
|
2023-01-15 12:14:05 +00:00
|
|
|
if (copts.filesyminfo)
|
2022-12-29 12:32:55 +00:00
|
|
|
GenStab_Function(funcobj, CMangler_GetLinkName(funcobj)->id);
|
|
|
|
}
|
|
|
|
|
|
|
|
SInt32 ObjGen_OutputStab(SymbolData *symbol, SInt32 strIdx) {
|
|
|
|
Section sectionID;
|
|
|
|
RelocDataT *rd;
|
|
|
|
|
|
|
|
sectionID = last_function_sect_id;
|
|
|
|
if (sectionID == SECT_DEFAULT)
|
|
|
|
sectionID = SECT_TEXT;
|
|
|
|
|
|
|
|
if (symbol->type == N_FUN) {
|
|
|
|
if (symbol->u.name[0] == 0) {
|
|
|
|
if (Sections[sectionID]) {
|
|
|
|
symbol->section = Sections[sectionID];
|
|
|
|
symbol->value = ObjGen_GetSectSize(Sections[sectionID]);
|
|
|
|
} else {
|
|
|
|
symbol->section = NULL;
|
|
|
|
symbol->value = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
rd = &RELOC_DATA(symbol->value);
|
|
|
|
symbol->section = rd->section;
|
|
|
|
symbol->value = rd->x4;
|
|
|
|
}
|
|
|
|
} else if (symbol->type == N_SLINE) {
|
|
|
|
symbol->u.strx = 0;
|
|
|
|
if (Sections[sectionID])
|
|
|
|
symbol->section = Sections[sectionID];
|
|
|
|
else
|
|
|
|
symbol->section = NULL;
|
|
|
|
} else if (symbol->type == N_STSYM) {
|
|
|
|
rd = &RELOC_DATA(symbol->value);
|
|
|
|
symbol->section = rd->section;
|
|
|
|
symbol->value = rd->x4;
|
|
|
|
if (symbol->section && (symbol->section->section.flags & S_ZEROFILL))
|
|
|
|
symbol->type = N_LCSYM;
|
|
|
|
} else if (symbol->type == N_SO || symbol->type == N_SOL) {
|
|
|
|
if (Sections[sectionID]) {
|
|
|
|
symbol->section = Sections[sectionID];
|
|
|
|
symbol->value = ObjGen_GetSectSize(Sections[sectionID]);
|
|
|
|
} else {
|
|
|
|
symbol->section = NULL;
|
|
|
|
symbol->value = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return MachO_OutputStab(symbol, strIdx);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_SetSectName() {
|
|
|
|
// empty, unknown args
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObjGen_DeclareInitFunction(Object *funcobj) {
|
|
|
|
SInt32 offset;
|
|
|
|
MachOSection *section;
|
|
|
|
GList *gl;
|
|
|
|
|
|
|
|
section = ObjGen_GetSection(SECT_MOD_INIT_FUNC);
|
|
|
|
offset = ObjGen_GetSectSize(section);
|
|
|
|
gl = ObjGen_GetSectionGList(section);
|
|
|
|
AppendGListLong(gl, 0);
|
|
|
|
|
|
|
|
ObjGen_Relocate(section, offset, ObjGen_GetHashNodeRelocID(funcobj, NULL, 0), RT_4, MW_RELOC_0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void SymContainedVars(void) {
|
|
|
|
ObjectList *list;
|
|
|
|
|
|
|
|
for (list = arguments; list; list = list->next) {
|
|
|
|
if (list->object->u.var.info->used && list->object->name->name[0] != '@')
|
|
|
|
GenStab_Parameter(list->object);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (list = locals; list; list = list->next) {
|
|
|
|
if (list->object->u.var.info->used && list->object->name->name[0] != '@')
|
|
|
|
GenStab_Var(list->object);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Boolean ObjGen_IsExported(Object *object) {
|
|
|
|
SInt32 id = ObjGen_GetHashNodeRelocID(object, NULL, -1);
|
|
|
|
if (id >= 0 && RELOC_DATA(id).type == RT_0)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void AppendGListZeros(GList *glist, SInt32 size) {
|
|
|
|
SInt32 pos = glist->size;
|
|
|
|
AppendGListNoData(glist, size);
|
|
|
|
memclr(*glist->data + pos, size);
|
|
|
|
}
|