Merge Dumper.cpp and AnalyzerWrappers.cpp into this file. Also, adjust the
[oota-llvm.git] / lib / Bytecode / Reader / 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 "Support/FileUtilities.h"
22 #include <cstdlib>
23 using namespace llvm;
24
25 namespace {
26   struct ar_hdr {
27     char name[16];
28     char date[12];
29     char uid[6];
30     char gid[6];
31     char mode[8];
32     char size[10];
33     char fmag[2];          // Always equal to '`\n'
34   };
35
36   enum ObjectType {
37     UserObject,            // A user .o/.bc file
38     Unknown,               // Unknown file, just ignore it
39     SVR4LongFilename,      // a "//" section used for long file names
40     ArchiveSymbolTable,    // Symbol table produced by ranlib.
41   };
42 }
43
44 /// getObjectType - Determine the type of object that this header represents.
45 /// This is capable of parsing the variety of special sections used for various
46 /// purposes.
47 ///
48 static enum ObjectType getObjectType(ar_hdr *H, std::string MemberName,
49                                      unsigned char *MemberData, unsigned Size) {
50   // Check for sections with special names...
51   if (MemberName == "__.SYMDEF       " || MemberName == "__.SYMDEF SORTED")
52     return ArchiveSymbolTable;
53   else if (MemberName == "//              ")
54     return SVR4LongFilename;
55
56   // Check to see if it looks like an llvm object file...
57   if (Size >= 4 && !memcmp(MemberData, "llvm", 4))
58     return UserObject;
59
60   return Unknown;
61 }
62
63 static inline bool Error(std::string *ErrorStr, const char *Message) {
64   if (ErrorStr) *ErrorStr = Message;
65   return true;
66 }
67
68 static bool ParseSymbolTableSection(unsigned char *Buffer, unsigned Size,
69                                     std::string *S) {
70   // Currently not supported (succeeds without doing anything)
71   return false;
72 }
73
74 static bool ReadArchiveBuffer(const std::string &ArchiveName,
75                               unsigned char *Buffer, unsigned Length,
76                               std::vector<Module*> &Objects,
77                               std::string *ErrorStr) {
78   if (Length < 8 || memcmp(Buffer, "!<arch>\n", 8))
79     return Error(ErrorStr, "signature incorrect for an archive file!");
80   Buffer += 8;  Length -= 8; // Skip the magic string.
81
82   std::vector<char> LongFilenames;
83
84   while (Length >= sizeof(ar_hdr)) {
85     ar_hdr *Hdr = (ar_hdr*)Buffer;
86     unsigned SizeFromHeader = atoi(Hdr->size);
87     if (SizeFromHeader + sizeof(ar_hdr) > Length)
88       return Error(ErrorStr, "invalid record length in archive file!");
89
90     unsigned char *MemberData = Buffer + sizeof(ar_hdr);
91     unsigned MemberSize = SizeFromHeader;
92     // Get name of archive member.
93     char *startp = Hdr->name;
94     char *endp = (char *) memchr (startp, '/', sizeof(ar_hdr));
95     if (memcmp (Hdr->name, "#1/", 3) == 0) {
96       // 4.4BSD/MacOSX long filenames are abbreviated as "#1/L", where L is an
97       // ASCII-coded decimal number representing the length of the name buffer,
98       // which is prepended to the archive member's contents.
99       unsigned NameLength = atoi (&Hdr->name[3]);
100       startp = (char *) MemberData;
101       endp = startp + NameLength;
102       MemberData += NameLength;
103       MemberSize -= NameLength;
104     } else if (startp == endp && isdigit (Hdr->name[1])) {
105       // SVR4 long filenames are abbreviated as "/I", where I is
106       // an ASCII-coded decimal index into the LongFilenames vector.
107       unsigned NameIndex = atoi (&Hdr->name[1]);
108       assert (LongFilenames.size () > NameIndex
109               && "SVR4-style long filename for archive member not found");
110       startp = &LongFilenames[NameIndex];
111       endp = strchr (startp, '/');
112     } else if (startp == endp && Hdr->name[1] == '/') {
113       // This is for the SVR4 long filename table (there might be other
114       // names starting with // but I don't know about them). Make sure that
115       // getObjectType sees it.
116       endp = &Hdr->name[sizeof (Hdr->name)];
117     }
118     if (!endp) {
119       // 4.4BSD/MacOSX *short* filenames are not guaranteed to have a
120       // terminator. Start at the end of the field and backtrack over spaces.
121       endp = startp + sizeof(Hdr->name);
122       while (endp[-1] == ' ')
123         --endp;
124     }
125     std::string MemberName (startp, endp);
126     std::string FullMemberName = ArchiveName + "(" + MemberName + ")";
127
128     switch (getObjectType(Hdr, MemberName, MemberData, MemberSize)) {
129     case SVR4LongFilename:
130       // If this is a long filename section, read all of the file names into the
131       // LongFilenames vector.
132       LongFilenames.assign (MemberData, MemberData + MemberSize);
133       break;
134     case UserObject: {
135       Module *M = ParseBytecodeBuffer(MemberData, MemberSize,
136                                       FullMemberName, ErrorStr);
137       if (!M) return true;
138       Objects.push_back(M);
139       break;
140     }
141     case ArchiveSymbolTable:
142       if (ParseSymbolTableSection(MemberData, MemberSize, ErrorStr))
143         return true;
144       break;
145     default:
146       std::cerr << "ReadArchiveBuffer: WARNING: Skipping unknown file: "
147                 << FullMemberName << "\n";
148       break;   // Just ignore unknown files.
149     }
150
151     // Round SizeFromHeader up to an even number...
152     SizeFromHeader = (SizeFromHeader+1)/2*2;
153     Buffer += sizeof(ar_hdr)+SizeFromHeader;   // Move to the next entry
154     Length -= sizeof(ar_hdr)+SizeFromHeader;
155   }
156
157   return Length != 0;
158 }
159
160
161 // ReadArchiveFile - Read bytecode files from the specified .a file, returning
162 // true on error, or false on success.  This does not support reading files from
163 // standard input.
164 //
165 bool llvm::ReadArchiveFile(const std::string &Filename,
166                            std::vector<Module*> &Objects,std::string *ErrorStr){
167   unsigned Length;
168
169     // mmap in the file all at once...
170   unsigned char *Buffer = 
171      (unsigned char*)ReadFileIntoAddressSpace(Filename, Length);
172   if (Buffer == 0) {
173     if (ErrorStr) *ErrorStr = "Error reading file '" + Filename + "'!";
174     return true;
175   }
176   
177   // Parse the archive files we mmap'ped in
178   bool Result = ReadArchiveBuffer(Filename, Buffer, Length, Objects, ErrorStr);
179   
180   // Unmmap the archive...
181   UnmapFileFromAddressSpace(Buffer, Length);
182
183   if (Result)    // Free any loaded objects
184     while (!Objects.empty()) {
185       delete Objects.back();
186       Objects.pop_back();
187     }
188   
189   return Result;
190 }