Unified · Split
| @@ -1188,6 +1188,34 @@ ST_FUNC void build_got_entries(TCCState *s1) · 1187 unmodified lines | |||
| 1188 | sym_index); | 1188 | sym_index); |
| 1189 | } | 1189 | } |
| 1190 | break; | 1190 | break; |
| 1191 | case R_ARM_THM_JUMP24: | ||
| 1192 | sym_index = ELFW(R_SYM)(rel->r_info); | ||
| 1193 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; | ||
| 1194 | /* We are relocating a jump from thumb code to arm code */ | ||
| 1195 | if (sym->st_shndx != SHN_UNDEF && !(sym->st_value & 1)) { | ||
| 1196 | int index; | ||
| 1197 | uint8_t *p; | ||
| 1198 | char *name, buf[1024]; | ||
| 1199 | Section *text_section; | ||
| 1200 | |||
| 1201 | name = symtab_section->link->data + sym->st_name; | ||
| 1202 | text_section = s1->sections[sym->st_shndx]; | ||
| 1203 | /* Modify reloc to target a thumb stub to switch to ARM */ | ||
| 1204 | snprintf(buf, sizeof(buf), "%s_from_thumb", name); | ||
| 1205 | index = put_elf_sym(symtab_section, | ||
| 1206 | text_section->data_offset + 1, | ||
| 1207 | sym->st_size, sym->st_info, 0, | ||
| 1208 | sym->st_shndx, buf); | ||
| 1209 | rel->r_info = ELFW(R_INFO)(index, type); | ||
| 1210 | /* Create a thumb stub fonction to switch to ARM mode */ | ||
| 1211 | put_elf_reloc(symtab_section, text_section, | ||
| 1212 | text_section->data_offset, R_ARM_JUMP24, | ||
| 1213 | sym_index); | ||
| 1214 | p = section_ptr_add(text_section, 8); | ||
| 1215 | put32(p, 0x4778); /* bx pc */ | ||
| 1216 | put32(p+2, 0x46c0); /* nop */ | ||
| 1217 | put32(p+4, 0xeafffffe); /* b $sym */ | ||
| 1218 | } | ||
| 1191 | #elif defined(TCC_TARGET_C67) | 1219 | #elif defined(TCC_TARGET_C67) |
| 1192 | case R_C60_GOT32: | 1220 | case R_C60_GOT32: |
| 1193 | case R_C60_GOTOFF: | 1221 | case R_C60_GOTOFF: |