| @@ -1365,6 +1365,48 @@ void patch_dynsym_undef(TCCState *s1, Section *s) · 1364 unmodified lines |
| 1365 | 1365 | #define EXTRA_RELITEMS 9 |
| 1366 | 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 | 1410 | /* output an ELF file */ |
| 1369 | 1411 | /* XXX: suppress unneeded sections */ |
| 1370 | 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 | 2027 | else |
| 1986 | 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 | 2033 | /* write elf file */ |
| 1990 | 2034 | if (file_type == TCC_OUTPUT_OBJ) |