OLD | NEW |
1 // Inferno libmach/executable.c | 1 // Inferno libmach/executable.c |
2 // http://code.google.com/p/inferno-os/source/browse/utils/libmach/executable.c | 2 // http://code.google.com/p/inferno-os/source/browse/utils/libmach/executable.c |
3 // | 3 // |
4 // Copyright © 1994-1999 Lucent Technologies Inc. | 4 // Copyright © 1994-1999 Lucent Technologies Inc. |
5 // Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.ne
t). | 5 // Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.ne
t). |
6 // Portions Copyright © 1997-1999 Vita Nuova Limited. | 6 // Portions Copyright © 1997-1999 Vita Nuova Limited. |
7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuov
a.com). | 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuov
a.com). |
8 // Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others. | 8 // Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others. |
9 // Portions Copyright © 2009 The Go Authors. All rights reserved. | 9 // Portions Copyright © 2009 The Go Authors. All rights reserved. |
10 // | 10 // |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 static int nextboot(int, Fhdr*, ExecHdr*); | 59 static int nextboot(int, Fhdr*, ExecHdr*); |
60 static int sparcboot(int, Fhdr*, ExecHdr*); | 60 static int sparcboot(int, Fhdr*, ExecHdr*); |
61 static int mipsboot(int, Fhdr*, ExecHdr*); | 61 static int mipsboot(int, Fhdr*, ExecHdr*); |
62 static int mips4kboot(int, Fhdr*, ExecHdr*); | 62 static int mips4kboot(int, Fhdr*, ExecHdr*); |
63 static int common(int, Fhdr*, ExecHdr*); | 63 static int common(int, Fhdr*, ExecHdr*); |
64 static int commonllp64(int, Fhdr*, ExecHdr*); | 64 static int commonllp64(int, Fhdr*, ExecHdr*); |
65 static int adotout(int, Fhdr*, ExecHdr*); | 65 static int adotout(int, Fhdr*, ExecHdr*); |
66 static int elfdotout(int, Fhdr*, ExecHdr*); | 66 static int elfdotout(int, Fhdr*, ExecHdr*); |
67 static int machdotout(int, Fhdr*, ExecHdr*); | 67 static int machdotout(int, Fhdr*, ExecHdr*); |
68 static int armdotout(int, Fhdr*, ExecHdr*); | 68 static int armdotout(int, Fhdr*, ExecHdr*); |
69 static» void» setsym(Fhdr*, int32, int32, int32, vlong); | 69 static» void» setsym(Fhdr*, vlong, int32, vlong, int32, vlong, int32); |
70 static void setdata(Fhdr*, uvlong, int32, vlong, int32); | 70 static void setdata(Fhdr*, uvlong, int32, vlong, int32); |
71 static void settext(Fhdr*, uvlong, uvlong, int32, vlong); | 71 static void settext(Fhdr*, uvlong, uvlong, int32, vlong); |
72 static void hswal(void*, int, uint32(*)(uint32)); | 72 static void hswal(void*, int, uint32(*)(uint32)); |
73 static uvlong _round(uvlong, uint32); | 73 static uvlong _round(uvlong, uint32); |
74 | 74 |
75 /* | 75 /* |
76 * definition of per-executable file type structures | 76 * definition of per-executable file type structures |
77 */ | 77 */ |
78 | 78 |
79 typedef struct Exectable{ | 79 typedef struct Exectable{ |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 adotout(int fd, Fhdr *fp, ExecHdr *hp) | 420 adotout(int fd, Fhdr *fp, ExecHdr *hp) |
421 { | 421 { |
422 int32 pgsize; | 422 int32 pgsize; |
423 | 423 |
424 USED(fd); | 424 USED(fd); |
425 pgsize = mach->pgsize; | 425 pgsize = mach->pgsize; |
426 settext(fp, hp->e.exechdr.entry, pgsize+sizeof(Exec), | 426 settext(fp, hp->e.exechdr.entry, pgsize+sizeof(Exec), |
427 hp->e.exechdr.text, sizeof(Exec)); | 427 hp->e.exechdr.text, sizeof(Exec)); |
428 setdata(fp, _round(pgsize+fp->txtsz+sizeof(Exec), pgsize), | 428 setdata(fp, _round(pgsize+fp->txtsz+sizeof(Exec), pgsize), |
429 hp->e.exechdr.data, fp->txtsz+sizeof(Exec), hp->e.exechdr.bss); | 429 hp->e.exechdr.data, fp->txtsz+sizeof(Exec), hp->e.exechdr.bss); |
430 » setsym(fp, hp->e.exechdr.syms, hp->e.exechdr.spsz, hp->e.exechdr.pcsz, f
p->datoff+fp->datsz); | 430 » setsym(fp, fp->datoff+fp->datsz, hp->e.exechdr.syms, 0, hp->e.exechdr.sp
sz, 0, hp->e.exechdr.pcsz); |
431 return 1; | 431 return 1; |
432 } | 432 } |
433 | 433 |
434 static void | 434 static void |
435 commonboot(Fhdr *fp) | 435 commonboot(Fhdr *fp) |
436 { | 436 { |
437 if (!(fp->entry & mach->ktmask)) | 437 if (!(fp->entry & mach->ktmask)) |
438 return; | 438 return; |
439 | 439 |
440 switch(fp->type) { /* boot image */ | 440 switch(fp->type) { /* boot image */ |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 char *p; | 518 char *p; |
519 uvlong *v; | 519 uvlong *v; |
520 } u; | 520 } u; |
521 u.p = (char*)&hp->e.exechdr; | 521 u.p = (char*)&hp->e.exechdr; |
522 entry = beswav(*u.v); | 522 entry = beswav(*u.v); |
523 | 523 |
524 pgsize = mach->pgsize; | 524 pgsize = mach->pgsize; |
525 settext(fp, entry, pgsize+fp->hdrsz, hp->e.exechdr.text, fp->hdrsz); | 525 settext(fp, entry, pgsize+fp->hdrsz, hp->e.exechdr.text, fp->hdrsz); |
526 setdata(fp, _round(pgsize+fp->txtsz+fp->hdrsz, pgsize), | 526 setdata(fp, _round(pgsize+fp->txtsz+fp->hdrsz, pgsize), |
527 hp->e.exechdr.data, fp->txtsz+fp->hdrsz, hp->e.exechdr.bss); | 527 hp->e.exechdr.data, fp->txtsz+fp->hdrsz, hp->e.exechdr.bss); |
528 » setsym(fp, hp->e.exechdr.syms, hp->e.exechdr.spsz, hp->e.exechdr.pcsz, f
p->datoff+fp->datsz); | 528 » setsym(fp, fp->datoff+fp->datsz, hp->e.exechdr.syms, 0, hp->e.exechdr.sp
sz, 0, hp->e.exechdr.pcsz); |
529 | 529 |
530 if(hp->e.exechdr.magic & DYN_MAGIC) { | 530 if(hp->e.exechdr.magic & DYN_MAGIC) { |
531 fp->txtaddr = 0; | 531 fp->txtaddr = 0; |
532 fp->dataddr = fp->txtsz; | 532 fp->dataddr = fp->txtsz; |
533 return 1; | 533 return 1; |
534 } | 534 } |
535 commonboot(fp); | 535 commonboot(fp); |
536 return 1; | 536 return 1; |
537 } | 537 } |
538 | 538 |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
751 */ | 751 */ |
752 if(ep->machine == SPARC64 && ep->phnum == 2) { | 752 if(ep->machine == SPARC64 && ep->phnum == 2) { |
753 uint32 txtaddr, txtsz, dataddr, bsssz; | 753 uint32 txtaddr, txtsz, dataddr, bsssz; |
754 | 754 |
755 txtaddr = ph[0].vaddr | 0x80000000; | 755 txtaddr = ph[0].vaddr | 0x80000000; |
756 txtsz = ph[0].filesz - ph[0].paddr; | 756 txtsz = ph[0].filesz - ph[0].paddr; |
757 dataddr = txtaddr + txtsz; | 757 dataddr = txtaddr + txtsz; |
758 bsssz = ph[0].memsz - ph[0].filesz; | 758 bsssz = ph[0].memsz - ph[0].filesz; |
759 settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, p
h[0].offset); | 759 settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, p
h[0].offset); |
760 setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz,
bsssz); | 760 setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz,
bsssz); |
761 » » » setsym(fp, ph[1].filesz, 0, ph[1].memsz, ph[1].offset); | 761 » » » setsym(fp, ph[1].offset, ph[1].filesz, 0, 0, 0, ph[1].me
msz); |
762 free(ph); | 762 free(ph); |
763 return 1; | 763 return 1; |
764 } | 764 } |
765 | 765 |
766 werrstr("No TEXT or DATA sections"); | 766 werrstr("No TEXT or DATA sections"); |
767 error: | |
768 free(ph); | 767 free(ph); |
769 free(sh); | 768 free(sh); |
770 return 0; | 769 return 0; |
771 } | 770 } |
772 | 771 |
773 settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset); | 772 settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset); |
774 setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, ph[id].memsz - p
h[id].filesz); | 773 setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, ph[id].memsz - p
h[id].filesz); |
775 if(is != -1) | 774 if(is != -1) |
776 » » setsym(fp, ph[is].filesz, 0, ph[is].memsz, ph[is].offset); | 775 » » setsym(fp, ph[is].offset, ph[is].filesz, 0, 0, 0, ph[is].memsz); |
777 else if(sh != 0){ | 776 else if(sh != 0){ |
778 char *buf; | 777 char *buf; |
779 uvlong symsize = 0; | 778 uvlong symsize = 0; |
780 uvlong symoff = 0; | 779 uvlong symoff = 0; |
781 uvlong pclnsz = 0; | 780 uvlong pclnsz = 0; |
| 781 uvlong pclnoff = 0; |
782 | 782 |
783 /* load shstrtab names */ | 783 /* load shstrtab names */ |
784 buf = malloc(sh[ep->shstrndx].size); | 784 buf = malloc(sh[ep->shstrndx].size); |
785 if (buf == 0) | 785 if (buf == 0) |
786 goto done; | 786 goto done; |
787 memset(buf, 0, sizeof buf); | 787 memset(buf, 0, sizeof buf); |
788 seek(fd, sh[ep->shstrndx].offset, 0); | 788 seek(fd, sh[ep->shstrndx].offset, 0); |
789 i = read(fd, buf, sh[ep->shstrndx].size); | 789 i = read(fd, buf, sh[ep->shstrndx].size); |
790 USED(i); // shut up ubuntu gcc | 790 USED(i); // shut up ubuntu gcc |
791 | 791 |
792 for(i = 0; i < ep->shnum; i++) { | 792 for(i = 0; i < ep->shnum; i++) { |
793 if (strcmp(&buf[sh[i].name], ".gosymtab") == 0) { | 793 if (strcmp(&buf[sh[i].name], ".gosymtab") == 0) { |
794 symsize = sh[i].size; | 794 symsize = sh[i].size; |
795 symoff = sh[i].offset; | 795 symoff = sh[i].offset; |
796 } | 796 } |
797 if (strcmp(&buf[sh[i].name], ".gopclntab") == 0) { | 797 if (strcmp(&buf[sh[i].name], ".gopclntab") == 0) { |
798 if (sh[i].offset != symoff+symsize) { | |
799 werrstr("pc line table not contiguous wi
th symbol table"); | |
800 free(buf); | |
801 goto error; | |
802 } | |
803 pclnsz = sh[i].size; | 798 pclnsz = sh[i].size; |
| 799 pclnoff = sh[i].offset; |
804 } | 800 } |
805 } | 801 } |
806 » » setsym(fp, symsize, 0, pclnsz, symoff); | 802 » » setsym(fp, symoff, symsize, 0, 0, pclnoff, pclnsz); |
807 free(buf); | 803 free(buf); |
808 } | 804 } |
809 done: | 805 done: |
810 free(ph); | 806 free(ph); |
811 free(sh); | 807 free(sh); |
812 return 1; | 808 return 1; |
813 } | 809 } |
814 | 810 |
815 static int | 811 static int |
816 elfdotout(int fd, Fhdr *fp, ExecHdr *hp) | 812 elfdotout(int fd, Fhdr *fp, ExecHdr *hp) |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
933 */ | 929 */ |
934 if(ep->machine == SPARC64 && ep->phnum == 2) { | 930 if(ep->machine == SPARC64 && ep->phnum == 2) { |
935 uint32 txtaddr, txtsz, dataddr, bsssz; | 931 uint32 txtaddr, txtsz, dataddr, bsssz; |
936 | 932 |
937 txtaddr = ph[0].vaddr | 0x80000000; | 933 txtaddr = ph[0].vaddr | 0x80000000; |
938 txtsz = ph[0].filesz - ph[0].paddr; | 934 txtsz = ph[0].filesz - ph[0].paddr; |
939 dataddr = txtaddr + txtsz; | 935 dataddr = txtaddr + txtsz; |
940 bsssz = ph[0].memsz - ph[0].filesz; | 936 bsssz = ph[0].memsz - ph[0].filesz; |
941 settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, p
h[0].offset); | 937 settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, p
h[0].offset); |
942 setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz,
bsssz); | 938 setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz,
bsssz); |
943 » » » setsym(fp, ph[1].filesz, 0, ph[1].memsz, ph[1].offset); | 939 » » » setsym(fp, ph[1].offset, ph[1].filesz, 0, 0, 0, ph[1].me
msz); |
944 free(ph); | 940 free(ph); |
945 return 1; | 941 return 1; |
946 } | 942 } |
947 | 943 |
948 werrstr("No TEXT or DATA sections"); | 944 werrstr("No TEXT or DATA sections"); |
949 error: | |
950 free(sh); | 945 free(sh); |
951 free(ph); | 946 free(ph); |
952 return 0; | 947 return 0; |
953 } | 948 } |
954 | 949 |
955 settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset); | 950 settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset); |
956 setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, ph[id].memsz - p
h[id].filesz); | 951 setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, ph[id].memsz - p
h[id].filesz); |
957 if(is != -1) | 952 if(is != -1) |
958 » » setsym(fp, ph[is].filesz, 0, ph[is].memsz, ph[is].offset); | 953 » » setsym(fp, ph[is].offset, ph[is].filesz, 0, 0, 0, ph[is].memsz); |
959 else if(sh != 0){ | 954 else if(sh != 0){ |
960 char *buf; | 955 char *buf; |
961 uvlong symsize = 0; | 956 uvlong symsize = 0; |
962 uvlong symoff = 0; | 957 uvlong symoff = 0; |
963 » » uvlong pclnsz = 0; | 958 » » uvlong pclnsize = 0; |
| 959 » » uvlong pclnoff = 0; |
964 | 960 |
965 /* load shstrtab names */ | 961 /* load shstrtab names */ |
966 buf = malloc(sh[ep->shstrndx].size); | 962 buf = malloc(sh[ep->shstrndx].size); |
967 if (buf == 0) | 963 if (buf == 0) |
968 goto done; | 964 goto done; |
969 memset(buf, 0, sizeof buf); | 965 memset(buf, 0, sizeof buf); |
970 seek(fd, sh[ep->shstrndx].offset, 0); | 966 seek(fd, sh[ep->shstrndx].offset, 0); |
971 i = read(fd, buf, sh[ep->shstrndx].size); | 967 i = read(fd, buf, sh[ep->shstrndx].size); |
972 USED(i); // shut up ubuntu gcc | 968 USED(i); // shut up ubuntu gcc |
973 | 969 |
974 for(i = 0; i < ep->shnum; i++) { | 970 for(i = 0; i < ep->shnum; i++) { |
975 if (strcmp(&buf[sh[i].name], ".gosymtab") == 0) { | 971 if (strcmp(&buf[sh[i].name], ".gosymtab") == 0) { |
976 symsize = sh[i].size; | 972 symsize = sh[i].size; |
977 symoff = sh[i].offset; | 973 symoff = sh[i].offset; |
978 } | 974 } |
979 if (strcmp(&buf[sh[i].name], ".gopclntab") == 0) { | 975 if (strcmp(&buf[sh[i].name], ".gopclntab") == 0) { |
980 » » » » if (sh[i].offset != symoff+symsize) { | 976 » » » » pclnsize = sh[i].size; |
981 » » » » » werrstr("pc line table not contiguous wi
th symbol table"); | 977 » » » » pclnoff = sh[i].offset; |
982 » » » » » free(buf); | |
983 » » » » » goto error; | |
984 » » » » } | |
985 » » » » pclnsz = sh[i].size; | |
986 } | 978 } |
987 } | 979 } |
988 » » setsym(fp, symsize, 0, pclnsz, symoff); | 980 » » setsym(fp, symoff, symsize, 0, 0, pclnoff, pclnsize); |
989 free(buf); | 981 free(buf); |
990 } | 982 } |
991 done: | 983 done: |
992 free(sh); | 984 free(sh); |
993 free(ph); | 985 free(ph); |
994 return 1; | 986 return 1; |
995 } | 987 } |
996 | 988 |
997 static int | 989 static int |
998 machdotout(int fd, Fhdr *fp, ExecHdr *hp) | 990 machdotout(int fd, Fhdr *fp, ExecHdr *hp) |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1202 } | 1194 } |
1203 if (textva == 0 || datava == 0) { | 1195 if (textva == 0 || datava == 0) { |
1204 free(cmd); | 1196 free(cmd); |
1205 free(cmdbuf); | 1197 free(cmdbuf); |
1206 return 0; | 1198 return 0; |
1207 } | 1199 } |
1208 /* compute entry by taking address after header - weird - BUG? */ | 1200 /* compute entry by taking address after header - weird - BUG? */ |
1209 settext(fp, textva+sizeof(Machhdr) + mp->sizeofcmds, textva, textsize, t
extoff); | 1201 settext(fp, textva+sizeof(Machhdr) + mp->sizeofcmds, textva, textsize, t
extoff); |
1210 setdata(fp, datava, datasize, dataoff, bsssize); | 1202 setdata(fp, datava, datasize, dataoff, bsssize); |
1211 if(symtab != 0) | 1203 if(symtab != 0) |
1212 » » setsym(fp, symtab->filesize, 0, pclntab? pclntab->filesize : 0,
symtab->fileoff); | 1204 » » setsym(fp, symtab->fileoff, symtab->filesize, 0, 0, 0, pclntab?
pclntab->filesize : 0); |
1213 free(cmd); | 1205 free(cmd); |
1214 free(cmdbuf); | 1206 free(cmdbuf); |
1215 return 1; | 1207 return 1; |
1216 bad: | 1208 bad: |
1217 free(cmd); | 1209 free(cmd); |
1218 free(cmdbuf); | 1210 free(cmdbuf); |
1219 return 0; | 1211 return 0; |
1220 } | 1212 } |
1221 | 1213 |
1222 /* | 1214 /* |
1223 * (Free|Net)BSD ARM header. | 1215 * (Free|Net)BSD ARM header. |
1224 */ | 1216 */ |
1225 static int | 1217 static int |
1226 armdotout(int fd, Fhdr *fp, ExecHdr *hp) | 1218 armdotout(int fd, Fhdr *fp, ExecHdr *hp) |
1227 { | 1219 { |
1228 uvlong kbase; | 1220 uvlong kbase; |
1229 | 1221 |
1230 USED(fd); | 1222 USED(fd); |
1231 settext(fp, hp->e.exechdr.entry, sizeof(Exec), hp->e.exechdr.text, sizeo
f(Exec)); | 1223 settext(fp, hp->e.exechdr.entry, sizeof(Exec), hp->e.exechdr.text, sizeo
f(Exec)); |
1232 setdata(fp, fp->txtsz, hp->e.exechdr.data, fp->txtsz, hp->e.exechdr.bss)
; | 1224 setdata(fp, fp->txtsz, hp->e.exechdr.data, fp->txtsz, hp->e.exechdr.bss)
; |
1233 » setsym(fp, hp->e.exechdr.syms, hp->e.exechdr.spsz, hp->e.exechdr.pcsz, f
p->datoff+fp->datsz); | 1225 » setsym(fp, fp->datoff+fp->datsz, hp->e.exechdr.syms, 0, hp->e.exechdr.sp
sz, 0, hp->e.exechdr.pcsz); |
1234 | 1226 |
1235 kbase = 0xF0000000; | 1227 kbase = 0xF0000000; |
1236 if ((fp->entry & kbase) == kbase) { /* Boot image */ | 1228 if ((fp->entry & kbase) == kbase) { /* Boot image */ |
1237 fp->txtaddr = kbase+sizeof(Exec); | 1229 fp->txtaddr = kbase+sizeof(Exec); |
1238 fp->name = "ARM *BSD boot image"; | 1230 fp->name = "ARM *BSD boot image"; |
1239 fp->hdrsz = 0; /* header stripped */ | 1231 fp->hdrsz = 0; /* header stripped */ |
1240 fp->dataddr = kbase+fp->txtsz; | 1232 fp->dataddr = kbase+fp->txtsz; |
1241 } | 1233 } |
1242 return 1; | 1234 return 1; |
1243 } | 1235 } |
(...skipping 10 matching lines...) Expand all Loading... |
1254 static void | 1246 static void |
1255 setdata(Fhdr *fp, uvlong a, int32 s, vlong off, int32 bss) | 1247 setdata(Fhdr *fp, uvlong a, int32 s, vlong off, int32 bss) |
1256 { | 1248 { |
1257 fp->dataddr = a; | 1249 fp->dataddr = a; |
1258 fp->datsz = s; | 1250 fp->datsz = s; |
1259 fp->datoff = off; | 1251 fp->datoff = off; |
1260 fp->bsssz = bss; | 1252 fp->bsssz = bss; |
1261 } | 1253 } |
1262 | 1254 |
1263 static void | 1255 static void |
1264 setsym(Fhdr *fp, int32 symsz, int32 sppcsz, int32 lnpcsz, vlong symoff) | 1256 setsym(Fhdr *fp, vlong symoff, int32 symsz, vlong sppcoff, int32 sppcsz, vlong l
npcoff, int32 lnpcsz) |
1265 { | 1257 { |
| 1258 fp->symoff = symoff; |
1266 fp->symsz = symsz; | 1259 fp->symsz = symsz; |
1267 » fp->symoff = symoff; | 1260 »······· |
| 1261 » if(sppcoff == 0) |
| 1262 » » sppcoff = symoff+symsz; |
| 1263 » fp->sppcoff = symoff; |
1268 fp->sppcsz = sppcsz; | 1264 fp->sppcsz = sppcsz; |
1269 » fp->sppcoff = fp->symoff+fp->symsz; | 1265 |
| 1266 » if(lnpcoff == 0) |
| 1267 » » lnpcoff = sppcoff + sppcsz; |
| 1268 » fp->lnpcoff = lnpcoff; |
1270 fp->lnpcsz = lnpcsz; | 1269 fp->lnpcsz = lnpcsz; |
1271 fp->lnpcoff = fp->sppcoff+fp->sppcsz; | |
1272 } | 1270 } |
1273 | 1271 |
1274 | 1272 |
1275 static uvlong | 1273 static uvlong |
1276 _round(uvlong a, uint32 b) | 1274 _round(uvlong a, uint32 b) |
1277 { | 1275 { |
1278 uvlong w; | 1276 uvlong w; |
1279 | 1277 |
1280 w = (a/b)*b; | 1278 w = (a/b)*b; |
1281 if (a!=w) | 1279 if (a!=w) |
1282 w += b; | 1280 w += b; |
1283 return(w); | 1281 return(w); |
1284 } | 1282 } |
OLD | NEW |