diff -rud clean/elf.h tinycc/elf.h --- clean/elf.h Wed Dec 6 15:42:37 2006 +++ tinycc/elf.h Wed Dec 6 15:41:17 2006 @@ -1589,9 +1589,9 @@ #define R_ARM_GLOB_DAT 21 /* Create GOT entry */ #define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ #define R_ARM_RELATIVE 23 /* Adjust by program base */ -#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ -#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ -#define R_ARM_GOT32 26 /* 32 bit GOT entry */ +#define R_ARM_GOTOFF32 24 /* 32 bit offset to GOT */ +#define R_ARM_BASE_PREL 25 /* 32 bit PC relative offset to section */ +#define R_ARM_GOT_BREL 26 /* 32 bit GOT entry */ #define R_ARM_PLT32 27 /* 32 bit PLT address */ #define R_ARM_GNU_VTENTRY 100 #define R_ARM_GNU_VTINHERIT 101 diff -rud clean/tccelf.c tinycc/tccelf.c --- clean/tccelf.c Wed Dec 6 15:42:37 2006 +++ tinycc/tccelf.c Wed Dec 6 15:54:47 2006 @@ -514,6 +514,12 @@ *(int *)ptr += s1->got_offsets[sym_index]; break; #elif defined(TCC_TARGET_ARM) +/* "ELF for the ARM Architecture" notation: + S = val A = *ptr P = addr + T = 0, no Thumb support in TCC + B(S) = s1->sections[sym->st_shndx]->sh_addr + GOT_ORG = s1->got->sh_addr + GOT(S) = s1->got->sh_addr + s1->got_offsets[sym_index] */ case R_ARM_PC24: case R_ARM_PLT32: { @@ -534,10 +540,16 @@ case R_ARM_ABS32: *(int *)ptr += val; break; - case R_ARM_GOTPC: - *(int *)ptr += s1->got->sh_addr - addr; + case R_ARM_GOTOFF32: + *(int *)ptr += val - s1->got->sh_addr; break; - case R_ARM_GOT32: + case R_ARM_BASE_PREL: /* previously called R_ARM_GOTPC */ + if(sym_index == STN_UNDEF) + *(int *)ptr += s1->got->sh_addr - addr; + else + *(int *)ptr += s1->sections[sym->st_shndx]->sh_addr - addr; + break; + case R_ARM_GOT_BREL: /* previously called R_ARM_GOT32 */ /* we load the got offset */ *(int *)ptr += s1->got_offsets[sym_index]; break; @@ -839,17 +851,17 @@ } break; #elif defined(TCC_TARGET_ARM) - case R_ARM_GOT32: - case R_ARM_GOTOFF: - case R_ARM_GOTPC: + case R_ARM_GOT_BREL: + case R_ARM_GOTOFF32: + case R_ARM_BASE_PREL: case R_ARM_PLT32: if (!s1->got) build_got(s1); - if (type == R_ARM_GOT32 || type == R_ARM_PLT32) { + if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) { sym_index = ELF32_R_SYM(rel->r_info); sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; /* look at the symbol got offset. If none, then add one */ - if (type == R_ARM_GOT32) + if (type == R_ARM_GOT_BREL) reloc_type = R_ARM_GLOB_DAT; else reloc_type = R_ARM_JUMP_SLOT;