From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2049) id DC2F6385E442; Mon, 14 Mar 2022 10:35:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DC2F6385E442 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Matthew Malcomson To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/ARM/heads/morello)] libgcc type handling. X-Act-Checkin: gcc X-Git-Author: Matthew Malcomson X-Git-Refname: refs/vendors/ARM/heads/morello X-Git-Oldrev: 9b82fa20f04768be50824a2e4ce8762a1a3db7ef X-Git-Newrev: 724db4b6920f23db62ad3a21abcc1908d8fe3ccf Message-Id: <20220314103552.DC2F6385E442@sourceware.org> Date: Mon, 14 Mar 2022 10:35:52 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 Mar 2022 10:35:53 -0000 https://gcc.gnu.org/g:724db4b6920f23db62ad3a21abcc1908d8fe3ccf commit 724db4b6920f23db62ad3a21abcc1908d8fe3ccf Author: Matthew Malcomson Date: Mon Mar 7 18:04:40 2022 +0000 libgcc type handling. Here we update various places throughout the FDE searching code using PC addresses. With the introduction of the distinction between an address and a pointer for capability architectures this has gotten a little unclear. The reasoning behind these changes is as follows: - read_encoded_value_with_base must be able to read in a capability, since we use that functionality for reading personality functions and landing pads. Hence all variables which we read in using that function should have a capability type. - The PC addresses are never written as capabilities directly. Hence reading in the addresses directly into capability types is a bit of a red flag. The existing code did this in a few different places when the encoding of the FDE was DW_EH_PE_absptr. This clause won't be entered for pure capability architectures, but it still makes for code which looks problematic to the reader. Hence we switch the types here to be addresses, which are fine in both capability and non-capability architectures. - The ob->pc_begin member *is* kept as a capability for no real reason other than consistency with the other `struct object` members which are `void *`. While reading in the PC start addresses of FDE's we could end up with a capability if the address is encoded in the right way, hence this member could end up containing a capability, but it's still only used for checking positions and hence could be an address. Diff: --- libgcc/unwind-dw2-fde.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c index 26be05d4aca..b58b381fd1a 100644 --- a/libgcc/unwind-dw2-fde.c +++ b/libgcc/unwind-dw2-fde.c @@ -361,9 +361,9 @@ static int fde_unencoded_compare (struct object *ob __attribute__((unused)), const fde *x, const fde *y) { - _Unwind_Ptr x_ptr, y_ptr; - memcpy (&x_ptr, x->pc_begin, sizeof (_Unwind_Ptr)); - memcpy (&y_ptr, y->pc_begin, sizeof (_Unwind_Ptr)); + _Unwind_Address x_ptr, y_ptr; + memcpy (&x_ptr, x->pc_begin, sizeof (_Unwind_Address)); + memcpy (&y_ptr, y->pc_begin, sizeof (_Unwind_Address)); if (x_ptr > y_ptr) return 1; @@ -721,8 +721,8 @@ add_fdes (struct object *ob, struct fde_accumulator *accu, const fde *this_fde) if (encoding == DW_EH_PE_absptr) { - _Unwind_Ptr ptr; - memcpy (&ptr, this_fde->pc_begin, sizeof (_Unwind_Ptr)); + _Unwind_Address ptr; + memcpy (&ptr, this_fde->pc_begin, sizeof (_Unwind_Address)); if (ptr == 0) continue; } @@ -866,7 +866,7 @@ linear_search_fdes (struct object *ob, const fde *this_fde, _Unwind_Address pc) } else { - _Unwind_Ptr mask; + _Unwind_Address mask; const unsigned char *p; p = read_encoded_value_with_base (encoding, base, @@ -876,9 +876,13 @@ linear_search_fdes (struct object *ob, const fde *this_fde, _Unwind_Address pc) /* Take care to ignore link-once functions that were removed. In these cases, the function address will be NULL, but if the encoding is smaller than a pointer a true NULL may not - be representable. Assume 0 in the representable bits is NULL. */ + be representable. Assume 0 in the representable bits is NULL. + + For capability targets we must check against the size of an + address, since the size of a pointer includes metadata which does + not determine whether the pointer is NULL or not. */ mask = size_of_encoded_value (encoding); - if (mask < sizeof (void *)) + if (mask < sizeof (_Unwind_Address)) mask = (((_Unwind_Ptr) 1) << (mask << 3)) - 1; else mask = -1; @@ -887,7 +891,7 @@ linear_search_fdes (struct object *ob, const fde *this_fde, _Unwind_Address pc) continue; } - if ((_Unwind_Ptr) pc - pc_begin < pc_range) + if (pc - (_Unwind_Address)pc_begin < (_Unwind_Address)pc_range) return this_fde; } @@ -907,12 +911,12 @@ binary_search_unencoded_fdes (struct object *ob, _Unwind_Address pc) { size_t i = (lo + hi) / 2; const fde *const f = vec->array[i]; - void *pc_begin; + uaddr pc_begin; uaddr pc_range; - memcpy (&pc_begin, (const void * const *) f->pc_begin, sizeof (void *)); + memcpy (&pc_begin, (const uaddr *) f->pc_begin, sizeof (uaddr)); memcpy (&pc_range, (const uaddr *) f->pc_begin + 1, sizeof (uaddr)); - if ((_Unwind_Address)pc < pc_begin) + if (pc < pc_begin) hi = i; else if (pc >= pc_begin + pc_range) lo = i + 1; @@ -944,7 +948,7 @@ binary_search_single_encoding_fdes (struct object *ob, _Unwind_Address pc) if ((_Unwind_Address) pc < pc_begin) hi = i; - else if ((_Unwind_Address) pc >= pc_begin + pc_range) + else if ((_Unwind_Address) pc >= pc_begin + (_Unwind_Address)pc_range) lo = i + 1; else return f; @@ -975,7 +979,7 @@ binary_search_mixed_encoding_fdes (struct object *ob, _Unwind_Address pc) if ((_Unwind_Address) pc < pc_begin) hi = i; - else if ((_Unwind_Address) pc >= pc_begin + pc_range) + else if ((_Unwind_Address) pc >= pc_begin + (_Unwind_Address)pc_range) lo = i + 1; else return f; @@ -996,7 +1000,7 @@ search_object (struct object* ob, _Unwind_Address pc) /* Despite the above comment, the normal reason to get here is that we've not processed this object before. A quick range check is in order. */ - if (pc < ob->pc_begin) + if (pc < (_Unwind_Address)ob->pc_begin) return NULL; } @@ -1054,7 +1058,7 @@ _Unwind_Find_FDE (_Unwind_Address pc, struct dwarf_eh_bases *bases) containing the pc. Note that pc_begin is sorted descending, and we expect objects to be non-overlapping. */ for (ob = seen_objects; ob; ob = ob->next) - if (pc >= ob->pc_begin) + if (pc >= (_Unwind_Address)ob->pc_begin) { f = search_object (ob, pc); if (f) @@ -1097,7 +1101,7 @@ _Unwind_Find_FDE (_Unwind_Address pc, struct dwarf_eh_bases *bases) encoding = get_fde_encoding (f); read_encoded_value_with_base (encoding, base_from_object (encoding, ob), f->pc_begin, &func); - bases->func = func; + bases->func = (void *) func; } return f;