Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1162,6 +1162,39 @@ } } +template class CheckedType { + T Val; + +public: + CheckedType(T Val) : Val(Val){}; + + operator uint64_t() { return Val; } + operator uint32_t() { + if (Val > UINT32_MAX) + fatal("checked type operation overflow"); + return Val; + } + + template CheckedType operator+(T2 R) { + if (R > getMax() || (this->Val > getMax() - R)) + fatal("checked type operation overflow"); + return this->Val + R; + } + + template CheckedType operator-(T2 R) { + if (R > this->Val) + fatal("checked type operation overflow"); + return this->Val - R; + } + +private: + T getMax() { return std::numeric_limits::max(); } +}; + +template CheckedType makeChecked(T Val) { + return CheckedType(Val); +} + // Adjusts the file alignment for a given output section and returns // its new file offset. The file offset must be the same with its // virtual address (modulo the page size) so that the loader can load @@ -1182,7 +1215,7 @@ // this formula: Off2 = Off1 + (VA2 - VA1). if (Sec == First) return alignTo(Off, Target->MaxPageSize, Sec->getVA()); - return First->getFileOffset() + Sec->getVA() - First->getVA(); + return makeChecked(First->getFileOffset()) + Sec->getVA() - First->getVA(); } template @@ -1194,7 +1227,7 @@ Off = getFileAlignment(Off, Sec); Sec->setFileOffset(Off); - Off += Sec->getSize(); + Off = makeChecked(Off) + Sec->getSize(); } template void Writer::assignFileOffsetsBinary() {