diff options
Diffstat (limited to 'src/cmd/6l/asm.c')
-rw-r--r-- | src/cmd/6l/asm.c | 61 |
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; } } |