1/*
2 * Copyright (c) 2011 Apple Inc. All rights reserved.
3 *
4 * @APPLE_APACHE_LICENSE_HEADER_START@
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * @APPLE_APACHE_LICENSE_HEADER_END@
19 */
20/*
21    InUseEnumerator.h
22    Malloc zone enumeration implemlentation.
23    Copyright (c) 2004-2011 Apple Inc. All rights reserved.
24 */
25
26#pragma once
27#ifndef __AUTO_INUSEENUMERATOR__
28#define __AUTO_INUSEENUMERATOR__
29
30#include <malloc/malloc.h>
31
32#include "Definitions.h"
33#include "Admin.h"
34
35namespace Auto {
36
37    //----- InUseEnumerator -----//
38
39    class InUseEnumerator {
40
41      private:
42
43        task_t                      _task;                          // task being probed
44        void                        *_context;                      // context passed back to callbacks
45        unsigned                    _type_mask;                     // selection of regions to be enumerated
46        vm_address_t                _zone_address;                  // task address of zone being probed
47        auto_memory_reader_t        _reader;                        // reader used to laod task memory
48        auto_vm_range_recorder_t    _recorder;                      // range recording function
49        kern_return_t               _error;                         // error from call back
50
51      public:
52
53        //
54        // Constructor
55        //
56        InUseEnumerator(task_t task, void *context, unsigned type_mask, vm_address_t zone_address, auto_memory_reader_t reader, auto_vm_range_recorder_t recorder)
57        : _task(task)
58        , _context(context)
59        , _type_mask(type_mask)
60        , _zone_address(zone_address)
61        , _reader(reader)
62        , _recorder(recorder)
63        , _error(KERN_SUCCESS)
64        {}
65
66
67        //
68        // read
69        //
70        // Read memory from the task into current memory.
71        //
72        inline void *read(void *task_address, usword_t size) {
73            void *local_address;                           // location where memory was read
74
75            kern_return_t err = _reader(_task, (vm_address_t)task_address, (vm_size_t)size, &local_address);
76
77            if (err) {
78                _error = err;
79                return NULL;
80            }
81
82            return local_address;
83        }
84
85
86        //
87        // record
88        //
89        // Inform requester of a block's existence.
90        //
91        inline void record(void *address, usword_t size, unsigned type) {
92            // if recording this type
93            if (_type_mask & type) {
94                // range to record
95                vm_range_t range;
96                range.address = (vm_address_t)address;
97                range.size = size;
98                // record
99                _recorder(_task, _context, type & _type_mask, &range, 1);
100            }
101        }
102
103
104        //
105        // scan
106        //
107        // Scan through a task's auto zone looking for
108        //
109        kern_return_t scan();
110
111
112    };
113
114
115};
116
117#endif // __AUTO_INUSEENUMERATOR__
118
119