'Construct the ROP chain into a list of elements which can be passed
to :func:`.flat`.
Arguments:
base(int):
The base address to build the rop-chain from. Defaults to
:attr:`base`.
description(dict):
Optional output argument, which will gets a mapping of
``address: description`` for each address on the stack,
starting at ``base``.'

def build(self, base=None, description=None):

    if (base is None):
        base = (self.base or 0)
    stack = DescriptiveStack(base)
    chain = self._chain
    iterable = enumerate(chain)
    for (idx, slot) in iterable:
        remaining = ((len(chain) - 1) - idx)
        address = stack.next
        if isinstance(slot, (int, long)):
            stack.describe(self.describe(slot))
            stack.append(slot)
        elif isinstance(slot, (str, unicode)):
            stack.describe(self.describe(slot))
            slot += self.generatePadding(stack.next, (len(slot) % context.bytes))
            for chunk in lists.group(context.bytes, slot):
                stack.append(chunk)
        elif isinstance(slot, srop.SigreturnFrame):
            stack.describe('Sigreturn    Frame')
            if ((slot.sp in (0, None)) and self.base):
                slot.sp = (stack.next + len(slot))
            registers = [slot.registers[i] for i in sorted(slot.registers.keys())]
            for register in registers:
                value = slot[register]
                description = self.describe(value)
                if description:
                    stack.describe(('%s    =    %s' % (register, description)))
                else:
                    stack.describe(('%s' % register))
                stack.append(value)
        elif isinstance(slot, Call):
            stack.describe(self.describe(slot))
            registers = dict(zip(slot.abi.register_arguments, slot.args))
            setRegisters = self.setRegisters(registers)
            for (register, gadgets) in setRegisters.items():
                value = registers[register]
                description = (self.describe(value) or ('arg%i' % slot.args.index(value)))
                stack.describe(('set    %s    =    %s' % (register, description)))
                stack.extend(gadgets)
            if (address != stack.next):
                stack.describe(slot.name)
            stack.append(slot.target)
            stackArguments = slot.args[len(slot.abi.register_arguments):]
            nextGadgetAddr = (stack.next + (context.bytes * len(stackArguments)))
            if slot.abi.returns:
                if remaining:
                    fix_size = (1 + len(stackArguments))
                    fix_bytes = (fix_size * context.bytes)
                    adjust = self.search(move=fix_bytes)
                    if (not adjust):
                        log.error(('Could    not    find    gadget    to    adjust    stack    by    %#x    bytes' % fix_bytes))
                    nextGadgetAddr = (stack.next + adjust.move)
                    stack.describe(('<adjust:    %s>' % self.describe(adjust)))
                    stack.append(adjust.address)
                    for pad in range(fix_bytes, adjust.move, context.bytes):
                        stackArguments.append(Padding())
                else:
                    stack.describe('<pad>')
                    stack.append(Padding())
            for (i, argument) in enumerate(stackArguments):
                if isinstance(argument, NextGadgetAddress):
                    stack.describe('<next    gadget>')
                    stack.append(nextGadgetAddr)
                else:
                    description = (self.describe(argument) or ('arg%i' % (i + len(registers))))
                    stack.describe(description)
                    stack.append(argument)
        else:
            stack.append(slot)
    start = base
    end = stack.next
    size = (stack.next - base)
    for (i, slot) in enumerate(stack):
        slot_address = (stack.address + (i * context.bytes))
        if isinstance(slot, (int, long)):
            pass
        elif isinstance(slot, (str, unicode)):
            pass
        elif isinstance(slot, AppendedArgument):
            stack[i] = stack.next
            stack.extend(slot.resolve(stack.next))
        elif isinstance(slot, CurrentStackPointer):
            stack[i] = slot_address
        elif isinstance(slot, Padding):
            stack[i] = self.generatePadding((i * context.bytes), context.bytes)
            stack.describe('<pad>', slot_address)
        elif isinstance(slot, Gadget):
            stack[i] = slot.address
            stack.describe(self.describe(slot), slot_address)
        else:
            pass
    return stack
