summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-07-09 05:14:23 +0000
committerChris Lattner <sabre@nondot.org>2008-07-09 05:14:23 +0000
commita660f4bb07e5a8cf446b00c498c8c4c1ec28a447 (patch)
tree2594b58ba6928d273d01ca864bbacf322aacc040 /llvm/lib/Bitcode/Reader/BitcodeReader.cpp
parent304deea9e6dc94ba6c4b8ea93322c0f71cf8a385 (diff)
downloadbcm5719-llvm-a660f4bb07e5a8cf446b00c498c8c4c1ec28a447.tar.gz
bcm5719-llvm-a660f4bb07e5a8cf446b00c498c8c4c1ec28a447.zip
Add a little wrapper header that is put around bc files when emitting
bc files for modules with a target triple that indicates they are for darwin. The reader unconditionally handles this, and the writer could turn this on for more targets if we care. This change has two benefits for darwin: 1) it allows us to encode the cpu type of the file in an easy to read place that doesn't require decoding the bc file. 2) it works around a bug (IMO) in darwin's AR where it is incapable of handling files that are not a multiple of 8 bytes long. BC files are only guaranteed to be multiples of 4 bytes long. llvm-svn: 53275
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp52
1 files changed, 51 insertions, 1 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 3fc6b175217..a8c62be88fc 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1184,6 +1184,47 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) {
return Error("Premature end of bitstream");
}
+/// SkipWrapperHeader - Some systems wrap bc files with a special header for
+/// padding or other reasons. The format of this header is:
+///
+/// struct bc_header {
+/// uint32_t Magic; // 0x0B17C0DE
+/// uint32_t Version; // Version, currently always 0.
+/// uint32_t BitcodeOffset; // Offset to traditional bitcode file.
+/// uint32_t BitcodeSize; // Size of traditional bitcode file.
+/// ... potentially other gunk ...
+/// };
+///
+/// This function is called when we find a file with a matching magic number.
+/// In this case, skip down to the subsection of the file that is actually a BC
+/// file.
+static bool SkipWrapperHeader(unsigned char *&BufPtr, unsigned char *&BufEnd) {
+ enum {
+ KnownHeaderSize = 4*4, // Size of header we read.
+ OffsetField = 2*4, // Offset in bytes to Offset field.
+ SizeField = 3*4 // Offset in bytes to Size field.
+ };
+
+
+ // Must contain the header!
+ if (BufEnd-BufPtr < KnownHeaderSize) return true;
+
+ unsigned Offset = ( BufPtr[OffsetField ] |
+ (BufPtr[OffsetField+1] << 8) |
+ (BufPtr[OffsetField+2] << 16) |
+ (BufPtr[OffsetField+3] << 24));
+ unsigned Size = ( BufPtr[SizeField ] |
+ (BufPtr[SizeField +1] << 8) |
+ (BufPtr[SizeField +2] << 16) |
+ (BufPtr[SizeField +3] << 24));
+
+ // Verify that Offset+Size fits in the file.
+ if (Offset+Size > unsigned(BufEnd-BufPtr))
+ return true;
+ BufPtr += Offset;
+ BufEnd = BufPtr+Size;
+ return false;
+}
bool BitcodeReader::ParseBitcode() {
TheModule = 0;
@@ -1192,7 +1233,16 @@ bool BitcodeReader::ParseBitcode() {
return Error("Bitcode stream should be a multiple of 4 bytes in length");
unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
- Stream.init(BufPtr, BufPtr+Buffer->getBufferSize());
+ unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
+
+ // If we have a wrapper header, parse it and ignore the non-bc file contents.
+ // The magic number is 0x0B17C0DE stored in little endian.
+ if (BufPtr != BufEnd && BufPtr[0] == 0xDE && BufPtr[1] == 0xC0 &&
+ BufPtr[2] == 0x17 && BufPtr[3] == 0x0B)
+ if (SkipWrapperHeader(BufPtr, BufEnd))
+ return Error("Invalid bitcode wrapper header");
+
+ Stream.init(BufPtr, BufEnd);
// Sniff for the signature.
if (Stream.Read(8) != 'B' ||
OpenPOWER on IntegriCloud