summaryrefslogtreecommitdiff
path: root/src/cmd/6l/asm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/6l/asm.c')
-rw-r--r--src/cmd/6l/asm.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c
index e1d114642..de6ea3a63 100644
--- a/src/cmd/6l/asm.c
+++ b/src/cmd/6l/asm.c
@@ -317,6 +317,63 @@ elfreloc1(Reloc *r, vlong sectoff)
}
int
+machoreloc1(Reloc *r, vlong sectoff)
+{
+ uint32 v;
+ Sym *rs;
+
+ rs = r->xsym;
+
+ if(rs->type == SHOSTOBJ) {
+ if(rs->dynid < 0) {
+ diag("reloc %d to non-macho symbol %s type=%d", r->type, rs->name, rs->type);
+ return -1;
+ }
+ v = rs->dynid;
+ v |= 1<<27; // external relocation
+ } else {
+ v = rs->sect->extnum;
+ if(v == 0) {
+ diag("reloc %d to symbol %s in non-macho section %s type=%d", r->type, rs->name, rs->sect->name, rs->type);
+ return -1;
+ }
+ }
+
+ switch(r->type) {
+ default:
+ return -1;
+ case D_ADDR:
+ v |= MACHO_X86_64_RELOC_UNSIGNED<<28;
+ break;
+ case D_PCREL:
+ v |= 1<<24; // pc-relative bit
+ v |= MACHO_X86_64_RELOC_BRANCH<<28;
+ break;
+ }
+
+ switch(r->siz) {
+ default:
+ return -1;
+ case 1:
+ v |= 0<<25;
+ break;
+ case 2:
+ v |= 1<<25;
+ break;
+ case 4:
+ v |= 2<<25;
+ break;
+ case 8:
+ v |= 3<<25;
+ break;
+ }
+
+ LPUT(sectoff);
+ LPUT(v);
+ return 0;
+}
+
+int
archreloc(Reloc *r, Sym *s, vlong *val)
{
USED(r);
@@ -677,6 +734,10 @@ asmb(void)
dwarfemitdebugsections();
break;
+ case Hdarwin:
+ if(isobj)
+ machoemitreloc();
+ break;
}
}