llvm.org GIT mirror llvm / d787a41
Implement the "mips endian" for r_info. Normally r_info is just a 32 of 64 bit number matching the endian of the rest of the file. Unfortunately, mips 64 bit little endian is special: The top 32 bits are a little endian number and the following 32 are a big endian one. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178694 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 7 years ago
4 changed file(s) with 85 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
329329 MaxAlign LLVM_ELF_COMMA false>)
330330 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
331331 Elf_Word r_info; // Symbol table index and type of relocation to apply
332
333 uint32_t getRInfo(bool isMips64EL) const {
334 assert(!isMips64EL);
335 return r_info;
336 }
337 void setRInfo(uint32_t R) {
338 r_info = R;
339 }
332340 };
333341
334342 template class ELFT,
338346 MaxAlign LLVM_ELF_COMMA true>)
339347 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
340348 Elf_Xword r_info; // Symbol table index and type of relocation to apply
349
350 uint64_t getRInfo(bool isMips64EL) const {
351 uint64_t t = r_info;
352 if (!isMips64EL)
353 return t;
354 // Mip64 little endian has a "special" encoding of r_info. Instead of one
355 // 64 bit little endian number, it is a little ending 32 bit number followed
356 // by a 32 bit big endian number.
357 return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
358 ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
359 return r_info;
360 }
361 void setRInfo(uint64_t R) {
362 // FIXME: Add mips64el support.
363 r_info = R;
364 }
341365 };
342366
343367 template class ELFT,
348372 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
349373 Elf_Word r_info; // Symbol table index and type of relocation to apply
350374 Elf_Sword r_addend; // Compute value for relocatable field by adding this
375
376 uint32_t getRInfo(bool isMips64EL) const {
377 assert(!isMips64EL);
378 return r_info;
379 }
380 void setRInfo(uint32_t R) {
381 r_info = R;
382 }
351383 };
352384
353385 template class ELFT,
358390 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
359391 Elf_Xword r_info; // Symbol table index and type of relocation to apply
360392 Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
393
394 uint64_t getRInfo(bool isMips64EL) const {
395 // Mip64 little endian has a "special" encoding of r_info. Instead of one
396 // 64 bit little endian number, it is a little ending 32 bit number followed
397 // by a 32 bit big endian number.
398 uint64_t t = r_info;
399 if (!isMips64EL)
400 return t;
401 return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
402 ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
403 }
404 void setRInfo(uint64_t R) {
405 // FIXME: Add mips64el support.
406 r_info = R;
407 }
361408 };
362409
363410 template
367414 endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
368415 struct Elf_Rel_Impl, isRela>
369416 : Elf_Rel_Base, isRela> {
370 using Elf_Rel_Base, isRela>::r_info;
371417 LLVM_ELF_IMPORT_TYPES(ELFT
372418 MaxAlign LLVM_ELF_COMMA true>)
373419
374420 // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
375421 // and ELF64_R_INFO macros defined in the ELF specification:
376 uint32_t getSymbol() const { return (uint32_t) (r_info >> 32); }
377 uint32_t getType() const {
378 return (uint32_t) (r_info & 0xffffffffL);
422 uint32_t getSymbol(bool isMips64EL) const {
423 return (uint32_t) (this->getRInfo(isMips64EL) >> 32);
424 }
425 uint32_t getType(bool isMips64EL) const {
426 return (uint32_t) (this->getRInfo(isMips64EL) & 0xffffffffL);
379427 }
380428 void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
381429 void setType(uint32_t t) { setSymbolAndType(getSymbol(), t); }
382430 void setSymbolAndType(uint32_t s, uint32_t t) {
383 r_info = ((uint64_t)s << 32) + (t&0xffffffffL);
431 this->setRInfo(((uint64_t)s << 32) + (t&0xffffffffL));
384432 }
385433 };
386434
388436 endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
389437 struct Elf_Rel_Impl, isRela>
390438 : Elf_Rel_Base, isRela> {
391 using Elf_Rel_Base, isRela>::r_info;
392439 LLVM_ELF_IMPORT_TYPES(ELFT
393440 MaxAlign LLVM_ELF_COMMA false>)
394441
395442 // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
396443 // and ELF32_R_INFO macros defined in the ELF specification:
397 uint32_t getSymbol() const { return (r_info >> 8); }
398 unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); }
444 uint32_t getSymbol(bool isMips64EL) const {
445 return this->getRInfo(isMips64EL) >> 8;
446 }
447 unsigned char getType(bool isMips64EL) const {
448 return (unsigned char) (this->getRInfo(isMips64EL) & 0x0ff);
449 }
399450 void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
400451 void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
401452 void setSymbolAndType(uint32_t s, unsigned char t) {
402 r_info = (s << 8) + t;
453 this->setRInfo((s << 8) + t);
403454 }
404455 };
405456
702753
703754 public:
704755 ELFObjectFile(MemoryBuffer *Object, error_code &ec);
756
757 bool isMips64EL() const {
758 return Header->e_machine == ELF::EM_MIPS &&
759 Header->getFileClass() == ELF::ELFCLASS64 &&
760 Header->getDataEncoding() == ELF::ELFDATA2LSB;
761 }
762
705763 virtual symbol_iterator begin_symbols() const;
706764 virtual symbol_iterator end_symbols() const;
707765
14661524 default :
14671525 report_fatal_error("Invalid section type in Rel!");
14681526 case ELF::SHT_REL : {
1469 symbolIdx = getRel(Rel)->getSymbol();
1527 symbolIdx = getRel(Rel)->getSymbol(isMips64EL());
14701528 break;
14711529 }
14721530 case ELF::SHT_RELA : {
1473 symbolIdx = getRela(Rel)->getSymbol();
1531 symbolIdx = getRela(Rel)->getSymbol(isMips64EL());
14741532 break;
14751533 }
14761534 }
15361594 default :
15371595 report_fatal_error("Invalid section type in Rel!");
15381596 case ELF::SHT_REL : {
1539 Result = getRel(Rel)->getType();
1597 Result = getRel(Rel)->getType(isMips64EL());
15401598 break;
15411599 }
15421600 case ELF::SHT_RELA : {
1543 Result = getRela(Rel)->getType();
1601 Result = getRela(Rel)->getType(isMips64EL());
15441602 break;
15451603 }
15461604 }
15601618 default :
15611619 return object_error::parse_failed;
15621620 case ELF::SHT_REL : {
1563 type = getRel(Rel)->getType();
1621 type = getRel(Rel)->getType(isMips64EL());
15641622 break;
15651623 }
15661624 case ELF::SHT_RELA : {
1567 type = getRela(Rel)->getType();
1625 type = getRela(Rel)->getType(isMips64EL());
15681626 break;
15691627 }
15701628 }
20582116 default:
20592117 return object_error::parse_failed;
20602118 case ELF::SHT_REL: {
2061 type = getRel(Rel)->getType();
2062 symbol_index = getRel(Rel)->getSymbol();
2119 type = getRel(Rel)->getType(isMips64EL());
2120 symbol_index = getRel(Rel)->getSymbol(isMips64EL());
20632121 // TODO: Read implicit addend from section data.
20642122 break;
20652123 }
20662124 case ELF::SHT_RELA: {
2067 type = getRela(Rel)->getType();
2068 symbol_index = getRela(Rel)->getSymbol();
2125 type = getRela(Rel)->getType(isMips64EL());
2126 symbol_index = getRela(Rel)->getSymbol(isMips64EL());
20692127 addend = getRela(Rel)->r_addend;
20702128 break;
20712129 }
129129
130130
131131 // MIPS64EL: RELOCATION RECORDS FOR [.eh_frame]:
132 // FIXME: llvm-objdump currently misprints the relocations for mips64el
132 // MIPS64EL-NEXT: R_MIPS_64
133133 // MIPS64EL: Contents of section .eh_frame:
134134 // MIPS64EL-NEXT: 0000
135135
77 RUN: | FileCheck %s -check-prefix ELF-x86-64
88 RUN: llvm-objdump -r %p/Inputs/trivial-object-test.elf-hexagon \
99 RUN: | FileCheck %s -check-prefix ELF-hexagon
10 RUN: llvm-objdump -r %p/Inputs/trivial-object-test.elf-mips64el \
11 RUN: | FileCheck %s -check-prefix ELF-MIPS64EL
1012
1113 RUN: llvm-objdump -r %p/Inputs/relocations.elf-x86-64 \
1214 RUN: | FileCheck %s -check-prefix ELF-complex-x86-64
3941 ELF-hexagon: R_HEX_B15_PCREL testf
4042 ELF-hexagon: R_HEX_B22_PCREL puts
4143
44 // Note: this file was produced with gas to make sure we don't end up in a
45 // situation where LLVM produces and accepts a broken file.
46 ELF-MIPS64EL: .data
47 ELF-MIPS64EL: R_MIPS_64
48
4249 ELF-complex-x86-64: .text
4350 ELF-complex-x86-64-NEXT: R_X86_64_8 .data-4
4451 ELF-complex-x86-64-NEXT: R_X86_64_16 .data-4