| @@ -1365,6 +1365,48 @@ void patch_dynsym_undef(TCCState *s1, Section *s) · 1364 unmodified lines |
| 1365 | #define EXTRA_RELITEMS 9 | 1365 | #define EXTRA_RELITEMS 9 |
| 1366 | #endif | 1366 | #endif |
| 1367 | | 1367 | |
| | 1368 | ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel) |
| | 1369 | { |
| | 1370 | int sym_index = ELFW(R_SYM) (rel->r_info); |
| | 1371 | ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index]; |
| | 1372 | unsigned long offset; |
| | 1373 | |
| | 1374 | if (sym_index >= s1->nb_got_offsets) |
| | 1375 | return; |
| | 1376 | offset = s1->got_offsets[sym_index]; |
| | 1377 | section_reserve(s1->got, offset + PTR_SIZE); |
| | 1378 | /* only works for x86-64 */ |
| | 1379 | put32(s1->got->data + offset, sym->st_value >> 32); |
| | 1380 | put32(s1->got->data + offset, sym->st_value & 0xffffffff); |
| | 1381 | } |
| | 1382 | |
| | 1383 | ST_FUNC void fill_got(TCCState *s1) |
| | 1384 | { |
| | 1385 | Section *s; |
| | 1386 | ElfW_Rel *rel, *rel_end; |
| | 1387 | int i; |
| | 1388 | |
| | 1389 | for(i = 1; i < s1->nb_sections; i++) { |
| | 1390 | s = s1->sections[i]; |
| | 1391 | if (s->sh_type != SHT_RELX) |
| | 1392 | continue; |
| | 1393 | /* no need to handle got relocations */ |
| | 1394 | if (s->link != symtab_section) |
| | 1395 | continue; |
| | 1396 | rel_end = (ElfW_Rel *) (s->data + s->data_offset); |
| | 1397 | for(rel = (ElfW_Rel *) s->data; rel < rel_end; rel++) { |
| | 1398 | switch (ELFW(R_TYPE) (rel->r_info)) { |
| | 1399 | case R_X86_64_GOT32: |
| | 1400 | case R_X86_64_GOTPCREL: |
| | 1401 | case R_X86_64_PLT32: |
| | 1402 | fill_got_entry(s1, rel); |
| | 1403 | break; |
| | 1404 | } |
| | 1405 | } |
| | 1406 | } |
| | 1407 | } |
| | 1408 | |
| | 1409 | |
| 1368 | /* output an ELF file */ | 1410 | /* output an ELF file */ |
| 1369 | /* XXX: suppress unneeded sections */ | 1411 | /* XXX: suppress unneeded sections */ |
| 1370 | static int elf_output_file(TCCState *s1, const char *filename) | 1412 | static int elf_output_file(TCCState *s1, const char *filename) |
| @@ -1985,6 +2027,8 @@ static int elf_output_file(TCCState *s1, const char *filename) · 614 unmodified lines |
| 1985 | else | 2027 | else |
| 1986 | ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */ | 2028 | ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */ |
| 1987 | } | 2029 | } |
| | 2030 | if (file_type == TCC_OUTPUT_EXE && s1->static_link) |
| | 2031 | fill_got(s1); |
| 1988 | | 2032 | |
| 1989 | /* write elf file */ | 2033 | /* write elf file */ |
| 1990 | if (file_type == TCC_OUTPUT_OBJ) | 2034 | if (file_type == TCC_OUTPUT_OBJ) |