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
955955 static void tcc_add_runtime(TCCState *s1)
956956 {
957957 char buf[1024];
958− int i;
959− Section *s;
960958
961959 if (!s1->nostdlib) {
962960 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
1000998 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1001999 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
10021000 }
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)) */
1006+static void tcc_add_linker_symbols(TCCState *s1)
1007+{
1008+ char buf[1024];
1009+ int i;
1010+ Section *s;
1011+
10041012 add_elf_sym(symtab_section,
10051013 text_section->data_offset, 0,
10061014 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
@@ -1059,6 +1067,28 @@ static char elf_interp[] = "/usr/libexec/ld-elf.so.1"; · 52 unmodified lines
10591067 static char elf_interp[] = "/lib/ld-linux.so.2";
10601068 #endif
10611069
1070+static 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+
10621092 /* output an ELF file */
10631093 /* XXX: suppress unneeded sections */
10641094 int tcc_output_file(TCCState *s1, const char *filename)
@@ -1082,8 +1112,6 @@ int tcc_output_file(TCCState *s1, const char *filename) · 17 unmodified lines
10821112 s1->nb_errors = 0;
10831113
10841114 if (file_type != TCC_OUTPUT_OBJ) {
1085− relocate_common_syms();
1086−
10871115 tcc_add_runtime(s1);
10881116 }
10891117
@@ -1095,6 +1123,9 @@ int tcc_output_file(TCCState *s1, const char *filename) · 5 unmodified lines
10951123 saved_dynamic_data_offset = 0; /* avoid warning */
10961124
10971125 if (file_type != TCC_OUTPUT_OBJ) {
1126+ relocate_common_syms();
1127+
1128+ tcc_add_linker_symbols(s1);
10981129
10991130 if (!s1->static_link) {
11001131 const char *name;
@@ -1310,7 +1341,11 @@ int tcc_output_file(TCCState *s1, const char *filename) · 209 unmodified lines
13101341 /* allocate program segment headers */
13111342 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
13121343
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+ }
13141349 if (phnum > 0) {
13151350 /* compute section to program header mapping */
13161351 if (s1->has_text_addr) {
@@ -1413,10 +1448,18 @@ int tcc_output_file(TCCState *s1, const char *filename) · 96 unmodified lines
14131448 ph->p_filesz = file_offset - ph->p_offset;
14141449 ph->p_memsz = addr - ph->p_vaddr;
14151450 ph++;
1416− /* if in the middle of a page, we duplicate the page in
1417− memory so that one copy is RX and the other is RW */
1418− if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1419− addr += ELF_PAGE_SIZE;
1451+ if (j == 0) {
1452+ if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1453+ /* if in the middle of a page, we duplicate the page in
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+ }
14201463 }
14211464
14221465 /* if interpreter, then add corresponing program header */
@@ -1566,103 +1609,111 @@ int tcc_output_file(TCCState *s1, const char *filename) · 143 unmodified lines
15661609 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
15671610 }
15681611
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−
16111612 /* write elf file */
16121613 if (file_type == TCC_OUTPUT_OBJ)
16131614 mode = 0666;
16141615 else
16151616 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);
16171618 if (fd < 0) {
16181619 error_noabort("could not write '%s'", filename);
16191620 goto fail;
16201621 }
1621− f = fdopen(fd, "w");
1622− fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1623− fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1624− offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1625− for(i=1;i<s1->nb_sections;i++) {
1626− s = s1->sections[section_order[i]];
1627− if (s->sh_type != SHT_NOBITS) {
1628− while (offset < s->sh_offset) {
1629− fputc(0, f);
1630− offset++;
1622+ f = fdopen(fd, "wb");
1623+
1624+#ifdef TCC_TARGET_COFF
1625+ if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1626+ tcc_output_coff(s1, f);
1627+ } else
1628+#endif
1629+ if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1630+ sort_syms(s1, symtab_section);
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;
16311683 }
1632− size = s->sh_size;
1633− fwrite(s->data, 1, size, f);
1634− offset += size;
16351684 }
1636− }
1637− while (offset < ehdr.e_shoff) {
1638− fputc(0, f);
1639− offset++;
1640− }
1685+
1686+ /* output section headers */
1687+ while (offset < ehdr.e_shoff) {
1688+ fputc(0, f);
1689+ offset++;
1690+ }
16411691
1642− /* output section headers */
1643− for(i=0;i<s1->nb_sections;i++) {
1644− sh = &shdr;
1645− memset(sh, 0, sizeof(Elf32_Shdr));
1646− s = s1->sections[i];
1647− if (s) {
1648− sh->sh_name = s->sh_name;
1649− sh->sh_type = s->sh_type;
1650− sh->sh_flags = s->sh_flags;
1651− sh->sh_entsize = s->sh_entsize;
1652− sh->sh_info = s->sh_info;
1653− if (s->link)
1654− sh->sh_link = s->link->sh_num;
1655− sh->sh_addralign = s->sh_addralign;
1656− sh->sh_addr = s->sh_addr;
1657− sh->sh_offset = s->sh_offset;
1658− sh->sh_size = s->sh_size;
1692+ for(i=0;i<s1->nb_sections;i++) {
1693+ sh = &shdr;
1694+ memset(sh, 0, sizeof(Elf32_Shdr));
1695+ s = s1->sections[i];
1696+ if (s) {
1697+ sh->sh_name = s->sh_name;
1698+ sh->sh_type = s->sh_type;
1699+ sh->sh_flags = s->sh_flags;
1700+ sh->sh_entsize = s->sh_entsize;
1701+ sh->sh_info = s->sh_info;
1702+ if (s->link)
1703+ sh->sh_link = s->link->sh_num;
1704+ sh->sh_addralign = s->sh_addralign;
1705+ sh->sh_addr = s->sh_addr;
1706+ sh->sh_offset = s->sh_offset;
1707+ sh->sh_size = s->sh_size;
1708+ }
1709+ fwrite(sh, 1, sizeof(Elf32_Shdr), f);
16591710 }
1660− fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1711+ } else {
1712+ tcc_output_binary(s1, f, section_order);
16611713 }
16621714 fclose(f);
16631715
16641716 ret = 0;
1665−#endif
16661717 the_end:
16671718 tcc_free(s1->symtab_to_dynsym);
16681719 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