From patchwork Mon Feb 4 17:22:59 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jack Howarth X-Patchwork-Id: 217998 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id D95AE2C02A5 for ; Tue, 5 Feb 2013 04:23:24 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1360603405; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type: Content-Disposition:User-Agent:Mailing-List:Precedence:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=0nP2eRl7H6dI8r7+2IowyOthxYY=; b=dbW3UqF41+2DjXW 1RoULBYOKbyscWR/LHLZwtp9heCk0Abwd7HYWAxvb6ARCeOsVaUr4OzFR+0PdpcX SOQlNjewhV7x2yJDWLinpegnQGMszPktb3tbsU1OTy5IOYiu/Hn54EI5R53/kSrO YsmGiQ9RScL/epka6ZFUS49qIe+k= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type:Content-Disposition:User-Agent:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=AvcrGijpmnG868j9MdTvRs24p3jzxy4H0+HG8XSAsObUedIMzidBGIUGJnWmRs G2mpUhDT+rOHwiXvTPZLHugqZirjQ2/SKR/JBrwuvq3pqVgIP03sHLQ2DAM5v30k XR/8f49mRHCJF1o9pZEAuCjRmTAuoZxvDSGBhhKN7cAfA=; Received: (qmail 13265 invoked by alias); 4 Feb 2013 17:23:19 -0000 Received: (qmail 13256 invoked by uid 22791); 4 Feb 2013 17:23:18 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SARE_SUB_OBFU_Q1 X-Spam-Check-By: sourceware.org Received: from bromo.med.uc.edu (HELO bromo.med.uc.edu) (129.137.3.146) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 04 Feb 2013 17:23:10 +0000 Received: from bromo.med.uc.edu (localhost.localdomain [127.0.0.1]) by bromo.med.uc.edu (Postfix) with ESMTP id 021FDB0011; Mon, 4 Feb 2013 12:23:09 -0500 (EST) Received: (from howarth@localhost) by bromo.med.uc.edu (8.14.3/8.14.3/Submit) id r14HN5PG023681; Mon, 4 Feb 2013 12:23:05 -0500 Date: Mon, 4 Feb 2013 12:22:59 -0500 From: Jack Howarth To: gcc-patches@gcc.gnu.org Cc: jakub@redhat.com, glider@google.com, dodji@redhat.com, kcc@google.com, dvyukov@google.com, mikestump@comcast.net, iain@codesourcery.com Subject: [PATCH] fix PR sanitizer/55617 via qsort Message-ID: <20130204172259.GA23606@bromo.med.uc.edu> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.18 (2008-05-17) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Currently darwin is unable to utilize libasan with constructors due to the lack of constructor priority support on that target. The asan_finish_file routine inserts an essential __asan_init into the array of constructors (via the __mod_init_func section). However the insertion occurs at the end, and due to the lack of priority support for constructors, these are executed from the front of the array of constructors on program startup. This causes code any instrumented code that executes before the __asan_init call to crash. The attached patch uses a va_gc vector of constructor symbol/priority records to queue this data inside machopic_asm_out_constructor. When the ctors vector is not empty, the finalize_ctors routine is called in darwin_file_end to sort the queue by priority, using a qsort stabilized on original position for identical priority, prior to emitting the constructors. The patch also adds a g++.dg/asan/pr55617.C test case which is targeted to i?86-*-darwin* and x86_64-*-darwin*. The patch reduces the failures observed when running.... make -k check-g++ RUNTESTFLAGS="--target_board=unix'{-fsanitize=address}'" from 323 to only 85 (which is similar to what linux shows). The cov.C testcase also fails on gcc trunk with -fsanitize=address when recrafted into a dynamic shared library http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55617#c28. This patch eliminates those crashes. This problem doesn't extend to when the shared library or module is dlopen'd (which works in stock gcc trunk and with this patch as well). The patch has been bootstrap and regression tested on x86_64-apple-darwin12. Okay for gcc trunk? Jack ps The issue of inter module priority support remains unresolved (as it is in clang/llvm). The only solution for both compilers is to reorder the linkage of the modules to insure that the module with the asan constructor appears first. /gcc 2013-02-04 Alexander Potapenko Jack Howarth Jakub Jelinek PR sanitizer/55617 * config/darwin.c (sort_ctor_records): Stabilized qsort on constructor priority by using original position. (finalize_ctors): New routine to sort constructors by priority before use in assemble_integer. (machopic_asm_out_constructor): Use finalize_ctors if needed. /gcc/testsuite 2013-02-04 Alexander Potapenko Jack Howarth Jakub Jelinek PR sanitizer/55617 * g++.dg/asan/pr55617.C: New test. Index: gcc/config/darwin.c =================================================================== --- gcc/config/darwin.c (revision 195685) +++ gcc/config/darwin.c (working copy) @@ -83,6 +83,14 @@ along with GCC; see the file COPYING3. kernel) the stubs might still be required, and this will be set true. */ int darwin_emit_branch_islands = false; +typedef struct GTY(()) ctor_record { + rtx symbol; + int priority; /* constructor priority */ + int position; /* original position */ +} ctor_record; + +static GTY(()) vec *ctors = NULL; + /* A flag to determine whether we are running c++ or obj-c++. This has to be settable from non-c-family contexts too (i.e. we can't use the c_dialect_ functions). */ @@ -1708,15 +1716,48 @@ machopic_select_rtx_section (enum machin void machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED) { + ctor_record new_elt = {symbol, priority, vec_safe_length (ctors)}; + + vec_safe_push (ctors, new_elt); + + if (! MACHOPIC_INDIRECT) + fprintf (asm_out_file, ".reference .constructors_used\n"); +} + +static int +sort_ctor_records (const void * a, const void * b) +{ + const ctor_record *ca = (const ctor_record *)a; + const ctor_record *cb = (const ctor_record *)b; + if (ca->priority > cb->priority) + return 1; + if (ca->priority < cb->priority) + return -1; + if (ca->position > cb->position) + return 1; + if (ca->position < cb->position) + return -1; + return 0; +} + +static void +finalize_ctors() +{ + unsigned int i; + ctor_record *elt; + if (MACHOPIC_INDIRECT) switch_to_section (darwin_sections[mod_init_section]); else switch_to_section (darwin_sections[constructor_section]); - assemble_align (POINTER_SIZE); - assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); - if (! MACHOPIC_INDIRECT) - fprintf (asm_out_file, ".reference .constructors_used\n"); + if (vec_safe_length (ctors) > 1) + ctors->qsort (sort_ctor_records); + FOR_EACH_VEC_SAFE_ELT (ctors, i, elt) + { + assemble_align (POINTER_SIZE); + assemble_integer (elt->symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); + } } void @@ -2762,6 +2803,8 @@ darwin_file_start (void) void darwin_file_end (void) { + if (!vec_safe_is_empty (ctors)) + finalize_ctors(); machopic_finish (asm_out_file); if (strcmp (lang_hooks.name, "GNU C++") == 0) {