21f1f7d84833252e3d097bce20e12437237d9b06
[oota-llvm.git] / lib / Archive / ArchiveReader.cpp
1 //===- ArchiveReader.cpp - Code to read LLVM bytecode from .a files -------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the ReadArchiveFile interface, which allows a linker to
11 // read all of the LLVM bytecode files contained in a .a file.  This file
12 // understands the standard system .a file format.  This can only handle the .a
13 // variant prevalent on Linux systems so far, but may be extended.  See
14 // information in this source file for more information:
15 //   http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/archive.c?cvsroot=src
16 //
17 //===----------------------------------------------------------------------===//
18
19 #include "llvm/Bytecode/Reader.h"
20 #include "llvm/Module.h"
21 #include "Config/sys/stat.h"
22 #include "Config/sys/mman.h"
23 #include "Config/fcntl.h"
24 #include <cstdlib>
25
26 namespace llvm {
27
28 namespace {
29   struct ar_hdr {
30     char name[16];
31     char date[12];
32     char uid[6];
33     char gid[6];
34     char mode[8];
35     char size[10];
36     char fmag[2];          // Always equal to '`\n'
37   };
38
39   enum ObjectType {
40     UserObject,            // A user .o/.bc file
41     Unknown,               // Unknown file, just ignore it
42     SVR4LongFilename,      // a "//" section used for long file names
43     ArchiveSymbolTable,    // Symbol table produced by ranlib.
44   };
45 }
46
47 /// getObjectType - Determine the type of object that this header represents.
48 /// This is capable of parsing the variety of special sections used for various
49 /// purposes.
50 ///
51 static enum ObjectType getObjectType(ar_hdr *H, unsigned char *MemberData,
52                                      unsigned Size) {
53   // Check for sections with special names...
54   if (!memcmp(H->name, "__.SYMDEF       ", 16))
55     return ArchiveSymbolTable;
56   if (!memcmp(H->name, "//              ", 16))
57     return SVR4LongFilename;
58
59   // Check to see if it looks like an llvm object file...
60   if (Size >= 4 && !memcmp(MemberData, "llvm", 4))
61     return UserObject;
62
63   return Unknown;
64 }
65
66 static inline bool Error(std::string *ErrorStr, const char *Message) {
67   if (ErrorStr) *ErrorStr = Message;
68   return true;
69 }
70
71 static bool ParseSymbolTableSection(unsigned char *Buffer, unsigned Size,
72                                     std::string *S) {
73   // Currently not supported (succeeds without doing anything)
74   return false;
75 }
76
77 static bool ReadArchiveBuffer(const std::string &ArchiveName,
78                               unsigned char *Buffer, unsigned Length,
79                               std::vector<Module*> &Objects,
80                               std::string *ErrorStr) {
81   if (Length < 8 || memcmp(Buffer, "!<arch>\n", 8))
82     return Error(ErrorStr, "signature incorrect for an archive file!");
83   Buffer += 8;  Length -= 8; // Skip the magic string.
84
85   std::vector<char> LongFilenames;
86
87   while (Length >= sizeof(ar_hdr)) {
88     ar_hdr *Hdr = (ar_hdr*)Buffer;
89     unsigned SizeFromHeader = atoi(Hdr->size);
90     if (SizeFromHeader + sizeof(ar_hdr) > Length)
91       return Error(ErrorStr, "invalid record length in archive file!");
92
93     unsigned char *MemberData = Buffer + sizeof(ar_hdr);
94     unsigned MemberSize = SizeFromHeader;
95     // Get name of archive member.
96     char *startp = Hdr->name;
97     char *endp = (char *) memchr (startp, '/', sizeof(ar_hdr));
98     if (memcmp (Hdr->name, "#1/", 3) == 0) {
99       // 4.4BSD/MacOSX long filenames are abbreviated as "#1/L", where L is an
100       // ASCII-coded decimal number representing the length of the name buffer,
101       // which is prepended to the archive member's contents.
102       unsigned NameLength = atoi (&Hdr->name[3]);
103       startp = (char *) MemberData;
104       endp = startp + NameLength;
105       MemberData += NameLength;
106       MemberSize -= NameLength;
107     } else if (startp == endp && isdigit (Hdr->name[1])) {
108       // SVR4 long filenames are abbreviated as "/I", where I is
109       // an ASCII-coded decimal index into the LongFilenames vector.
110       unsigned NameIndex = atoi (&Hdr->name[1]);
111       assert (LongFilenames.size () > NameIndex
112               && "SVR4-style long filename for archive member not found");
113       startp = &LongFilenames[NameIndex];
114       endp = strchr (startp, '/');
115     }
116     if (!endp) {
117       // 4.4BSD/MacOSX *short* filenames are not guaranteed to have a
118       // terminator. Start at the end of the field and backtrack over spaces.
119       endp = startp + sizeof(Hdr->name);
120       while (endp[-1] == ' ')
121         --endp;
122     }
123     std::string MemberName (startp, endp);
124     std::string FullMemberName = ArchiveName + "(" + MemberName + ")";
125
126     switch (getObjectType(Hdr, MemberData, MemberSize)) {
127     case SVR4LongFilename:
128       // If this is a long filename section, read all of the file names into the
129       // LongFilenames vector.
130       LongFilenames.assign (MemberData, MemberData + MemberSize);
131       break;
132     case UserObject: {
133       Module *M = ParseBytecodeBuffer(MemberData, MemberSize,
134                                       FullMemberName, ErrorStr);
135       if (!M) return true;
136       Objects.push_back(M);
137       break;
138     }
139     case ArchiveSymbolTable:
140       if (ParseSymbolTableSection(MemberData, MemberSize, ErrorStr))
141         return true;
142       break;
143     default:
144       std::cerr << "ReadArchiveBuffer: WARNING: Skipping unknown file: "
145                 << FullMemberName << "\n";
146       break;   // Just ignore unknown files.
147     }
148
149     // Round SizeFromHeader up to an even number...
150     SizeFromHeader = (SizeFromHeader+1)/2*2;
151     Buffer += sizeof(ar_hdr)+SizeFromHeader;   // Move to the next entry
152     Length -= sizeof(ar_hdr)+SizeFromHeader;
153   }
154
155   return Length != 0;
156 }
157
158
159 // ReadArchiveFile - Read bytecode files from the specified .a file, returning
160 // true on error, or false on success.  This does not support reading files from
161 // standard input.
162 //
163 bool ReadArchiveFile(const std::string &Filename, std::vector<Module*> &Objects,
164                      std::string *ErrorStr) {
165   int FD = open(Filename.c_str(), O_RDONLY);
166   if (FD == -1)
167     return Error(ErrorStr, "Error opening file!");
168   
169   // Stat the file to get its length...
170   struct stat StatBuf;
171   if (fstat(FD, &StatBuf) == -1 || StatBuf.st_size == 0)
172     return Error(ErrorStr, "Error stat'ing file!");
173   
174     // mmap in the file all at once...
175   int Length = StatBuf.st_size;
176   unsigned char *Buffer = (unsigned char*)mmap(0, Length, PROT_READ, 
177                                                MAP_PRIVATE, FD, 0);
178   if (Buffer == (unsigned char*)MAP_FAILED)
179     return Error(ErrorStr, "Error mmapping file!");
180   
181   // Parse the archive files we mmap'ped in
182   bool Result = ReadArchiveBuffer(Filename, Buffer, Length, Objects, ErrorStr);
183   
184   // Unmmap the archive...
185   munmap((char*)Buffer, Length);
186
187   if (Result)    // Free any loaded objects
188     while (!Objects.empty()) {
189       delete Objects.back();
190       Objects.pop_back();
191     }
192   
193   return Result;
194 }
195
196 } // End llvm namespace