llvm.org GIT mirror llvm / 250bfb1
Remove the LLVM specific archive index. Archive files (.a) can have a symbol table indicating which object files in them define which symbols. The purpose of this symbol table is to speed up linking by allowing the linker the read only the .o files it is actually going to use instead of having to parse every object's symbol table. LLVM's archive library currently supports a LLVM specific format for such table. It is hard to see any value in that now that llvm-ld is gone: * System linkers don't use it: GNU ar uses the same plugin as the linker to create archive files with a regular index. The OS X ar creates no symbol table for IL files, I assume the linker just parses all IL files. * It doesn't interact well with archives having both IL and native objects. * We probably don't want to be responsible for yet another archive format variant. This patch then: * Removes support for creating and reading such index from lib/Archive. * Remove llvm-ranlib, since there is nothing left for it to do. We should in the future add support for regular indexes to llvm-ar for both native and IL objects. When we do that, llvm-ranlib should be reimplemented as a symlink to llvm-ar, as it is equivalent to "ar s". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184019 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 7 years ago
19 changed file(s) with 19 addition(s) and 391 deletion(s). Raw diff Collapse all Expand all
2020 lli
2121 llvm-link
2222 llvm-ar
23 llvm-ranlib
2423 llvm-nm
2524 llvm-prof
2625 llvm-config
282282 This modifier requests that an archive index (or symbol table) be added to the
283283 archive. This is the default mode of operation. The symbol table will contain
284284 all the externally visible functions and global variables defined by all the
285 bitcode files in the archive. Using this modifier is more efficient that using
286 llvm-ranlib|llvm-ranlib which also creates the symbol table.
285 bitcode files in the archive.
287286
288287
289288
398397 This field is the archive file member magic number. Its content is always the
399398 two characters back tick (0x60) and newline (0x0A). This provides some measure
400399 utility in identifying archive files that have been corrupted.
401
402
403
404 The LLVM symbol table has the special name "#_LLVM_SYM_TAB_#". It is presumed
405 that no regular archive member file will want this name. The LLVM symbol table
406 is simply composed of a sequence of triplets: byte offset, length of symbol,
407 and the symbol itself. Symbols are not null or newline terminated. Here are
408 the details on each of these items:
409400
410401
411402 offset - vbr encoded 32-bit integer
454445 --------
455446
456447
457 llvm-ranlib|llvm-ranlib, ar(1)
448 ar(1)
+0
-61
docs/CommandGuide/llvm-ranlib.rst less more
None llvm-ranlib - Generate index for LLVM archive
1 =============================================
2
3
4 SYNOPSIS
5 --------
6
7
8 **llvm-ranlib** [--version] [-help]
9
10
11 DESCRIPTION
12 -----------
13
14
15 The **llvm-ranlib** command is similar to the common Unix utility, ``ranlib``. It
16 adds or updates the symbol table in an LLVM archive file. Note that using the
17 **llvm-ar** modifier *s* is usually more efficient than running **llvm-ranlib**
18 which is only provided only for completness and compatibility. Unlike other
19 implementations of ``ranlib``, **llvm-ranlib** indexes LLVM bitcode files, not
20 native object modules. You can list the contents of the symbol table with the
21 ``llvm-nm -s`` command.
22
23
24 OPTIONS
25 -------
26
27
28
29 *archive-file*
30
31 Specifies the archive-file to which the symbol table is added or updated.
32
33
34
35 *--version*
36
37 Print the version of **llvm-ranlib** and exit without building a symbol table.
38
39
40
41 *-help*
42
43 Print usage help for **llvm-ranlib** and exit without building a symbol table.
44
45
46
47
48 EXIT STATUS
49 -----------
50
51
52 If **llvm-ranlib** succeeds, it will exit with 0. If an error occurs, a non-zero
53 exit code will be returned.
54
55
56 SEE ALSO
57 --------
58
59
60 llvm-ar|llvm-ar, ranlib(1)
4949 enum Flags {
5050 SVR4SymbolTableFlag = 1, ///< Member is a SVR4 symbol table
5151 BSD4SymbolTableFlag = 2, ///< Member is a BSD4 symbol table
52 LLVMSymbolTableFlag = 4, ///< Member is an LLVM symbol table
53 BitcodeFlag = 8, ///< Member is bitcode
54 HasPathFlag = 16, ///< Member has a full or partial path
55 HasLongFilenameFlag = 32, ///< Member uses the long filename syntax
56 StringTableFlag = 64 ///< Member is an ar(1) format string table
52 BitcodeFlag = 4, ///< Member is bitcode
53 HasPathFlag = 8, ///< Member has a full or partial path
54 HasLongFilenameFlag = 16, ///< Member uses the long filename syntax
55 StringTableFlag = 32 ///< Member is an ar(1) format string table
5756 };
5857
5958 /// @}
115114 /// @returns true iff the member is a BSD4.4 (non-LLVM) symbol table
116115 /// @brief Determine if this member is a BSD4.4 symbol table.
117116 bool isBSD4SymbolTable() const { return flags&BSD4SymbolTableFlag; }
118
119 /// @returns true iff the archive member is the LLVM symbol table
120 /// @brief Determine if this member is the LLVM symbol table.
121 bool isLLVMSymbolTable() const { return flags&LLVMSymbolTableFlag; }
122117
123118 /// @returns true iff the archive member is the ar(1) string table
124119 /// @brief Determine if this member is the ar(1) string table.
444439 /// into memory.
445440 explicit Archive(const sys::Path& filename, LLVMContext& C);
446441
447 /// @param data The symbol table data to be parsed
448 /// @param len The length of the symbol table data
449 /// @param error Set to address of a std::string to get error messages
450 /// @returns false on error
451 /// @brief Parse the symbol table at \p data.
452 bool parseSymbolTable(const void* data,unsigned len,std::string* error);
453
454442 /// @returns A fully populated ArchiveMember or 0 if an error occurred.
455443 /// @brief Parse the header of a member starting at \p At
456444 ArchiveMember* parseMemberHeader(
473461 /// @returns false on error
474462 /// @brief Load just the symbol table.
475463 bool loadSymbolTable(std::string* ErrMessage);
476
477 /// @brief Write the symbol table to an ofstream.
478 void writeSymbolTable(std::ofstream& ARFile);
479464
480465 /// Writes one ArchiveMember to an ofstream. If an error occurs, returns
481466 /// false, otherwise true. If an error occurs and error is non-null then
8989 else
9090 flags &= ~BSD4SymbolTableFlag;
9191
92 // LLVM symbol tables have a very specific name
93 if (path.str() == ARFILE_LLVM_SYMTAB_NAME)
94 flags |= LLVMSymbolTableFlag;
95 else
96 flags &= ~LLVMSymbolTableFlag;
97
9892 // String table name
9993 if (path.str() == ARFILE_STRTAB_NAME)
10094 flags |= StringTableFlag;
2121 #define ARFILE_MAGIC "!\n" ///< magic string
2222 #define ARFILE_MAGIC_LEN (sizeof(ARFILE_MAGIC)-1) ///< length of magic string
2323 #define ARFILE_SVR4_SYMTAB_NAME "/ " ///< SVR4 symtab entry name
24 #define ARFILE_LLVM_SYMTAB_NAME "#_LLVM_SYM_TAB_#" ///< LLVM symtab entry name
2524 #define ARFILE_BSD4_SYMTAB_NAME "__.SYMDEF SORTED" ///< BSD4 symtab entry name
2625 #define ARFILE_STRTAB_NAME "// " ///< Name of string table
2726 #define ARFILE_PAD "\n" ///< inter-file align padding
3636 return Result;
3737 }
3838
39 // Completely parse the Archive's symbol table and populate symTab member var.
40 bool
41 Archive::parseSymbolTable(const void* data, unsigned size, std::string* error) {
42 const char* At = (const char*) data;
43 const char* End = At + size;
44 while (At < End) {
45 unsigned offset = readInteger(At, End);
46 if (At == End) {
47 if (error)
48 *error = "Ran out of data reading vbr_uint for symtab offset!";
49 return false;
50 }
51 unsigned length = readInteger(At, End);
52 if (At == End) {
53 if (error)
54 *error = "Ran out of data reading vbr_uint for symtab length!";
55 return false;
56 }
57 if (At + length > End) {
58 if (error)
59 *error = "Malformed symbol table: length not consistent with size";
60 return false;
61 }
62 // we don't care if it can't be inserted (duplicate entry)
63 symTab.insert(std::make_pair(std::string(At, length), offset));
64 At += length;
65 }
66 symTabSize = size;
67 return true;
68 }
69
7039 // This member parses an ArchiveMemberHeader that is presumed to be pointed to
7140 // by At. The At pointer is updated to the byte just after the header, which
7241 // can be variable in size.
10776 // for long file names. This library doesn't generate either of those but
10877 // it will accept them. If the name starts with #1/ and the remainder is
10978 // digits, then those digits specify the length of the name that is
110 // stored immediately following the header. The special name
111 // __LLVM_SYM_TAB__ identifies the symbol table for LLVM bitcode.
112 // Anything else is a regular, short filename that is terminated with
113 // a '/' and blanks.
79 // stored immediately following the header. Anything else is a regular, short
80 // filename that is terminated with a '/' and blanks.
11481
11582 std::string pathname;
11683 switch (Hdr->name[0]) {
12895 *error = "invalid long filename";
12996 return 0;
13097 }
131 } else if (Hdr->name[1] == '_' &&
132 (0 == memcmp(Hdr->name, ARFILE_LLVM_SYMTAB_NAME, 16))) {
133 // The member is using a long file name (>15 chars) format.
134 // This format is standard for 4.4BSD and Mac OSX operating
135 // systems. LLVM uses it similarly. In this format, the
136 // remainder of the name field (after #1/) specifies the
137 // length of the file name which occupy the first bytes of
138 // the member's data. The pathname already has the #1/ stripped.
139 pathname.assign(ARFILE_LLVM_SYMTAB_NAME);
140 flags |= ArchiveMember::LLVMSymbolTableFlag;
14198 }
14299 break;
143100 case '/':
258215
259216 At += 8; // Skip the magic string.
260217
261 bool seenSymbolTable = false;
262218 bool foundFirstFile = false;
263219 while (At < End) {
264220 // parse the member header
290246 if ((intptr_t(At) & 1) == 1)
291247 At++;
292248 delete mbr;
293 } else if (mbr->isLLVMSymbolTable()) {
294 // This is the LLVM symbol table for the archive. If we've seen it
295 // already, its an error. Otherwise, parse the symbol table and move on.
296 if (seenSymbolTable) {
297 if (error)
298 *error = "invalid archive: multiple symbol tables";
299 return false;
300 }
301 if (!parseSymbolTable(mbr->getData(), mbr->getSize(), error))
302 return false;
303 seenSymbolTable = true;
304 At += mbr->getSize();
305 if ((intptr_t(At) & 1) == 1)
306 At++;
307 delete mbr; // We don't need this member in the list of members.
308249 } else {
309250 // This is just a regular file. If its the first one, save its offset.
310251 // Otherwise just push it on the list and move on to the next file.
411352 }
412353 }
413354
414 // See if its the symbol table
415 if (mbr->isLLVMSymbolTable()) {
416 if (!parseSymbolTable(mbr->getData(), mbr->getSize(), ErrorMsg)) {
417 delete mbr;
418 return false;
419 }
420
421 At += mbr->getSize();
422 if ((intptr_t(At) & 1) == 1)
423 At++;
424 delete mbr;
425 // Can't be any more symtab headers so just advance
426 FirstFile = At;
427 } else {
428 // There's no symbol table in the file. We have to rebuild it from scratch
429 // because the intent of this method is to get the symbol table loaded so
430 // it can be searched efficiently.
431 // Add the member to the members list
432 members.push_back(mbr);
433 }
355 // There's no symbol table in the file. We have to rebuild it from scratch
356 // because the intent of this method is to get the symbol table loaded so
357 // it can be searched efficiently.
358 // Add the member to the members list
359 members.push_back(mbr);
434360
435361 firstFileOffset = FirstFile - base;
436362 return true;
112112 memcpy(hdr.name,ARFILE_SVR4_SYMTAB_NAME,16);
113113 } else if (mbr.isBSD4SymbolTable()) {
114114 memcpy(hdr.name,ARFILE_BSD4_SYMTAB_NAME,16);
115 } else if (mbr.isLLVMSymbolTable()) {
116 memcpy(hdr.name,ARFILE_LLVM_SYMTAB_NAME,16);
117115 } else if (TruncateNames) {
118116 const char* nm = mbrPath.c_str();
119117 unsigned len = mbrPath.length();
288286 return false;
289287 }
290288
291 // Write out the LLVM symbol table as an archive member to the file.
292 void
293 Archive::writeSymbolTable(std::ofstream& ARFile) {
294
295 // Construct the symbol table's header
296 ArchiveMemberHeader Hdr;
297 Hdr.init();
298 memcpy(Hdr.name,ARFILE_LLVM_SYMTAB_NAME,16);
299 uint64_t secondsSinceEpoch = sys::TimeValue::now().toEpochTime();
300 char buffer[32];
301 sprintf(buffer, "%-8o", 0644);
302 memcpy(Hdr.mode,buffer,8);
303 sprintf(buffer, "%-6u", sys::Process::GetCurrentUserId());
304 memcpy(Hdr.uid,buffer,6);
305 sprintf(buffer, "%-6u", sys::Process::GetCurrentGroupId());
306 memcpy(Hdr.gid,buffer,6);
307 sprintf(buffer,"%-12u", unsigned(secondsSinceEpoch));
308 memcpy(Hdr.date,buffer,12);
309 sprintf(buffer,"%-10u",symTabSize);
310 memcpy(Hdr.size,buffer,10);
311
312 // Write the header
313 ARFile.write((char*)&Hdr, sizeof(Hdr));
314
315 #ifndef NDEBUG
316 // Save the starting position of the symbol tables data content.
317 unsigned startpos = ARFile.tellp();
318 #endif
319
320 // Write out the symbols sequentially
321 for ( Archive::SymTabType::iterator I = symTab.begin(), E = symTab.end();
322 I != E; ++I)
323 {
324 // Write out the file index
325 writeInteger(I->second, ARFile);
326 // Write out the length of the symbol
327 writeInteger(I->first.length(), ARFile);
328 // Write out the symbol
329 ARFile.write(I->first.data(), I->first.length());
330 }
331
332 #ifndef NDEBUG
333 // Now that we're done with the symbol table, get the ending file position
334 unsigned endpos = ARFile.tellp();
335 #endif
336
337 // Make sure that the amount we wrote is what we pre-computed. This is
338 // critical for file integrity purposes.
339 assert(endpos - startpos == symTabSize && "Invalid symTabSize computation");
340
341 // Make sure the symbol table is even sized
342 if (symTabSize % 2 != 0 )
343 ARFile << ARFILE_PAD;
344 }
345
346289 // Write the entire archive to the file specified when the archive was created.
347290 // This writes to a temporary file first. Options are for creating a symbol
348291 // table, flattening the file names (no directories, 15 chars max) and
452395 }
453396 }
454397
455 // Put out the LLVM symbol table now.
456 writeSymbolTable(FinalFile);
457
458398 // Copy the temporary file contents being sure to skip the file's magic
459399 // number.
460400 FinalFile.write(base + sizeof(ARFILE_MAGIC)-1,
2323 static bool isInternalMember(const ArchiveMemberHeader &amh) {
2424 static const char *const internals[] = {
2525 "/",
26 "//",
27 "#_LLVM_SYM_TAB_#"
26 "//"
2827 };
2928
3029 StringRef name = amh.getName();
0 test/Regression/Archive
11 =======================
22
3 This directory contains various tests of llvm-ar and llvm-ranlib to ensure
3 This directory contains various tests of llvm-ar and to ensure
44 compatibility reading other ar(1) formats. It also provides a basic
55 functionality test for these tools.
66
215215 r"\bllvm-extract\b", r"\bllvm-jistlistener\b",
216216 r"\bllvm-link\b", r"\bllvm-mc\b",
217217 r"\bllvm-nm\b", r"\bllvm-objdump\b",
218 r"\bllvm-prof\b", r"\bllvm-ranlib\b",
218 r"\bllvm-prof\b", r"\bllvm-size\b",
219219 r"\bllvm-rtdyld\b", r"\bllvm-shlib\b",
220 r"\bllvm-size\b",
221220 # Match llvmc but not -llvmc
222221 NOHYPHEN + r"\bllvmc\b",
223222 r"\blto\b",
1313 add_subdirectory(llvm-mc)
1414
1515 add_subdirectory(llc)
16 add_subdirectory(llvm-ranlib)
1716 add_subdirectory(llvm-ar)
1817 add_subdirectory(llvm-nm)
1918 add_subdirectory(llvm-size)
1515 ;===------------------------------------------------------------------------===;
1616
1717 [common]
18 subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener llvm-link llvm-mc llvm-nm llvm-objdump llvm-prof llvm-ranlib llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup
18 subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener llvm-link llvm-mc llvm-nm llvm-objdump llvm-prof llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup
1919
2020 [component_0]
2121 type = Group
2727 # in parallel builds. Please retain this ordering.
2828 DIRS := llvm-config
2929 PARALLEL_DIRS := opt llvm-as llvm-dis \
30 llc llvm-ranlib llvm-ar llvm-nm \
30 llc llvm-ar llvm-nm \
3131 llvm-prof llvm-link \
3232 lli llvm-extract llvm-mc \
3333 bugpoint llvm-bcanalyzer \
375375 const char* data = reinterpret_cast(I->getData());
376376
377377 // Skip things that don't make sense to print
378 if (I->isLLVMSymbolTable() || I->isSVR4SymbolTable() ||
378 if (I->isSVR4SymbolTable() ||
379379 I->isBSD4SymbolTable() || (!DontSkipBitcode && I->isBitcode()))
380380 continue;
381381
+0
-5
tools/llvm-ranlib/CMakeLists.txt less more
None set(LLVM_LINK_COMPONENTS archive)
1
2 add_llvm_tool(llvm-ranlib
3 llvm-ranlib.cpp
4 )
+0
-22
tools/llvm-ranlib/LLVMBuild.txt less more
None ;===- ./tools/llvm-ranlib/LLVMBuild.txt ------------------------*- Conf -*--===;
1 ;
2 ; The LLVM Compiler Infrastructure
3 ;
4 ; This file is distributed under the University of Illinois Open Source
5 ; License. See LICENSE.TXT for details.
6 ;
7 ;===------------------------------------------------------------------------===;
8 ;
9 ; This is an LLVMBuild description file for the components in this subdirectory.
10 ;
11 ; For more information on the LLVMBuild system, please see:
12 ;
13 ; http://llvm.org/docs/LLVMBuild.html
14 ;
15 ;===------------------------------------------------------------------------===;
16
17 [component_0]
18 type = Tool
19 name = llvm-ranlib
20 parent = Tools
21 required_libraries = Archive
+0
-17
tools/llvm-ranlib/Makefile less more
None ##===- tools/llvm-ranlib/Makefile --------------------------*- Makefile -*-===##
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file is distributed under the University of Illinois Open Source
5 # License. See LICENSE.TXT for details.
6 #
7 ##===----------------------------------------------------------------------===##
8
9 LEVEL := ../..
10 TOOLNAME := llvm-ranlib
11 LINK_COMPONENTS := archive
12
13 # This tool has no plugins, optimize startup time.
14 TOOL_NO_EXPORTS := 1
15
16 include $(LEVEL)/Makefile.common
+0
-98
tools/llvm-ranlib/llvm-ranlib.cpp less more
None //===-- llvm-ranlib.cpp - LLVM archive index generator --------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Adds or updates an index (symbol table) for an LLVM archive file.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/IR/LLVMContext.h"
14 #include "llvm/Bitcode/Archive.h"
15 #include "llvm/IR/Module.h"
16 #include "llvm/Support/CommandLine.h"
17 #include "llvm/Support/FileSystem.h"
18 #include "llvm/Support/Format.h"
19 #include "llvm/Support/ManagedStatic.h"
20 #include "llvm/Support/PrettyStackTrace.h"
21 #include "llvm/Support/Signals.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include
24 using namespace llvm;
25
26 // llvm-ar operation code and modifier flags
27 static cl::opt
28 ArchiveName(cl::Positional, cl::Optional, cl::desc(""));
29
30 static cl::opt
31 Verbose("verbose",cl::Optional,cl::init(false),
32 cl::desc("Print the symbol table"));
33
34 // printSymbolTable - print out the archive's symbol table.
35 void printSymbolTable(Archive* TheArchive) {
36 outs() << "\nArchive Symbol Table:\n";
37 const Archive::SymTabType& symtab = TheArchive->getSymbolTable();
38 for (Archive::SymTabType::const_iterator I=symtab.begin(), E=symtab.end();
39 I != E; ++I ) {
40 unsigned offset = TheArchive->getFirstFileOffset() + I->second;
41 outs() << " " << format("%9u", offset) << "\t" << I->first <<"\n";
42 }
43 }
44
45 int main(int argc, char **argv) {
46 // Print a stack trace if we signal out.
47 llvm::sys::PrintStackTraceOnErrorSignal();
48 llvm::PrettyStackTraceProgram X(argc, argv);
49
50 LLVMContext &Context = getGlobalContext();
51 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
52
53 // Have the command line options parsed and handle things
54 // like --help and --version.
55 cl::ParseCommandLineOptions(argc, argv,
56 "LLVM Archive Index Generator (llvm-ranlib)\n\n"
57 " This program adds or updates an index of bitcode symbols\n"
58 " to an LLVM archive file."
59 );
60
61 int exitCode = 0;
62
63 // Check the path name of the archive
64 sys::Path ArchivePath;
65 if (!ArchivePath.set(ArchiveName)) {
66 errs() << argv[0] << ": " << "Archive name invalid: " << ArchiveName <<
67 "\n";
68 return 1;
69 }
70
71 // Make sure it exists, we don't create empty archives
72 bool Exists;
73 if (llvm::sys::fs::exists(ArchivePath.str(), Exists) || !Exists) {
74 errs() << argv[0] << ": " << "Archive file does not exist" <<
75 ArchivePath.str() << "\n";
76 return 1;
77 }
78
79 std::string err_msg;
80 OwningPtr
81 AutoArchive(Archive::OpenAndLoad(ArchivePath, Context, &err_msg));
82 Archive* TheArchive = AutoArchive.get();
83 if (!TheArchive) {
84 errs() << argv[0] << ": " << err_msg << "\n";
85 return 1;
86 }
87
88 if (TheArchive->writeToDisk(true, false, &err_msg )) {
89 errs() << argv[0] << ": " << err_msg << "\n";
90 return 1;
91 }
92
93 if (Verbose)
94 printSymbolTable(TheArchive);
95
96 return exitCode;
97 }