]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/ld: support for relocation variants
authorAustin Clements <austin@google.com>
Mon, 22 Dec 2014 19:42:37 +0000 (14:42 -0500)
committerAustin Clements <austin@google.com>
Wed, 7 Jan 2015 20:35:37 +0000 (20:35 +0000)
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>
include/link.h
src/cmd/5l/asm.c
src/cmd/5l/l.h
src/cmd/6l/asm.c
src/cmd/6l/l.h
src/cmd/8l/asm.c
src/cmd/8l/l.h
src/cmd/9l/asm.c
src/cmd/9l/l.h
src/cmd/ld/data.c

index 190df7f373755250d720b3d314dfae93c946cdba..bc163d6e4be674089de73d9d74ae6516d8076d73 100644 (file)
@@ -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
 {
index c95e43bcc0136dda2cdd06d74025cc387bb4a30b..59930791262c4fedfd45784ce6ffac11d8738f4a 100644 (file)
@@ -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)
 {
index c881a544af952cae5e1f0bff20a8bcb761f3640b..f9cdc5bd7e132c714cbee4527a81adb4cbacc01a 100644 (file)
@@ -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);
index 20be4d6dbcd4413af4bf8f751720cec15e3526d3..032c1eea09205ff626a507e97a50acd78b7fbbfa 100644 (file)
@@ -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)
 {
index ff2e69452e60dcb5c66a95fc541d054de91f0b5d..24eaa453ddb71f3b6cdd690e349112459be1428f 100644 (file)
@@ -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);
index ff4911b88af0b4b0257a9377be6cc0ee9d2cfe4d..44d1ecc0356e476d358b11db6f5cee242a01cec6 100644 (file)
@@ -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)
 {
index 70d3a4bb4f893ef7e3bb699bca8423132488f6aa..3c84d1b21ffdcd0ab01fcf234a2daa5b0e1c2f16 100644 (file)
@@ -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);
index 936cf8723ea869781a7dee2490fda3c28c0c6ac6..00651d5714edbaa44cca6b02d03bba550acb26c9 100644 (file)
@@ -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)
 {
index dda741c56b4c8c1ea88cb263213a9325056691ea..9d8a4fae2c5720dbc95b8f2ec9ff201d733b6ff0 100644 (file)
@@ -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);
 
index 3cf0bbdfe19118fd1f633466c7b9514d2d2d350e..48e8a5886637d7dcaea9056c6bafdca86b762f33 100644 (file)
@@ -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: