Skip to content

Commit 7c90706

Browse files
committedJan 2, 2018
Reland [PPC64] Port to ppc64le - initial version
Initial working version of libunwind for PowerPC 64. Tested on little-endian ppc64 host only. Based on the existing PowerPC 32 code. It supports: - context save/restore (unw_getcontext, unw_init_local, unw_resume) - read/write from/to saved registers - backtrace (unw_step) Patch by Leandro Lupori! Differential Revision: https://reviews.llvm.org/D41386 Now builds with LIBUNWIND_ENABLE_CROSS_UNWINDING=ON should work. llvm-svn: 321680
1 parent ecf9054 commit 7c90706

10 files changed

+931
-5
lines changed
 

‎libunwind/include/__libunwind_config.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 8
1919
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64 32
2020
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC 112
21+
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64 110
2122
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 95
2223
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM 287
2324
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 31
@@ -39,6 +40,11 @@
3940
# define _LIBUNWIND_CURSOR_SIZE 33
4041
# endif
4142
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64
43+
# elif defined(__powerpc64__)
44+
# define _LIBUNWIND_TARGET_PPC64 1
45+
# define _LIBUNWIND_CONTEXT_SIZE 136
46+
# define _LIBUNWIND_CURSOR_SIZE 148
47+
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64
4248
# elif defined(__ppc__)
4349
# define _LIBUNWIND_TARGET_PPC 1
4450
# define _LIBUNWIND_CONTEXT_SIZE 117
@@ -84,13 +90,14 @@
8490
# define _LIBUNWIND_TARGET_I386
8591
# define _LIBUNWIND_TARGET_X86_64 1
8692
# define _LIBUNWIND_TARGET_PPC 1
93+
# define _LIBUNWIND_TARGET_PPC64 1
8794
# define _LIBUNWIND_TARGET_AARCH64 1
8895
# define _LIBUNWIND_TARGET_ARM 1
8996
# define _LIBUNWIND_TARGET_OR1K 1
9097
# define _LIBUNWIND_TARGET_MIPS_O32 1
9198
# define _LIBUNWIND_TARGET_MIPS_N64 1
92-
# define _LIBUNWIND_CONTEXT_SIZE 128
93-
# define _LIBUNWIND_CURSOR_SIZE 140
99+
# define _LIBUNWIND_CONTEXT_SIZE 136
100+
# define _LIBUNWIND_CURSOR_SIZE 148
94101
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
95102
#endif // _LIBUNWIND_IS_NATIVE_ONLY
96103

‎libunwind/include/libunwind.h

+114
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,120 @@ enum {
325325
UNW_PPC_SPEFSCR = 112
326326
};
327327

