llvm.org GIT mirror llvm / 602706e
[Object] Support reading 64-bit MIPS ELF archives The 64-bit MIPS ELF archive file format is used by MIPS64 targets. The main difference from a regular archive file is the symbol table format: 1. ar_name is equal to "/SYM64/" 2. number of symbols and offsets are 64-bit integers http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf Page 96 The patch allows reading of such archive files by llvm-nm, llvm-objdump and other tools. But it does not support archive files with number of symbols and/or offsets exceed 2^32. I think it is a rather rare case requires more significant modification of `Archive` class code. http://reviews.llvm.org/D7546 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229520 91177308-0d34-0410-b5e6-96231b3b80d8 Simon Atanasyan 5 years ago
4 changed file(s) with 53 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
177177
178178 enum Kind {
179179 K_GNU,
180 K_MIPS64,
180181 K_BSD,
181182 K_COFF
182183 };
161161 return object_error::parse_failed;
162162
163163 // GNU long file names end with a /.
164 if (Parent->kind() == K_GNU) {
164 if (Parent->kind() == K_GNU || Parent->kind() == K_MIPS64) {
165165 StringRef::size_type End = StringRef(addr).find('/');
166166 return StringRef(addr, End);
167167 }
272272 return;
273273 }
274274
275 if (Name == "/") {
275 // MIPS 64-bit ELF archives use a special format of a symbol table.
276 // This format is marked by `ar_name` field equals to "/SYM64/".
277 // For detailed description see page 96 in the following document:
278 // http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf
279
280 bool has64SymTable = false;
281 if (Name == "/" || Name == "/SYM64/") {
276282 SymbolTable = i;
283 if (Name == "/SYM64/")
284 has64SymTable = true;
277285
278286 ++i;
279287 if (i == e) {
284292 }
285293
286294 if (Name == "//") {
287 Format = K_GNU;
295 Format = has64SymTable ? K_MIPS64 : K_GNU;
288296 StringTable = i;
289297 ++i;
290298 FirstRegular = i;
293301 }
294302
295303 if (Name[0] != '/') {
296 Format = K_GNU;
304 Format = has64SymTable ? K_MIPS64 : K_GNU;
297305 FirstRegular = i;
298306 ec = object_error::success;
299307 return;
347355
348356 ErrorOr Archive::Symbol::getMember() const {
349357 const char *Buf = Parent->SymbolTable->getBuffer().begin();
350 const char *Offsets = Buf + 4;
358 const char *Offsets = Buf;
359 if (Parent->kind() == K_MIPS64)
360 Offsets += sizeof(uint64_t);
361 else
362 Offsets += sizeof(uint32_t);
351363 uint32_t Offset = 0;
352364 if (Parent->kind() == K_GNU) {
353365 Offset =
354366 *(reinterpret_cast(Offsets) + SymbolIndex);
367 } else if (Parent->kind() == K_MIPS64) {
368 Offset =
369 *(reinterpret_cast(Offsets) + SymbolIndex);
355370 } else if (Parent->kind() == K_BSD) {
356371 // The SymbolIndex is an index into the ranlib structs that start at
357372 // Offsets (the first uint32_t is the number of bytes of the ranlib
448463 uint32_t symbol_count = 0;
449464 symbol_count = *reinterpret_cast(buf);
450465 buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t)));
466 } else if (kind() == K_MIPS64) {
467 uint64_t symbol_count = *reinterpret_cast(buf);
468 buf += sizeof(uint64_t) + (symbol_count * (sizeof(uint64_t)));
451469 } else if (kind() == K_BSD) {
452470 // The __.SYMDEF or "__.SYMDEF SORTED" member starts with a uint32_t
453471 // which is the number of bytes of ranlib structs that follow. The ranlib
485503 uint32_t symbol_count = 0;
486504 if (kind() == K_GNU) {
487505 symbol_count = *reinterpret_cast(buf);
506 } else if (kind() == K_MIPS64) {
507 symbol_count = *reinterpret_cast(buf);
488508 } else if (kind() == K_BSD) {
489509 symbol_count = (*reinterpret_cast(buf)) /
490510 (sizeof(uint32_t) * 2);
0 # Check reading IRIX 6.0 64-bit archive file.
1 RUN: llvm-nm %p/Inputs/archive-test.a-irix6-mips64el | FileCheck %s
2
3 CHECK: f1.o:
4 CHECK-NEXT: 00000028 T f1
5 CHECK-NEXT: 00000000 d s_d
6 CHECK-NEXT: 00000000 t s_foo
7
8 CHECK: f2.o:
9 CHECK-NEXT: 00000028 T f2
10 CHECK-NEXT: 00000000 d s_d
11 CHECK-NEXT: 00000000 t s_foo
12
13 CHECK: f3.o:
14 CHECK-NEXT: 00000028 T f3
15 CHECK-NEXT: 00000000 d s_d
16 CHECK-NEXT: 00000000 t s_foo
17
18 CHECK: f4.o:
19 CHECK-NEXT: 00000028 T f4
20 CHECK-NEXT: 00000000 d s_d
21 CHECK-NEXT: 00000000 t s_foo
22
23 CHECK: f5.o:
24 CHECK-NEXT: 00000028 T f5
25 CHECK-NEXT: 00000000 d s_d
26 CHECK-NEXT: 00000000 t s_foo