From patchwork Fri Oct 28 20:39:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 16932 Received: (qmail 52437 invoked by alias); 28 Oct 2016 20:39:19 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 52419 invoked by uid 89); 28 Oct 2016 20:39:18 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.3 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=neighbors, adapt, NEXT, Forward X-HELO: mx1.redhat.com Subject: Re: [PATCH] malloc: Use accessors for chunk metadata access To: "Carlos O'Donell" , GNU C Library References: <5443da2a-7b59-929f-c6ce-ad6c19b0f2ea@redhat.com> <06e061fc-47ad-8c0b-589f-e1a3f265e47d@redhat.com> From: Florian Weimer Message-ID: <8c3b786c-f6ef-84a7-0fe2-3c6a66b15431@redhat.com> Date: Fri, 28 Oct 2016 22:39:13 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 In-Reply-To: <06e061fc-47ad-8c0b-589f-e1a3f265e47d@redhat.com> On 10/28/2016 05:07 PM, Carlos O'Donell wrote: > On 10/28/2016 10:52 AM, Florian Weimer wrote: >> /* check for chunk from non-main arena */ >> -#define chunk_non_main_arena(p) ((p)->size & NON_MAIN_ARENA) >> +#define chunk_main_arena(p) (((p)->mchunk_size & NON_MAIN_ARENA) == 0) > > Comment is wrong now :} Hmph. I've taken the opportunity to adjust the chunk layout comment as well, in preparation for documenting where the encryption happens. Florian malloc: Update comments about chunk layout 2016-10-28 Florian Weimer * malloc/malloc.c: Update chunk layout comments. (chunk_main_arena): Update comment. diff --git a/malloc/malloc.c b/malloc/malloc.c index a10477e..584edbf 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -1070,18 +1070,19 @@ struct malloc_chunk { chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk, if allocated | | + | Size of previous chunk, if unallocated (P clear) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of chunk, in bytes |M|P| + | Size of chunk, in bytes |A|M|P| mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | User data starts here... . . . . (malloc_usable_size() bytes) . . | nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of chunk | + | (size of chunk, but used for application data) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of next chunk, in bytes |A|0|1| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - Where "chunk" is the front of the chunk for the purpose of most of the malloc code, but "mem" is the pointer that is returned to the @@ -1094,9 +1095,9 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Free chunks are stored in circular doubly-linked lists, and look like this: chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk | + | Size of previous chunk, if unallocated (P clear) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `head:' | Size of chunk, in bytes |P| + `head:' | Size of chunk, in bytes |A|0|P| mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Forward pointer to next chunk in list | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -1108,6 +1109,8 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ `foot:' | Size of chunk, in bytes | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of next chunk, in bytes |A|0|0| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ The P (PREV_INUSE) bit, stored in the unused low-order bit of the chunk size (which is always a multiple of two words), is an in-use @@ -1120,12 +1123,21 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ the size of the previous chunk, and might even get a memory addressing fault when trying to do so. + The A (NON_MAIN_ARENA) bit is cleared for chunks on the initial, + main arena, described by the main_arena variable. When additional + threads are spawned, each thread receives its own arena (up to a + configurable limit, after which arenas are reused for multiple + threads), and the chunks in these arenas have the A bit set. To + find the arena for a chunk on such a non-main arena, heap_for_ptr + performs a bit mask operation and indirection through the ar_ptr + member of the per-heap header heap_info (see arena.c). + Note that the `foot' of the current chunk is actually represented as the prev_size of the NEXT chunk. This makes it easier to deal with alignments etc but can be very confusing when trying to extend or adapt this code. - The two exceptions to all this are + The three exceptions to all this are: 1. The special chunk `top' doesn't bother using the trailing size field since there is no next contiguous chunk @@ -1135,8 +1147,16 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2. Chunks allocated via mmap, which have the second-lowest-order bit M (IS_MMAPPED) set in their size fields. Because they are - allocated one-by-one, each must contain its own trailing size field. + allocated one-by-one, each must contain its own trailing size + field. If the M bit is set, the other bits are ignored + (because mmapped chunks are neither in an arena, nor adjacent + to a freed chunk). The M bit is also used for chunks which + originally came from a dumped heap via malloc_set_state in + hooks.c. + 3. Chunks in fastbins are treated as allocated chunks from the + point of view of the chunk allocator. They are consolidated + with their neighbors only in bulk, in malloc_consolidate. */ /* @@ -1215,7 +1235,7 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ the chunk to the user, if necessary. */ #define NON_MAIN_ARENA 0x4 -/* check for chunk from non-main arena */ +/* Check for chunk from main arena. */ #define chunk_main_arena(p) (((p)->mchunk_size & NON_MAIN_ARENA) == 0) /* Mark a chunk as not being on the main arena. */