328+
// 64-bit ppc register numbers
329+
enum {
330+
UNW_PPC64_R0 = 0,
331+
UNW_PPC64_R1 = 1,
332+
UNW_PPC64_R2 = 2,
333+
UNW_PPC64_R3 = 3,
334+
UNW_PPC64_R4 = 4,
335+
UNW_PPC64_R5 = 5,
336+
UNW_PPC64_R6 = 6,
337+
UNW_PPC64_R7 = 7,
338+
UNW_PPC64_R8 = 8,
339+
UNW_PPC64_R9 = 9,
340+
UNW_PPC64_R10 = 10,
341+
UNW_PPC64_R11 = 11,
342+
UNW_PPC64_R12 = 12,
343+
UNW_PPC64_R13 = 13,
344+
UNW_PPC64_R14 = 14,
345+
UNW_PPC64_R15 = 15,
346+
UNW_PPC64_R16 = 16,
347+
UNW_PPC64_R17 = 17,
348+
UNW_PPC64_R18 = 18,
349+
UNW_PPC64_R19 = 19,
350+
UNW_PPC64_R20 = 20,
351+
UNW_PPC64_R21 = 21,
352+
UNW_PPC64_R22 = 22,
353+
UNW_PPC64_R23 = 23,
354+
UNW_PPC64_R24 = 24,
355+
UNW_PPC64_R25 = 25,
356+
UNW_PPC64_R26 = 26,
357+
UNW_PPC64_R27 = 27,
358+
UNW_PPC64_R28 = 28,
359+
UNW_PPC64_R29 = 29,
360+
UNW_PPC64_R30 = 30,
361+
UNW_PPC64_R31 = 31,
362+
UNW_PPC64_F0 = 32,
363+
UNW_PPC64_F1 = 33,
364+
UNW_PPC64_F2 = 34,
365+
UNW_PPC64_F3 = 35,
366+
UNW_PPC64_F4 = 36,
367+
UNW_PPC64_F5 = 37,
368+
UNW_PPC64_F6 = 38,
369+
UNW_PPC64_F7 = 39,
370+
UNW_PPC64_F8 = 40,
371+
UNW_PPC64_F9 = 41,
372+
UNW_PPC64_F10 = 42,
373+
UNW_PPC64_F11 = 43,
374+
UNW_PPC64_F12 = 44,
375+
UNW_PPC64_F13 = 45,
376+
UNW_PPC64_F14 = 46,
377+
UNW_PPC64_F15 = 47,
378+
UNW_PPC64_F16 = 48,
379+
UNW_PPC64_F17 = 49,
380+
UNW_PPC64_F18 = 50,
381+
UNW_PPC64_F19 = 51,
382+
UNW_PPC64_F20 = 52,
383+
UNW_PPC64_F21 = 53,
384+
UNW_PPC64_F22 = 54,
385+
UNW_PPC64_F23 = 55,
386+
UNW_PPC64_F24 = 56,
387+
UNW_PPC64_F25 = 57,
388+
UNW_PPC64_F26 = 58,
389+
UNW_PPC64_F27 = 59,
390+
UNW_PPC64_F28 = 60,
391+
UNW_PPC64_F29 = 61,
392+
UNW_PPC64_F30 = 62,
393+
UNW_PPC64_F31 = 63,
394+
UNW_PPC64_LR = 64,
395+
UNW_PPC64_CTR = 65,
396+
UNW_PPC64_CR0 = 66,
397+
UNW_PPC64_CR1 = 67,
398+
UNW_PPC64_CR2 = 68,
399+
UNW_PPC64_CR3 = 69,
400+
UNW_PPC64_CR4 = 70,
401+
UNW_PPC64_CR5 = 71,
402+
UNW_PPC64_CR6 = 72,
403+
UNW_PPC64_CR7 = 73,
404+
UNW_PPC64_XER = 74,
405+
UNW_PPC64_V0 = 75,
406+
UNW_PPC64_V1 = 76,
407+
UNW_PPC64_V2 = 77,
408+
UNW_PPC64_V3 = 78,
409+
UNW_PPC64_V4 = 79,
410+
UNW_PPC64_V5 = 80,
411+
UNW_PPC64_V6 = 81,
412+
UNW_PPC64_V7 = 82,
413+
UNW_PPC64_V8 = 83,
414+
UNW_PPC64_V9 = 84,
415+
UNW_PPC64_V10 = 85,
416+
UNW_PPC64_V11 = 86,
417+
UNW_PPC64_V12 = 87,
418+
UNW_PPC64_V13 = 88,
419+
UNW_PPC64_V14 = 89,
420+
UNW_PPC64_V15 = 90,
421+
UNW_PPC64_V16 = 91,
422+
UNW_PPC64_V17 = 92,
423+
UNW_PPC64_V18 = 93,
424+
UNW_PPC64_V19 = 94,
425+
UNW_PPC64_V20 = 95,
426+
UNW_PPC64_V21 = 96,
427+
UNW_PPC64_V22 = 97,
428+
UNW_PPC64_V23 = 98,
429+
UNW_PPC64_V24 = 99,
430+
UNW_PPC64_V25 = 100,
431+
UNW_PPC64_V26 = 101,
432+
UNW_PPC64_V27 = 102,
433+
UNW_PPC64_V28 = 103,
434+
UNW_PPC64_V29 = 104,
435+
UNW_PPC64_V30 = 105,
436+
UNW_PPC64_V31 = 106,
437+
UNW_PPC64_VRSAVE = 107,
438+
UNW_PPC64_VSCR = 108,
439+
UNW_PPC64_FPSCR = 109
440+
};
441+
328442
// 64-bit ARM64 registers
329443
enum {
330444
UNW_ARM64_X0 = 0,

‎libunwind/src/AddressSpace.hpp

+7
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,13 @@ struct unw_addr_space_ppc : public unw_addr_space {
697697
RemoteAddressSpace<Pointer32<BigEndian>> oas;
698698
};
699699

700+
/// unw_addr_space_ppc is the concrete instance that a unw_addr_space_t points
701+
/// to when examining a 64-bit PowerPC process.
702+
struct unw_addr_space_ppc64 : public unw_addr_space {
703+
unw_addr_space_ppc64(task_t task) : oas(task) {}
704+
RemoteAddressSpace<Pointer64<LittleEndian>> oas;
705+
};
706+
700707
#endif // UNW_REMOTE
701708

702709
} // namespace libunwind

