size += READ32LE(&sh[i]->size);
bool elfReadProgram(ELFHeader *eh, u8 *data, int& size, bool parseDebug){  int count = READ16LE(&eh->e_phnum);  int i;    if(READ32LE(&eh->e_entry) == 0x2000000)    cpuIsMultiBoot = true;  // read program headers... should probably move this code down  u8 *p = data + READ32LE(&eh->e_phoff);  size = 0;  for(i = 0; i < count; i++) {    ELFProgramHeader *ph = (ELFProgramHeader *)p;    p += sizeof(ELFProgramHeader);    if(READ16LE(&eh->e_phentsize) != sizeof(ELFProgramHeader)) {      p += READ16LE(&eh->e_phentsize) - sizeof(ELFProgramHeader);    }    //    printf("PH %d %08x %08x %08x %08x %08x %08x %08x %08x\n",    //     i, ph->type, ph->offset, ph->vaddr, ph->paddr,    //     ph->filesz, ph->memsz, ph->flags, ph->align);    if(cpuIsMultiBoot) {      if(READ32LE(&ph->paddr) >= 0x2000000 &&         READ32LE(&ph->paddr) <= 0x203ffff) {        memcpy(&workRAM[READ32LE(&ph->paddr) & 0x3ffff],               data + READ32LE(&ph->offset),               READ32LE(&ph->filesz));      }          } else {      if(READ32LE(&ph->paddr) >= 0x8000000 &&         READ32LE(&ph->paddr) <= 0x9ffffff) {        memcpy(&rom[READ32LE(&ph->paddr) & 0x1ffffff],               data + READ32LE(&ph->offset),               READ32LE(&ph->filesz));        size += READ32LE(&ph->filesz);      }    }  }  char *stringTable = NULL;  // read section headers  p = data + READ32LE(&eh->e_shoff);  count = READ16LE(&eh->e_shnum);  ELFSectionHeader **sh = (ELFSectionHeader **)    malloc(sizeof(ELFSectionHeader *) * count);    for(i = 0; i < count; i++) {    sh[i] = (ELFSectionHeader *)p;    p += sizeof(ELFSectionHeader);    if(READ16LE(&eh->e_shentsize) != sizeof(ELFSectionHeader))      p += READ16LE(&eh->e_shentsize) - sizeof(ELFSectionHeader);  }  if(READ16LE(&eh->e_shstrndx) != 0) {    stringTable = (char *)elfReadSection(data,                                         sh[READ16LE(&eh->e_shstrndx)]);  }    elfSectionHeaders = sh;  elfSectionHeadersStringTable = stringTable;  elfSectionHeadersCount = count;  for(i = 0; i < count; i++) {    //    printf("SH %d %-20s %08x %08x %08x %08x %08x %08x %08x %08x\n",    //   i, &stringTable[sh[i]->name], sh[i]->name, sh[i]->type,    //   sh[i]->flags, sh[i]->addr, sh[i]->offset, sh[i]->size,    //   sh[i]->link, sh[i]->info);    if(READ32LE(&sh[i]->flags) & 2) { // load section      if(cpuIsMultiBoot) {        if(READ32LE(&sh[i]->addr) >= 0x2000000 &&           READ32LE(&sh[i]->addr) <= 0x203ffff) {          memcpy(&workRAM[READ32LE(&sh[i]->addr) & 0x3ffff], data +                 READ32LE(&sh[i]->offset),                 READ32LE(&sh[i]->size));        }            } else {        if(READ32LE(&sh[i]->addr) >= 0x8000000 &&           READ32LE(&sh[i]->addr) <= 0x9ffffff) {          memcpy(&rom[READ32LE(&sh[i]->addr) & 0x1ffffff],                 data + READ32LE(&sh[i]->offset),                 READ32LE(&sh[i]->size));          size += READ32LE(&sh[i]->size);        }      }          }  }  if(parseDebug) {    fprintf(stderr, "Parsing debug info\n");    ELFSectionHeader *dbgHeader = elfGetSectionByName(".debug_info");    if(dbgHeader == NULL) {      fprintf(stderr, "Cannot find debug information\n");      goto end;          }    ELFSectionHeader *h = elfGetSectionByName(".debug_abbrev");    if(h == NULL) {      fprintf(stderr, "Cannot find abbreviation table\n");      goto end;    }        elfDebugInfo = (DebugInfo *)calloc(sizeof(DebugInfo), 1);    u8 *abbrevdata = elfReadSection(data, h);    h = elfGetSectionByName(".debug_str");    if(h == NULL)      elfDebugStrings = NULL;    else      elfDebugStrings = (char *)elfReadSection(data, h);        u8 *debugdata = elfReadSection(data, dbgHeader);        elfDebugInfo->debugdata = data;    elfDebugInfo->infodata = debugdata;        u32 total = READ32LE(&dbgHeader->size);    u8 *end = debugdata + total;    u8 *ddata = debugdata;        CompileUnit *last = NULL;    CompileUnit *unit = NULL;        while(ddata < end) {      unit = elfParseCompUnit(ddata, abbrevdata);      unit->offset = ddata-debugdata;      elfParseLineInfo(unit, data);      if(last == NULL)        elfCompileUnits = unit;      else        last->next = unit;      last = unit;      ddata += 4 + unit->length;    }    elfParseAranges(data);    CompileUnit *comp = elfCompileUnits;    while(comp) {      ARanges *r = elfDebugInfo->ranges;      for(int i = 0; i < elfDebugInfo->numRanges; i++)        if(r[i].offset == comp->offset) {          comp->ranges = &r[i];          break;        }      comp = comp->next;    }    elfParseCFA(data);    elfReadSymtab(data);  } end:    if(sh) {    free(sh);  }  elfSectionHeaders = NULL;  elfSectionHeadersStringTable = NULL;  elfSectionHeadersCount = 0;    return true;}