diff options
Diffstat (limited to 'src/libmach/executable.c')
-rw-r--r-- | src/libmach/executable.c | 62 |
1 files changed, 31 insertions, 31 deletions
diff --git a/src/libmach/executable.c b/src/libmach/executable.c index 34da72151..33000ed07 100644 --- a/src/libmach/executable.c +++ b/src/libmach/executable.c @@ -66,7 +66,7 @@ static int adotout(int, Fhdr*, ExecHdr*); static int elfdotout(int, Fhdr*, ExecHdr*); static int machdotout(int, Fhdr*, ExecHdr*); static int armdotout(int, Fhdr*, ExecHdr*); -static void setsym(Fhdr*, int32, int32, int32, vlong); +static void setsym(Fhdr*, vlong, int32, vlong, int32, vlong, int32); static void setdata(Fhdr*, uvlong, int32, vlong, int32); static void settext(Fhdr*, uvlong, uvlong, int32, vlong); static void hswal(void*, int, uint32(*)(uint32)); @@ -427,7 +427,7 @@ adotout(int fd, Fhdr *fp, ExecHdr *hp) hp->e.exechdr.text, sizeof(Exec)); setdata(fp, _round(pgsize+fp->txtsz+sizeof(Exec), pgsize), hp->e.exechdr.data, fp->txtsz+sizeof(Exec), hp->e.exechdr.bss); - setsym(fp, hp->e.exechdr.syms, hp->e.exechdr.spsz, hp->e.exechdr.pcsz, fp->datoff+fp->datsz); + setsym(fp, fp->datoff+fp->datsz, hp->e.exechdr.syms, 0, hp->e.exechdr.spsz, 0, hp->e.exechdr.pcsz); return 1; } @@ -525,7 +525,7 @@ commonllp64(int unused, Fhdr *fp, ExecHdr *hp) settext(fp, entry, pgsize+fp->hdrsz, hp->e.exechdr.text, fp->hdrsz); setdata(fp, _round(pgsize+fp->txtsz+fp->hdrsz, pgsize), hp->e.exechdr.data, fp->txtsz+fp->hdrsz, hp->e.exechdr.bss); - setsym(fp, hp->e.exechdr.syms, hp->e.exechdr.spsz, hp->e.exechdr.pcsz, fp->datoff+fp->datsz); + setsym(fp, fp->datoff+fp->datsz, hp->e.exechdr.syms, 0, hp->e.exechdr.spsz, 0, hp->e.exechdr.pcsz); if(hp->e.exechdr.magic & DYN_MAGIC) { fp->txtaddr = 0; @@ -758,13 +758,12 @@ elf64dotout(int fd, Fhdr *fp, ExecHdr *hp) bsssz = ph[0].memsz - ph[0].filesz; settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, ph[0].offset); setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz, bsssz); - setsym(fp, ph[1].filesz, 0, ph[1].memsz, ph[1].offset); + setsym(fp, ph[1].offset, ph[1].filesz, 0, 0, 0, ph[1].memsz); free(ph); return 1; } werrstr("No TEXT or DATA sections"); -error: free(ph); free(sh); return 0; @@ -773,12 +772,13 @@ error: settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset); setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, ph[id].memsz - ph[id].filesz); if(is != -1) - setsym(fp, ph[is].filesz, 0, ph[is].memsz, ph[is].offset); + setsym(fp, ph[is].offset, ph[is].filesz, 0, 0, 0, ph[is].memsz); else if(sh != 0){ char *buf; uvlong symsize = 0; uvlong symoff = 0; uvlong pclnsz = 0; + uvlong pclnoff = 0; /* load shstrtab names */ buf = malloc(sh[ep->shstrndx].size); @@ -786,7 +786,8 @@ error: goto done; memset(buf, 0, sizeof buf); seek(fd, sh[ep->shstrndx].offset, 0); - read(fd, buf, sh[ep->shstrndx].size); + i = read(fd, buf, sh[ep->shstrndx].size); + USED(i); // shut up ubuntu gcc for(i = 0; i < ep->shnum; i++) { if (strcmp(&buf[sh[i].name], ".gosymtab") == 0) { @@ -794,15 +795,11 @@ error: symoff = sh[i].offset; } if (strcmp(&buf[sh[i].name], ".gopclntab") == 0) { - if (sh[i].offset != symoff+symsize) { - werrstr("pc line table not contiguous with symbol table"); - free(buf); - goto error; - } pclnsz = sh[i].size; + pclnoff = sh[i].offset; } } - setsym(fp, symsize, 0, pclnsz, symoff); + setsym(fp, symoff, symsize, 0, 0, pclnoff, pclnsz); free(buf); } done: @@ -939,13 +936,12 @@ elfdotout(int fd, Fhdr *fp, ExecHdr *hp) bsssz = ph[0].memsz - ph[0].filesz; settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, ph[0].offset); setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz, bsssz); - setsym(fp, ph[1].filesz, 0, ph[1].memsz, ph[1].offset); + setsym(fp, ph[1].offset, ph[1].filesz, 0, 0, 0, ph[1].memsz); free(ph); return 1; } werrstr("No TEXT or DATA sections"); -error: free(sh); free(ph); return 0; @@ -954,12 +950,13 @@ error: settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset); setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, ph[id].memsz - ph[id].filesz); if(is != -1) - setsym(fp, ph[is].filesz, 0, ph[is].memsz, ph[is].offset); + setsym(fp, ph[is].offset, ph[is].filesz, 0, 0, 0, ph[is].memsz); else if(sh != 0){ char *buf; uvlong symsize = 0; uvlong symoff = 0; - uvlong pclnsz = 0; + uvlong pclnsize = 0; + uvlong pclnoff = 0; /* load shstrtab names */ buf = malloc(sh[ep->shstrndx].size); @@ -967,7 +964,8 @@ error: goto done; memset(buf, 0, sizeof buf); seek(fd, sh[ep->shstrndx].offset, 0); - read(fd, buf, sh[ep->shstrndx].size); + i = read(fd, buf, sh[ep->shstrndx].size); + USED(i); // shut up ubuntu gcc for(i = 0; i < ep->shnum; i++) { if (strcmp(&buf[sh[i].name], ".gosymtab") == 0) { @@ -975,15 +973,11 @@ error: symoff = sh[i].offset; } if (strcmp(&buf[sh[i].name], ".gopclntab") == 0) { - if (sh[i].offset != symoff+symsize) { - werrstr("pc line table not contiguous with symbol table"); - free(buf); - goto error; - } - pclnsz = sh[i].size; + pclnsize = sh[i].size; + pclnoff = sh[i].offset; } } - setsym(fp, symsize, 0, pclnsz, symoff); + setsym(fp, symoff, symsize, 0, 0, pclnoff, pclnsize); free(buf); } done: @@ -1207,7 +1201,7 @@ machdotout(int fd, Fhdr *fp, ExecHdr *hp) settext(fp, textva+sizeof(Machhdr) + mp->sizeofcmds, textva, textsize, textoff); setdata(fp, datava, datasize, dataoff, bsssize); if(symtab != 0) - setsym(fp, symtab->filesize, 0, pclntab? pclntab->filesize : 0, symtab->fileoff); + setsym(fp, symtab->fileoff, symtab->filesize, 0, 0, 0, pclntab? pclntab->filesize : 0); free(cmd); free(cmdbuf); return 1; @@ -1228,7 +1222,7 @@ armdotout(int fd, Fhdr *fp, ExecHdr *hp) USED(fd); settext(fp, hp->e.exechdr.entry, sizeof(Exec), hp->e.exechdr.text, sizeof(Exec)); setdata(fp, fp->txtsz, hp->e.exechdr.data, fp->txtsz, hp->e.exechdr.bss); - setsym(fp, hp->e.exechdr.syms, hp->e.exechdr.spsz, hp->e.exechdr.pcsz, fp->datoff+fp->datsz); + setsym(fp, fp->datoff+fp->datsz, hp->e.exechdr.syms, 0, hp->e.exechdr.spsz, 0, hp->e.exechdr.pcsz); kbase = 0xF0000000; if ((fp->entry & kbase) == kbase) { /* Boot image */ @@ -1259,14 +1253,20 @@ setdata(Fhdr *fp, uvlong a, int32 s, vlong off, int32 bss) } static void -setsym(Fhdr *fp, int32 symsz, int32 sppcsz, int32 lnpcsz, vlong symoff) +setsym(Fhdr *fp, vlong symoff, int32 symsz, vlong sppcoff, int32 sppcsz, vlong lnpcoff, int32 lnpcsz) { - fp->symsz = symsz; fp->symoff = symoff; + fp->symsz = symsz; + + if(sppcoff == 0) + sppcoff = symoff+symsz; + fp->sppcoff = symoff; fp->sppcsz = sppcsz; - fp->sppcoff = fp->symoff+fp->symsz; + + if(lnpcoff == 0) + lnpcoff = sppcoff + sppcsz; + fp->lnpcoff = lnpcoff; fp->lnpcsz = lnpcsz; - fp->lnpcoff = fp->sppcoff+fp->sppcsz; } |