From: Shenghou Ma Date: Sun, 7 Oct 2012 20:20:17 +0000 (+0800) Subject: cmd/ld, cmd/5l: support R_ARM_PC24 and R_ARM_JUMP24, fix R_ARM_CALL X-Git-Tag: go1.1rc2~2208 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=65b782e951e21e6e9293547d73f1e839cec2dc82;p=gostls13.git cmd/ld, cmd/5l: support R_ARM_PC24 and R_ARM_JUMP24, fix R_ARM_CALL 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 --- diff --git a/src/cmd/5l/5.out.h b/src/cmd/5l/5.out.h index 23ff6210e3..b9b0525701 100644 --- a/src/cmd/5l/5.out.h +++ b/src/cmd/5l/5.out.h @@ -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 diff --git a/src/cmd/5l/asm.c b/src/cmd/5l/asm.c index b265a15cdb..51a2809676 100644 --- a/src/cmd/5l/asm.c +++ b/src/cmd/5l/asm.c @@ -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; diff --git a/src/cmd/ld/elf.h b/src/cmd/ld/elf.h index 8568548a91..f5d0713e48 100644 --- a/src/cmd/ld/elf.h +++ b/src/cmd/ld/elf.h @@ -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. */ diff --git a/src/cmd/ld/ldelf.c b/src/cmd/ld/ldelf.c index 01f66464a2..e0f989c065 100644 --- a/src/cmd/ld/ldelf.c +++ b/src/cmd/ld/ldelf.c @@ -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):