| @@ -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: |