Skip to content

Commit e0ef787

Browse files
authored
remove LSDA pointer from EhFrameHeader (#23388)
1 parent b17064f commit e0ef787

2 files changed

Lines changed: 122 additions & 33 deletions

File tree

compiler/src/dmd/backend/dwarfdbginf.d

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ static if (1)
8484

8585
import dmd.common.outbuffer;
8686

87-
8887
nothrow:
8988
private:
9089

@@ -654,19 +653,26 @@ static if (1)
654653
*/
655654

656655
const bool AArch64 = AArch64();
656+
const bool AppleAArch64 = AArch64 && config.objfmt == OBJ_MACH;
657+
657658
const uint startsize = cast(uint)buf.length();
658659

659660
// Length of CIE, not including padding
660-
const uint cielen = 4 + 4 + 1 + // (length of CIE) + (CIE ID) + (version_)
661+
uint cielen = 4 + 4 + 1 + // (length of CIE) + (CIE ID) + (version_)
661662
(ehunwind ? 5 : 3) + // "zPLR"0 : "zR"0
662663
1 + 1 + 1 + // (code alignment factor) + (data alignment factor) + (return address register)
663-
(ehunwind ? 8 : 2) + // (1:Augmentation Length) +
664-
// (1:personality pointer encoding) +
665-
// (4:personality pointer reference) +
666-
// (1:address encoding for LSDA) +
667-
// (1:encoding of addresses in FDE)
668-
// : (1:Augmentation Length) + (1:encoding of addresses in FDE)
669-
(AArch64 ? 3 : 5);
664+
(ehunwind ? 8 : 2) + // (1:Augmentation Length) +
665+
// P (1:personality pointer encoding) +
666+
// L (4:LSDA pointer reference) +
667+
// L (1:address encoding for LSDA) +
668+
// R (1:encoding of addresses in FDE)
669+
// : (1:Augmentation Length) +
670+
// (1:encoding of addresses in FDE)
671+
(AArch64 ? 3 : 5); // CFA beginning state
672+
if (AppleAArch64 && ehunwind)
673+
{
674+
cielen -= /* L */ 1 + /* L */ (4 + 1);
675+
}
670676

671677
const uint pad = -cielen & (AArch64 ? 3 : (I64 ? 7 : 3)); // pad to addressing unit size boundary
672678
const uint length = cielen + pad - 4;
@@ -676,7 +682,12 @@ static if (1)
676682
buf.write32(0); // CIE ID
677683
buf.writeByten(1); // version_
678684
if (ehunwind)
679-
buf.write("zPLR".ptr, 5); // Augmentation String
685+
{
686+
if (AppleAArch64)
687+
buf.write("zPR".ptr, 4); // Augmentation String
688+
else
689+
buf.write("zPLR".ptr, 5); // Augmentation String
690+
}
680691
else
681692
buf.writen("zR".ptr, 3);
682693
// not present: EH Data: 4 bytes for I32, 8 bytes for I64
@@ -714,18 +725,27 @@ static if (1)
714725
address_pointer_encoding = DW_EH_PE_pcrel | DW_EH_PE_ptr;
715726
}
716727
}
717-
buf.writeByten(7); // Augmentation Length
718-
buf.writeByten(personality_pointer_encoding); // P: personality routine address encoding
719-
/* MACHOBJ 64: pcrel 1 length 2 extern 1 RELOC_GOT
720-
* 32: [4] address x0013 pcrel 0 length 2 value xfc type 4 RELOC_LOCAL_SECTDIFF
721-
* [5] address x0000 pcrel 0 length 2 value xc7 type 1 RELOC_PAIR
722-
*/
723-
if (config.objfmt == OBJ_ELF)
724-
elf_dwarf_reftoident(dfseg, buf.length(), personality, 0);
728+
if (AppleAArch64)
729+
{
730+
buf.writeByten(2); // Augmentation Length
731+
buf.writeByten(personality_pointer_encoding); // P: personality routine address encoding
732+
buf.writeByten(address_pointer_encoding); // R: encoding of addresses in FDE
733+
}
725734
else
726-
mach_dwarf_reftoident(dfseg, buf.length(), personality, 0);
727-
buf.writeByten(LSDA_pointer_encoding); // L: address encoding for LSDA in FDE
728-
buf.writeByten(address_pointer_encoding); // R: encoding of addresses in FDE
735+
{
736+
buf.writeByten(7); // Augmentation Length
737+
buf.writeByten(personality_pointer_encoding); // P: personality routine address encoding
738+
/* MACHOBJ 64: pcrel 1 length 2 extern 1 RELOC_GOT
739+
* 32: [4] address x0013 pcrel 0 length 2 value xfc type 4 RELOC_LOCAL_SECTDIFF
740+
* [5] address x0000 pcrel 0 length 2 value xc7 type 1 RELOC_PAIR
741+
*/
742+
if (config.objfmt == OBJ_ELF)
743+
elf_dwarf_reftoident(dfseg, buf.length(), personality, 0);
744+
else
745+
mach_dwarf_reftoident(dfseg, buf.length(), personality, 0);
746+
buf.writeByten(LSDA_pointer_encoding); // L: address encoding for LSDA in FDE
747+
buf.writeByten(address_pointer_encoding); // R: encoding of addresses in FDE
748+
}
729749
}
730750
else
731751
{

compiler/src/dmd/backend/machobj.d

Lines changed: 81 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -943,13 +943,15 @@ void MachObj_term(const(char)[] objfilename)
943943
rel.r_length = 3;
944944
rel.r_extern = r.funcsym.Sclass == SC.locstat ? 0 : 1;
945945
if (rel.r_extern == 1)
946-
assert(s.Sxtrnnum < nsyms);
946+
assert(r.funcsym.Sxtrnnum < nsyms);
947947
machobj.fobjbuf.write(&rel, rel.sizeof);
948948
foffset += (rel).sizeof;
949949
++nreloc;
950950

951951
rel.r_type = ARM64_RELOC_UNSIGNED;
952-
rel.r_symbolnum = s.Sxtrnnum;
952+
if (rel.r_extern == 1)
953+
rel.r_symbolnum = s.Sxtrnnum;
954+
assert(s.Sxtrnnum < nsyms);
953955
machobj.fobjbuf.write(&rel, rel.sizeof);
954956
foffset += rel.sizeof;
955957
++nreloc;
@@ -1735,6 +1737,7 @@ static if (0)
17351737
dysymtab_cmd.nindirectsyms += machobj.indirectsymbuf1.length() / (Symbol*).sizeof;
17361738
for (int i = 0; i < dysymtab_cmd.nindirectsyms; i++)
17371739
{ Symbol* s = (cast(Symbol**)machobj.indirectsymbuf1.buf)[i];
1740+
assert(s.Sxtrnnum < symtab_cmd.nsyms);
17381741
machobj.fobjbuf.write32(s.Sxtrnnum);
17391742
}
17401743
}
@@ -1744,6 +1747,7 @@ static if (0)
17441747
dysymtab_cmd.nindirectsyms += n;
17451748
for (int i = 0; i < n; i++)
17461749
{ Symbol* s = (cast(Symbol**)machobj.indirectsymbuf2.buf)[i];
1750+
assert(s.Sxtrnnum < symtab_cmd.nsyms);
17471751
machobj.fobjbuf.write32(s.Sxtrnnum);
17481752
}
17491753
}
@@ -2017,21 +2021,54 @@ int MachObj_comdatsize(Symbol* s, targ_size_t symsize)
20172021
@trusted
20182022
int MachObj_comdat(Symbol* s)
20192023
{
2020-
const(char)* sectname;
2021-
const(char)* segname;
2022-
int p2align;
2023-
int flags;
2024-
20252024
//printf("MachObj_comdat(Symbol* %s)\n",s.Sident.ptr);
20262025
//symbol_print(*s);
20272026
//symbol_debug(s);
20282027

2028+
int p2align;
2029+
if (config.target_cpu == TARGET_AArch64 && config.objfmt == OBJ_MACH)
2030+
{
2031+
/* write out the symbol with an n_desc of N_WEAK_DEF.
2032+
*/
2033+
if (tyfunc(s.ty()))
2034+
{
2035+
p2align = 2; // 4 byte alignment
2036+
s.Sseg = cseg; // functions go into cseg
2037+
}
2038+
else if ((s.ty() & mTYLINK) == mTYweakLinkage)
2039+
{
2040+
s.Sfl = FL.data;
2041+
p2align = 4; // 16 byte alignment
2042+
MachObj_data_start(s, 1 << p2align, s.Sseg);
2043+
}
2044+
else if ((s.ty() & mTYLINK) == mTYthread)
2045+
{
2046+
s.Sfl = FL.tlsdata;
2047+
p2align = 4;
2048+
if (I64)
2049+
s.Sseg = objmod.tlsseg().SDseg;
2050+
else
2051+
s.Sseg = getsegment2(machobj.seg_tlscoal_nt, "__tlscoal_nt", "__DATA", p2align, S_COALESCED);
2052+
MachObj_data_start(s, 1 << p2align, s.Sseg);
2053+
}
2054+
else
2055+
{
2056+
s.Sfl = FL.data;
2057+
const(char)* sectname = "__datacoal_nt";
2058+
const(char)* segname = "__DATA";
2059+
p2align = 4; // 16 byte alignment
2060+
s.Sseg = getsegment2(machobj.seg_datacoal_nt, sectname, segname, p2align, S_COALESCED);
2061+
MachObj_data_start(s, 1 << p2align, s.Sseg);
2062+
}
2063+
}
2064+
else
2065+
{
20292066
if (tyfunc(s.ty()))
20302067
{
2031-
sectname = "__textcoal_nt";
2032-
segname = "__TEXT";
2068+
const(char)* sectname = "__textcoal_nt";
2069+
const(char)* segname = "__TEXT";
20332070
p2align = 2; // 4 byte alignment
2034-
flags = S_COALESCED | S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS;
2071+
int flags = S_COALESCED | S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS;
20352072
s.Sseg = getsegment2(machobj.seg_textcoal_nt, sectname, segname, p2align, flags);
20362073
}
20372074
else if ((s.ty() & mTYLINK) == mTYweakLinkage)
@@ -2053,11 +2090,12 @@ int MachObj_comdat(Symbol* s)
20532090
else
20542091
{
20552092
s.Sfl = FL.data;
2056-
sectname = "__datacoal_nt";
2057-
segname = "__DATA";
2093+
const(char)* sectname = "__datacoal_nt";
2094+
const(char)* segname = "__DATA";
20582095
p2align = 4; // 16 byte alignment
20592096
s.Sseg = getsegment2(machobj.seg_datacoal_nt, sectname, segname, p2align, S_COALESCED);
20602097
MachObj_data_start(s, 1 << p2align, s.Sseg);
2098+
}
20612099
}
20622100
// find or create new segment
20632101
if (s.Salignment > (1 << p2align))
@@ -2076,6 +2114,37 @@ int MachObj_readonly_comdat(Symbol* s)
20762114
assert(0);
20772115
}
20782116

