uchar siz;
uchar done;
int32 type;
+ int32 variant; // RV_*: variant on computed value
int64 add;
int64 xadd;
LSym* sym;
R_USEFIELD,
};
+// Reloc.variant
+enum
+{
+ RV_NONE, // identity variant
+};
+
// Auto.type
enum
{
return -1;
}
+vlong
+archrelocvariant(Reloc *r, LSym *s, vlong t)
+{
+ USED(r);
+ USED(s);
+ sysfatal("unexpected relocation variant");
+ return t;
+}
+
static Reloc *
addpltreloc(Link *ctxt, LSym *plt, LSym *got, LSym *sym, int typ)
{
void adddynrela(LSym *rel, LSym *s, Reloc *r);
void adddynsym(Link *ctxt, LSym *s);
int archreloc(Reloc *r, LSym *s, vlong *val);
+vlong archrelocvariant(Reloc *r, LSym *s, vlong t);
void asmb(void);
int elfreloc1(Reloc *r, vlong sectoff);
void elfsetupplt(void);
return -1;
}
+vlong
+archrelocvariant(Reloc *r, LSym *s, vlong t)
+{
+ USED(r);
+ USED(s);
+ sysfatal("unexpected relocation variant");
+ return t;
+}
+
void
elfsetupplt(void)
{
void adddynrela(LSym *rela, LSym *s, Reloc *r);
void adddynsym(Link *ctxt, LSym *s);
int archreloc(Reloc *r, LSym *s, vlong *val);
+vlong archrelocvariant(Reloc *r, LSym *s, vlong t);
void asmb(void);
int elfreloc1(Reloc *r, vlong sectoff);
void elfsetupplt(void);
return -1;
}
+vlong
+archrelocvariant(Reloc *r, LSym *s, vlong t)
+{
+ USED(r);
+ USED(s);
+ sysfatal("unexpected relocation variant");
+ return t;
+}
+
void
elfsetupplt(void)
{
void adddynrela(LSym *rela, LSym *s, Reloc *r);
void adddynsym(Link *ctxt, LSym *s);
int archreloc(Reloc *r, LSym *s, vlong *val);
+vlong archrelocvariant(Reloc *r, LSym *s, vlong t);
void asmb(void);
int elfreloc1(Reloc *r, vlong sectoff);
void elfsetupplt(void);
return -1;
}
+vlong
+archrelocvariant(Reloc *r, LSym *s, vlong t)
+{
+ USED(r);
+ USED(s);
+ sysfatal("unexpected relocation variant");
+ return t;
+}
+
void
adddynsym(Link *ctxt, LSym *s)
{
void adddynrel(LSym *s, Reloc *r);
void adddynsym(Link *ctxt, LSym *s);
int archreloc(Reloc *r, LSym *s, vlong *val);
+vlong archrelocvariant(Reloc *r, LSym *s, vlong t);
void listinit(void);
vlong rnd(vlong, int32);
o = r->sym->size + r->add;
break;
}
+ if(r->variant != RV_NONE)
+ o = archrelocvariant(r, s, o);
//print("relocate %s %#llux (%#llux+%#llux, size %d) => %s %#llux +%#llx [%llx]\n", s->name, (uvlong)(s->value+off), (uvlong)s->value, (uvlong)r->off, r->siz, r->sym ? r->sym->name : "<nil>", (uvlong)symaddr(r->sym), (vlong)r->add, (vlong)o);
switch(siz) {
default: