From 42d69bd0e596c47f188697272019f0ef230e6f9e Mon Sep 17 00:00:00 2001 From: John Reiser Date: Mon, 5 Feb 2007 22:34:23 -0800 Subject: [PATCH] debug PackMachFat --- src/file.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++-- src/file.h | 18 ++++++------------ src/p_mach.cpp | 29 ++++++++++++++++++----------- src/ui.cpp | 4 ++-- 4 files changed, 70 insertions(+), 27 deletions(-) diff --git a/src/file.cpp b/src/file.cpp index b9436c0f..88663175 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -104,8 +104,10 @@ void FileBase::sopen() assert(0); #endif } - ::fstat(_fd, &st); - _length = st.st_size; + if (!(_fd < 0)) { + ::fstat(_fd, &st); + _length = st.st_size; + } } @@ -358,6 +360,16 @@ void OutputFile::write(const void *buf, int len) bytes_written += len; } +off_t OutputFile::st_size() const +{ + if (opt->to_stdout) { // might be a pipe ==> .st_size is invalid + return bytes_written; // too big if seek()+write() instead of rewrite() + } + struct stat my_st; + ::fstat(_fd, &my_st); + return my_st.st_size; +} + void OutputFile::write(const MemBuffer *buf, int len) { @@ -372,6 +384,36 @@ void OutputFile::write(const MemBuffer &buf, int len) write(&buf, len); } +void OutputFile::rewrite(const void *buf, int len) +{ + assert(!opt->to_stdout); + write(buf, len); + bytes_written -= len; // restore +} + +void OutputFile::seek(off_t off, int whence) +{ + assert(!opt->to_stdout); + super::seek(off,whence); +} + +void OutputFile::set_extent(off_t offset, off_t length) +{ + super::set_extent(offset, length); + bytes_written = 0; + if (0==offset && (off_t)~0u==length) { + ::fstat(_fd, &st); + _length = st.st_size - offset; + } +} + +off_t OutputFile::clear_offset() +{ + _offset = 0; + ::lseek(_fd, 0, SEEK_END); + _length = tell(); + return _length; +} void OutputFile::dump(const char *name, const void *buf, int len, int flags) { diff --git a/src/file.h b/src/file.h index 183bbb4c..b6382ddc 100644 --- a/src/file.h +++ b/src/file.h @@ -61,6 +61,7 @@ public: const char *getName() const { return _name; } virtual off_t st_size() const; // { return _length; } virtual void set_extent(off_t offset, off_t length); + virtual off_t tell() const; protected: void sopen(); @@ -68,7 +69,6 @@ protected: virtual int readx(void *buf, int len); virtual void write(const void *buf, int len); virtual void seek(off_t off, int whence); - virtual off_t tell() const; int _fd; int _flags; @@ -132,21 +132,15 @@ public: virtual void write(const void *buf, int len); virtual void write(const MemBuffer *buf, int len); virtual void write(const MemBuffer &buf, int len); + virtual void set_extent(off_t offset, off_t length); + virtual off_t clear_offset(); // returns actual length off_t getBytesWritten() const { return bytes_written; } + virtual off_t st_size() const; // { return _length; } // FIXME - these won't work when using the '--stdout' option - virtual void seek(off_t off, int whence) - { - assert(!opt->to_stdout); - super::seek(off,whence); - } - virtual void rewrite(const void *buf, int len) - { - assert(!opt->to_stdout); - write(buf, len); - bytes_written -= len; // restore - } + virtual void seek(off_t off, int whence); + virtual void rewrite(const void *buf, int len); // util static void dump(const char *name, const void *buf, int len, int flags=-1); diff --git a/src/p_mach.cpp b/src/p_mach.cpp index 361c9035..1ca66eeb 100644 --- a/src/p_mach.cpp +++ b/src/p_mach.cpp @@ -285,9 +285,9 @@ void PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader segcmdo.filesize = fo->getBytesWritten(); segcmdo.vmsize += segcmdo.filesize; fo->seek(sizeof(mhdro), SEEK_SET); - fo->write(&segcmdo, sizeof(segcmdo)); - fo->write(&threado, sizeof(threado)); - fo->write(&linfo, sizeof(linfo)); + fo->rewrite(&segcmdo, sizeof(segcmdo)); + fo->rewrite(&threado, sizeof(threado)); + fo->rewrite(&linfo, sizeof(linfo)); } void PackMachI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader @@ -299,9 +299,9 @@ void PackMachI386::pack4(OutputFile *fo, Filter &ft) // append PackHeader segcmdo.filesize = fo->getBytesWritten(); segcmdo.vmsize += segcmdo.filesize; fo->seek(sizeof(mhdro), SEEK_SET); - fo->write(&segcmdo, sizeof(segcmdo)); - fo->write(&threado, sizeof(threado)); - fo->write(&linfo, sizeof(linfo)); + fo->rewrite(&segcmdo, sizeof(segcmdo)); + fo->rewrite(&threado, sizeof(threado)); + fo->rewrite(&linfo, sizeof(linfo)); } void PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader @@ -643,14 +643,17 @@ const int *PackMachFat::getFilters() const void PackMachFat::pack(OutputFile *fo) { + unsigned const in_size = this->file_size; fo->write(&fat_head, sizeof(fat_head.fat) + fat_head.fat.nfat_arch * sizeof(fat_head.arch[0])); + unsigned length; for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) { - unsigned base = fo->getBytesWritten(); - base += ~(~0u<clear_offset(); // actual length + base += ~(~0u<seek(base, SEEK_SET); fo->set_extent(base, ~0u); + ph.u_file_size = fat_head.arch[j].size; fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size); switch (fat_head.arch[j].cputype) { case PackMachFat::CPU_TYPE_I386: { @@ -669,12 +672,16 @@ void PackMachFat::pack(OutputFile *fo) } break; } // switch cputype fat_head.arch[j].offset = base; - fat_head.arch[j].size = fo->getBytesWritten() - base; + length = fo->clear_offset(); + fat_head.arch[j].size = length - base; } - fo->set_extent(0, ~0u); + ph.u_file_size = in_size;; + fi->set_extent(0, in_size); + fo->seek(0, SEEK_SET); - fo->write(&fat_head, sizeof(fat_head.fat) + + fo->rewrite(&fat_head, sizeof(fat_head.fat) + fat_head.fat.nfat_arch * sizeof(fat_head.arch[0])); + fo->set_extent(0, length); } void PackMachFat::unpack(OutputFile */*fo*/) diff --git a/src/ui.cpp b/src/ui.cpp index e4df2955..f9dc9f0c 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -504,7 +504,7 @@ void UiPacker::uiPackStart(const OutputFile *fo) void UiPacker::uiPackEnd(const OutputFile *fo) { - uiUpdate(fo->getBytesWritten()); + uiUpdate(fo->st_size()); if (s->mode == M_QUIET) return; @@ -521,7 +521,7 @@ void UiPacker::uiPackEnd(const OutputFile *fo) else if (opt->to_stdout) name = ""; con_fprintf(stdout,"%s\n", - mkline(p->ph.u_file_size, fo->getBytesWritten(), + mkline(p->ph.u_file_size, fo->st_size(), p->ph.u_len, p->ph.c_len, p->getName(), fn_basename(name))); printSetNl(0);