2117+
/* Arm64 __LD, __compact_unwind section
2118+
Layout:
2119+
2120+
struct compact_unwind_entry_64 {
2121+
uint64_t function_start; // address of function (or range start)
2122+
uint32_t function_length; // length of the function/range
2123+
uint32_t encoding; // 32-bit compact unwind encoding
2124+
uint64_t personality; // pointer to personality function (or 0)
2125+
uint64_t lsda; // pointer to LSDA (language-specific data area) or 0
2126+
};
2127+
2128+
Encoding:
2129+
2130+
Bits Meaning
2131+
31 IS_NOT_FUNCTION_START
2132+
30 HAS_LSDA
2133+
29-28 Personality index (0-3)
2134+
27-24 Mode
2135+
2136+
arm64 modes (most relevant today):
2137+
0x02000000 - Frameless (leaf function)
2138+
0x04000000 - Frame-based (standard stp x29,x30 prologue)
2139+
0x03000000 - DWARF fallback (points into __eh_frame)
2140+
2141+
# See the raw compact unwind section in an object file
2142+
otool -s __LD __compact_unwind myfile.o -v
2143+
2144+
See the canonical reference for all bitfields in LLVM:
2145+
https://github.com/llvm/llvm-project/blob/main/libunwind/include/mach-o/compact_unwind_encoding.h
2146+
*/
2147+
20792148
/***********************************
20802149
* Returns:
20812150
* jump table segment for function s

0 commit comments

Comments
 (0)