History

fixed linker symbol generation - output format support

bellard committed 22 years ago

Commit 38e8a231 parent bb07bf31 file · +141 −90Browse files

Unified · Split

tccelf.c+141−90
@@ -955,8 +955,6 @@ static void add_init_array_defines(TCCState *s1, const char *section_name) · 954 unmodified lines
955static void tcc_add_runtime(TCCState *s1)955static void tcc_add_runtime(TCCState *s1)
956{956{
957 char buf[1024];957 char buf[1024];
958 int i;
959 Section *s;
960 958
961 if (!s1->nostdlib) {959 if (!s1->nostdlib) {
962 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");960 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
@@ -1000,7 +998,17 @@ static void tcc_add_runtime(TCCState *s1) · 37 unmodified lines
1000 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {998 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1001 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");999 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1002 }1000 }
1003 /* add various standard linker symbols */1001}
1002
1003/* add various standard linker symbols (must be done after the
1004 sections are filled (for example after allocating common
1005 symbols)) */
1006static void tcc_add_linker_symbols(TCCState *s1)
1007{
1008 char buf[1024];
1009 int i;
1010 Section *s;
1011
1004 add_elf_sym(symtab_section, 1012 add_elf_sym(symtab_section,
1005 text_section->data_offset, 0,1013 text_section->data_offset, 0,
1006 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),1014 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
@@ -1059,6 +1067,28 @@ static char elf_interp[] = "/usr/libexec/ld-elf.so.1"; · 52 unmodified lines
1059static char elf_interp[] = "/lib/ld-linux.so.2";1067static char elf_interp[] = "/lib/ld-linux.so.2";
1060#endif1068#endif
1061 1069
1070static void tcc_output_binary(TCCState *s1, FILE *f,
1071 const int *section_order)
1072{
1073 Section *s;
1074 int i, offset, size;
1075
1076 offset = 0;
1077 for(i=1;i<s1->nb_sections;i++) {
1078 s = s1->sections[section_order[i]];
1079 if (s->sh_type != SHT_NOBITS &&
1080 (s->sh_flags & SHF_ALLOC)) {
1081 while (offset < s->sh_offset) {
1082 fputc(0, f);
1083 offset++;
1084 }
1085 size = s->sh_size;
1086 fwrite(s->data, 1, size, f);
1087 offset += size;
1088 }
1089 }
1090}
1091
1062/* output an ELF file */1092/* output an ELF file */
1063/* XXX: suppress unneeded sections */1093/* XXX: suppress unneeded sections */
1064int tcc_output_file(TCCState *s1, const char *filename)1094int tcc_output_file(TCCState *s1, const char *filename)
@@ -1082,8 +1112,6 @@ int tcc_output_file(TCCState *s1, const char *filename) · 17 unmodified lines
1082 s1->nb_errors = 0;1112 s1->nb_errors = 0;
1083 1113
1084 if (file_type != TCC_OUTPUT_OBJ) {1114 if (file_type != TCC_OUTPUT_OBJ) {
1085 relocate_common_syms();
1086
1087 tcc_add_runtime(s1);1115 tcc_add_runtime(s1);
1088 }1116 }
1089 1117
@@ -1095,6 +1123,9 @@ int tcc_output_file(TCCState *s1, const char *filename) · 5 unmodified lines
1095 saved_dynamic_data_offset = 0; /* avoid warning */1123 saved_dynamic_data_offset = 0; /* avoid warning */
1096 1124
1097 if (file_type != TCC_OUTPUT_OBJ) {1125 if (file_type != TCC_OUTPUT_OBJ) {
1126 relocate_common_syms();
1127
1128 tcc_add_linker_symbols(s1);
1098 1129
1099 if (!s1->static_link) {1130 if (!s1->static_link) {
1100 const char *name;1131 const char *name;
@@ -1310,7 +1341,11 @@ int tcc_output_file(TCCState *s1, const char *filename) · 209 unmodified lines
1310 /* allocate program segment headers */1341 /* allocate program segment headers */
1311 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));1342 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1312 1343
1313 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);1344 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1345 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1346 } else {
1347 file_offset = 0;
1348 }
1314 if (phnum > 0) {1349 if (phnum > 0) {
1315 /* compute section to program header mapping */1350 /* compute section to program header mapping */
1316 if (s1->has_text_addr) { 1351 if (s1->has_text_addr) {
@@ -1413,10 +1448,18 @@ int tcc_output_file(TCCState *s1, const char *filename) · 96 unmodified lines
1413 ph->p_filesz = file_offset - ph->p_offset;1448 ph->p_filesz = file_offset - ph->p_offset;
1414 ph->p_memsz = addr - ph->p_vaddr;1449 ph->p_memsz = addr - ph->p_vaddr;
1415 ph++;1450 ph++;
1416 /* if in the middle of a page, we duplicate the page in1451 if (j == 0) {
1417 memory so that one copy is RX and the other is RW */1452 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1418 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)1453 /* if in the middle of a page, we duplicate the page in
1419 addr += ELF_PAGE_SIZE;1454 memory so that one copy is RX and the other is RW */
1455 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1456 addr += ELF_PAGE_SIZE;
1457 } else {
1458 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1459 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1460 ~(ELF_PAGE_SIZE - 1);
1461 }
1462 }
1420 }1463 }
1421 1464
1422 /* if interpreter, then add corresponing program header */1465 /* if interpreter, then add corresponing program header */
@@ -1566,103 +1609,111 @@ int tcc_output_file(TCCState *s1, const char *filename) · 143 unmodified lines
1566 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */1609 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1567 }1610 }
1568 1611
1569#ifdef TCC_TARGET_COFF
1570 ret = tcc_output_coff(s1, filename);
1571#else
1572 sort_syms(s1, symtab_section);
1573
1574 /* align to 4 */
1575 file_offset = (file_offset + 3) & -4;
1576
1577 /* fill header */
1578 ehdr.e_ident[0] = ELFMAG0;
1579 ehdr.e_ident[1] = ELFMAG1;
1580 ehdr.e_ident[2] = ELFMAG2;
1581 ehdr.e_ident[3] = ELFMAG3;
1582 ehdr.e_ident[4] = ELFCLASS32;
1583 ehdr.e_ident[5] = ELFDATA2LSB;
1584 ehdr.e_ident[6] = EV_CURRENT;
1585#ifdef __FreeBSD__
1586 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1587#endif
1588#ifdef TCC_TARGET_ARM
1589 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1590#endif
1591 switch(file_type) {
1592 default:
1593 case TCC_OUTPUT_EXE:
1594 ehdr.e_type = ET_EXEC;
1595 break;
1596 case TCC_OUTPUT_DLL:
1597 ehdr.e_type = ET_DYN;
1598 break;
1599 case TCC_OUTPUT_OBJ:
1600 ehdr.e_type = ET_REL;
1601 break;
1602 }
1603 ehdr.e_machine = EM_TCC_TARGET;
1604 ehdr.e_version = EV_CURRENT;
1605 ehdr.e_shoff = file_offset;
1606 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1607 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1608 ehdr.e_shnum = shnum;
1609 ehdr.e_shstrndx = shnum - 1;
1610
1611 /* write elf file */1612 /* write elf file */
1612 if (file_type == TCC_OUTPUT_OBJ)1613 if (file_type == TCC_OUTPUT_OBJ)
1613 mode = 0666;1614 mode = 0666;
1614 else1615 else
1615 mode = 0777;1616 mode = 0777;
1616 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode); 1617 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1617 if (fd < 0) {1618 if (fd < 0) {
1618 error_noabort("could not write '%s'", filename);1619 error_noabort("could not write '%s'", filename);
1619 goto fail;1620 goto fail;
1620 }1621 }
1621 f = fdopen(fd, "w");1622 f = fdopen(fd, "wb");
1622 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);1623
1623 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);1624#ifdef TCC_TARGET_COFF
1624 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);1625 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1625 for(i=1;i<s1->nb_sections;i++) {1626 tcc_output_coff(s1, f);
1626 s = s1->sections[section_order[i]];1627 } else
1627 if (s->sh_type != SHT_NOBITS) {1628#endif
1628 while (offset < s->sh_offset) {1629 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1629 fputc(0, f);1630 sort_syms(s1, symtab_section);
1630 offset++;1631
1632 /* align to 4 */
1633 file_offset = (file_offset + 3) & -4;
1634
1635 /* fill header */
1636 ehdr.e_ident[0] = ELFMAG0;
1637 ehdr.e_ident[1] = ELFMAG1;
1638 ehdr.e_ident[2] = ELFMAG2;
1639 ehdr.e_ident[3] = ELFMAG3;
1640 ehdr.e_ident[4] = ELFCLASS32;
1641 ehdr.e_ident[5] = ELFDATA2LSB;
1642 ehdr.e_ident[6] = EV_CURRENT;
1643#ifdef __FreeBSD__
1644 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1645#endif
1646#ifdef TCC_TARGET_ARM
1647 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1648#endif
1649 switch(file_type) {
1650 default:
1651 case TCC_OUTPUT_EXE:
1652 ehdr.e_type = ET_EXEC;
1653 break;
1654 case TCC_OUTPUT_DLL:
1655 ehdr.e_type = ET_DYN;
1656 break;
1657 case TCC_OUTPUT_OBJ:
1658 ehdr.e_type = ET_REL;
1659 break;
1660 }
1661 ehdr.e_machine = EM_TCC_TARGET;
1662 ehdr.e_version = EV_CURRENT;
1663 ehdr.e_shoff = file_offset;
1664 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1665 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1666 ehdr.e_shnum = shnum;
1667 ehdr.e_shstrndx = shnum - 1;
1668
1669 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1670 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1671 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1672
1673 for(i=1;i<s1->nb_sections;i++) {
1674 s = s1->sections[section_order[i]];
1675 if (s->sh_type != SHT_NOBITS) {
1676 while (offset < s->sh_offset) {
1677 fputc(0, f);
1678 offset++;
1679 }
1680 size = s->sh_size;
1681 fwrite(s->data, 1, size, f);
1682 offset += size;
1631 }1683 }
1632 size = s->sh_size;
1633 fwrite(s->data, 1, size, f);
1634 offset += size;
1635 }1684 }
1636 }1685
1637 while (offset < ehdr.e_shoff) {1686 /* output section headers */
1638 fputc(0, f);1687 while (offset < ehdr.e_shoff) {
1639 offset++;1688 fputc(0, f);
1640 }1689 offset++;
1690 }
1641 1691
1642 /* output section headers */1692 for(i=0;i<s1->nb_sections;i++) {
1643 for(i=0;i<s1->nb_sections;i++) {1693 sh = &shdr;
1644 sh = &shdr;1694 memset(sh, 0, sizeof(Elf32_Shdr));
1645 memset(sh, 0, sizeof(Elf32_Shdr));1695 s = s1->sections[i];
1646 s = s1->sections[i];1696 if (s) {
1647 if (s) {1697 sh->sh_name = s->sh_name;
1648 sh->sh_name = s->sh_name;1698 sh->sh_type = s->sh_type;
1649 sh->sh_type = s->sh_type;1699 sh->sh_flags = s->sh_flags;
1650 sh->sh_flags = s->sh_flags;1700 sh->sh_entsize = s->sh_entsize;
1651 sh->sh_entsize = s->sh_entsize;1701 sh->sh_info = s->sh_info;
1652 sh->sh_info = s->sh_info;1702 if (s->link)
1653 if (s->link)1703 sh->sh_link = s->link->sh_num;
1654 sh->sh_link = s->link->sh_num;1704 sh->sh_addralign = s->sh_addralign;
1655 sh->sh_addralign = s->sh_addralign;1705 sh->sh_addr = s->sh_addr;
1656 sh->sh_addr = s->sh_addr;1706 sh->sh_offset = s->sh_offset;
1657 sh->sh_offset = s->sh_offset;1707 sh->sh_size = s->sh_size;
1658 sh->sh_size = s->sh_size;1708 }
1709 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1659 }1710 }
1660 fwrite(sh, 1, sizeof(Elf32_Shdr), f);1711 } else {
1712 tcc_output_binary(s1, f, section_order);
1661 }1713 }
1662 fclose(f);1714 fclose(f);
1663 1715
1664 ret = 0;1716 ret = 0;
1665#endif
1666 the_end:1717 the_end:
1667 tcc_free(s1->symtab_to_dynsym);1718 tcc_free(s1->symtab_to_dynsym);
1668 tcc_free(section_order);1719 tcc_free(section_order);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t