code: def _conc_alloc_size(self, sim_size):
          
          if self.state.solver.symbolic(sim_size):
              size = self.state.solver.max_int(sim_size)
              if size > self.state.libc.max_variable_size:
                  l.warning("Allocation request of %d bytes exceeded maximum of %d bytes; allocating %d bytes",
                            size, self.state.libc.max_variable_size, size)
                  size = self.state.libc.max_variable_size
          else:
              size = self.state.solver.eval(sim_size)
          return size
docs: Concretizes a size argument, if necessary, to something that makes sense when allocating space. Here we just
          maximize its potential size up to the maximum variable size specified in the libc plugin.
  
          TODO:
          Further consideration of the tradeoffs of this approach is probably warranted. SimHeapPTMalloc especially makes
          a lot of different concretization strategy assumptions, but this function handles one of the more important
          problems that any heap implementation will face: how to decide the amount of space to allocate upon request for
          a symbolic size. Either we do as we do here and silently constrain the amount returned to a default max value,
          or we could add a path constraint to the state to prevent exploration of any paths that would have legitimately
          occurred given a larger allocation size.
  
          The first approach (the silent maximum) has its benefit in that the explored state space will not be
          constrained. Sometimes this could work out, as when an allocation is returned that is smaller than requested but
          which the program doesn't end up making full use of anyways. Alternatively, this lack of fidelity could cause
          the program to overwrite other allocations made, since it should be able to assume the allocation is as large as
          it requested it be.
  
          The second approach (the path constraint) has its benefit in that no paths will be explored that *could* fail
          when an allocation is made too small. On the other hand, as stated above, some of these paths might not have
          failed anyways, and doing this causes us to lose the opportunity to explore those paths.
  
          Perhaps these behaviors could be parameterized in the future?