xref: /aosp_15_r20/bionic/libc/malloc_debug/tools/gen_malloc.pl (revision 8d67ca893c1523eb926b9080dbe4e2ffd2a27ba1)
1*8d67ca89SAndroid Build Coastguard Worker#!/usr/bin/perl -w
2*8d67ca89SAndroid Build Coastguard Worker# Copyright (C) 2018 The Android Open Source Project
3*8d67ca89SAndroid Build Coastguard Worker# All rights reserved.
4*8d67ca89SAndroid Build Coastguard Worker#
5*8d67ca89SAndroid Build Coastguard Worker# Redistribution and use in source and binary forms, with or without
6*8d67ca89SAndroid Build Coastguard Worker# modification, are permitted provided that the following conditions
7*8d67ca89SAndroid Build Coastguard Worker# are met:
8*8d67ca89SAndroid Build Coastguard Worker#  * Redistributions of source code must retain the above copyright
9*8d67ca89SAndroid Build Coastguard Worker#    notice, this list of conditions and the following disclaimer.
10*8d67ca89SAndroid Build Coastguard Worker#  * Redistributions in binary form must reproduce the above copyright
11*8d67ca89SAndroid Build Coastguard Worker#    notice, this list of conditions and the following disclaimer in
12*8d67ca89SAndroid Build Coastguard Worker#    the documentation and/or other materials provided with the
13*8d67ca89SAndroid Build Coastguard Worker#    distribution.
14*8d67ca89SAndroid Build Coastguard Worker#
15*8d67ca89SAndroid Build Coastguard Worker# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16*8d67ca89SAndroid Build Coastguard Worker# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17*8d67ca89SAndroid Build Coastguard Worker# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18*8d67ca89SAndroid Build Coastguard Worker# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19*8d67ca89SAndroid Build Coastguard Worker# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20*8d67ca89SAndroid Build Coastguard Worker# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21*8d67ca89SAndroid Build Coastguard Worker# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22*8d67ca89SAndroid Build Coastguard Worker# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23*8d67ca89SAndroid Build Coastguard Worker# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24*8d67ca89SAndroid Build Coastguard Worker# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25*8d67ca89SAndroid Build Coastguard Worker# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*8d67ca89SAndroid Build Coastguard Worker# SUCH DAMAGE.
27*8d67ca89SAndroid Build Coastguard Worker
28*8d67ca89SAndroid Build Coastguard Workeruse strict;
29*8d67ca89SAndroid Build Coastguard Worker
30*8d67ca89SAndroid Build Coastguard Workersub PrintHeader() {
31*8d67ca89SAndroid Build Coastguard Worker  print <<EOT;
32*8d67ca89SAndroid Build Coastguard Worker/*
33*8d67ca89SAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project
34*8d67ca89SAndroid Build Coastguard Worker * All rights reserved.
35*8d67ca89SAndroid Build Coastguard Worker *
36*8d67ca89SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
37*8d67ca89SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
38*8d67ca89SAndroid Build Coastguard Worker * are met:
39*8d67ca89SAndroid Build Coastguard Worker *  * Redistributions of source code must retain the above copyright
40*8d67ca89SAndroid Build Coastguard Worker *    notice, this list of conditions and the following disclaimer.
41*8d67ca89SAndroid Build Coastguard Worker *  * Redistributions in binary form must reproduce the above copyright
42*8d67ca89SAndroid Build Coastguard Worker *    notice, this list of conditions and the following disclaimer in
43*8d67ca89SAndroid Build Coastguard Worker *    the documentation and/or other materials provided with the
44*8d67ca89SAndroid Build Coastguard Worker *    distribution.
45*8d67ca89SAndroid Build Coastguard Worker *
46*8d67ca89SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
47*8d67ca89SAndroid Build Coastguard Worker * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
48*8d67ca89SAndroid Build Coastguard Worker * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
49*8d67ca89SAndroid Build Coastguard Worker * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
50*8d67ca89SAndroid Build Coastguard Worker * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
51*8d67ca89SAndroid Build Coastguard Worker * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
52*8d67ca89SAndroid Build Coastguard Worker * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
53*8d67ca89SAndroid Build Coastguard Worker * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
54*8d67ca89SAndroid Build Coastguard Worker * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
55*8d67ca89SAndroid Build Coastguard Worker * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
56*8d67ca89SAndroid Build Coastguard Worker * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57*8d67ca89SAndroid Build Coastguard Worker * SUCH DAMAGE.
58*8d67ca89SAndroid Build Coastguard Worker */
59*8d67ca89SAndroid Build Coastguard Worker
60*8d67ca89SAndroid Build Coastguard Worker// Generated by gen_malloc.pl, do not modify.
61*8d67ca89SAndroid Build Coastguard Worker
62*8d67ca89SAndroid Build Coastguard WorkerEOT
63*8d67ca89SAndroid Build Coastguard Worker}
64*8d67ca89SAndroid Build Coastguard Worker
65*8d67ca89SAndroid Build Coastguard Workersub PrintMainloop() {
66*8d67ca89SAndroid Build Coastguard Worker  print <<EOT;
67*8d67ca89SAndroid Build Coastguard Workervoid BenchmarkMalloc(MallocEntry entries[], size_t total_entries, size_t max_allocs) {
68*8d67ca89SAndroid Build Coastguard Worker  void* ptrs[max_allocs];
69*8d67ca89SAndroid Build Coastguard Worker
70*8d67ca89SAndroid Build Coastguard Worker  for (size_t i = 0; i < total_entries; i++) {
71*8d67ca89SAndroid Build Coastguard Worker    switch (entries[i].type) {
72*8d67ca89SAndroid Build Coastguard Worker    case MALLOC:
73*8d67ca89SAndroid Build Coastguard Worker      ptrs[entries[i].idx] = malloc(entries[i].size);
74*8d67ca89SAndroid Build Coastguard Worker      // Touch at least one byte of the allocation to make sure that
75*8d67ca89SAndroid Build Coastguard Worker      // PSS for this allocation is counted.
76*8d67ca89SAndroid Build Coastguard Worker      reinterpret_cast<uint8_t*>(ptrs[entries[i].idx])[0] = 10;
77*8d67ca89SAndroid Build Coastguard Worker      break;
78*8d67ca89SAndroid Build Coastguard Worker    case CALLOC:
79*8d67ca89SAndroid Build Coastguard Worker      ptrs[entries[i].idx] = calloc(entries[i].arg2, entries[i].size);
80*8d67ca89SAndroid Build Coastguard Worker      // Touch at least one byte of the allocation to make sure that
81*8d67ca89SAndroid Build Coastguard Worker      // PSS for this allocation is counted.
82*8d67ca89SAndroid Build Coastguard Worker      reinterpret_cast<uint8_t*>(ptrs[entries[i].idx])[0] = 20;
83*8d67ca89SAndroid Build Coastguard Worker      break;
84*8d67ca89SAndroid Build Coastguard Worker    case MEMALIGN:
85*8d67ca89SAndroid Build Coastguard Worker      ptrs[entries[i].idx] = memalign(entries[i].arg2, entries[i].size);
86*8d67ca89SAndroid Build Coastguard Worker      // Touch at least one byte of the allocation to make sure that
87*8d67ca89SAndroid Build Coastguard Worker      // PSS for this allocation is counted.
88*8d67ca89SAndroid Build Coastguard Worker      reinterpret_cast<uint8_t*>(ptrs[entries[i].idx])[0] = 30;
89*8d67ca89SAndroid Build Coastguard Worker      break;
90*8d67ca89SAndroid Build Coastguard Worker    case REALLOC:
91*8d67ca89SAndroid Build Coastguard Worker      if (entries[i].arg2 == 0) {
92*8d67ca89SAndroid Build Coastguard Worker        ptrs[entries[i].idx] = realloc(nullptr, entries[i].size);
93*8d67ca89SAndroid Build Coastguard Worker      } else {
94*8d67ca89SAndroid Build Coastguard Worker        ptrs[entries[i].idx] = realloc(ptrs[entries[i].arg2 - 1], entries[i].size);
95*8d67ca89SAndroid Build Coastguard Worker      }
96*8d67ca89SAndroid Build Coastguard Worker      // Touch at least one byte of the allocation to make sure that
97*8d67ca89SAndroid Build Coastguard Worker      // PSS for this allocation is counted.
98*8d67ca89SAndroid Build Coastguard Worker      reinterpret_cast<uint8_t*>(ptrs[entries[i].idx])[0] = 40;
99*8d67ca89SAndroid Build Coastguard Worker      break;
100*8d67ca89SAndroid Build Coastguard Worker    case FREE:
101*8d67ca89SAndroid Build Coastguard Worker      free(ptrs[entries[i].idx]);
102*8d67ca89SAndroid Build Coastguard Worker      break;
103*8d67ca89SAndroid Build Coastguard Worker    }
104*8d67ca89SAndroid Build Coastguard Worker  }
105*8d67ca89SAndroid Build Coastguard Worker}
106*8d67ca89SAndroid Build Coastguard Worker
107*8d67ca89SAndroid Build Coastguard WorkerEOT
108*8d67ca89SAndroid Build Coastguard Worker}
109*8d67ca89SAndroid Build Coastguard Worker
110*8d67ca89SAndroid Build Coastguard Workersub PrintDefinitions() {
111*8d67ca89SAndroid Build Coastguard Worker  print <<EOT;
112*8d67ca89SAndroid Build Coastguard Workerenum AllocEnum : uint8_t {
113*8d67ca89SAndroid Build Coastguard Worker  MALLOC = 0,
114*8d67ca89SAndroid Build Coastguard Worker  CALLOC,
115*8d67ca89SAndroid Build Coastguard Worker  MEMALIGN,
116*8d67ca89SAndroid Build Coastguard Worker  REALLOC,
117*8d67ca89SAndroid Build Coastguard Worker  FREE,
118*8d67ca89SAndroid Build Coastguard Worker};
119*8d67ca89SAndroid Build Coastguard Worker
120*8d67ca89SAndroid Build Coastguard Workerstruct MallocEntry {
121*8d67ca89SAndroid Build Coastguard Worker  AllocEnum type;
122*8d67ca89SAndroid Build Coastguard Worker  size_t idx;
123*8d67ca89SAndroid Build Coastguard Worker  size_t size;
124*8d67ca89SAndroid Build Coastguard Worker  size_t arg2;
125*8d67ca89SAndroid Build Coastguard Worker};
126*8d67ca89SAndroid Build Coastguard Worker
127*8d67ca89SAndroid Build Coastguard WorkerEOT
128*8d67ca89SAndroid Build Coastguard Worker}
129*8d67ca89SAndroid Build Coastguard Worker
130*8d67ca89SAndroid Build Coastguard Workersub PrintUsageAndExit() {
131*8d67ca89SAndroid Build Coastguard Worker  print "USAGE: gen_malloc.pl [-d][-i][-m] THREAD_ID STRUCT_NAME MAX_SLOT_NAME < ALLOCS.txt\n";
132*8d67ca89SAndroid Build Coastguard Worker  print "  -d\n";
133*8d67ca89SAndroid Build Coastguard Worker  print "    Print the structure definitions.\n";
134*8d67ca89SAndroid Build Coastguard Worker  print "  -i\n";
135*8d67ca89SAndroid Build Coastguard Worker  print "    Ignore missing allocations.\n";
136*8d67ca89SAndroid Build Coastguard Worker  print "  -m\n";
137*8d67ca89SAndroid Build Coastguard Worker  print "    Print the main loop code that can reproduce the trace.\n";
138*8d67ca89SAndroid Build Coastguard Worker  print "  THREAD_ID\n";
139*8d67ca89SAndroid Build Coastguard Worker  print "    The thread for which entries will be printed.\n";
140*8d67ca89SAndroid Build Coastguard Worker  print "  STRUCT_NAME\n";
141*8d67ca89SAndroid Build Coastguard Worker  print "    The name of the structure containing all of the entries.\n";
142*8d67ca89SAndroid Build Coastguard Worker  print "  MAX_SLOT_NAME\n";
143*8d67ca89SAndroid Build Coastguard Worker  print "    The name of the name of the maximum slots variable.\n";
144*8d67ca89SAndroid Build Coastguard Worker  print "  ALLOCS.txt\n";
145*8d67ca89SAndroid Build Coastguard Worker  print "    A file generated by the malloc debug option record_allocs\n";
146*8d67ca89SAndroid Build Coastguard Worker  exit(1);
147*8d67ca89SAndroid Build Coastguard Worker}
148*8d67ca89SAndroid Build Coastguard Worker
149*8d67ca89SAndroid Build Coastguard Workersub GetSlot($) {
150*8d67ca89SAndroid Build Coastguard Worker  my ($opts) = @_;
151*8d67ca89SAndroid Build Coastguard Worker
152*8d67ca89SAndroid Build Coastguard Worker  if (scalar(@{$opts->{empty_slots}}) == 0) {
153*8d67ca89SAndroid Build Coastguard Worker    return $opts->{last_slot}++;
154*8d67ca89SAndroid Build Coastguard Worker  } else {
155*8d67ca89SAndroid Build Coastguard Worker    return pop(@{$opts->{empty_slots}});
156*8d67ca89SAndroid Build Coastguard Worker  }
157*8d67ca89SAndroid Build Coastguard Worker}
158*8d67ca89SAndroid Build Coastguard Worker
159*8d67ca89SAndroid Build Coastguard Workersub PrintFreeSlots($) {
160*8d67ca89SAndroid Build Coastguard Worker  my ($opts) = @_;
161*8d67ca89SAndroid Build Coastguard Worker
162*8d67ca89SAndroid Build Coastguard Worker  if (scalar(@{$opts->{empty_slots}}) == $opts->{last_slot}) {
163*8d67ca89SAndroid Build Coastguard Worker    return;
164*8d67ca89SAndroid Build Coastguard Worker  }
165*8d67ca89SAndroid Build Coastguard Worker
166*8d67ca89SAndroid Build Coastguard Worker  print "\n    // Free rest of the allocs.\n";
167*8d67ca89SAndroid Build Coastguard Worker  my @sorted_empty_slots = sort({$a <=> $b} @{$opts->{empty_slots}});
168*8d67ca89SAndroid Build Coastguard Worker  my $slot = 0;
169*8d67ca89SAndroid Build Coastguard Worker  my $last_slot = $opts->{last_slot};
170*8d67ca89SAndroid Build Coastguard Worker  while ($slot < $last_slot) {
171*8d67ca89SAndroid Build Coastguard Worker    my $empty_slot = $last_slot;
172*8d67ca89SAndroid Build Coastguard Worker    if (scalar(@sorted_empty_slots) != 0) {
173*8d67ca89SAndroid Build Coastguard Worker      $empty_slot = shift(@sorted_empty_slots);
174*8d67ca89SAndroid Build Coastguard Worker    }
175*8d67ca89SAndroid Build Coastguard Worker    for (; $slot < $empty_slot; $slot++) {
176*8d67ca89SAndroid Build Coastguard Worker      print "  {FREE, $slot, 0, 0},\n";
177*8d67ca89SAndroid Build Coastguard Worker    }
178*8d67ca89SAndroid Build Coastguard Worker    $slot++;
179*8d67ca89SAndroid Build Coastguard Worker  }
180*8d67ca89SAndroid Build Coastguard Worker}
181*8d67ca89SAndroid Build Coastguard Worker
182*8d67ca89SAndroid Build Coastguard Workersub PrintAlloc($$$$$$) {
183*8d67ca89SAndroid Build Coastguard Worker  my ($opts, $cur_thread, $pointer, $name, $size, $arg2) = @_;
184*8d67ca89SAndroid Build Coastguard Worker
185*8d67ca89SAndroid Build Coastguard Worker  if ($opts->{thread} eq $cur_thread) {
186*8d67ca89SAndroid Build Coastguard Worker    my $slot = GetSlot($opts);
187*8d67ca89SAndroid Build Coastguard Worker    $opts->{pointers}->{$pointer} = $slot;
188*8d67ca89SAndroid Build Coastguard Worker    print "  {$name, $slot, $size, $arg2},\n";
189*8d67ca89SAndroid Build Coastguard Worker  } else {
190*8d67ca89SAndroid Build Coastguard Worker    $opts->{pointers}->{$pointer} = -1;
191*8d67ca89SAndroid Build Coastguard Worker  }
192*8d67ca89SAndroid Build Coastguard Worker}
193*8d67ca89SAndroid Build Coastguard Worker
194*8d67ca89SAndroid Build Coastguard Workersub PrintEntries($$) {
195*8d67ca89SAndroid Build Coastguard Worker  my ($thread, $ignore_missing_allocations) = @_;
196*8d67ca89SAndroid Build Coastguard Worker
197*8d67ca89SAndroid Build Coastguard Worker  my $opts = {};
198*8d67ca89SAndroid Build Coastguard Worker  $opts->{thread} = $thread;
199*8d67ca89SAndroid Build Coastguard Worker  $opts->{empty_slots} = [];
200*8d67ca89SAndroid Build Coastguard Worker  $opts->{last_slot} = 0;
201*8d67ca89SAndroid Build Coastguard Worker  $opts->{pointers} = {};
202*8d67ca89SAndroid Build Coastguard Worker
203*8d67ca89SAndroid Build Coastguard Worker  while (<>) {
204*8d67ca89SAndroid Build Coastguard Worker    if (!/^(\d+):\s*/) {
205*8d67ca89SAndroid Build Coastguard Worker      continue
206*8d67ca89SAndroid Build Coastguard Worker    }
207*8d67ca89SAndroid Build Coastguard Worker    my $cur_thread = $1;
208*8d67ca89SAndroid Build Coastguard Worker
209*8d67ca89SAndroid Build Coastguard Worker    $_ = $';
210*8d67ca89SAndroid Build Coastguard Worker    if (/^malloc\s+(\S+)\s+(\d+)/) {
211*8d67ca89SAndroid Build Coastguard Worker      my $pointer = $1;
212*8d67ca89SAndroid Build Coastguard Worker      my $size = $2;
213*8d67ca89SAndroid Build Coastguard Worker      PrintAlloc($opts, $cur_thread, $pointer, "MALLOC", $size, 0);
214*8d67ca89SAndroid Build Coastguard Worker    } elsif (/^calloc\s+(\S+)\s+(\d+)\s+(\d+)/) {
215*8d67ca89SAndroid Build Coastguard Worker      my $pointer = $1;
216*8d67ca89SAndroid Build Coastguard Worker      my $nmemb = $2;
217*8d67ca89SAndroid Build Coastguard Worker      my $size = $3;
218*8d67ca89SAndroid Build Coastguard Worker      PrintAlloc($opts, $cur_thread, $pointer, "CALLOC", $size, $nmemb);
219*8d67ca89SAndroid Build Coastguard Worker    } elsif (/^memalign\s+(\S+)\s+(\d+)\s+(\d+)/) {
220*8d67ca89SAndroid Build Coastguard Worker      my $pointer = $1;
221*8d67ca89SAndroid Build Coastguard Worker      my $align = $2;
222*8d67ca89SAndroid Build Coastguard Worker      my $size = $3;
223*8d67ca89SAndroid Build Coastguard Worker      PrintAlloc($opts, $cur_thread, $pointer, "MEMALIGN", $size, $align);
224*8d67ca89SAndroid Build Coastguard Worker    } elsif (/^free\s+(\S+)/) {
225*8d67ca89SAndroid Build Coastguard Worker      my $pointer = $1;
226*8d67ca89SAndroid Build Coastguard Worker      if (!exists $opts->{pointers}->{$pointer}) {
227*8d67ca89SAndroid Build Coastguard Worker        if ($ignore_missing_allocations) {
228*8d67ca89SAndroid Build Coastguard Worker          warn "WARNING: $.: Unknown allocation $pointer ignored on $cur_thread\n";
229*8d67ca89SAndroid Build Coastguard Worker          next;
230*8d67ca89SAndroid Build Coastguard Worker        } else {
231*8d67ca89SAndroid Build Coastguard Worker          die "$.: Unknown allocation $pointer on $cur_thread\n";
232*8d67ca89SAndroid Build Coastguard Worker        }
233*8d67ca89SAndroid Build Coastguard Worker      } elsif ($opts->{pointers}->{$pointer} != -1) {
234*8d67ca89SAndroid Build Coastguard Worker        print "  {FREE, $opts->{pointers}->{$pointer}, 0, 0},\n";
235*8d67ca89SAndroid Build Coastguard Worker        push @{$opts->{empty_slots}}, $opts->{pointers}->{$pointer};
236*8d67ca89SAndroid Build Coastguard Worker      }
237*8d67ca89SAndroid Build Coastguard Worker    } elsif (/^realloc\s+(\S+)\s+(\S+)\s+(\d+)/) {
238*8d67ca89SAndroid Build Coastguard Worker      my $new_pointer = $1;
239*8d67ca89SAndroid Build Coastguard Worker      my $old_pointer = $2;
240*8d67ca89SAndroid Build Coastguard Worker      my $size = $3;
241*8d67ca89SAndroid Build Coastguard Worker
242*8d67ca89SAndroid Build Coastguard Worker      if ($thread ne $cur_thread) {
243*8d67ca89SAndroid Build Coastguard Worker        if ($new_pointer ne $old_pointer) {
244*8d67ca89SAndroid Build Coastguard Worker          $opts->{pointers}->{$new_pointer} = -1;
245*8d67ca89SAndroid Build Coastguard Worker          delete $opts->{pointers}->{$old_pointer};
246*8d67ca89SAndroid Build Coastguard Worker        }
247*8d67ca89SAndroid Build Coastguard Worker      } elsif ($old_pointer eq "0x0") {
248*8d67ca89SAndroid Build Coastguard Worker        my $slot = GetSlot($opts);
249*8d67ca89SAndroid Build Coastguard Worker        # This was a realloc(nullptr, size) call.
250*8d67ca89SAndroid Build Coastguard Worker        print "  {REALLOC, $slot, $size, 0},\n";
251*8d67ca89SAndroid Build Coastguard Worker        $opts->{pointers}->{$new_pointer} = $slot;
252*8d67ca89SAndroid Build Coastguard Worker      } else {
253*8d67ca89SAndroid Build Coastguard Worker        if (!exists $opts->{pointers}->{$old_pointer}) {
254*8d67ca89SAndroid Build Coastguard Worker          if ($ignore_missing_allocations) {
255*8d67ca89SAndroid Build Coastguard Worker            warn "WARNING: $.: Unknown realloc allocation $old_pointer ignored on $cur_thread\n";
256*8d67ca89SAndroid Build Coastguard Worker            next;
257*8d67ca89SAndroid Build Coastguard Worker          } else {
258*8d67ca89SAndroid Build Coastguard Worker            die "Unknown realloc allocation $old_pointer on $cur_thread\n";
259*8d67ca89SAndroid Build Coastguard Worker          }
260*8d67ca89SAndroid Build Coastguard Worker        }
261*8d67ca89SAndroid Build Coastguard Worker
262*8d67ca89SAndroid Build Coastguard Worker        if ($opts->{pointers}->{$old_pointer} != -1) {
263*8d67ca89SAndroid Build Coastguard Worker          # Reuse the same slot, no need to get a new one.
264*8d67ca89SAndroid Build Coastguard Worker          my $slot = $opts->{pointers}->{$old_pointer};
265*8d67ca89SAndroid Build Coastguard Worker          printf("    {REALLOC, $slot, $size, %d},\n", $slot + 1);
266*8d67ca89SAndroid Build Coastguard Worker
267*8d67ca89SAndroid Build Coastguard Worker          # NOTE: It is possible that old pointer and new pointer are the
268*8d67ca89SAndroid Build Coastguard Worker          # same (a realloc returns the same pointer).
269*8d67ca89SAndroid Build Coastguard Worker          if ($new_pointer ne $old_pointer) {
270*8d67ca89SAndroid Build Coastguard Worker            $opts->{pointers}->{$new_pointer} = $slot;
271*8d67ca89SAndroid Build Coastguard Worker            delete $opts->{pointers}->{$old_pointer};
272*8d67ca89SAndroid Build Coastguard Worker          }
273*8d67ca89SAndroid Build Coastguard Worker        }
274*8d67ca89SAndroid Build Coastguard Worker      }
275*8d67ca89SAndroid Build Coastguard Worker    } elsif (!/^thread_done/) {
276*8d67ca89SAndroid Build Coastguard Worker      die "$.: Unknown line $_\n";
277*8d67ca89SAndroid Build Coastguard Worker    }
278*8d67ca89SAndroid Build Coastguard Worker  }
279*8d67ca89SAndroid Build Coastguard Worker
280*8d67ca89SAndroid Build Coastguard Worker  PrintFreeSlots($opts);
281*8d67ca89SAndroid Build Coastguard Worker
282*8d67ca89SAndroid Build Coastguard Worker  return $opts->{last_slot};
283*8d67ca89SAndroid Build Coastguard Worker}
284*8d67ca89SAndroid Build Coastguard Worker
285*8d67ca89SAndroid Build Coastguard Workersub ProcessArgs($) {
286*8d67ca89SAndroid Build Coastguard Worker  my ($opts) = @_;
287*8d67ca89SAndroid Build Coastguard Worker
288*8d67ca89SAndroid Build Coastguard Worker  $opts->{print_definitions} = 0;
289*8d67ca89SAndroid Build Coastguard Worker  $opts->{ignore_missing_allocations} = 0;
290*8d67ca89SAndroid Build Coastguard Worker  $opts->{print_mainloop} = 0;
291*8d67ca89SAndroid Build Coastguard Worker  my @args = ();
292*8d67ca89SAndroid Build Coastguard Worker  while (scalar(@ARGV)) {
293*8d67ca89SAndroid Build Coastguard Worker    my $arg = pop(@ARGV);
294*8d67ca89SAndroid Build Coastguard Worker    if ($arg =~ /^-/) {
295*8d67ca89SAndroid Build Coastguard Worker      if ($arg eq "-d") {
296*8d67ca89SAndroid Build Coastguard Worker        $opts->{print_definitions} = 1;
297*8d67ca89SAndroid Build Coastguard Worker      } elsif ($arg eq "-i") {
298*8d67ca89SAndroid Build Coastguard Worker        $opts->{ignore_missing_allocations} = 1;
299*8d67ca89SAndroid Build Coastguard Worker      } elsif ($arg eq "-m") {
300*8d67ca89SAndroid Build Coastguard Worker        $opts->{print_mainloop} = 1;
301*8d67ca89SAndroid Build Coastguard Worker      } else {
302*8d67ca89SAndroid Build Coastguard Worker        print "Unknown option $arg\n";
303*8d67ca89SAndroid Build Coastguard Worker        PrintUsageAndExit();
304*8d67ca89SAndroid Build Coastguard Worker      }
305*8d67ca89SAndroid Build Coastguard Worker    } else {
306*8d67ca89SAndroid Build Coastguard Worker      unshift @args, $arg;
307*8d67ca89SAndroid Build Coastguard Worker    }
308*8d67ca89SAndroid Build Coastguard Worker  }
309*8d67ca89SAndroid Build Coastguard Worker
310*8d67ca89SAndroid Build Coastguard Worker  return @args;
311*8d67ca89SAndroid Build Coastguard Worker}
312*8d67ca89SAndroid Build Coastguard Worker
313*8d67ca89SAndroid Build Coastguard Workermy $opts = {};
314*8d67ca89SAndroid Build Coastguard Workermy @args = ProcessArgs($opts);
315*8d67ca89SAndroid Build Coastguard Workerif (scalar(@args) != 3) {
316*8d67ca89SAndroid Build Coastguard Worker  PrintUsageAndExit();
317*8d67ca89SAndroid Build Coastguard Worker}
318*8d67ca89SAndroid Build Coastguard Worker
319*8d67ca89SAndroid Build Coastguard Workermy $thread = $args[0];
320*8d67ca89SAndroid Build Coastguard Workermy $struct_name = $args[1];
321*8d67ca89SAndroid Build Coastguard Workermy $max_slot_name = $args[2];
322*8d67ca89SAndroid Build Coastguard Worker
323*8d67ca89SAndroid Build Coastguard WorkerPrintHeader();
324*8d67ca89SAndroid Build Coastguard Workerif ($opts->{print_definitions}) {
325*8d67ca89SAndroid Build Coastguard Worker  PrintDefinitions();
326*8d67ca89SAndroid Build Coastguard Worker}
327*8d67ca89SAndroid Build Coastguard Workerif ($opts->{print_mainloop}) {
328*8d67ca89SAndroid Build Coastguard Worker  PrintMainloop();
329*8d67ca89SAndroid Build Coastguard Worker}
330*8d67ca89SAndroid Build Coastguard Worker
331*8d67ca89SAndroid Build Coastguard Workerprint "static MallocEntry ${struct_name}[] = {\n";
332*8d67ca89SAndroid Build Coastguard Workermy $total_slots = PrintEntries($thread, $opts->{ignore_missing_allocations});
333*8d67ca89SAndroid Build Coastguard Workerprint "};\n";
334*8d67ca89SAndroid Build Coastguard Workerprint "static constexpr size_t ${max_slot_name} = $total_slots;\n";
335