‎libunwind/src/Registers.hpp

+577
Large diffs are not rendered by default.

‎libunwind/src/UnwindCursor.hpp

+19
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,13 @@ class UnwindCursor : public AbstractUnwindCursor{
501501
}
502502
#endif
503503

504+
#if defined(_LIBUNWIND_TARGET_PPC64)
505+
int stepWithCompactEncoding(Registers_ppc64 &) {
506+
return UNW_EINVAL;
507+
}
508+
#endif
509+
510+
504511
#if defined(_LIBUNWIND_TARGET_AARCH64)
505512
int stepWithCompactEncoding(Registers_arm64 &) {
506513
return CompactUnwinder_arm64<A>::stepWithCompactEncoding(
@@ -553,6 +560,12 @@ class UnwindCursor : public AbstractUnwindCursor{
553560
}
554561
#endif
555562

563+
#if defined(_LIBUNWIND_TARGET_PPC64)
564+
bool compactSaysUseDwarf(Registers_ppc64 &, uint32_t *) const {
565+
return true;
566+
}
567+
#endif
568+
556569
#if defined(_LIBUNWIND_TARGET_AARCH64)
557570
bool compactSaysUseDwarf(Registers_arm64 &, uint32_t *offset) const {
558571
if ((_info.format & UNWIND_ARM64_MODE_MASK) == UNWIND_ARM64_MODE_DWARF) {
@@ -601,6 +614,12 @@ class UnwindCursor : public AbstractUnwindCursor{
601614
}
602615
#endif
603616

617+
#if defined(_LIBUNWIND_TARGET_PPC64)
618+
compact_unwind_encoding_t dwarfEncoding(Registers_ppc64 &) const {
619+
return 0;
620+
}
621+
#endif
622+
604623
#if defined(_LIBUNWIND_TARGET_AARCH64)
605624
compact_unwind_encoding_t dwarfEncoding(Registers_arm64 &) const {
606625
return UNWIND_ARM64_MODE_DWARF;

‎libunwind/src/UnwindRegistersRestore.S

+95
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,101 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind16Registers_x86_646jumptoEv)
128128
ret # rip was saved here
129129

130130

131+
#elif defined(__powerpc64__)
132+
133+
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)
134+
//
135+
// void libunwind::Registers_ppc64::jumpto()
136+
//
137+
// On entry:
138+
// thread_state pointer is in r3
139+
//
140+
141+
// restore integral registers
142+
// skip r0 for now
143+
// skip r1 for now
144+
ld %r2, 32(%r3)
145+
// skip r3 for now
146+
// skip r4 for now
147+
// skip r5 for now
148+
ld %r6, 64(%r3)
149+
ld %r7, 72(%r3)
150+
ld %r8, 80(%r3)
151+
ld %r9, 88(%r3)
152+
ld %r10, 96(%r3)
153+
ld %r11, 104(%r3)
154+
ld %r12, 112(%r3)
155+
ld %r13, 120(%r3)
156+
ld %r14, 128(%r3)
157+
ld %r15, 136(%r3)
158+
ld %r16, 144(%r3)
159+
ld %r17, 152(%r3)
160+
ld %r18, 160(%r3)
161+
ld %r19, 168(%r3)
162+
ld %r20, 176(%r3)
163+
ld %r21, 184(%r3)
164+
ld %r22, 192(%r3)
165+
ld %r23, 200(%r3)
166+
ld %r24, 208(%r3)
167+
ld %r25, 216(%r3)
168+
ld %r26, 224(%r3)
169+
ld %r27, 232(%r3)
170+
ld %r28, 240(%r3)
171+
ld %r29, 248(%r3)
172+
ld %r30, 256(%r3)
173+
ld %r31, 264(%r3)
174+
175+
//restore float registers
176+
lfd %f0, 312(%r3)
177+
lfd %f1, 320(%r3)
178+
lfd %f2, 328(%r3)
179+
lfd %f3, 336(%r3)
180+
lfd %f4, 344(%r3)
181+
lfd %f5, 352(%r3)
182+
lfd %f6, 360(%r3)
183+
lfd %f7, 368(%r3)
184+
lfd %f8, 376(%r3)
185+
lfd %f9, 384(%r3)
186+
lfd %f10, 392(%r3)
187+
lfd %f11, 400(%r3)
188+
lfd %f12, 408(%r3)
189+
lfd %f13, 416(%r3)
190+
lfd %f14, 424(%r3)
191+
lfd %f15, 432(%r3)
192+
lfd %f16, 440(%r3)
193+
lfd %f17, 448(%r3)
194+
lfd %f18, 456(%r3)
195+
lfd %f19, 464(%r3)
196+
lfd %f20, 472(%r3)
197+
lfd %f21, 480(%r3)
198+
lfd %f22, 488(%r3)
199+
lfd %f23, 496(%r3)
200+
lfd %f24, 504(%r3)
201+
lfd %f25, 512(%r3)
202+
lfd %f26, 520(%r3)
203+
lfd %f27, 528(%r3)
204+
lfd %f28, 536(%r3)
205+
lfd %f29, 544(%r3)
206+
lfd %f30, 552(%r3)
207+
lfd %f31, 560(%r3)
208+
209+
//TODO: restore vector registers
210+
211+
// Lnovec:
212+
ld %r0, 272(%r3) // __cr
213+
mtcr %r0
214+
ld %r0, 296(%r3) // __ctr
215+
mtctr %r0
216+
ld %r0, 0(%r3) // __ssr0
217+
mtctr %r0
218+
219+
ld %r0, 16(%r3)
220+
ld %r5, 56(%r3)
221+
ld %r4, 48(%r3)
222+
ld %r1, 24(%r3)
223+
ld %r3, 40(%r3)
224+
bctr
225+
131226
#elif defined(__ppc__)
132227

133228
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)

‎libunwind/src/UnwindRegistersSave.S

+103
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,109 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
237237
DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
238238
teq $0, $0
239239

240+
#elif defined(__powerpc64__)
241+
242+
//
243+
// extern int unw_getcontext(unw_context_t* thread_state)
244+
//
245+
// On entry:
246+
// thread_state pointer is in r3
247+
//
248+
DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
249+
std %r0, 16(%r3)
250+
mflr %r0
251+
std %r0, 0(%r3) // store lr as ssr0
252+
std %r1, 24(%r3)
253+
std %r2, 32(%r3)
254+
std %r3, 40(%r3)
255+
std %r4, 48(%r3)
256+
std %r5, 56(%r3)
257+
std %r6, 64(%r3)
258+
std %r7, 72(%r3)
259+
std %r8, 80(%r3)
260+
std %r9, 88(%r3)
261+
std %r10, 96(%r3)
262+
std %r11, 104(%r3)
263+
std %r12, 112(%r3)
264+
std %r13, 120(%r3)
265+
std %r14, 128(%r3)
266+
std %r15, 136(%r3)
267+
std %r16, 144(%r3)
268+
std %r17, 152(%r3)
269+
std %r18, 160(%r3)
270+
std %r19, 168(%r3)
271+
std %r20, 176(%r3)
272+
std %r21, 184(%r3)
273+
std %r22, 192(%r3)
274+
std %r23, 200(%r3)
275+
std %r24, 208(%r3)
276+
std %r25, 216(%r3)
277+
std %r26, 224(%r3)
278+
std %r27, 232(%r3)
279+
std %r28, 240(%r3)
280+
std %r29, 248(%r3)
281+
std %r30, 256(%r3)
282+
std %r31, 264(%r3)
283+
284+
mfcr %r0
285+
std %r0, 272(%r3)
286+
287+
mfxer %r0
288+
std %r0, 280(%r3)
289+
290+
mflr %r0
291+
std %r0, 288(%r3)
292+
293+
mfctr %r0
294+
std %r0, 296(%r3)
295+
296+
mfvrsave %r0
297+
std %r0, 304(%r3)
298+
299+
// save float registers
300+
stfd %f0, 312(%r3)
301+
stfd %f1, 320(%r3)
302+
stfd %f2, 328(%r3)
303+
stfd %f3, 336(%r3)
304+
stfd %f4, 344(%r3)
305+
stfd %f5, 352(%r3)
306+
stfd %f6, 360(%r3)
307+
stfd %f7, 368(%r3)
308+
stfd %f8, 376(%r3)
309+
stfd %f9, 384(%r3)
310+
stfd %f10, 392(%r3)
311+
stfd %f11, 400(%r3)
312+
stfd %f12, 408(%r3)
313+
stfd %f13, 416(%r3)
314+
stfd %f14, 424(%r3)
315+
stfd %f15, 432(%r3)
316+
stfd %f16, 440(%r3)
317+
stfd %f17, 448(%r3)
318+
stfd %f18, 456(%r3)
319+
stfd %f19, 464(%r3)
320+
stfd %f20, 472(%r3)
321+
stfd %f21, 480(%r3)
322+
stfd %f22, 488(%r3)
323+
stfd %f23, 496(%r3)
324+
stfd %f24, 504(%r3)
325+
stfd %f25, 512(%r3)
326+
stfd %f26, 520(%r3)
327+
stfd %f27, 528(%r3)
328+
stfd %f28, 536(%r3)
329+
stfd %f29, 544(%r3)
330+
stfd %f30, 552(%r3)
331+
stfd %f31, 560(%r3)
332+
333+
mffs %f0
334+
stfd %f0, 568(%r3)
335+
336+
//TODO: save vector registers
337+
338+
339+
li %r3, 0 // return UNW_ESUCCESS
340+
blr
341+
342+
240343
#elif defined(__ppc__)
241344

242345
;

‎libunwind/src/assembly.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
#ifndef UNWIND_ASSEMBLY_H
1717
#define UNWIND_ASSEMBLY_H
1818

19-
#if defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__)
19+
#if defined(__powerpc64__)
20+
#define SEPARATOR ;
21+
#elif defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__)
2022
#define SEPARATOR @
2123
#elif defined(__arm64__)
2224
#define SEPARATOR %%

‎libunwind/src/config.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@
6363
#define _LIBUNWIND_BUILD_SJLJ_APIS
6464
#endif
6565

66-
#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ppc64__)
66+
#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__)
6767
#define _LIBUNWIND_SUPPORT_FRAME_APIS
6868
#endif
6969

7070
#if defined(__i386__) || defined(__x86_64__) || \
71-
defined(__ppc__) || defined(__ppc64__) || \
71+
defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) || \
7272
(!defined(__APPLE__) && defined(__arm__)) || \
7373
(defined(__arm64__) || defined(__aarch64__)) || \
7474
defined(__mips__)

‎libunwind/src/libunwind.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ _LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor,
5151
# define REGISTER_KIND Registers_x86
5252
#elif defined(__x86_64__)
5353
# define REGISTER_KIND Registers_x86_64
54+
#elif defined(__powerpc64__)
55+
# define REGISTER_KIND Registers_ppc64
5456
#elif defined(__ppc__)
5557
# define REGISTER_KIND Registers_ppc
5658
#elif defined(__aarch64__)

0 commit comments

Comments
 (0)
Please sign in to comment.