]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/ld, cmd/5l: support R_ARM_PC24 and R_ARM_JUMP24, fix R_ARM_CALL
authorShenghou Ma <minux.ma@gmail.com>
Sun, 7 Oct 2012 20:20:17 +0000 (04:20 +0800)
committerShenghou Ma <minux.ma@gmail.com>
Sun, 7 Oct 2012 20:20:17 +0000 (04:20 +0800)
1. R_ARM_CALL can also be used to call a PLT entry
2. add support for R_ARM_PC24 and R_ARM_JUMP24
3. refactor, remove D_PLT32 in favor of D_CALL

Fixes #4006.

R=rsc, dave
CC=fullung, golang-dev
https://golang.org/cl/6622057

src/cmd/5l/5.out.h
src/cmd/5l/asm.c
src/cmd/ld/elf.h
src/cmd/ld/ldelf.c

index 23ff6210e30928d1be9420f631e0d03bf26c2818..b9b05257015f203548fb921a7ed24c860a26582d 100644 (file)
@@ -270,8 +270,7 @@ enum        as
 #define        D_PLT0          (D_NONE+43) // R_ARM_PLT32, 1st inst: add ip, pc, #0xNN00000
 #define        D_PLT1          (D_NONE+44) // R_ARM_PLT32, 2nd inst: add ip, ip, #0xNN000
 #define        D_PLT2          (D_NONE+45) // R_ARM_PLT32, 3rd inst: ldr pc, [ip, #0xNNN]!
-#define        D_PLT32         (D_NONE+46) // R_ARM_PLT32, bl xxxxx
-#define        D_CALL          (D_NONE+47) // R_ARM_CALL, bl xxxxx
+#define        D_CALL          (D_NONE+46) // R_ARM_PLT32/R_ARM_CALL/R_ARM_JUMP24, bl xxxxx or b yyyyy
 
 /*
  * this is the ranlib header
index b265a15cdb440c21e5700c95515dcfeb1db5ce96..51a2809676af13ea6de9ce75516d30b513ca7958 100644 (file)
@@ -137,7 +137,7 @@ adddynrel(Sym *s, Reloc *r)
 
        // Handle relocations found in ELF object files.
        case 256 + R_ARM_PLT32:
-               r->type = D_PLT32;
+               r->type = D_CALL;
                if(targ->dynimpname != nil && !targ->dynexport) {
                        addpltsym(targ);
                        r->sym = lookup(".plt", 0);
@@ -184,7 +184,11 @@ adddynrel(Sym *s, Reloc *r)
 
        case 256 + R_ARM_CALL:
                r->type = D_CALL;
-               r->add += 0;
+               if(targ->dynimpname != nil && !targ->dynexport) {
+                       addpltsym(targ);
+                       r->sym = lookup(".plt", 0);
+                       r->add = braddoff(r->add, targ->plt / 4);
+               }
                return;
 
        case 256 + R_ARM_REL32: // R_ARM_REL32
@@ -206,6 +210,16 @@ adddynrel(Sym *s, Reloc *r)
                }
                r->sym = S;
                return;
+
+       case 256 + R_ARM_PC24:
+       case 256 + R_ARM_JUMP24:
+               r->type = D_CALL;
+               if(targ->dynimpname != nil && !targ->dynexport) {
+                       addpltsym(targ);
+                       r->sym = lookup(".plt", 0);
+                       r->add = braddoff(r->add, targ->plt / 4);
+               }
+               return;
        }
        
        // Handle references to ELF symbols from our own object files.
@@ -290,21 +304,19 @@ archreloc(Reloc *r, Sym *s, vlong *val)
                *val = 0xe5bcf000U +
                        (0xfff & (uint32)(symaddr(r->sym) - (symaddr(lookup(".plt", 0)) + r->off) + r->add + 8));
                return 0;
-       case D_PLT32: // bl XXXXXX or b YYYYYY in R_ARM_PLT32
-               *val = (0xff000000U & (uint32)r->add) +
-                       (0xffffff & (uint32)((symaddr(r->sym) + (0xffffffU & (uint32)r->add) * 4) - (s->value + r->off)) / 4);
-               return 0;
-       case D_CALL: // bl XXXXXX
-               *val = braddoff(0xeb000000U, (0xffffff & (uint32)((symaddr(r->sym) + ((uint32)r->add) * 4 - (s->value + r->off)) / 4)));
-               return 0;
-       }
-       return -1;
+       case D_CALL: // bl XXXXXX or b YYYYYY
+               *val = braddoff((0xff000000U & (uint32)r->add), 
+                               (0xffffff & (uint32)
+                                  ((symaddr(r->sym) + ((uint32)r->add) * 4 - (s->value + r->off)) / 4)));
+       return 0;
+}
+return -1;
 }
 
 static Reloc *
 addpltreloc(Sym *plt, Sym *got, Sym *sym, int typ)
 {
-       Reloc *r;
+Reloc *r;
        r = addrel(plt);
        r->sym = got;
        r->off = plt->size;
index 8568548a91b3492704f32fe20e01a4090a48bcf2..f5d0713e48c2577519ed1859d1b0a87a20e242ce 100644 (file)
@@ -564,6 +564,7 @@ typedef struct {
 #define        R_ARM_GOT32             26      /* Add PC-relative GOT offset. */
 #define        R_ARM_PLT32             27      /* Add PC-relative PLT offset. */
 #define        R_ARM_CALL              28
+#define        R_ARM_JUMP24    29
 #define        R_ARM_V4BX              40
 #define        R_ARM_GOT_PREL          96
 #define        R_ARM_GNU_VTENTRY       100
@@ -575,7 +576,7 @@ typedef struct {
 #define        R_ARM_RPC24             254
 #define        R_ARM_RBASE             255
 
-#define        R_ARM_COUNT             33      /* Count of defined relocation types. */
+#define        R_ARM_COUNT             37      /* Count of defined relocation types. */
 
 
 #define        R_386_NONE      0       /* No relocation. */
index 01f66464a2ed607e69fea8ff1a87c5450d47aeb2..e0f989c065aaf15c8ed9c8b0edb0f0f3fd733968 100644 (file)
@@ -852,6 +852,8 @@ reltype(char *pn, int elftype, uchar *siz)
        case R('5', R_ARM_CALL):
        case R('5', R_ARM_V4BX):
        case R('5', R_ARM_GOT_PREL):
+       case R('5', R_ARM_PC24):
+       case R('5', R_ARM_JUMP24):
        case R('6', R_X86_64_PC32):
        case R('6', R_X86_64_PLT32):
        case R('6', R_X86_64_GOTPCREL):