mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +00:00
cmd/ld: support for relocation variants
Most ppc64 relocations come in six or more variants where the basic relocation formula is the same, but which bits of the computed value are installed where changes. Introduce the concept of "variants" for internal relocations to support this. Since this applies to architecture-independent relocation types like R_PCREL, we do this in relocsym. Currently there is only an identity variant. A later CL that adds support for ppc64 ELF relocations will introduce more. Change-Id: I0c5f0e7dbe5beece79cd24fe36267d37c52f1a0c Reviewed-on: https://go-review.googlesource.com/2005 Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
fcdffb3f33
commit
ac5a1ac318
10 changed files with 49 additions and 0 deletions
|
@ -77,6 +77,7 @@ struct Reloc
|
|||
uchar siz;
|
||||
uchar done;
|
||||
int32 type;
|
||||
int32 variant; // RV_*: variant on computed value
|
||||
int64 add;
|
||||
int64 xadd;
|
||||
LSym* sym;
|
||||
|
@ -257,6 +258,12 @@ enum
|
|||
R_USEFIELD,
|
||||
};
|
||||
|
||||
// Reloc.variant
|
||||
enum
|
||||
{
|
||||
RV_NONE, // identity variant
|
||||
};
|
||||
|
||||
// Auto.type
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -371,6 +371,15 @@ archreloc(Reloc *r, LSym *s, vlong *val)
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -83,6 +83,7 @@ void adddynrel(LSym *s, Reloc *r);
|
|||
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);
|
||||
|
|
|
@ -396,6 +396,15 @@ archreloc(Reloc *r, LSym *s, vlong *val)
|
|||
return -1;
|
||||
}
|
||||
|
||||
vlong
|
||||
archrelocvariant(Reloc *r, LSym *s, vlong t)
|
||||
{
|
||||
USED(r);
|
||||
USED(s);
|
||||
sysfatal("unexpected relocation variant");
|
||||
return t;
|
||||
}
|
||||
|
||||
void
|
||||
elfsetupplt(void)
|
||||
{
|
||||
|
|
|
@ -90,6 +90,7 @@ void adddynrel(LSym *s, Reloc *r);
|
|||
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);
|
||||
|
|
|
@ -364,6 +364,15 @@ archreloc(Reloc *r, LSym *s, vlong *val)
|
|||
return -1;
|
||||
}
|
||||
|
||||
vlong
|
||||
archrelocvariant(Reloc *r, LSym *s, vlong t)
|
||||
{
|
||||
USED(r);
|
||||
USED(s);
|
||||
sysfatal("unexpected relocation variant");
|
||||
return t;
|
||||
}
|
||||
|
||||
void
|
||||
elfsetupplt(void)
|
||||
{
|
||||
|
|
|
@ -74,6 +74,7 @@ void adddynrel(LSym *s, Reloc *r);
|
|||
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);
|
||||
|
|
|
@ -177,6 +177,15 @@ archreloc(Reloc *r, LSym *s, vlong *val)
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -86,6 +86,7 @@ void adddynlib(char *lib);
|
|||
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);
|
||||
|
||||
|
|
|
@ -309,6 +309,8 @@ relocsym(LSym *s)
|
|||
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:
|
||||
|
|
Loading…
Reference in a new issue