From d16017da3480f10f8dbac692b72e87ab82e2f8d7 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Fri, 23 Aug 2019 09:21:26 +0000 Subject: re PR target/91306 ([MSP430] libgcc/crtstuff.c: Alignment of frame_dummy .init_array entry is too big) 2019-08-23 Jozef Lawrynowicz PR target/91306 * crtstuff.c (__CTOR_LIST__): Align to the "__alignof__" the array element type, instead of "sizeof" the element type. (__DTOR_LIST__): Likewise. (__TMC_LIST__): Likewise. (__do_global_dtors_aux_fini_array_entry): Likewise. (__frame_dummy_init_array_entry): Likewise. (__CTOR_END__): Likewise. (__DTOR_END__): Likweise. (__FRAME_END__): Likewise. (__TMC_END__): Likewise. From-SVN: r274846 --- libgcc/ChangeLog | 14 ++++++++++++++ libgcc/crtstuff.c | 33 +++++++++++++++++---------------- 2 files changed, 31 insertions(+), 16 deletions(-) (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index c793ea4..2067437 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,17 @@ +2019-08-23 Jozef Lawrynowicz + + PR target/91306 + * crtstuff.c (__CTOR_LIST__): Align to the "__alignof__" the array + element type, instead of "sizeof" the element type. + (__DTOR_LIST__): Likewise. + (__TMC_LIST__): Likewise. + (__do_global_dtors_aux_fini_array_entry): Likewise. + (__frame_dummy_init_array_entry): Likewise. + (__CTOR_END__): Likewise. + (__DTOR_END__): Likweise. + (__FRAME_END__): Likewise. + (__TMC_END__): Likewise. + 2019-08-20 Lili Cui * config/i386/cpuinfo.h: Add INTEL_COREI7_TIGERLAKE and diff --git a/libgcc/crtstuff.c b/libgcc/crtstuff.c index 4927a9f..c8a8e2c 100644 --- a/libgcc/crtstuff.c +++ b/libgcc/crtstuff.c @@ -233,11 +233,11 @@ CTOR_LIST_BEGIN; static func_ptr force_to_data[1] __attribute__ ((__used__)) = { }; asm (__LIBGCC_CTORS_SECTION_ASM_OP__); STATIC func_ptr __CTOR_LIST__[1] - __attribute__ ((__used__, aligned(sizeof(func_ptr)))) + __attribute__ ((__used__, aligned(__alignof__(func_ptr)))) = { (func_ptr) (-1) }; #else STATIC func_ptr __CTOR_LIST__[1] - __attribute__ ((__used__, section(".ctors"), aligned(sizeof(func_ptr)))) + __attribute__ ((__used__, section(".ctors"), aligned(__alignof__(func_ptr)))) = { (func_ptr) (-1) }; #endif /* __CTOR_LIST__ alternatives */ @@ -246,11 +246,11 @@ DTOR_LIST_BEGIN; #elif defined(__LIBGCC_DTORS_SECTION_ASM_OP__) asm (__LIBGCC_DTORS_SECTION_ASM_OP__); STATIC func_ptr __DTOR_LIST__[1] - __attribute__ ((aligned(sizeof(func_ptr)))) + __attribute__ ((aligned(__alignof__(func_ptr)))) = { (func_ptr) (-1) }; #else STATIC func_ptr __DTOR_LIST__[1] - __attribute__((section(".dtors"), aligned(sizeof(func_ptr)))) + __attribute__((section(".dtors"), aligned(__alignof__(func_ptr)))) = { (func_ptr) (-1) }; #endif /* __DTOR_LIST__ alternatives */ #endif /* USE_INITFINI_ARRAY */ @@ -265,7 +265,7 @@ STATIC EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[] #if USE_TM_CLONE_REGISTRY STATIC func_ptr __TMC_LIST__[] - __attribute__((used, section(".tm_clone_table"), aligned(sizeof(void*)))) + __attribute__((used, section(".tm_clone_table"), aligned(__alignof__(void*)))) = { }; # ifdef HAVE_GAS_HIDDEN extern func_ptr __TMC_END__[] __attribute__((__visibility__ ("hidden"))); @@ -430,8 +430,8 @@ __do_global_dtors_aux (void) CRT_CALL_STATIC_FUNCTION (FINI_SECTION_ASM_OP, __do_global_dtors_aux) #elif defined (FINI_ARRAY_SECTION_ASM_OP) static func_ptr __do_global_dtors_aux_fini_array_entry[] - __attribute__ ((__used__, section(".fini_array"), aligned(sizeof(func_ptr)))) - = { __do_global_dtors_aux }; + __attribute__ ((__used__, section(".fini_array"), + aligned(__alignof__(func_ptr)))) = { __do_global_dtors_aux }; #else /* !FINI_SECTION_ASM_OP && !FINI_ARRAY_SECTION_ASM_OP */ static void __attribute__((used)) __do_global_dtors_aux_1 (void) @@ -474,8 +474,8 @@ frame_dummy (void) CRT_CALL_STATIC_FUNCTION (__LIBGCC_INIT_SECTION_ASM_OP__, frame_dummy) #else /* defined(__LIBGCC_INIT_SECTION_ASM_OP__) */ static func_ptr __frame_dummy_init_array_entry[] - __attribute__ ((__used__, section(".init_array"), aligned(sizeof(func_ptr)))) - = { frame_dummy }; + __attribute__ ((__used__, section(".init_array"), + aligned(__alignof__(func_ptr)))) = { frame_dummy }; #endif /* !defined(__LIBGCC_INIT_SECTION_ASM_OP__) */ #endif /* USE_EH_FRAME_REGISTRY || USE_TM_CLONE_REGISTRY */ @@ -588,11 +588,11 @@ CTOR_LIST_END; static func_ptr force_to_data[1] __attribute__ ((__used__)) = { }; asm (__LIBGCC_CTORS_SECTION_ASM_OP__); STATIC func_ptr __CTOR_END__[1] - __attribute__((aligned(sizeof(func_ptr)))) + __attribute__((aligned(__alignof__(func_ptr)))) = { (func_ptr) 0 }; #else STATIC func_ptr __CTOR_END__[1] - __attribute__((section(".ctors"), aligned(sizeof(func_ptr)))) + __attribute__((section(".ctors"), aligned(__alignof__(func_ptr)))) = { (func_ptr) 0 }; #endif @@ -607,16 +607,16 @@ func_ptr __DTOR_END__[1] #ifndef __LIBGCC_DTORS_SECTION_ASM_OP__ section(".dtors"), #endif - aligned(sizeof(func_ptr)), visibility ("hidden"))) + aligned(__alignof__(func_ptr)), visibility ("hidden"))) = { (func_ptr) 0 }; #elif defined(__LIBGCC_DTORS_SECTION_ASM_OP__) asm (__LIBGCC_DTORS_SECTION_ASM_OP__); STATIC func_ptr __DTOR_END__[1] - __attribute__ ((used, aligned(sizeof(func_ptr)))) + __attribute__ ((used, aligned(__alignof__(func_ptr)))) = { (func_ptr) 0 }; #else STATIC func_ptr __DTOR_END__[1] - __attribute__((used, section(".dtors"), aligned(sizeof(func_ptr)))) + __attribute__((used, section(".dtors"), aligned(__alignof__(func_ptr)))) = { (func_ptr) 0 }; #endif #endif /* USE_INITFINI_ARRAY */ @@ -635,7 +635,7 @@ typedef short int32; # endif STATIC EH_FRAME_SECTION_CONST int32 __FRAME_END__[] __attribute__ ((used, section(__LIBGCC_EH_FRAME_SECTION_NAME__), - aligned(sizeof(int32)))) + aligned(__alignof__(int32)))) = { 0 }; #endif /* __LIBGCC_EH_FRAME_SECTION_NAME__ */ @@ -644,7 +644,8 @@ STATIC EH_FRAME_SECTION_CONST int32 __FRAME_END__[] static # endif func_ptr __TMC_END__[] - __attribute__((used, section(".tm_clone_table"), aligned(sizeof(void *)))) + __attribute__((used, section(".tm_clone_table"), + aligned(__alignof__(void *)))) # ifdef HAVE_GAS_HIDDEN __attribute__((__visibility__ ("hidden"))) = { }; # else -- cgit v1.1 From 2f2aeda98f3aa24034a700e7efcb6c1a9397836f Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 3 Sep 2019 15:08:28 +0000 Subject: Remove Cell Broadband Engine SPU targets From-SVN: r275343 --- libgcc/ChangeLog | 5 + libgcc/config.host | 10 - libgcc/config/spu/cache.S | 43 --- libgcc/config/spu/cachemgr.c | 438 ------------------------------ libgcc/config/spu/divmodti4.c | 188 ------------- libgcc/config/spu/divv2df3.c | 195 ------------- libgcc/config/spu/float_disf.c | 31 --- libgcc/config/spu/float_unsdidf.c | 54 ---- libgcc/config/spu/float_unsdisf.c | 31 --- libgcc/config/spu/float_unssidf.c | 45 --- libgcc/config/spu/mfc_multi_tag_release.c | 72 ----- libgcc/config/spu/mfc_multi_tag_reserve.c | 84 ------ libgcc/config/spu/mfc_tag_release.c | 59 ---- libgcc/config/spu/mfc_tag_reserve.c | 51 ---- libgcc/config/spu/mfc_tag_table.c | 39 --- libgcc/config/spu/multi3.c | 119 -------- libgcc/config/spu/t-elf | 59 ---- 17 files changed, 5 insertions(+), 1518 deletions(-) delete mode 100644 libgcc/config/spu/cache.S delete mode 100644 libgcc/config/spu/cachemgr.c delete mode 100644 libgcc/config/spu/divmodti4.c delete mode 100644 libgcc/config/spu/divv2df3.c delete mode 100644 libgcc/config/spu/float_disf.c delete mode 100644 libgcc/config/spu/float_unsdidf.c delete mode 100644 libgcc/config/spu/float_unsdisf.c delete mode 100644 libgcc/config/spu/float_unssidf.c delete mode 100644 libgcc/config/spu/mfc_multi_tag_release.c delete mode 100644 libgcc/config/spu/mfc_multi_tag_reserve.c delete mode 100644 libgcc/config/spu/mfc_tag_release.c delete mode 100644 libgcc/config/spu/mfc_tag_reserve.c delete mode 100644 libgcc/config/spu/mfc_tag_table.c delete mode 100644 libgcc/config/spu/multi3.c delete mode 100644 libgcc/config/spu/t-elf (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 2067437..1ffb236 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-03 Ulrich Weigand + + * config.host: Remove references to spu. + * config/spu/: Remove directory. + 2019-08-23 Jozef Lawrynowicz PR target/91306 diff --git a/libgcc/config.host b/libgcc/config.host index 503ebb6..a397670 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -189,9 +189,6 @@ sparc64*-*-*) sparc*-*-*) cpu_type=sparc ;; -spu*-*-*) - cpu_type=spu - ;; s390*-*-*) cpu_type=s390 ;; @@ -1369,13 +1366,6 @@ sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux ;; sparc64-*-netbsd*) ;; -spu-*-elf*) - tmake_file="$tmake_file spu/t-elf t-libgcc-pic t-fdpbit" - extra_parts="$extra_parts \ - libgcc_cachemgr.a libgcc_cachemgr_nonatomic.a \ - libgcc_cache8k.a libgcc_cache16k.a libgcc_cache32k.a \ - libgcc_cache64k.a libgcc_cache128k.a" - ;; tic6x-*-uclinux) tmake_file="${tmake_file} t-softfp-sfdf t-softfp-excl t-softfp \ c6x/t-elf c6x/t-uclinux t-crtstuff-pic t-libgcc-pic \ diff --git a/libgcc/config/spu/cache.S b/libgcc/config/spu/cache.S deleted file mode 100644 index 1affe63..0000000 --- a/libgcc/config/spu/cache.S +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (C) 2008-2019 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -. */ - - .data - .p2align 7 - .global __cache -__cache: - .rept __CACHE_SIZE__ * 8 - .fill 128 - .endr - - .p2align 7 - .global __cache_tag_array -__cache_tag_array: - .rept __CACHE_SIZE__ * 2 - .long 1, 1, 1, 1 - .fill 128-16 - .endr -__end_cache_tag_array: - - .globl __cache_tag_array_size - .set __cache_tag_array_size, __end_cache_tag_array-__cache_tag_array - diff --git a/libgcc/config/spu/cachemgr.c b/libgcc/config/spu/cachemgr.c deleted file mode 100644 index 32b2a0e..0000000 --- a/libgcc/config/spu/cachemgr.c +++ /dev/null @@ -1,438 +0,0 @@ -/* Copyright (C) 2008-2019 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -. */ - -#include -#include -#include -#include - -extern unsigned long long __ea_local_store; -extern char __cache_tag_array_size; - -#define LINE_SIZE 128 -#define TAG_MASK (LINE_SIZE - 1) - -#define WAYS 4 -#define SET_MASK ((int) &__cache_tag_array_size - LINE_SIZE) - -#define CACHE_LINES ((int) &__cache_tag_array_size / \ - sizeof (struct __cache_tag_array) * WAYS) - -struct __cache_tag_array -{ - unsigned int tag_lo[WAYS]; - unsigned int tag_hi[WAYS]; - void *base[WAYS]; - int reserved[WAYS]; - vector unsigned short dirty_bits[WAYS]; -}; - -extern struct __cache_tag_array __cache_tag_array[]; -extern char __cache[]; - -/* In order to make the code seem a little cleaner, and to avoid having - 64/32 bit ifdefs all over the place, we use macros. */ - -#ifdef __EA64__ -typedef unsigned long long addr; - -#define CHECK_TAG(_entry, _way, _tag) \ - ((_entry)->tag_lo[(_way)] == ((_tag) & 0xFFFFFFFF) \ - && (_entry)->tag_hi[(_way)] == ((_tag) >> 32)) - -#define GET_TAG(_entry, _way) \ - ((unsigned long long)(_entry)->tag_hi[(_way)] << 32 \ - | (unsigned long long)(_entry)->tag_lo[(_way)]) - -#define SET_TAG(_entry, _way, _tag) \ - (_entry)->tag_lo[(_way)] = (_tag) & 0xFFFFFFFF; \ - (_entry)->tag_hi[(_way)] = (_tag) >> 32 - -#else /*__EA32__*/ -typedef unsigned long addr; - -#define CHECK_TAG(_entry, _way, _tag) \ - ((_entry)->tag_lo[(_way)] == (_tag)) - -#define GET_TAG(_entry, _way) \ - ((_entry)->tag_lo[(_way)]) - -#define SET_TAG(_entry, _way, _tag) \ - (_entry)->tag_lo[(_way)] = (_tag) - -#endif - -/* In GET_ENTRY, we cast away the high 32 bits, - as the tag is only in the low 32. */ - -#define GET_ENTRY(_addr) \ - ((struct __cache_tag_array *) \ - si_to_uint (si_a (si_and (si_from_uint ((unsigned int) (addr) (_addr)), \ - si_from_uint (SET_MASK)), \ - si_from_uint ((unsigned int) __cache_tag_array)))) - -#define GET_CACHE_LINE(_addr, _way) \ - ((void *) (__cache + ((_addr) & SET_MASK) * WAYS) + ((_way) * LINE_SIZE)); - -#define CHECK_DIRTY(_vec) (si_to_uint (si_orx ((qword) (_vec)))) -#define SET_EMPTY(_entry, _way) ((_entry)->tag_lo[(_way)] = 1) -#define CHECK_EMPTY(_entry, _way) ((_entry)->tag_lo[(_way)] == 1) - -#define LS_FLAG 0x80000000 -#define SET_IS_LS(_entry, _way) ((_entry)->reserved[(_way)] |= LS_FLAG) -#define CHECK_IS_LS(_entry, _way) ((_entry)->reserved[(_way)] & LS_FLAG) -#define GET_LRU(_entry, _way) ((_entry)->reserved[(_way)] & ~LS_FLAG) - -static int dma_tag = 32; - -static void -__cache_evict_entry (struct __cache_tag_array *entry, int way) -{ - addr tag = GET_TAG (entry, way); - - if (CHECK_DIRTY (entry->dirty_bits[way]) && !CHECK_IS_LS (entry, way)) - { -#ifdef NONATOMIC - /* Non-atomic writes. */ - unsigned int oldmask, mach_stat; - char *line = ((void *) 0); - - /* Enter critical section. */ - mach_stat = spu_readch (SPU_RdMachStat); - spu_idisable (); - - /* Issue DMA request. */ - line = GET_CACHE_LINE (entry->tag_lo[way], way); - mfc_put (line, tag, LINE_SIZE, dma_tag, 0, 0); - - /* Wait for DMA completion. */ - oldmask = mfc_read_tag_mask (); - mfc_write_tag_mask (1 << dma_tag); - mfc_read_tag_status_all (); - mfc_write_tag_mask (oldmask); - - /* Leave critical section. */ - if (__builtin_expect (mach_stat & 1, 0)) - spu_ienable (); -#else - /* Allocate a buffer large enough that we know it has 128 bytes - that are 128 byte aligned (for DMA). */ - - char buffer[LINE_SIZE + 127]; - qword *buf_ptr = (qword *) (((unsigned int) (buffer) + 127) & ~127); - qword *line = GET_CACHE_LINE (entry->tag_lo[way], way); - qword bits; - unsigned int mach_stat; - - /* Enter critical section. */ - mach_stat = spu_readch (SPU_RdMachStat); - spu_idisable (); - - do - { - /* We atomically read the current memory into a buffer - modify the dirty bytes in the buffer, and write it - back. If writeback fails, loop and try again. */ - - mfc_getllar (buf_ptr, tag, 0, 0); - mfc_read_atomic_status (); - - /* The method we're using to write 16 dirty bytes into - the buffer at a time uses fsmb which in turn uses - the least significant 16 bits of word 0, so we - load the bits and rotate so that the first bit of - the bitmap is in the first bit that fsmb will use. */ - - bits = (qword) entry->dirty_bits[way]; - bits = si_rotqbyi (bits, -2); - - /* Si_fsmb creates the mask of dirty bytes. - Use selb to nab the appropriate bits. */ - buf_ptr[0] = si_selb (buf_ptr[0], line[0], si_fsmb (bits)); - - /* Rotate to next 16 byte section of cache. */ - bits = si_rotqbyi (bits, 2); - - buf_ptr[1] = si_selb (buf_ptr[1], line[1], si_fsmb (bits)); - bits = si_rotqbyi (bits, 2); - buf_ptr[2] = si_selb (buf_ptr[2], line[2], si_fsmb (bits)); - bits = si_rotqbyi (bits, 2); - buf_ptr[3] = si_selb (buf_ptr[3], line[3], si_fsmb (bits)); - bits = si_rotqbyi (bits, 2); - buf_ptr[4] = si_selb (buf_ptr[4], line[4], si_fsmb (bits)); - bits = si_rotqbyi (bits, 2); - buf_ptr[5] = si_selb (buf_ptr[5], line[5], si_fsmb (bits)); - bits = si_rotqbyi (bits, 2); - buf_ptr[6] = si_selb (buf_ptr[6], line[6], si_fsmb (bits)); - bits = si_rotqbyi (bits, 2); - buf_ptr[7] = si_selb (buf_ptr[7], line[7], si_fsmb (bits)); - bits = si_rotqbyi (bits, 2); - - mfc_putllc (buf_ptr, tag, 0, 0); - } - while (mfc_read_atomic_status ()); - - /* Leave critical section. */ - if (__builtin_expect (mach_stat & 1, 0)) - spu_ienable (); -#endif - } - - /* In any case, marking the lo tag with 1 which denotes empty. */ - SET_EMPTY (entry, way); - entry->dirty_bits[way] = (vector unsigned short) si_from_uint (0); -} - -void -__cache_evict (__ea void *ea) -{ - addr tag = (addr) ea & ~TAG_MASK; - struct __cache_tag_array *entry = GET_ENTRY (ea); - int i = 0; - - /* Cycles through all the possible ways an address could be at - and evicts the way if found. */ - - for (i = 0; i < WAYS; i++) - if (CHECK_TAG (entry, i, tag)) - __cache_evict_entry (entry, i); -} - -static void * -__cache_fill (int way, addr tag) -{ - unsigned int oldmask, mach_stat; - char *line = ((void *) 0); - - /* Reserve our DMA tag. */ - if (dma_tag == 32) - dma_tag = mfc_tag_reserve (); - - /* Enter critical section. */ - mach_stat = spu_readch (SPU_RdMachStat); - spu_idisable (); - - /* Issue DMA request. */ - line = GET_CACHE_LINE (tag, way); - mfc_get (line, tag, LINE_SIZE, dma_tag, 0, 0); - - /* Wait for DMA completion. */ - oldmask = mfc_read_tag_mask (); - mfc_write_tag_mask (1 << dma_tag); - mfc_read_tag_status_all (); - mfc_write_tag_mask (oldmask); - - /* Leave critical section. */ - if (__builtin_expect (mach_stat & 1, 0)) - spu_ienable (); - - return (void *) line; -} - -static void -__cache_miss (__ea void *ea, struct __cache_tag_array *entry, int way) -{ - - addr tag = (addr) ea & ~TAG_MASK; - unsigned int lru = 0; - int i = 0; - int idx = 0; - - /* If way > 4, then there are no empty slots, so we must evict - the least recently used entry. */ - if (way >= 4) - { - for (i = 0; i < WAYS; i++) - { - if (GET_LRU (entry, i) > lru) - { - lru = GET_LRU (entry, i); - idx = i; - } - } - __cache_evict_entry (entry, idx); - way = idx; - } - - /* Set the empty entry's tag and fill it's cache line. */ - - SET_TAG (entry, way, tag); - entry->reserved[way] = 0; - - /* Check if the address is just an effective address within the - SPU's local store. */ - - /* Because the LS is not 256k aligned, we can't do a nice and mask - here to compare, so we must check the whole range. */ - - if ((addr) ea >= (addr) __ea_local_store - && (addr) ea < (addr) (__ea_local_store + 0x40000)) - { - SET_IS_LS (entry, way); - entry->base[way] = - (void *) ((unsigned int) ((addr) ea - - (addr) __ea_local_store) & ~0x7f); - } - else - { - entry->base[way] = __cache_fill (way, tag); - } -} - -void * -__cache_fetch_dirty (__ea void *ea, int n_bytes_dirty) -{ -#ifdef __EA64__ - unsigned int tag_hi; - qword etag_hi; -#endif - unsigned int tag_lo; - struct __cache_tag_array *entry; - - qword etag_lo; - qword equal; - qword bit_mask; - qword way; - - /* This first chunk, we merely fill the pointer and tag. */ - - entry = GET_ENTRY (ea); - -#ifndef __EA64__ - tag_lo = - si_to_uint (si_andc - (si_shufb - (si_from_uint ((addr) ea), si_from_uint (0), - si_from_uint (0x00010203)), si_from_uint (TAG_MASK))); -#else - tag_lo = - si_to_uint (si_andc - (si_shufb - (si_from_ullong ((addr) ea), si_from_uint (0), - si_from_uint (0x04050607)), si_from_uint (TAG_MASK))); - - tag_hi = - si_to_uint (si_shufb - (si_from_ullong ((addr) ea), si_from_uint (0), - si_from_uint (0x00010203))); -#endif - - /* Increment LRU in reserved bytes. */ - si_stqd (si_ai (si_lqd (si_from_ptr (entry), 48), 1), - si_from_ptr (entry), 48); - -missreturn: - /* Check if the entry's lo_tag is equal to the address' lo_tag. */ - etag_lo = si_lqd (si_from_ptr (entry), 0); - equal = si_ceq (etag_lo, si_from_uint (tag_lo)); -#ifdef __EA64__ - /* And the high tag too. */ - etag_hi = si_lqd (si_from_ptr (entry), 16); - equal = si_and (equal, (si_ceq (etag_hi, si_from_uint (tag_hi)))); -#endif - - if ((si_to_uint (si_orx (equal)) == 0)) - goto misshandler; - - if (n_bytes_dirty) - { - /* way = 0x40,0x50,0x60,0x70 for each way, which is also the - offset of the appropriate dirty bits. */ - way = si_shli (si_clz (si_gbb (equal)), 2); - - /* To create the bit_mask, we set it to all 1s (uint -1), then we - shift it over (128 - n_bytes_dirty) times. */ - - bit_mask = si_from_uint (-1); - - bit_mask = - si_shlqby (bit_mask, si_from_uint ((LINE_SIZE - n_bytes_dirty) / 8)); - - bit_mask = - si_shlqbi (bit_mask, si_from_uint ((LINE_SIZE - n_bytes_dirty) % 8)); - - /* Rotate it around to the correct offset. */ - bit_mask = - si_rotqby (bit_mask, - si_from_uint (-1 * ((addr) ea & TAG_MASK) / 8)); - - bit_mask = - si_rotqbi (bit_mask, - si_from_uint (-1 * ((addr) ea & TAG_MASK) % 8)); - - /* Update the dirty bits. */ - si_stqx (si_or (si_lqx (si_from_ptr (entry), way), bit_mask), - si_from_ptr (entry), way); - }; - - /* We've definitely found the right entry, set LRU (reserved) to 0 - maintaining the LS flag (MSB). */ - - si_stqd (si_andc - (si_lqd (si_from_ptr (entry), 48), - si_and (equal, si_from_uint (~(LS_FLAG)))), - si_from_ptr (entry), 48); - - return (void *) - si_to_uint (si_a - (si_orx - (si_and (si_lqd (si_from_ptr (entry), 32), equal)), - si_from_uint (((unsigned int) (addr) ea) & TAG_MASK))); - -misshandler: - equal = si_ceqi (etag_lo, 1); - __cache_miss (ea, entry, (si_to_uint (si_clz (si_gbb (equal))) - 16) >> 2); - goto missreturn; -} - -void * -__cache_fetch (__ea void *ea) -{ - return __cache_fetch_dirty (ea, 0); -} - -void -__cache_touch (__ea void *ea __attribute__ ((unused))) -{ - /* NO-OP for now. */ -} - -void __cache_flush (void) __attribute__ ((destructor)); -void -__cache_flush (void) -{ - struct __cache_tag_array *entry = __cache_tag_array; - unsigned int i; - int j; - - /* Cycle through each cache entry and evict all used ways. */ - - for (i = 0; i < CACHE_LINES / WAYS; i++) - { - for (j = 0; j < WAYS; j++) - if (!CHECK_EMPTY (entry, j)) - __cache_evict_entry (entry, j); - - entry++; - } -} diff --git a/libgcc/config/spu/divmodti4.c b/libgcc/config/spu/divmodti4.c deleted file mode 100644 index db9fdf9..0000000 --- a/libgcc/config/spu/divmodti4.c +++ /dev/null @@ -1,188 +0,0 @@ -/* Copyright (C) 2008-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - . */ - -#include - -typedef unsigned int UTItype __attribute__ ((mode (TI))); -typedef int TItype __attribute__ ((mode (TI))); -TItype __divti3 (TItype u, TItype v); -TItype __modti3 (TItype u, TItype v); -UTItype __udivti3 (UTItype u, UTItype v); -UTItype __umodti3 (UTItype u, UTItype v); -UTItype __udivmodti4 (UTItype u, UTItype v, UTItype *w); - -union qword_UTItype - { - qword q; - UTItype t; - }; - -inline static qword -si_from_UTItype (UTItype t) -{ - union qword_UTItype u; - u.t = t; - return u.q; -} - -inline static UTItype -si_to_UTItype (qword q) -{ - union qword_UTItype u; - u.q = q; - return u.t; -} - -inline static unsigned int -count_leading_zeros (UTItype x) -{ - qword c = si_clz (*(qword *) & x); - qword cmp0 = si_cgti (c, 31); - qword cmp1 = si_and (cmp0, si_shlqbyi (cmp0, 4)); - qword cmp2 = si_and (cmp1, si_shlqbyi (cmp0, 8)); - qword s = si_a (c, si_and (cmp0, si_shlqbyi (c, 4))); - s = si_a (s, si_and (cmp1, si_shlqbyi (c, 8))); - s = si_a (s, si_and (cmp2, si_shlqbyi (c, 12))); - return si_to_uint (s); -} - -/* Based on implementation of udivmodsi4, which is essentially - * an optimized version of libgcc/udivmodsi4.c - clz %7,%2 - clz %4,%1 - il %5,1 - fsmbi %0,0 - sf %7,%4,%7 - ori %3,%1,0 - shl %5,%5,%7 - shl %4,%2,%7 -1: or %8,%0,%5 - rotmi %5,%5,-1 - clgt %6,%4,%3 - sf %7,%4,%3 - rotmi %4,%4,-1 - selb %0,%8,%0,%6 - selb %3,%7,%3,%6 -3: brnz %5,1b - */ - -UTItype -__udivmodti4 (UTItype num, UTItype den, UTItype * rp) -{ - qword shift = - si_from_uint (count_leading_zeros (den) - count_leading_zeros (num)); - qword n0 = si_from_UTItype (num); - qword d0 = si_from_UTItype (den); - qword bit = si_andi (si_fsmbi (1), 1); - qword r0 = si_il (0); - qword m1 = si_fsmbi (0x000f); - qword mask, r1, n1; - - d0 = si_shlqbybi (si_shlqbi (d0, shift), shift); - bit = si_shlqbybi (si_shlqbi (bit, shift), shift); - - do - { - r1 = si_or (r0, bit); - - // n1 = n0 - d0 in TImode - n1 = si_bg (d0, n0); - n1 = si_shlqbyi (n1, 4); - n1 = si_sf (m1, n1); - n1 = si_bgx (d0, n0, n1); - n1 = si_shlqbyi (n1, 4); - n1 = si_sf (m1, n1); - n1 = si_bgx (d0, n0, n1); - n1 = si_shlqbyi (n1, 4); - n1 = si_sf (m1, n1); - n1 = si_sfx (d0, n0, n1); - - mask = si_fsm (si_cgti (n1, -1)); - r0 = si_selb (r0, r1, mask); - n0 = si_selb (n0, n1, mask); - bit = si_rotqmbii (bit, -1); - d0 = si_rotqmbii (d0, -1); - } - while (si_to_uint (si_orx (bit))); - if (rp) - *rp = si_to_UTItype (n0); - return si_to_UTItype (r0); -} - -UTItype -__udivti3 (UTItype n, UTItype d) -{ - return __udivmodti4 (n, d, (UTItype *)0); -} - -UTItype -__umodti3 (UTItype n, UTItype d) -{ - UTItype w; - __udivmodti4 (n, d, &w); - return w; -} - -TItype -__divti3 (TItype n, TItype d) -{ - int c = 0; - TItype w; - - if (n < 0) - { - c = ~c; - n = -n; - } - if (d < 0) - { - c = ~c; - d = -d; - } - - w = __udivmodti4 (n, d, (UTItype *)0); - if (c) - w = -w; - return w; -} - -TItype -__modti3 (TItype n, TItype d) -{ - int c = 0; - TItype w; - - if (n < 0) - { - c = ~c; - n = -n; - } - if (d < 0) - { - c = ~c; - d = -d; - } - - __udivmodti4 (n, d, (UTItype *) &w); - if (c) - w = -w; - return w; -} diff --git a/libgcc/config/spu/divv2df3.c b/libgcc/config/spu/divv2df3.c deleted file mode 100644 index f4e95a9..0000000 --- a/libgcc/config/spu/divv2df3.c +++ /dev/null @@ -1,195 +0,0 @@ -/* Copyright (C) 2009-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - . */ - -#include - -vector double __divv2df3 (vector double a_in, vector double b_in); - -/* __divv2df3 divides the vector dividend a by the vector divisor b and - returns the resulting vector quotient. Maximum error about 0.5 ulp - over entire double range including denorms, compared to true result - in round-to-nearest rounding mode. Handles Inf or NaN operands and - results correctly. */ - -vector double -__divv2df3 (vector double a_in, vector double b_in) -{ - /* Variables */ - vec_int4 exp, exp_bias; - vec_uint4 no_underflow, overflow; - vec_float4 mant_bf, inv_bf; - vec_ullong2 exp_a, exp_b; - vec_ullong2 a_nan, a_zero, a_inf, a_denorm, a_denorm0; - vec_ullong2 b_nan, b_zero, b_inf, b_denorm, b_denorm0; - vec_ullong2 nan; - vec_uint4 a_exp, b_exp; - vec_ullong2 a_mant_0, b_mant_0; - vec_ullong2 a_exp_1s, b_exp_1s; - vec_ullong2 sign_exp_mask; - - vec_double2 a, b; - vec_double2 mant_a, mant_b, inv_b, q0, q1, q2, mult; - - /* Constants */ - vec_uint4 exp_mask_u32 = spu_splats((unsigned int)0x7FF00000); - vec_uchar16 splat_hi = (vec_uchar16){0,1,2,3, 0,1,2,3, 8, 9,10,11, 8,9,10,11}; - vec_uchar16 swap_32 = (vec_uchar16){4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11}; - vec_ullong2 exp_mask = spu_splats(0x7FF0000000000000ULL); - vec_ullong2 sign_mask = spu_splats(0x8000000000000000ULL); - vec_float4 onef = spu_splats(1.0f); - vec_double2 one = spu_splats(1.0); - vec_double2 exp_53 = (vec_double2)spu_splats(0x0350000000000000ULL); - - sign_exp_mask = spu_or(sign_mask, exp_mask); - - /* Extract the floating point components from each of the operands including - * exponent and mantissa. - */ - a_exp = (vec_uint4)spu_and((vec_uint4)a_in, exp_mask_u32); - a_exp = spu_shuffle(a_exp, a_exp, splat_hi); - b_exp = (vec_uint4)spu_and((vec_uint4)b_in, exp_mask_u32); - b_exp = spu_shuffle(b_exp, b_exp, splat_hi); - - a_mant_0 = (vec_ullong2)spu_cmpeq((vec_uint4)spu_andc((vec_ullong2)a_in, sign_exp_mask), 0); - a_mant_0 = spu_and(a_mant_0, spu_shuffle(a_mant_0, a_mant_0, swap_32)); - - b_mant_0 = (vec_ullong2)spu_cmpeq((vec_uint4)spu_andc((vec_ullong2)b_in, sign_exp_mask), 0); - b_mant_0 = spu_and(b_mant_0, spu_shuffle(b_mant_0, b_mant_0, swap_32)); - - a_exp_1s = (vec_ullong2)spu_cmpeq(a_exp, exp_mask_u32); - b_exp_1s = (vec_ullong2)spu_cmpeq(b_exp, exp_mask_u32); - - /* Identify all possible special values that must be accommodated including: - * +-denorm, +-0, +-infinity, and NaNs. - */ - a_denorm0= (vec_ullong2)spu_cmpeq(a_exp, 0); - a_nan = spu_andc(a_exp_1s, a_mant_0); - a_zero = spu_and (a_denorm0, a_mant_0); - a_inf = spu_and (a_exp_1s, a_mant_0); - a_denorm = spu_andc(a_denorm0, a_zero); - - b_denorm0= (vec_ullong2)spu_cmpeq(b_exp, 0); - b_nan = spu_andc(b_exp_1s, b_mant_0); - b_zero = spu_and (b_denorm0, b_mant_0); - b_inf = spu_and (b_exp_1s, b_mant_0); - b_denorm = spu_andc(b_denorm0, b_zero); - - /* Scale denorm inputs to into normalized numbers by conditionally scaling the - * input parameters. - */ - a = spu_sub(spu_or(a_in, exp_53), spu_sel(exp_53, a_in, sign_mask)); - a = spu_sel(a_in, a, a_denorm); - - b = spu_sub(spu_or(b_in, exp_53), spu_sel(exp_53, b_in, sign_mask)); - b = spu_sel(b_in, b, b_denorm); - - /* Extract the divisor and dividend exponent and force parameters into the signed - * range [1.0,2.0) or [-1.0,2.0). - */ - exp_a = spu_and((vec_ullong2)a, exp_mask); - exp_b = spu_and((vec_ullong2)b, exp_mask); - - mant_a = spu_sel(a, one, (vec_ullong2)exp_mask); - mant_b = spu_sel(b, one, (vec_ullong2)exp_mask); - - /* Approximate the single reciprocal of b by using - * the single precision reciprocal estimate followed by one - * single precision iteration of Newton-Raphson. - */ - mant_bf = spu_roundtf(mant_b); - inv_bf = spu_re(mant_bf); - inv_bf = spu_madd(spu_nmsub(mant_bf, inv_bf, onef), inv_bf, inv_bf); - - /* Perform 2 more Newton-Raphson iterations in double precision. The - * result (q1) is in the range (0.5, 2.0). - */ - inv_b = spu_extend(inv_bf); - inv_b = spu_madd(spu_nmsub(mant_b, inv_b, one), inv_b, inv_b); - q0 = spu_mul(mant_a, inv_b); - q1 = spu_madd(spu_nmsub(mant_b, q0, mant_a), inv_b, q0); - - /* Determine the exponent correction factor that must be applied - * to q1 by taking into account the exponent of the normalized inputs - * and the scale factors that were applied to normalize them. - */ - exp = spu_rlmaska(spu_sub((vec_int4)exp_a, (vec_int4)exp_b), -20); - exp = spu_add(exp, (vec_int4)spu_add(spu_and((vec_int4)a_denorm, -0x34), spu_and((vec_int4)b_denorm, 0x34))); - - /* Bias the quotient exponent depending on the sign of the exponent correction - * factor so that a single multiplier will ensure the entire double precision - * domain (including denorms) can be achieved. - * - * exp bias q1 adjust exp - * ===== ======== ========== - * positive 2^+65 -65 - * negative 2^-64 +64 - */ - exp_bias = spu_xor(spu_rlmaska(exp, -31), 64); - exp = spu_sub(exp, exp_bias); - - q1 = spu_sel(q1, (vec_double2)spu_add((vec_int4)q1, spu_sl(exp_bias, 20)), exp_mask); - - /* Compute a multiplier (mult) to applied to the quotient (q1) to produce the - * expected result. On overflow, clamp the multiplier to the maximum non-infinite - * number in case the rounding mode is not round-to-nearest. - */ - exp = spu_add(exp, 0x3FF); - no_underflow = spu_cmpgt(exp, 0); - overflow = spu_cmpgt(exp, 0x7FE); - exp = spu_and(spu_sl(exp, 20), (vec_int4)no_underflow); - exp = spu_and(exp, (vec_int4)exp_mask); - - mult = spu_sel((vec_double2)exp, (vec_double2)(spu_add((vec_uint4)exp_mask, -1)), (vec_ullong2)overflow); - - /* Handle special value conditions. These include: - * - * 1) IF either operand is a NaN OR both operands are 0 or INFINITY THEN a NaN - * results. - * 2) ELSE IF the dividend is an INFINITY OR the divisor is 0 THEN a INFINITY results. - * 3) ELSE IF the dividend is 0 OR the divisor is INFINITY THEN a 0 results. - */ - mult = spu_andc(mult, (vec_double2)spu_or(a_zero, b_inf)); - mult = spu_sel(mult, (vec_double2)exp_mask, spu_or(a_inf, b_zero)); - - nan = spu_or(a_nan, b_nan); - nan = spu_or(nan, spu_and(a_zero, b_zero)); - nan = spu_or(nan, spu_and(a_inf, b_inf)); - - mult = spu_or(mult, (vec_double2)nan); - - /* Scale the final quotient */ - - q2 = spu_mul(q1, mult); - - return (q2); -} - - -/* We use the same function for vector and scalar division. Provide the - scalar entry point as an alias. */ -double __divdf3 (double a, double b) - __attribute__ ((__alias__ ("__divv2df3"))); - -/* Some toolchain builds used the __fast_divdf3 name for this helper function. - Provide this as another alternate entry point for compatibility. */ -double __fast_divdf3 (double a, double b) - __attribute__ ((__alias__ ("__divv2df3"))); - diff --git a/libgcc/config/spu/float_disf.c b/libgcc/config/spu/float_disf.c deleted file mode 100644 index 1cdfa80..0000000 --- a/libgcc/config/spu/float_disf.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2008-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - . */ - -/* Prototype. */ -float __floatdisf (long long x); - -float __floatdisf (long long x) -{ - /* The SPU back-end now generates inline code for this conversion. - This file is solely used to provide the __floatdisf functions - for objects generated with prior versions of GCC. */ - return x; -} diff --git a/libgcc/config/spu/float_unsdidf.c b/libgcc/config/spu/float_unsdidf.c deleted file mode 100644 index 81dab3c..0000000 --- a/libgcc/config/spu/float_unsdidf.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 2006-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - . */ - -#include -const unsigned char __didf_scale[16] __attribute__ ((__aligned__ (16))) = { - 0x00, 0x00, 0x04, 0x3e, - 0x00, 0x00, 0x04, 0x1e, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; -const unsigned char __didf_pat[16] __attribute__ ((__aligned__ (16))) = { - 0x02, 0x03, 0x10, 0x11, - 0x12, 0x13, 0x80, 0x80, - 0x06, 0x07, 0x14, 0x15, - 0x16, 0x17, 0x80, 0x80 -}; - -/* double __float_unsdidf (unsigned long long int) - Construct two exact doubles representing the high and low parts (in - parallel), then add them. */ -qword __float_unsdidf (qword DI); -qword -__float_unsdidf (qword DI) -{ - qword t0, t1, t2, t3, t4, t5, t6, t7, t8; - t0 = si_clz (DI); - t1 = si_shl (DI, t0); - t2 = si_ceqi (t0, 32); - t3 = si_sf (t0, *(const qword *) __didf_scale); - t4 = si_a (t1, t1); - t5 = si_andc (t3, t2); - t6 = si_shufb (t5, t4, *(const qword *) __didf_pat); - t7 = si_shlqbii (t6, 4); - t8 = si_shlqbyi (t7, 8); - return si_dfa (t7, t8); -} diff --git a/libgcc/config/spu/float_unsdisf.c b/libgcc/config/spu/float_unsdisf.c deleted file mode 100644 index 93e1bd306..0000000 --- a/libgcc/config/spu/float_unsdisf.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2008-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - . */ - -/* Prototype. */ -float __floatundisf (unsigned long long x); - -float __floatundisf (unsigned long long x) -{ - /* The SPU back-end now generates inline code for this conversion. - This file is solely used to provide the __floatundisf function - for objects generated with prior versions of GCC. */ - return x; -} diff --git a/libgcc/config/spu/float_unssidf.c b/libgcc/config/spu/float_unssidf.c deleted file mode 100644 index 7f78977..0000000 --- a/libgcc/config/spu/float_unssidf.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2006-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - . */ - -#include -const unsigned char __sidf_pat[16] __attribute__ ((__aligned__ (16))) = { - 0x02, 0x03, 0x10, 0x11, - 0x12, 0x13, 0x80, 0x80, - 0x06, 0x07, 0x14, 0x15, - 0x16, 0x17, 0x80, 0x80 -}; - -/* double __float_unssidf (unsigned int SI) */ -qword __float_unssidf (qword SI); -qword -__float_unssidf (qword SI) -{ - qword t0, t1, t2, t3, t4, t5, t6, t7; - t0 = si_clz (SI); - t1 = si_il (1054); - t2 = si_shl (SI, t0); - t3 = si_ceqi (t0, 32); - t4 = si_sf (t0, t1); - t5 = si_a (t2, t2); - t6 = si_andc (t4, t3); - t7 = si_shufb (t6, t5, *(const qword *) __sidf_pat); - return si_shlqbii (t7, 4); -} diff --git a/libgcc/config/spu/mfc_multi_tag_release.c b/libgcc/config/spu/mfc_multi_tag_release.c deleted file mode 100644 index 36ce140..0000000 --- a/libgcc/config/spu/mfc_multi_tag_release.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (C) 2007-2019 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -. */ - -#include -extern vector unsigned int __mfc_tag_table; - -/* Release a sequential group of tags from exclusive use. The sequential - group of tags is the range starting from through - +-1. Upon successful release, MFC_DMA_TAG_VALID - is returned and the tags become available for future reservation. - - If the specified tags were not previously reserved, no action is - taken and MFC_DMA_TAG_INVALID is returned. */ - -unsigned int -__mfc_multi_tag_release (unsigned int first_tag, unsigned int number_of_tags) -{ - vector unsigned int table_copy, tmp, tmp1; - vector unsigned int one = (vector unsigned int) - { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; - vector unsigned int is_invalid; - unsigned int last_tag; - vector unsigned int has_been_reserved; - - last_tag = first_tag + number_of_tags; - - table_copy = spu_sl (one, number_of_tags); - table_copy = spu_rl (table_copy, -last_tag); - table_copy = spu_xor (table_copy, -1); - - /* Make sure the tags are in range and valid. */ - tmp = spu_cmpgt (spu_promote(last_tag, 0), 32); - tmp1 = spu_cmpgt (spu_promote(number_of_tags, 0), 32); - is_invalid = spu_cmpgt (spu_promote(first_tag, 0), 31); - - /* All bits are set to 1 if invalid, 0 if valid. */ - is_invalid = spu_or (tmp, is_invalid); - is_invalid = spu_or (tmp1, is_invalid); - - /* check whether these tags have been reserved */ - tmp = spu_rlmask (one, (int)-number_of_tags); - tmp1 = spu_sl (__mfc_tag_table, first_tag); - has_been_reserved = spu_cmpgt(tmp1, tmp); - - is_invalid = spu_or (has_been_reserved, is_invalid); - - table_copy = spu_sel (__mfc_tag_table, table_copy, table_copy); - __mfc_tag_table = spu_sel (table_copy, __mfc_tag_table, is_invalid); - - return spu_extract (is_invalid, 0); -} - diff --git a/libgcc/config/spu/mfc_multi_tag_reserve.c b/libgcc/config/spu/mfc_multi_tag_reserve.c deleted file mode 100644 index 598c14e..0000000 --- a/libgcc/config/spu/mfc_multi_tag_reserve.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (C) 2007-2019 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -. */ - -#include -extern vector unsigned int __mfc_tag_table; - -/* Reserve a sequential group of tags for exclusive use. The number of - tags to be reserved is specified by the parameter. - This routine returns the first tag ID for a sequential list of - available tags and marks them as reserved. The reserved group - of tags is in the range starting from the returned tag through - the returned tag + -1. - - If the number of tags requested exceeds the number of available - sequential tags, then MFC_DMA_TAG_INVALID is returned indicating - that the request could not be serviced. */ - -unsigned int -__mfc_multi_tag_reserve (unsigned int number_of_tags) -{ - vector unsigned int table_copy; - vector unsigned int one = (vector unsigned int) - { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; - vector unsigned int count_busy, is_valid; - vector unsigned int count_total; - vector unsigned int count_avail = (vector unsigned int) { 0, 0, 0, 0 }; - vector unsigned int index = (vector unsigned int) { 0, 0, 0, 0 }; - - table_copy = __mfc_tag_table; - - - /* count_busy: number of consecutive busy tags - count_avail: number of consecutive free tags - table_copy: temporary copy of the tag table - count_total: sum of count_busy and count_avail - index: index of the current working tag */ - do - { - table_copy = spu_sl (table_copy, count_avail); - - count_busy = spu_cntlz (table_copy); - table_copy = spu_sl (table_copy, count_busy); - count_avail = spu_cntlz (spu_xor(table_copy, -1)); - count_total = spu_add (count_busy, count_avail); - index = spu_add (index, count_total); - } - while (spu_extract (count_avail, 0) < number_of_tags - && spu_extract (table_copy, 0) != 0); - - index = spu_sub (index, count_avail); - - /* is_valid is set to 0xFFFFFFFF if table_copy == 0, 0 otherwise. */ - is_valid = spu_cmpeq (table_copy, 0); - index = spu_sel (index, is_valid, is_valid); - - /* Now I need to actually mark the tags as used. */ - table_copy = spu_sl (one, number_of_tags); - table_copy = spu_rl (table_copy, -number_of_tags - spu_extract (index, 0)); - table_copy = spu_sel (table_copy, __mfc_tag_table, table_copy); - __mfc_tag_table = spu_sel (table_copy, __mfc_tag_table, is_valid); - - return spu_extract (index, 0); -} - diff --git a/libgcc/config/spu/mfc_tag_release.c b/libgcc/config/spu/mfc_tag_release.c deleted file mode 100644 index 29e8bac..0000000 --- a/libgcc/config/spu/mfc_tag_release.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (C) 2007-2019 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -. */ - -#include -extern vector unsigned int __mfc_tag_table; - -/* Release the specified DMA tag from exclusive use. Once released, the - tag is available for future reservation. Upon successful release, - MFC_DMA_TAG_VALID is returned. If the specified tag is not in the - range 0 to 31, or had not been reserved, no action is taken and - MFC_DMA_TAG_INVALID is returned. */ - -unsigned int -__mfc_tag_release (unsigned int tag) -{ - vector unsigned int is_invalid; - vector unsigned int mask = (vector unsigned int) - { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; - vector signed int zero = (vector signed int) { 0, 0, 0, 0 }; - - vector signed int has_been_reserved; - - /* Check if the tag is out of range. */ - is_invalid = spu_cmpgt (spu_promote (tag, 0), 31); - - /* Check whether the tag has been reserved, set to all 1 if has not - been reserved, 0 otherwise. */ - has_been_reserved = (vector signed int) spu_rl (__mfc_tag_table, tag); - has_been_reserved = (vector signed int) spu_cmpgt (zero, has_been_reserved); - - /* Set invalid. */ - is_invalid = spu_or ((vector unsigned int) has_been_reserved, is_invalid); - - mask = spu_rlmask (mask, (int)(-tag)); - __mfc_tag_table = spu_or (__mfc_tag_table, mask); - - return spu_extract(is_invalid, 0); -} - diff --git a/libgcc/config/spu/mfc_tag_reserve.c b/libgcc/config/spu/mfc_tag_reserve.c deleted file mode 100644 index e2e09da..0000000 --- a/libgcc/config/spu/mfc_tag_reserve.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (C) 2007-2019 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -. */ - -#include -extern vector unsigned int __mfc_tag_table; - -/* Reserves a DMA tag for exclusive use. This routine returns an available - tag id in the range 0 to 31 and marks the tag as reserved. If no tags - are available, MFC_DMA_TAG_INVALID is returned indicating that all tags - are already reserved. */ - -unsigned int -__mfc_tag_reserve (void) -{ - vector unsigned int mask = (vector unsigned int) - { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; - vector unsigned int count_zeros, is_valid; - vector signed int count_neg; - - count_zeros = spu_cntlz (__mfc_tag_table); - count_neg = spu_sub (0, (vector signed int) count_zeros); - - mask = spu_rlmask (mask, (vector signed int) count_neg); - __mfc_tag_table = spu_andc (__mfc_tag_table, mask); - - is_valid = spu_cmpeq (count_zeros, 32); - count_zeros = spu_sel (count_zeros, is_valid, is_valid); - - return spu_extract (count_zeros, 0); -} - diff --git a/libgcc/config/spu/mfc_tag_table.c b/libgcc/config/spu/mfc_tag_table.c deleted file mode 100644 index 34a640a..0000000 --- a/libgcc/config/spu/mfc_tag_table.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2007-2019 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -. */ - -/* The free tag table used by the MFC tag manager, with tag0 - reserved for the overlay manager. */ -__vector unsigned int -__mfc_tag_table = (__vector unsigned int) { 0x7FFFFFFF, -1, -1, -1 }; - -/* Arrange to release tag0 if overlays are not present. */ -static void __mfc_tag_init (void) __attribute__ ((constructor)); - -static void -__mfc_tag_init (void) -{ - extern void _ovly_table __attribute__ ((weak)); - - if (&_ovly_table == 0) - __mfc_tag_table = (__vector unsigned int) { -1, -1, -1, -1 }; -} diff --git a/libgcc/config/spu/multi3.c b/libgcc/config/spu/multi3.c deleted file mode 100644 index c582e46..0000000 --- a/libgcc/config/spu/multi3.c +++ /dev/null @@ -1,119 +0,0 @@ -/* Copyright (C) 2008-2019 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - . */ - -#include - -typedef int TItype __attribute__ ((mode (TI))); - -union qword_TItype - { - qword q; - TItype t; - }; - -inline static qword -si_from_TItype (TItype t) -{ - union qword_TItype u; - u.t = t; - return u.q; -} - -inline static TItype -si_to_TItype (qword q) -{ - union qword_TItype u; - u.q = q; - return u.t; -} - -/* A straight forward vectorization and unrolling of - * short l[8], r[8]; - * TItype total = 0; - * for (i = 0; i < 8; i++) - * for (j = 0; j < 8; j++) - * total += (TItype)((l[7-i] * r[7-j]) << (16 * (i + j))); - */ -TItype -__multi3 (TItype l, TItype r) -{ - qword u = si_from_TItype (l); - qword v = si_from_TItype (r); - qword splat0 = si_shufb (v, v, si_ilh (0x0001)); - qword splat1 = si_shufb (v, v, si_ilh (0x0203)); - qword splat2 = si_shufb (v, v, si_ilh (0x0405)); - qword splat3 = si_shufb (v, v, si_ilh (0x0607)); - qword splat4 = si_shufb (v, v, si_ilh (0x0809)); - qword splat5 = si_shufb (v, v, si_ilh (0x0a0b)); - qword splat6 = si_shufb (v, v, si_ilh (0x0c0d)); - qword splat7 = si_shufb (v, v, si_ilh (0x0e0f)); - - qword part0l = si_shlqbyi (si_mpyu (u, splat0), 14); - qword part1h = si_shlqbyi (si_mpyhhu (u, splat1), 14); - qword part1l = si_shlqbyi (si_mpyu (u, splat1), 12); - qword part2h = si_shlqbyi (si_mpyhhu (u, splat2), 12); - qword part2l = si_shlqbyi (si_mpyu (u, splat2), 10); - qword part3h = si_shlqbyi (si_mpyhhu (u, splat3), 10); - qword part3l = si_shlqbyi (si_mpyu (u, splat3), 8); - qword part4h = si_shlqbyi (si_mpyhhu (u, splat4), 8); - qword part4l = si_shlqbyi (si_mpyu (u, splat4), 6); - qword part5h = si_shlqbyi (si_mpyhhu (u, splat5), 6); - qword part5l = si_shlqbyi (si_mpyu (u, splat5), 4); - qword part6h = si_shlqbyi (si_mpyhhu (u, splat6), 4); - qword part6l = si_shlqbyi (si_mpyu (u, splat6), 2); - qword part7h = si_shlqbyi (si_mpyhhu (u, splat7), 2); - qword part7l = si_mpyu (u, splat7); - - qword carry, total0, total1, total2, total3, total4; - qword total5, total6, total7, total8, total9, total10; - qword total; - - total0 = si_a (si_a (si_a (part0l, part1h), si_a (part1l, part2h)), part7l); - total1 = si_a (part2l, part3h); - total2 = si_a (part3l, part4h); - total3 = si_a (part4l, part5h); - total4 = si_a (part5l, part6h); - total5 = si_a (part6l, part7h); - total6 = si_a (total0, total1); - total7 = si_a (total2, total3); - total8 = si_a (total4, total5); - total9 = si_a (total6, total7); - total10 = si_a (total8, total9); - - carry = si_cg (part2l, part3h); - carry = si_a (carry, si_cg (part3l, part4h)); - carry = si_a (carry, si_cg (part4l, part5h)); - carry = si_a (carry, si_cg (part5l, part6h)); - carry = si_a (carry, si_cg (part6l, part7h)); - carry = si_a (carry, si_cg (total0, total1)); - carry = si_a (carry, si_cg (total2, total3)); - carry = si_a (carry, si_cg (total4, total5)); - carry = si_a (carry, si_cg (total6, total7)); - carry = si_a (carry, si_cg (total8, total9)); - carry = si_shlqbyi (carry, 4); - - total = si_cg (total10, carry); - total = si_shlqbyi (total, 4); - total = si_cgx (total10, carry, total); - total = si_shlqbyi (total, 4); - total = si_addx (total10, carry, total); - return si_to_TItype (total); -} diff --git a/libgcc/config/spu/t-elf b/libgcc/config/spu/t-elf deleted file mode 100644 index 29536e8..0000000 --- a/libgcc/config/spu/t-elf +++ /dev/null @@ -1,59 +0,0 @@ -# Don't let CTOR_LIST end up in sdata section. -# FIXME: This is the default. -CRTSTUFF_T_CFLAGS = - -# We exclude those because the libgcc2.c default versions do not support -# the SPU single-precision format (round towards zero). We provide our -# own versions below and/or via direct expansion. -LIB2FUNCS_EXCLUDE = _floatdisf _floatundisf _floattisf _floatunstisf - -LIB2ADD_ST = $(srcdir)/config/spu/float_unssidf.c \ - $(srcdir)/config/spu/float_unsdidf.c \ - $(srcdir)/config/spu/float_unsdisf.c \ - $(srcdir)/config/spu/float_disf.c \ - $(srcdir)/config/spu/mfc_tag_table.c \ - $(srcdir)/config/spu/mfc_tag_reserve.c \ - $(srcdir)/config/spu/mfc_tag_release.c \ - $(srcdir)/config/spu/mfc_multi_tag_reserve.c \ - $(srcdir)/config/spu/mfc_multi_tag_release.c \ - $(srcdir)/config/spu/multi3.c \ - $(srcdir)/config/spu/divmodti4.c \ - $(srcdir)/config/spu/divv2df3.c - -# Build TImode conversion routines to support Fortran 128-bit -# integer data types. -LIB2_SIDITI_CONV_FUNCS = yes - -HOST_LIBGCC2_CFLAGS += -mwarn-reloc -D__IN_LIBGCC2 - -# Neither gcc or newlib seem to have a standard way to generate multiple -# crt*.o files. So we don't use the standard crt0.o name anymore. - -cachemgr.o: $(srcdir)/config/spu/cachemgr.c - $(gcc_compile) -c $< - -# Specialised rule to add a -D flag. -cachemgr_nonatomic.o: $(srcdir)/config/spu/cachemgr.c - $(gcc_compile) -DNONATOMIC -c $< - -libgcc_%.a: %.o - $(AR_FOR_TARGET) -rcs $@ $< - -cache8k.o: $(srcdir)/config/spu/cache.S - $(gcc_compile) -D__CACHE_SIZE__=8 -c $< - -cache16k.o: $(srcdir)/config/spu/cache.S - $(gcc_compile) -D__CACHE_SIZE__=16 -c $< - -cache32k.o: $(srcdir)/config/spu/cache.S - $(gcc_compile) -D__CACHE_SIZE__=32 -c $< - -cache64k.o: $(srcdir)/config/spu/cache.S - $(gcc_compile) -D__CACHE_SIZE__=64 -c $< - -cache128k.o: $(srcdir)/config/spu/cache.S - $(gcc_compile) -D__CACHE_SIZE__=128 -c $< - -# We provide our own version of __divdf3 that performs better and has -# better support for non-default rounding modes. -DPBIT_FUNCS := $(filter-out _div_df, $(DPBIT_FUNCS)) -- cgit v1.1 From 2f4d895197e7b137f50624bef58c9b614bf081e5 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Sat, 7 Sep 2019 00:09:21 +0000 Subject: RISC-V: Re-enable -msave-restore for shared libraries. This re-enables -msave-restore for shared libraries, and uses the t-slibgcc-libgcc file to get the save-restore routines included directly in shared libraries so that we don't need to indirect through the PLT to reach them, which doesn't work. gcc/ * config/riscv/riscv.c (riscv_option_override): Revert 2019-08-30 change. libgcc/ * config.host (riscv*-*-linux*): Add t-slibgcc-libgcc to tmake_file. (riscv*-*-freebsd*): Likewise. From-SVN: r275478 --- libgcc/ChangeLog | 5 +++++ libgcc/config.host | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 1ffb236..df5d996 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-06 Jim Wilson + + * config.host (riscv*-*-linux*): Add t-slibgcc-libgcc to tmake_file. + (riscv*-*-freebsd*): Likewise. + 2019-09-03 Ulrich Weigand * config.host: Remove references to spu. diff --git a/libgcc/config.host b/libgcc/config.host index a397670..1db5287 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -1201,12 +1201,12 @@ pru-*-*) tm_file="$tm_file pru/pru-abi.h" ;; riscv*-*-linux*) - tmake_file="${tmake_file} riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address}" + tmake_file="${tmake_file} riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address} t-slibgcc-libgcc" extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o crtendS.o crtbeginT.o" md_unwind_header=riscv/linux-unwind.h ;; riscv*-*-freebsd*) - tmake_file="${tmake_file} riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address}" + tmake_file="${tmake_file} riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address} t-slibgcc-libgcc" extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o crtendS.o crtbeginT.o" ;; riscv*-*-*) -- cgit v1.1 From 91dfef9610b8844c62dc7186a9aea9a6aca9805c Mon Sep 17 00:00:00 2001 From: "Jose E. Marchesi" Date: Mon, 9 Sep 2019 12:13:23 +0200 Subject: GCC port for eBPF This patch series introduces a port of GCC to eBPF, which is a virtual machine that resides in the Linux kernel. Initially intended for user-level packet capture and filtering, eBPF is nowadays generalized to serve as a general-purpose infrastructure also for non-networking purposes. The binutils support is already upstream. See https://sourceware.org/ml/binutils/2019-05/msg00306.html. ChangeLog: * MAINTAINERS: Add myself as the maintainer of the eBPF port. Remove myself from Write After Approval section. * configure.ac: Support for bpf-*-* targets. * configure: Regenerate. contrib/ChangeLog: * config-list.mk (LIST): Disable go in bpf-*-* targets. gcc/ChangeLog: * doc/invoke.texi (Option Summary): Cover eBPF. (eBPF Options): New section. * doc/extend.texi (BPF Built-in Functions): Likewise. (BPF Kernel Helpers): Likewise. * config.gcc: Support for bpf-*-* targets. * common/config/bpf/bpf-common.c: New file. * config/bpf/t-bpf: Likewise. * config/bpf/predicates.md: Likewise. * config/bpf/constraints.md: Likewise. * config/bpf/bpf.opt: Likewise. * config/bpf/bpf.md: Likewise. * config/bpf/bpf.h: Likewise. * config/bpf/bpf.c: Likewise. * config/bpf/bpf-protos.h: Likewise. * config/bpf/bpf-opts.h: Likewise. * config/bpf/bpf-helpers.h: Likewise. * config/bpf/bpf-helpers.def: Likewise. gcc/testsuite/ChangeLog: * gcc.dg/builtins-config.h: eBPF doesn't support C99 standard functions. * gcc.c-torture/compile/20101217-1.c: Add a function prototype for printf. * gcc.c-torture/compile/20000211-1.c: Skip if target bpf-*-*. * gcc.c-torture/compile/poor.c: Likewise. * gcc.c-torture/compile/pr25311.c: Likewise. * gcc.c-torture/compile/pr39928-1.c: Likewise. * gcc.c-torture/compile/pr70061.c: Likewise. * gcc.c-torture/compile/920501-7.c: Likewise. * gcc.c-torture/compile/20000403-1.c: Likewise. * gcc.c-torture/compile/20001226-1.c: Likewise. * gcc.c-torture/compile/20030903-1.c: Likewise. * gcc.c-torture/compile/20031125-1.c: Likewise. * gcc.c-torture/compile/20040101-1.c: Likewise. * gcc.c-torture/compile/20040317-2.c: Likewise. * gcc.c-torture/compile/20040726-1.c: Likewise. * gcc.c-torture/compile/20051216-1.c: Likewise. * gcc.c-torture/compile/900313-1.c: Likewise. * gcc.c-torture/compile/920625-1.c: Likewise. * gcc.c-torture/compile/930421-1.c: Likewise. * gcc.c-torture/compile/930623-1.c: Likewise. * gcc.c-torture/compile/961004-1.c: Likewise. * gcc.c-torture/compile/980504-1.c: Likewise. * gcc.c-torture/compile/980816-1.c: Likewise. * gcc.c-torture/compile/990625-1.c: Likewise. * gcc.c-torture/compile/DFcmp.c: Likewise. * gcc.c-torture/compile/HIcmp.c: Likewise. * gcc.c-torture/compile/HIset.c: Likewise. * gcc.c-torture/compile/QIcmp.c: Likewise. * gcc.c-torture/compile/QIset.c: Likewise. * gcc.c-torture/compile/SFset.c: Likewise. * gcc.c-torture/compile/SIcmp.c: Likewise. * gcc.c-torture/compile/SIset.c: Likewise. * gcc.c-torture/compile/UHIcmp.c: Likewise. * gcc.c-torture/compile/UQIcmp.c: Likewise. * gcc.c-torture/compile/USIcmp.c: Likewise. * gcc.c-torture/compile/consec.c: Likewise. * gcc.c-torture/compile/limits-fndefn.c: Likewise. * gcc.c-torture/compile/lll.c: Likewise. * gcc.c-torture/compile/parms.c: Likewise. * gcc.c-torture/compile/pass.c: Likewise. * gcc.c-torture/compile/pp.c: Likewise. * gcc.c-torture/compile/pr32399.c: Likewise. * gcc.c-torture/compile/pr34091.c: Likewise. * gcc.c-torture/compile/pr34688.c: Likewise. * gcc.c-torture/compile/pr37258.c: Likewise. * gcc.c-torture/compile/pr37327.c: Likewise. * gcc.c-torture/compile/pr37381.c: Likewise. * gcc.c-torture/compile/pr37669-2.c: Likewise. * gcc.c-torture/compile/pr37669.c: Likewise. * gcc.c-torture/compile/pr37742-3.c: Likewise. * gcc.c-torture/compile/pr44063.c: Likewise. * gcc.c-torture/compile/pr48596.c: Likewise. * gcc.c-torture/compile/pr51856.c: Likewise. * gcc.c-torture/compile/pr54428.c: Likewise. * gcc.c-torture/compile/pr54713-1.c: Likewise. * gcc.c-torture/compile/pr54713-2.c: Likewise. * gcc.c-torture/compile/pr54713-3.c: Likewise. * gcc.c-torture/compile/pr55921.c: Likewise. * gcc.c-torture/compile/pr70240.c: Likewise. * gcc.c-torture/compile/pr70355.c: Likewise. * gcc.c-torture/compile/pr82052.c: Likewise. * gcc.c-torture/compile/pr83487.c: Likewise. * gcc.c-torture/compile/pr86122.c: Likewise. * gcc.c-torture/compile/pret-arg.c: Likewise. * gcc.c-torture/compile/regs-arg-size.c: Likewise. * gcc.c-torture/compile/structret.c: Likewise. * gcc.c-torture/compile/uuarg.c: Likewise. * gcc.dg/20001009-1.c: Likewise. * gcc.dg/20020418-1.c: Likewise. * gcc.dg/20020426-2.c: Likewise. * gcc.dg/20020430-1.c: Likewise. * gcc.dg/20040306-1.c: Likewise. * gcc.dg/20040622-2.c: Likewise. * gcc.dg/20050603-2.c: Likewise. * gcc.dg/20050629-1.c: Likewise. * gcc.dg/20061026.c: Likewise. * gcc.dg/Warray-bounds-3.c: Likewise. * gcc.dg/Warray-bounds-30.c: Likewise. * gcc.dg/Wframe-larger-than-2.c: Likewise. * gcc.dg/Wframe-larger-than.c: Likewise. * gcc.dg/Wrestrict-11.c: Likewise. * gcc.c-torture/compile/20000804-1.c: Likewise. * lib/target-supports.exp (check_effective_target_trampolines): Adapt to eBPF. (check_effective_target_indirect_jumps): Likewise. (check_effective_target_nonlocal_goto): Likewise. (check_effective_target_global_constructor): Likewise. (check_effective_target_return_address): Likewise. * gcc.target/bpf/bpf.exp: New file. * gcc.target/bpf/builtin-load.c: Likewise. * cc.target/bpf/constant-calls.c: Likewise. * gcc.target/bpf/diag-funargs.c: Likewise. * gcc.target/bpf/diag-funargs-2.c: Likewise. * gcc.target/bpf/diag-funargs-3.c: Likewise. * gcc.target/bpf/diag-indcalls.c: Likewise. * gcc.target/bpf/helper-bind.c: Likewise. * gcc.target/bpf/helper-bpf-redirect.c: Likewise. * gcc.target/bpf/helper-clone-redirect.c: Likewise. * gcc.target/bpf/helper-csum-diff.c: Likewise. * gcc.target/bpf/helper-csum-update.c: Likewise. * gcc.target/bpf/helper-current-task-under-cgroup.c: Likewise. * gcc.target/bpf/helper-fib-lookup.c: Likewise. * gcc.target/bpf/helper-get-cgroup-classid.c: Likewise. * gcc.target/bpf/helper-get-current-cgroup-id.c: Likewise. * gcc.target/bpf/helper-get-current-comm.c: Likewise. * gcc.target/bpf/helper-get-current-pid-tgid.c: Likewise. * gcc.target/bpf/helper-get-current-task.c: Likewise. * gcc.target/bpf/helper-get-current-uid-gid.c: Likewise. * gcc.target/bpf/helper-get-hash-recalc.c: Likewise. * gcc.target/bpf/helper-get-listener-sock.c: Likewise. * gcc.target/bpf/helper-get-local-storage.c: Likewise. * gcc.target/bpf/helper-get-numa-node-id.c: Likewise. * gcc.target/bpf/helper-get-prandom-u32.c: Likewise. * gcc.target/bpf/helper-get-route-realm.c: Likewise. * gcc.target/bpf/helper-get-smp-processor-id.c: Likewise. * gcc.target/bpf/helper-get-socket-cookie.c: Likewise. * gcc.target/bpf/helper-get-socket-uid.c: Likewise. * gcc.target/bpf/helper-getsockopt.c: Likewise. * gcc.target/bpf/helper-get-stack.c: Likewise. * gcc.target/bpf/helper-get-stackid.c: Likewise. * gcc.target/bpf/helper-ktime-get-ns.c: Likewise. * gcc.target/bpf/helper-l3-csum-replace.c: Likewise. * gcc.target/bpf/helper-l4-csum-replace.c: Likewise. * gcc.target/bpf/helper-lwt-push-encap.c: Likewise. * gcc.target/bpf/helper-lwt-seg6-action.c: Likewise. * gcc.target/bpf/helper-lwt-seg6-adjust-srh.c: Likewise. * gcc.target/bpf/helper-lwt-seg6-store-bytes.c: Likewise. * gcc.target/bpf/helper-map-delete-elem.c: Likewise. * gcc.target/bpf/helper-map-lookup-elem.c: Likewise. * gcc.target/bpf/helper-map-peek-elem.c: Likewise. * gcc.target/bpf/helper-map-pop-elem.c: Likewise. * gcc.target/bpf/helper-map-push-elem.c: Likewise. * gcc.target/bpf/helper-map-update-elem.c: Likewise. * gcc.target/bpf/helper-msg-apply-bytes.c: Likewise. * gcc.target/bpf/helper-msg-cork-bytes.c: Likewise. * gcc.target/bpf/helper-msg-pop-data.c: Likewise. * gcc.target/bpf/helper-msg-pull-data.c: Likewise. * gcc.target/bpf/helper-msg-push-data.c: Likewise. * gcc.target/bpf/helper-msg-redirect-hash.c: Likewise. * gcc.target/bpf/helper-msg-redirect-map.c: Likewise. * gcc.target/bpf/helper-override-return.c: Likewise. * gcc.target/bpf/helper-perf-event-output.c: Likewise. * gcc.target/bpf/helper-perf-event-read.c: Likewise. * gcc.target/bpf/helper-perf-event-read-value.c: Likewise. * gcc.target/bpf/helper-perf-prog-read-value.c: Likewise. * gcc.target/bpf/helper-probe-read.c: Likewise. * gcc.target/bpf/helper-probe-read-str.c: Likewise. * gcc.target/bpf/helper-probe-write-user.c: Likewise. * gcc.target/bpf/helper-rc-keydown.c: Likewise. * gcc.target/bpf/helper-rc-pointer-rel.c: Likewise. * gcc.target/bpf/helper-rc-repeat.c: Likewise. * gcc.target/bpf/helper-redirect-map.c: Likewise. * gcc.target/bpf/helper-set-hash.c: Likewise. * gcc.target/bpf/helper-set-hash-invalid.c: Likewise. * gcc.target/bpf/helper-setsockopt.c: Likewise. * gcc.target/bpf/helper-skb-adjust-room.c: Likewise. * gcc.target/bpf/helper-skb-cgroup-id.c: Likewise. * gcc.target/bpf/helper-skb-change-head.c: Likewise. * gcc.target/bpf/helper-skb-change-proto.c: Likewise. * gcc.target/bpf/helper-skb-change-tail.c: Likewise. * gcc.target/bpf/helper-skb-change-type.c: Likewise. * gcc.target/bpf/helper-skb-ecn-set-ce.c: Likewise. * gcc.target/bpf/helper-skb-get-tunnel-key.c: Likewise. * gcc.target/bpf/helper-skb-get-tunnel-opt.c: Likewise. * gcc.target/bpf/helper-skb-get-xfrm-state.c: Likewise. * gcc.target/bpf/helper-skb-load-bytes.c: Likewise. * gcc.target/bpf/helper-skb-load-bytes-relative.c: Likewise. * gcc.target/bpf/helper-skb-pull-data.c: Likewise. * gcc.target/bpf/helper-skb-set-tunnel-key.c: Likewise. * gcc.target/bpf/helper-skb-set-tunnel-opt.c: Likewise. * gcc.target/bpf/helper-skb-store-bytes.c: Likewise. * gcc.target/bpf/helper-skb-under-cgroup.c: Likewise. * gcc.target/bpf/helper-skb-vlan-pop.c: Likewise. * gcc.target/bpf/helper-skb-vlan-push.c: Likewise. * gcc.target/bpf/helper-skc-lookup-tcp.c: Likewise. * gcc.target/bpf/helper-sk-fullsock.c: Likewise. * gcc.target/bpf/helper-sk-lookup-tcp.c: Likewise. * gcc.target/bpf/helper-sk-lookup-upd.c: Likewise. * gcc.target/bpf/helper-sk-redirect-hash.c: Likewise. * gcc.target/bpf/helper-sk-redirect-map.c: Likewise. * gcc.target/bpf/helper-sk-release.c: Likewise. * gcc.target/bpf/helper-sk-select-reuseport.c: Likewise. * gcc.target/bpf/helper-sk-storage-delete.c: Likewise. * gcc.target/bpf/helper-sk-storage-get.c: Likewise. * gcc.target/bpf/helper-sock-hash-update.c: Likewise. * gcc.target/bpf/helper-sock-map-update.c: Likewise. * gcc.target/bpf/helper-sock-ops-cb-flags-set.c: Likewise. * gcc.target/bpf/helper-spin-lock.c: Likewise. * gcc.target/bpf/helper-spin-unlock.c: Likewise. * gcc.target/bpf/helper-strtol.c: Likewise. * gcc.target/bpf/helper-strtoul.c: Likewise. * gcc.target/bpf/helper-sysctl-get-current-value.c: Likewise. * gcc.target/bpf/helper-sysctl-get-name.c: Likewise. * gcc.target/bpf/helper-sysctl-get-new-value.c: Likewise. * gcc.target/bpf/helper-sysctl-set-new-value.c: Likewise. * gcc.target/bpf/helper-tail-call.c: Likewise. * gcc.target/bpf/helper-tcp-check-syncookie.c: Likewise. * gcc.target/bpf/helper-tcp-sock.c: Likewise. * gcc.target/bpf/helper-trace-printk.c: Likewise. * gcc.target/bpf/helper-xdp-adjust-head.c: Likewise. * gcc.target/bpf/helper-xdp-adjust-meta.c: Likewise. * gcc.target/bpf/helper-xdp-adjust-tail.c: Likewise. * gcc.target/bpf/skb-ancestor-cgroup-id.c: Likewise. * gcc.target/bpf/sync-fetch-and-add.c: Likewise. libgcc/ChangeLog: * config.host: Set cpu_type for bpf-*-* targets. * config/bpf/t-bpf: Likewise. * config/bpf/crtn.S: Likewise. * config/bpf/crti.S: New file. From-SVN: r275506 --- libgcc/ChangeLog | 7 +++++++ libgcc/config.host | 7 +++++++ libgcc/config/bpf/crti.S | 0 libgcc/config/bpf/crtn.S | 0 libgcc/config/bpf/t-bpf | 23 +++++++++++++++++++++++ 5 files changed, 37 insertions(+) create mode 100644 libgcc/config/bpf/crti.S create mode 100644 libgcc/config/bpf/crtn.S create mode 100644 libgcc/config/bpf/t-bpf (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index df5d996..fdbc009 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,10 @@ +2019-09-09 Jose E. Marchesi + + * config.host: Set cpu_type for bpf-*-* targets. + * config/bpf/t-bpf: Likewise. + * config/bpf/crtn.S: Likewise. + * config/bpf/crti.S: New file. + 2019-09-06 Jim Wilson * config.host (riscv*-*-linux*): Add t-slibgcc-libgcc to tmake_file. diff --git a/libgcc/config.host b/libgcc/config.host index 1db5287..b5826fe 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -107,6 +107,9 @@ avr-*-*) bfin*-*) cpu_type=bfin ;; +bpf-*-*) + cpu_type=bpf + ;; cr16-*-*) ;; crisv32-*-*) @@ -523,6 +526,10 @@ bfin*-*) tmake_file="$tmake_file bfin/t-bfin t-fdpbit" extra_parts="crtbegin.o crtend.o crti.o crtn.o" ;; +bpf-*-*) + tmake_file="$tmake_file ${cpu_type}/t-${cpu_type}" + extra_parts="crti.o crtn.o" + ;; cr16-*-elf) tmake_file="${tmake_file} cr16/t-cr16 cr16/t-crtlibid t-fdpbit" extra_parts="$extra_parts crti.o crtn.o crtlibid.o" diff --git a/libgcc/config/bpf/crti.S b/libgcc/config/bpf/crti.S new file mode 100644 index 0000000..e69de29 diff --git a/libgcc/config/bpf/crtn.S b/libgcc/config/bpf/crtn.S new file mode 100644 index 0000000..e69de29 diff --git a/libgcc/config/bpf/t-bpf b/libgcc/config/bpf/t-bpf new file mode 100644 index 0000000..88129a7 --- /dev/null +++ b/libgcc/config/bpf/t-bpf @@ -0,0 +1,23 @@ +LIB2ADDEH = + +crti.o: $(srcdir)/config/bpf/crti.S + $(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< + +crtn.o: $(srcdir)/config/bpf/crtn.S + $(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< + +# Some of the functions defined in libgcc2 exceed the eBPF stack +# limit, or other restrictions imposed by this peculiar target. +# Therefore we have to exclude them here. +# +# Patterns in bpf.md must guarantee that no calls to the excluded +# functions are ever generated, and compiler tests should make sure +# this holds. +# +# Note that the modes in the function names below are misleading: di +# means TImode. +LIB2FUNCS_EXCLUDE = _mulvdi3 _divdi3 _moddi3 _divmoddi4 _udivdi3 _umoddi3 \ + _udivmoddi4 + +# Prevent building "advanced" stuff (for example, gcov support). +INHIBIT_LIBC_CFLAGS = -Dinhibit_libc -- cgit v1.1 From b1e21e5a5d19b436f948710e09157c5b3244f541 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 09:37:00 +0200 Subject: [ARM/FDPIC v6 02/24] [ARM] FDPIC: Handle arm*-*-uclinuxfdpiceabi in configure scripts The new arm-uclinuxfdpiceabi target behaves pretty much like arm-linux-gnueabi. In order to enable the same set of features, we have to update several configure scripts that generally match targets like *-*-linux*: in most places, we add *-uclinux* where there is already *-linux*, or uclinux* when there is already linux*. In gcc/config.gcc and libgcc/config.host we use *-*-uclinuxfdpiceabi because there is already a different behaviour for *-*uclinux* target. In libtool.m4, we use uclinuxfdpiceabi in cases where ELF shared libraries support is required, as uclinux does not guarantee that. 2019-09-10 Christophe Lyon config/ * futex.m4: Handle *-uclinux*. * tls.m4 (GCC_CHECK_TLS): Likewise. gcc/ * config.gcc: Handle *-*-uclinuxfdpiceabi. libatomic/ * configure.tgt: Handle arm*-*-uclinux*. * configure: Regenerate. libgcc/ * config.host: Handle *-*-uclinuxfdpiceabi. libitm/ * configure.tgt: Handle *-*-uclinux*. * configure: Regenerate. * libtool.m4: Handle uclinuxfdpiceabi. From-SVN: r275564 --- libgcc/ChangeLog | 4 ++++ libgcc/config.host | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index fdbc009..7696452 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,7 @@ +2019-09-10 Christophe Lyon + + * config.host: Handle *-*-uclinuxfdpiceabi. + 2019-09-09 Jose E. Marchesi * config.host: Set cpu_type for bpf-*-* targets. diff --git a/libgcc/config.host b/libgcc/config.host index b5826fe..728e543e 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -248,7 +248,7 @@ case ${host} in tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip t-slibgcc t-slibgcc-fuchsia" extra_parts="crtbegin.o crtend.o" ;; -*-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu) +*-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu | *-*-uclinuxfdpiceabi) tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-linux" extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o" if test x$enable_vtable_verify = xyes; then @@ -453,7 +453,7 @@ arm*-*-netbsdelf*) ;; esac ;; -arm*-*-linux*) # ARM GNU/Linux with ELF +arm*-*-linux* | arm*-*-uclinuxfdpiceabi) tmake_file="${tmake_file} arm/t-arm t-fixedpoint-gnu-prefix t-crtfm" tmake_file="${tmake_file} arm/t-elf arm/t-bpabi arm/t-linux-eabi t-slibgcc-libgcc" tm_file="$tm_file arm/bpabi-lib.h" -- cgit v1.1 From 11189793b6ef60645d5d1126d0bd9d0dd83e6583 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 09:43:37 +0200 Subject: [ARM/FDPIC v6 05/24] [ARM] FDPIC: Fix __do_global_dtors_aux and frame_dummy generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In FDPIC, we need to make sure __do_global_dtors_aux and frame_dummy are referenced by their address, not by pointers to the function descriptors. 2019-09-10 Christophe Lyon Mickaël Guêné libgcc/ * libgcc/crtstuff.c: Add support for FDPIC. Co-Authored-By: Mickaël Guêné From-SVN: r275567 --- libgcc/ChangeLog | 7 ++++++- libgcc/crtstuff.c | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 7696452..bb41129 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,6 +1,11 @@ 2019-09-10 Christophe Lyon + Mickaël Guêné - * config.host: Handle *-*-uclinuxfdpiceabi. + * libgcc/crtstuff.c: Add support for FDPIC. + +2019-09-10 Christophe Lyon + + * config.host: Handle *-*-uclinuxfdpiceabi. 2019-09-09 Jose E. Marchesi diff --git a/libgcc/crtstuff.c b/libgcc/crtstuff.c index c8a8e2c..c93e1cb 100644 --- a/libgcc/crtstuff.c +++ b/libgcc/crtstuff.c @@ -429,9 +429,17 @@ __do_global_dtors_aux (void) #ifdef FINI_SECTION_ASM_OP CRT_CALL_STATIC_FUNCTION (FINI_SECTION_ASM_OP, __do_global_dtors_aux) #elif defined (FINI_ARRAY_SECTION_ASM_OP) +#if defined(__FDPIC__) +__asm__("\t.equ\t__do_global_dtors_aux_alias, __do_global_dtors_aux\n"); +extern char __do_global_dtors_aux_alias; +static void *__do_global_dtors_aux_fini_array_entry[] +__attribute__ ((__used__, section(".fini_array"), aligned(sizeof(void *)))) + = { &__do_global_dtors_aux_alias }; +#else /* defined(__FDPIC__) */ static func_ptr __do_global_dtors_aux_fini_array_entry[] __attribute__ ((__used__, section(".fini_array"), aligned(__alignof__(func_ptr)))) = { __do_global_dtors_aux }; +#endif /* defined(__FDPIC__) */ #else /* !FINI_SECTION_ASM_OP && !FINI_ARRAY_SECTION_ASM_OP */ static void __attribute__((used)) __do_global_dtors_aux_1 (void) @@ -473,9 +481,17 @@ frame_dummy (void) #ifdef __LIBGCC_INIT_SECTION_ASM_OP__ CRT_CALL_STATIC_FUNCTION (__LIBGCC_INIT_SECTION_ASM_OP__, frame_dummy) #else /* defined(__LIBGCC_INIT_SECTION_ASM_OP__) */ +#if defined(__FDPIC__) +__asm__("\t.equ\t__frame_dummy_alias, frame_dummy\n"); +extern char __frame_dummy_alias; +static void *__frame_dummy_init_array_entry[] +__attribute__ ((__used__, section(".init_array"), aligned(sizeof(void *)))) + = { &__frame_dummy_alias }; +#else /* defined(__FDPIC__) */ static func_ptr __frame_dummy_init_array_entry[] __attribute__ ((__used__, section(".init_array"), aligned(__alignof__(func_ptr)))) = { frame_dummy }; +#endif /* defined(__FDPIC__) */ #endif /* !defined(__LIBGCC_INIT_SECTION_ASM_OP__) */ #endif /* USE_EH_FRAME_REGISTRY || USE_TM_CLONE_REGISTRY */ -- cgit v1.1 From 5d727a4b20257275df59182b00f3bf240772cd0d Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 09:47:49 +0200 Subject: [ARM/FDPIC v6 06/24] [ARM] FDPIC: Add support for c++ exceptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The main difference with existing support is that function addresses are function descriptor addresses instead. This means that all code dealing with function pointers now has to cope with function descriptors instead. For the same reason, Linux kernel helpers can no longer be called by dereferencing their address, so we implement wrappers that directly call the kernel helpers. When restoring a function address, we also have to restore the FDPIC register value (r9). 2019-09-10 Christophe Lyon Mickaël Guêné gcc/ * ginclude/unwind-arm-common.h (unwinder_cache): Add reserved5 field. libgcc/ * config/arm/linux-atomic.c (__kernel_cmpxchg): Add FDPIC support. (__kernel_dmb): Likewise. (__fdpic_cmpxchg): New function. (__fdpic_dmb): New function. * config/arm/unwind-arm.h (FDPIC_REGNUM): New define. (gnu_Unwind_Find_got): New function. (_Unwind_decode_typeinfo_ptr): Add FDPIC support. * unwind-arm-common.inc (UCB_PR_GOT): New. (funcdesc_t): New struct. (get_eit_entry): Add FDPIC support. (unwind_phase2): Likewise. (unwind_phase2_forced): Likewise. (__gnu_Unwind_RaiseException): Likewise. (__gnu_Unwind_Resume): Likewise. (__gnu_Unwind_Backtrace): Likewise. * unwind-pe.h (read_encoded_value_with_base): Likewise. libstdc++/ * libsupc++/eh_personality.cc (get_ttype_entry): Add FDPIC support. Co-Authored-By: Mickaël Guêné From-SVN: r275568 --- libgcc/ChangeLog | 20 +++++++++ libgcc/config/arm/linux-atomic.c | 55 ++++++++++++++++++++++- libgcc/config/arm/unwind-arm.h | 31 ++++++++++++- libgcc/unwind-arm-common.inc | 94 ++++++++++++++++++++++++++++++++++++++++ libgcc/unwind-pe.h | 17 ++++++++ 5 files changed, 214 insertions(+), 3 deletions(-) (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index bb41129..8f29b5e 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,6 +1,26 @@ 2019-09-10 Christophe Lyon Mickaël Guêné + * config/arm/linux-atomic.c (__kernel_cmpxchg): Add FDPIC support. + (__kernel_dmb): Likewise. + (__fdpic_cmpxchg): New function. + (__fdpic_dmb): New function. + * config/arm/unwind-arm.h (FDPIC_REGNUM): New define. + (gnu_Unwind_Find_got): New function. + (_Unwind_decode_typeinfo_ptr): Add FDPIC support. + * unwind-arm-common.inc (UCB_PR_GOT): New. + (funcdesc_t): New struct. + (get_eit_entry): Add FDPIC support. + (unwind_phase2): Likewise. + (unwind_phase2_forced): Likewise. + (__gnu_Unwind_RaiseException): Likewise. + (__gnu_Unwind_Resume): Likewise. + (__gnu_Unwind_Backtrace): Likewise. + * unwind-pe.h (read_encoded_value_with_base): Likewise. + +2019-09-10 Christophe Lyon + Mickaël Guêné + * libgcc/crtstuff.c: Add support for FDPIC. 2019-09-10 Christophe Lyon diff --git a/libgcc/config/arm/linux-atomic.c b/libgcc/config/arm/linux-atomic.c index 06a6d46..565f829 100644 --- a/libgcc/config/arm/linux-atomic.c +++ b/libgcc/config/arm/linux-atomic.c @@ -25,11 +25,62 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* Kernel helper for compare-and-exchange. */ typedef int (__kernel_cmpxchg_t) (int oldval, int newval, int *ptr); -#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0) + +#define STR(X) #X +#define XSTR(X) STR(X) + +#define KERNEL_CMPXCHG 0xffff0fc0 + +#if __FDPIC__ +/* Non-FDPIC ABIs call __kernel_cmpxchg directly by dereferencing its + address, but under FDPIC we would generate a broken call + sequence. That's why we have to implement __kernel_cmpxchg and + __kernel_dmb here: this way, the FDPIC call sequence works. */ +#define __kernel_cmpxchg __fdpic_cmpxchg +#else +#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) KERNEL_CMPXCHG) +#endif /* Kernel helper for memory barrier. */ typedef void (__kernel_dmb_t) (void); -#define __kernel_dmb (*(__kernel_dmb_t *) 0xffff0fa0) + +#define KERNEL_DMB 0xffff0fa0 + +#if __FDPIC__ +#define __kernel_dmb __fdpic_dmb +#else +#define __kernel_dmb (*(__kernel_dmb_t *) KERNEL_DMB) +#endif + +#if __FDPIC__ +static int __fdpic_cmpxchg (int oldval, int newval, int *ptr) +{ + int result; + + asm volatile ( + "ldr ip, 1f\n\t" + "bx ip\n\t" + "1:\n\t" + ".word " XSTR(KERNEL_CMPXCHG) "\n\t" + : "=r" (result) + : "r" (oldval) , "r" (newval), "r" (ptr) + : "r3", "memory"); + /* The result is actually returned by the kernel helper, we need + this to avoid a warning. */ + return result; +} + +static void __fdpic_dmb (void) +{ + asm volatile ( + "ldr ip, 1f\n\t" + "bx ip\n\t" + "1:\n\t" + ".word " XSTR(KERNEL_DMB) "\n\t" + ); +} + +#endif /* Note: we implement byte, short and int versions of atomic operations using the above kernel helpers; see linux-atomic-64bit.c for "long long" (64-bit) diff --git a/libgcc/config/arm/unwind-arm.h b/libgcc/config/arm/unwind-arm.h index 43c5379..2bf320a 100644 --- a/libgcc/config/arm/unwind-arm.h +++ b/libgcc/config/arm/unwind-arm.h @@ -33,9 +33,33 @@ /* Use IP as a scratch register within the personality routine. */ #define UNWIND_POINTER_REG 12 +#define FDPIC_REGNUM 9 + +#define STR(x) #x +#define XSTR(x) STR(x) + #ifdef __cplusplus extern "C" { #endif +_Unwind_Ptr __attribute__((weak)) __gnu_Unwind_Find_got (_Unwind_Ptr); + +static inline _Unwind_Ptr gnu_Unwind_Find_got (_Unwind_Ptr ptr) +{ + _Unwind_Ptr res; + + if (__gnu_Unwind_Find_got) + res = __gnu_Unwind_Find_got (ptr); + else + { + asm volatile ("mov %[result], r" XSTR(FDPIC_REGNUM) + : [result]"=r" (res) + : + :); + } + + return res; +} + /* Decode an R_ARM_TARGET2 relocation. */ static inline _Unwind_Word _Unwind_decode_typeinfo_ptr (_Unwind_Word base __attribute__ ((unused)), @@ -48,7 +72,12 @@ extern "C" { if (!tmp) return 0; -#if (defined(linux) && !defined(__uClinux__)) || defined(__NetBSD__) \ +#if __FDPIC__ + /* For FDPIC, we store the offset of the GOT entry. */ + /* So, first get GOT from dynamic linker and then use indirect access. */ + tmp += gnu_Unwind_Find_got (ptr); + tmp = *(_Unwind_Word *) tmp; +#elif (defined(linux) && !defined(__uClinux__)) || defined(__NetBSD__) \ || defined(__FreeBSD__) || defined(__fuchsia__) /* Pc-relative indirect. */ #define _GLIBCXX_OVERRIDE_TTYPE_ENCODING (DW_EH_PE_pcrel | DW_EH_PE_indirect) diff --git a/libgcc/unwind-arm-common.inc b/libgcc/unwind-arm-common.inc index fd572fe..0bacc11 100644 --- a/libgcc/unwind-arm-common.inc +++ b/libgcc/unwind-arm-common.inc @@ -62,6 +62,7 @@ __gnu_Unwind_Find_exidx (_Unwind_Ptr, int *); #define UCB_PR_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved2) #define UCB_SAVED_CALLSITE_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved3) #define UCB_FORCED_STOP_ARG(ucbp) ((ucbp)->unwinder_cache.reserved4) +#define UCB_PR_GOT(ucbp) ((ucbp)->unwinder_cache.reserved5) /* Unwind descriptors. */ @@ -85,6 +86,16 @@ typedef struct __EIT_entry _uw content; } __EIT_entry; +#ifdef __FDPIC__ + +/* Only used in FDPIC case. */ +struct funcdesc_t +{ + unsigned int ptr; + unsigned int got; +}; +#endif + /* Assembly helper functions. */ /* Restore core register state. Never returns. */ @@ -259,7 +270,21 @@ get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address) { /* One of the predefined standard routines. */ _uw idx = (*(_uw *) ucbp->pr_cache.ehtp >> 24) & 0xf; +#if __FDPIC__ + { + struct funcdesc_t *funcdesc + = (struct funcdesc_t *) __gnu_unwind_get_pr_addr (idx); + if (funcdesc) + { + UCB_PR_ADDR (ucbp) = funcdesc->ptr; + UCB_PR_GOT (ucbp) = funcdesc->got; + } + else + UCB_PR_ADDR (ucbp) = 0; + } +#else UCB_PR_ADDR (ucbp) = __gnu_unwind_get_pr_addr (idx); +#endif if (UCB_PR_ADDR (ucbp) == 0) { /* Failed */ @@ -270,6 +295,10 @@ get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address) { /* Execute region offset to PR */ UCB_PR_ADDR (ucbp) = selfrel_offset31 (ucbp->pr_cache.ehtp); +#if __FDPIC__ + UCB_PR_GOT (ucbp) + = (unsigned int) gnu_Unwind_Find_got ((_Unwind_Ptr) UCB_PR_ADDR (ucbp)); +#endif } return _URC_OK; } @@ -291,14 +320,29 @@ unwind_phase2 (_Unwind_Control_Block * ucbp, phase2_vrs * vrs) UCB_SAVED_CALLSITE_ADDR (ucbp) = VRS_PC(vrs); /* Call the pr to decide what to do. */ +#if __FDPIC__ + { + volatile struct funcdesc_t funcdesc; + funcdesc.ptr = UCB_PR_ADDR (ucbp); + funcdesc.got = UCB_PR_GOT (ucbp); + pr_result = ((personality_routine) &funcdesc) + (_US_UNWIND_FRAME_STARTING, ucbp, (_Unwind_Context *) vrs); + } +#else pr_result = ((personality_routine) UCB_PR_ADDR (ucbp)) (_US_UNWIND_FRAME_STARTING, ucbp, (_Unwind_Context *) vrs); +#endif } while (pr_result == _URC_CONTINUE_UNWIND); if (pr_result != _URC_INSTALL_CONTEXT) abort(); +#if __FDPIC__ + /* r9 could have been lost due to PLT jump. Restore correct value. */ + vrs->core.r[FDPIC_REGNUM] = gnu_Unwind_Find_got (VRS_PC (vrs)); +#endif + uw_restore_core_regs (vrs, &vrs->core); } @@ -346,8 +390,18 @@ unwind_phase2_forced (_Unwind_Control_Block *ucbp, phase2_vrs *entry_vrs, next_vrs = saved_vrs; /* Call the pr to decide what to do. */ +#if __FDPIC__ + { + volatile struct funcdesc_t funcdesc; + funcdesc.ptr = UCB_PR_ADDR (ucbp); + funcdesc.got = UCB_PR_GOT (ucbp); + pr_result = ((personality_routine) &funcdesc) + (action, ucbp, (void *) &next_vrs); + } +#else pr_result = ((personality_routine) UCB_PR_ADDR (ucbp)) (action, ucbp, (void *) &next_vrs); +#endif saved_vrs.prev_sp = VRS_SP (&next_vrs); } @@ -384,6 +438,11 @@ unwind_phase2_forced (_Unwind_Control_Block *ucbp, phase2_vrs *entry_vrs, return _URC_FAILURE; } +#if __FDPIC__ + /* r9 could have been lost due to PLT jump. Restore correct value. */ + saved_vrs.core.r[FDPIC_REGNUM] = gnu_Unwind_Find_got (VRS_PC (&saved_vrs)); +#endif + uw_restore_core_regs (&saved_vrs, &saved_vrs.core); } @@ -429,8 +488,18 @@ __gnu_Unwind_RaiseException (_Unwind_Control_Block * ucbp, return _URC_FAILURE; /* Call the pr to decide what to do. */ +#if __FDPIC__ + { + volatile struct funcdesc_t funcdesc; + funcdesc.ptr = UCB_PR_ADDR (ucbp); + funcdesc.got = UCB_PR_GOT (ucbp); + pr_result = ((personality_routine) &funcdesc) + (_US_VIRTUAL_UNWIND_FRAME, ucbp, (void *) &saved_vrs); + } +#else pr_result = ((personality_routine) UCB_PR_ADDR (ucbp)) (_US_VIRTUAL_UNWIND_FRAME, ucbp, (void *) &saved_vrs); +#endif } while (pr_result == _URC_CONTINUE_UNWIND); @@ -488,13 +557,27 @@ __gnu_Unwind_Resume (_Unwind_Control_Block * ucbp, phase2_vrs * entry_vrs) } /* Call the cached PR. */ +#if __FDPIC__ + { + volatile struct funcdesc_t funcdesc; + funcdesc.ptr = UCB_PR_ADDR (ucbp); + funcdesc.got = UCB_PR_GOT (ucbp); + pr_result = ((personality_routine) &funcdesc) + (_US_UNWIND_FRAME_RESUME, ucbp, (_Unwind_Context *) entry_vrs); + } +#else pr_result = ((personality_routine) UCB_PR_ADDR (ucbp)) (_US_UNWIND_FRAME_RESUME, ucbp, (_Unwind_Context *) entry_vrs); +#endif switch (pr_result) { case _URC_INSTALL_CONTEXT: /* Upload the registers to enter the landing pad. */ +#if __FDPIC__ + /* r9 could have been lost due to PLT jump. Restore correct value. */ + entry_vrs->core.r[FDPIC_REGNUM] = gnu_Unwind_Find_got (VRS_PC (entry_vrs)); +#endif uw_restore_core_regs (entry_vrs, &entry_vrs->core); case _URC_CONTINUE_UNWIND: @@ -586,9 +669,20 @@ __gnu_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument, } /* Call the pr to decide what to do. */ +#if __FDPIC__ + { + volatile struct funcdesc_t funcdesc; + funcdesc.ptr = UCB_PR_ADDR (ucbp); + funcdesc.got = UCB_PR_GOT (ucbp); + code = ((personality_routine) &funcdesc) + (_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND, + ucbp, (void *) &saved_vrs); + } +#else code = ((personality_routine) UCB_PR_ADDR (ucbp)) (_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND, ucbp, (void *) &saved_vrs); +#endif } while (code != _URC_END_OF_STACK && code != _URC_FAILURE); diff --git a/libgcc/unwind-pe.h b/libgcc/unwind-pe.h index 4ed1c66..1c9dae5 100644 --- a/libgcc/unwind-pe.h +++ b/libgcc/unwind-pe.h @@ -262,10 +262,27 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base, if (result != 0) { +#if __FDPIC__ + /* FDPIC relative addresses imply taking the GOT address + into account. */ + if ((encoding & DW_EH_PE_pcrel) && (encoding & DW_EH_PE_indirect)) + { + result += gnu_Unwind_Find_got ((_Unwind_Ptr) u); + result = *(_Unwind_Internal_Ptr *) result; + } + else + { + result += ((encoding & 0x70) == DW_EH_PE_pcrel + ? (_Unwind_Internal_Ptr) u : base); + if (encoding & DW_EH_PE_indirect) + result = *(_Unwind_Internal_Ptr *) result; + } +#else result += ((encoding & 0x70) == DW_EH_PE_pcrel ? (_Unwind_Internal_Ptr) u : base); if (encoding & DW_EH_PE_indirect) result = *(_Unwind_Internal_Ptr *) result; +#endif } } -- cgit v1.1 From ae1152e5a01301c9dfec42fc5c117a9b782e353e Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 09:55:20 +0200 Subject: [ARM/FDPIC v6 11/24] [ARM] FDPIC: Add support to unwind FDPIC signal frame MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2019-09-10 Christophe Lyon Mickaël Guêné libgcc/ * unwind-arm-common.inc (ARM_SET_R7_RT_SIGRETURN) (THUMB2_SET_R7_RT_SIGRETURN, FDPIC_LDR_R12_WITH_FUNCDESC) (FDPIC_LDR_R9_WITH_GOT, FDPIC_LDR_PC_WITH_RESTORER) (FDPIC_FUNCDESC_OFFSET, ARM_NEW_RT_SIGFRAME_UCONTEXT) (ARM_UCONTEXT_SIGCONTEXT, ARM_SIGCONTEXT_R0, FDPIC_T2_LDR_R12_WITH_FUNCDESC) (FDPIC_T2_LDR_R9_WITH_GOT, FDPIC_T2_LDR_PC_WITH_RESTORER): New. (__gnu_personality_sigframe_fdpic): New. (get_eit_entry): Add FDPIC signal frame support. Co-Authored-By: Mickaël Guêné From-SVN: r275573 --- libgcc/ChangeLog | 13 +++++ libgcc/unwind-arm-common.inc | 122 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 8f29b5e..d6d73e9 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,6 +1,19 @@ 2019-09-10 Christophe Lyon Mickaël Guêné + libgcc/ + * unwind-arm-common.inc (ARM_SET_R7_RT_SIGRETURN) + (THUMB2_SET_R7_RT_SIGRETURN, FDPIC_LDR_R12_WITH_FUNCDESC) + (FDPIC_LDR_R9_WITH_GOT, FDPIC_LDR_PC_WITH_RESTORER) + (FDPIC_FUNCDESC_OFFSET, ARM_NEW_RT_SIGFRAME_UCONTEXT) + (ARM_UCONTEXT_SIGCONTEXT, ARM_SIGCONTEXT_R0, FDPIC_T2_LDR_R12_WITH_FUNCDESC) + (FDPIC_T2_LDR_R9_WITH_GOT, FDPIC_T2_LDR_PC_WITH_RESTORER): New. + (__gnu_personality_sigframe_fdpic): New. + (get_eit_entry): Add FDPIC signal frame support. + +2019-09-10 Christophe Lyon + Mickaël Guêné + * config/arm/linux-atomic.c (__kernel_cmpxchg): Add FDPIC support. (__kernel_dmb): Likewise. (__fdpic_cmpxchg): New function. diff --git a/libgcc/unwind-arm-common.inc b/libgcc/unwind-arm-common.inc index 0bacc11..c9a82b79 100644 --- a/libgcc/unwind-arm-common.inc +++ b/libgcc/unwind-arm-common.inc @@ -30,6 +30,26 @@ #include #endif +#if __FDPIC__ +/* Load r7 with rt_sigreturn value. */ +#define ARM_SET_R7_RT_SIGRETURN 0xe3a070ad /* mov r7, #0xad */ +#define THUMB2_SET_R7_RT_SIGRETURN 0x07adf04f /* mov.w r7, #0xad */ + +/* FDPIC jump to restorer sequence. */ +#define FDPIC_LDR_R12_WITH_FUNCDESC 0xe59fc004 /* ldr r12, [pc, #4] */ +#define FDPIC_LDR_R9_WITH_GOT 0xe59c9004 /* ldr r9, [r12, #4] */ +#define FDPIC_LDR_PC_WITH_RESTORER 0xe59cf000 /* ldr pc, [r12] */ +#define FDPIC_T2_LDR_R12_WITH_FUNCDESC 0xc008f8df /* ldr.w r12, [pc, #8] */ +#define FDPIC_T2_LDR_R9_WITH_GOT 0x9004f8dc /* ldr.w r9, [r12, #4] */ +#define FDPIC_T2_LDR_PC_WITH_RESTORER 0xf000f8dc /* ldr.w pc, [r12] */ +#define FDPIC_FUNCDESC_OFFSET 12 + +/* Signal frame offsets. */ +#define ARM_NEW_RT_SIGFRAME_UCONTEXT 0x80 +#define ARM_UCONTEXT_SIGCONTEXT 0x14 +#define ARM_SIGCONTEXT_R0 0xc +#endif + /* We add a prototype for abort here to avoid creating a dependency on target headers. */ extern void abort (void); @@ -199,6 +219,45 @@ search_EIT_table (const __EIT_entry * table, int nrec, _uw return_address) } } +#if __FDPIC__ +/* VFP is not restored, but this is sufficient to allow unwinding. */ +static _Unwind_Reason_Code +__gnu_personality_sigframe_fdpic (_Unwind_State state, + _Unwind_Control_Block *ucbp, + _Unwind_Context *context) +{ + unsigned int sp; + unsigned int pc; + unsigned int funcdesc; + unsigned int handler; + unsigned int first_handler_instruction; + int i; + + _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, &sp); + _Unwind_VRS_Get (context, _UVRSC_CORE, R_PC, _UVRSD_UINT32, &pc); + + funcdesc = *(unsigned int *)((pc & ~1) + FDPIC_FUNCDESC_OFFSET); + handler = *(unsigned int *)(funcdesc); + first_handler_instruction = *(unsigned int *)(handler & ~1); + + /* Adjust SP to point to the start of registers according to + signal type. */ + if (first_handler_instruction == ARM_SET_R7_RT_SIGRETURN + || first_handler_instruction == THUMB2_SET_R7_RT_SIGRETURN) + sp += ARM_NEW_RT_SIGFRAME_UCONTEXT + + ARM_UCONTEXT_SIGCONTEXT + + ARM_SIGCONTEXT_R0; + else + sp += ARM_UCONTEXT_SIGCONTEXT + + ARM_SIGCONTEXT_R0; + /* Restore regs saved on stack by the kernel. */ + for (i = 0; i < 16; i++) + _Unwind_VRS_Set (context, _UVRSC_CORE, i, _UVRSD_UINT32, sp + 4 * i); + + return _URC_CONTINUE_UNWIND; +} +#endif + /* Find the exception index table eintry for the given address. Fill in the relevant fields of the UCB. Returns _URC_FAILURE if an error occurred, _URC_OK on success. */ @@ -222,6 +281,27 @@ get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address) &nrec); if (!eitp) { +#if __FDPIC__ + /* If we are unwinding a signal handler then perhaps we have + reached a trampoline. Try to detect jump to restorer + sequence. */ + _uw *pc = (_uw *)((return_address+2) & ~1); + if ((pc[0] == FDPIC_LDR_R12_WITH_FUNCDESC + && pc[1] == FDPIC_LDR_R9_WITH_GOT + && pc[2] == FDPIC_LDR_PC_WITH_RESTORER) + || (pc[0] == FDPIC_T2_LDR_R12_WITH_FUNCDESC + && pc[1] == FDPIC_T2_LDR_R9_WITH_GOT + && pc[2] == FDPIC_T2_LDR_PC_WITH_RESTORER)) + { + struct funcdesc_t *funcdesc + = (struct funcdesc_t *) &__gnu_personality_sigframe_fdpic; + + UCB_PR_ADDR (ucbp) = funcdesc->ptr; + UCB_PR_GOT (ucbp) = funcdesc->got; + + return _URC_OK; + } +#endif UCB_PR_ADDR (ucbp) = 0; return _URC_FAILURE; } @@ -236,6 +316,27 @@ get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address) if (!eitp) { +#if __FDPIC__ + /* If we are unwinding a signal handler then perhaps we have + reached a trampoline. Try to detect jump to restorer + sequence. */ + _uw *pc = (_uw *)((return_address+2) & ~1); + if ((pc[0] == FDPIC_LDR_R12_WITH_FUNCDESC + && pc[1] == FDPIC_LDR_R9_WITH_GOT + && pc[2] == FDPIC_LDR_PC_WITH_RESTORER) + || (pc[0] == FDPIC_T2_LDR_R12_WITH_FUNCDESC + && pc[1] == FDPIC_T2_LDR_R9_WITH_GOT + && pc[2] == FDPIC_T2_LDR_PC_WITH_RESTORER)) + { + struct funcdesc_t *funcdesc + = (struct funcdesc_t *) &__gnu_personality_sigframe_fdpic; + + UCB_PR_ADDR (ucbp) = funcdesc->ptr; + UCB_PR_GOT (ucbp) = funcdesc->got; + + return _URC_OK; + } +#endif UCB_PR_ADDR (ucbp) = 0; return _URC_FAILURE; } @@ -244,6 +345,27 @@ get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address) /* Can this frame be unwound at all? */ if (eitp->content == EXIDX_CANTUNWIND) { +#if __FDPIC__ + /* If we are unwinding a signal handler then perhaps we have + reached a trampoline. Try to detect jump to restorer + sequence. */ + _uw *pc = (_uw *)((return_address+2) & ~1); + if ((pc[0] == FDPIC_LDR_R12_WITH_FUNCDESC + && pc[1] == FDPIC_LDR_R9_WITH_GOT + && pc[2] == FDPIC_LDR_PC_WITH_RESTORER) + || (pc[0] == FDPIC_T2_LDR_R12_WITH_FUNCDESC + && pc[1] == FDPIC_T2_LDR_R9_WITH_GOT + && pc[2] == FDPIC_T2_LDR_PC_WITH_RESTORER)) + { + struct funcdesc_t *funcdesc + = (struct funcdesc_t *) &__gnu_personality_sigframe_fdpic; + + UCB_PR_ADDR (ucbp) = funcdesc->ptr; + UCB_PR_GOT (ucbp) = funcdesc->got; + + return _URC_OK; + } +#endif UCB_PR_ADDR (ucbp) = 0; return _URC_END_OF_STACK; } -- cgit v1.1 From 84818dbb70375810557ce9d8880c4345e845c01d Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Tue, 10 Sep 2019 09:58:44 +0200 Subject: [ARM/FDPIC v6 13/24] [ARM] FDPIC: Force LSB bit for PC in Cortex-M architecture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this, when we are unwinding across a signal frame we can jump to an even address which leads to an exception. This is needed in __gnu_persnality_sigframe_fdpic() when restoring the PC from the signal frame since the PC saved by the kernel has the LSB bit set to zero. 2019-09-10 Christophe Lyon Mickaël Guêné libgcc/ * config/arm/unwind-arm.c (_Unwind_VRS_Set): Handle thumb-only architecture. Co-Authored-By: Mickaël Guêné From-SVN: r275575 --- libgcc/ChangeLog | 7 ++++++- libgcc/config/arm/unwind-arm.c | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index d6d73e9..d61374d 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,7 +1,12 @@ 2019-09-10 Christophe Lyon Mickaël Guêné - libgcc/ + * config/arm/unwind-arm.c (_Unwind_VRS_Set): Handle thumb-only + architecture. + +2019-09-10 Christophe Lyon + Mickaël Guêné + * unwind-arm-common.inc (ARM_SET_R7_RT_SIGRETURN) (THUMB2_SET_R7_RT_SIGRETURN, FDPIC_LDR_R12_WITH_FUNCDESC) (FDPIC_LDR_R9_WITH_GOT, FDPIC_LDR_PC_WITH_RESTORER) diff --git a/libgcc/config/arm/unwind-arm.c b/libgcc/config/arm/unwind-arm.c index 9ba73e7..8313ee0 100644 --- a/libgcc/config/arm/unwind-arm.c +++ b/libgcc/config/arm/unwind-arm.c @@ -199,6 +199,11 @@ _Unwind_VRS_Result _Unwind_VRS_Set (_Unwind_Context *context, return _UVRSR_FAILED; vrs->core.r[regno] = *(_uw *) valuep; +#if defined(__thumb__) + /* Force LSB bit since we always run thumb code. */ + if (regno == R_PC) + vrs->core.r[regno] |= 1; +#endif return _UVRSR_OK; case _UVRSC_VFP: -- cgit v1.1