| @@ -1694,54 +1694,65 @@ ST_FUNC int pe_add_dll(struct TCCState *s, const char *libname) · 1693 unmodified lines |
| 1694 | 1694 | |
| 1695 | 1695 | /* ------------------------------------------------------------- */ |
| 1696 | 1696 | #ifdef TCC_TARGET_X86_64 |
| 1697 | | −ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack) |
| 1697 | +static unsigned pe_add_uwwind_info(TCCState *s1) |
| 1698 | 1698 | { |
| 1699 | | − static const char uw_info[] = { |
| 1700 | | − 0x01, // UBYTE: 3 Version , UBYTE: 5 Flags |
| 1701 | | − 0x04, // UBYTE Size of prolog |
| 1702 | | − 0x02, // UBYTE Count of unwind codes |
| 1703 | | − 0x05, // UBYTE: 4 Frame Register (rbp), UBYTE: 4 Frame Register offset (scaled) |
| 1704 | | − // USHORT * n Unwind codes array |
| 1705 | | − // 0x0b, 0x01, 0xff, 0xff, // stack size |
| 1706 | | − 0x04, 0x03, // set frame ptr (mov rsp -> rbp) |
| 1707 | | − 0x01, 0x50 // push reg (rbp) |
| 1708 | | − }; |
| 1699 | + if (NULL == s1->uw_pdata) { |
| 1700 | + s1->uw_pdata = find_section(tcc_state, ".pdata"); |
| 1701 | + s1->uw_pdata->sh_addralign = 4; |
| 1702 | + s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0, text_section->sh_num, NULL); |
| 1703 | + } |
| 1709 | 1704 | |
| 1710 | | − struct pe_uw *pe_uw = &tcc_state->pe_unwind; |
| 1705 | + if (0 == s1->uw_offs) { |
| 1706 | + /* As our functions all have the same stackframe, we use one entry for all */ |
| 1707 | + static const unsigned char uw_info[] = { |
| 1708 | + 0x01, // UBYTE: 3 Version , UBYTE: 5 Flags |
| 1709 | + 0x04, // UBYTE Size of prolog |
| 1710 | + 0x02, // UBYTE Count of unwind codes |
| 1711 | + 0x05, // UBYTE: 4 Frame Register (rbp), UBYTE: 4 Frame Register offset (scaled) |
| 1712 | + // USHORT * n Unwind codes array |
| 1713 | + // 0x0b, 0x01, 0xff, 0xff, // stack size |
| 1714 | + 0x04, 0x03, // set frame ptr (mov rsp -> rbp) |
| 1715 | + 0x01, 0x50 // push reg (rbp) |
| 1716 | + }; |
| 1711 | 1717 | |
| 1712 | | − Section *uw, *pd; |
| 1713 | | − WORD *p1; |
| 1714 | | − DWORD *p2; |
| 1715 | | − unsigned o2; |
| 1718 | + Section *s = text_section; |
| 1719 | + unsigned char *p; |
| 1716 | 1720 | |
| 1717 | | − uw = data_section; |
| 1718 | | − pd = pe_uw->pdata; |
| 1719 | | − if (NULL == pd) |
| 1720 | | − { |
| 1721 | | − pe_uw->pdata = pd = find_section(tcc_state, ".pdata"); |
| 1722 | | − pe_uw->pdata->sh_addralign = 4; |
| 1723 | | − section_ptr_add(uw, -uw->data_offset & 3); |
| 1724 | | − pe_uw->offs_1 = uw->data_offset; |
| 1725 | | − p1 = section_ptr_add(uw, sizeof uw_info); |
| 1726 | | − /* use one common entry for all functions */ |
| 1727 | | − memcpy(p1, uw_info, sizeof uw_info); |
| 1728 | | − pe_uw->sym_1 = put_elf_sym(symtab_section, 0, 0, 0, 0, text_section->sh_num, NULL); |
| 1729 | | − pe_uw->sym_2 = put_elf_sym(symtab_section, 0, 0, 0, 0, uw->sh_num, NULL); |
| 1721 | + section_ptr_add(s, -s->data_offset & 3); /* align */ |
| 1722 | + s1->uw_offs = s->data_offset; |
| 1723 | + p = section_ptr_add(s, sizeof uw_info); |
| 1724 | + memcpy(p, uw_info, sizeof uw_info); |
| 1730 | 1725 | } |
| 1731 | 1726 | |
| 1732 | | − o2 = pd->data_offset; |
| 1733 | | − p2 = section_ptr_add(pd, 3 * sizeof (DWORD)); |
| 1727 | + return s1->uw_offs; |
| 1728 | +} |
| 1729 | + |
| 1730 | +ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack) |
| 1731 | +{ |
| 1732 | + TCCState *s1 = tcc_state; |
| 1733 | + Section *pd; |
| 1734 | + unsigned o, n, d; |
| 1735 | + struct /* _RUNTIME_FUNCTION */ { |
| 1736 | + DWORD BeginAddress; |
| 1737 | + DWORD EndAddress; |
| 1738 | + DWORD UnwindData; |
| 1739 | + } *p; |
| 1740 | + |
| 1741 | + d = pe_add_uwwind_info(s1); |
| 1742 | + pd = s1->uw_pdata; |
| 1743 | + o = pd->data_offset; |
| 1744 | + p = section_ptr_add(pd, sizeof *p); |
| 1745 | + |
| 1734 | 1746 | /* record this function */ |
| 1735 | | − p2[0] = start; |
| 1736 | | − p2[1] = end; |
| 1737 | | − p2[2] = pe_uw->offs_1; |
| 1747 | + p->BeginAddress = start; |
| 1748 | + p->EndAddress = end; |
| 1749 | + p->UnwindData = d; |
| 1750 | + |
| 1738 | 1751 | /* put relocations on it */ |
| 1739 | | − put_elf_reloc(symtab_section, pd, o2, R_X86_64_RELATIVE, pe_uw->sym_1); |
| 1740 | | − put_elf_reloc(symtab_section, pd, o2+4, R_X86_64_RELATIVE, pe_uw->sym_1); |
| 1741 | | − put_elf_reloc(symtab_section, pd, o2+8, R_X86_64_RELATIVE, pe_uw->sym_2); |
| 1752 | + for (n = o + sizeof *p; o < n; o += sizeof p->BeginAddress) |
| 1753 | + put_elf_reloc(symtab_section, pd, o, R_X86_64_RELATIVE, s1->uw_sym); |
| 1742 | 1754 | } |
| 1743 | 1755 | #endif |
| 1744 | | − |
| 1745 | 1756 | /* ------------------------------------------------------------- */ |
| 1746 | 1757 | #ifdef TCC_TARGET_X86_64 |
| 1747 | 1758 | #define PE_STDSYM(n,s) n |