[lld] r200240 - [PECOFF] Implement some relocations for x86-64.
Rui Ueyama
ruiu at google.com
Mon Jan 27 11:23:13 PST 2014
Author: ruiu
Date: Mon Jan 27 13:23:12 2014
New Revision: 200240
URL: http://llvm.org/viewvc/llvm-project?rev=200240&view=rev
Log:
[PECOFF] Implement some relocations for x86-64.
Modified:
lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=200240&r1=200239&r2=200240&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Mon Jan 27 13:23:12 2014
@@ -48,6 +48,7 @@
using llvm::support::ulittle16_t;
using llvm::support::ulittle32_t;
+using llvm::support::ulittle64_t;
using llvm::COFF::DataDirectoryIndex;
namespace lld {
@@ -467,6 +468,25 @@ AtomChunk::buildAtomRvaMap(std::map<cons
atomRva[layout->_atom] = layout->_virtualAddr;
}
+static int getSectionIndex(uint64_t targetAddr,
+ const std::vector<uint64_t> §ionRva) {
+ int i = 1;
+ for (uint64_t rva : sectionRva) {
+ if (targetAddr < rva)
+ return i;
+ ++i;
+ }
+ return i;
+}
+
+static uint32_t getSectionStartAddr(uint64_t targetAddr,
+ const std::vector<uint64_t> §ionRva) {
+ for (int i = 0, e = sectionRva.size(); i < e; ++i)
+ if (i == e - 1 || (sectionRva[i] <= targetAddr && targetAddr <= sectionRva[i + 1]))
+ return sectionRva[i];
+ llvm_unreachable("Section missing");
+}
+
void AtomChunk::applyRelocations32(uint8_t *buffer,
std::map<const Atom *, uint64_t> &atomRva,
std::vector<uint64_t> §ionRva,
@@ -504,28 +524,14 @@ void AtomChunk::applyRelocations32(uint8
*relocSite32 = targetAddr - disp;
break;
}
- case llvm::COFF::IMAGE_REL_I386_SECTION: {
+ case llvm::COFF::IMAGE_REL_I386_SECTION:
// The 16-bit section index that contains the target symbol.
- uint16_t i = 1;
- for (uint64_t rva : sectionRva) {
- if (targetAddr < rva) {
- *relocSite16 = i;
- break;
- }
- ++i;
- }
+ *relocSite16 = getSectionIndex(targetAddr, sectionRva);
break;
- }
case llvm::COFF::IMAGE_REL_I386_SECREL:
// The 32-bit relative address from the beginning of the section that
// contains the target symbol.
- for (int i = 0, e = sectionRva.size(); i < e; ++i) {
- if (i == e - 1 || (sectionRva[i] <= targetAddr &&
- targetAddr <= sectionRva[i + 1])) {
- *relocSite32 = targetAddr - sectionRva[i];
- break;
- }
- }
+ *relocSite32 = targetAddr - getSectionStartAddr(targetAddr, sectionRva);
break;
default:
llvm_unreachable("Unsupported relocation kind");
@@ -545,11 +551,19 @@ void AtomChunk::applyRelocations64(uint8
if (ref->kindNamespace() != Reference::KindNamespace::COFF)
continue;
- auto relocSite32 = reinterpret_cast<ulittle32_t *>(
- buffer + layout->_fileOffset + ref->offsetInAtom());
+ uint8_t *loc = buffer + layout->_fileOffset + ref->offsetInAtom();
+ auto relocSite16 = reinterpret_cast<ulittle16_t *>(loc);
+ auto relocSite32 = reinterpret_cast<ulittle32_t *>(loc);
+ auto relocSite64 = reinterpret_cast<ulittle64_t *>(loc);
uint64_t targetAddr = atomRva[ref->target()];
switch (ref->kindValue()) {
+ case llvm::COFF::IMAGE_REL_AMD64_ADDR64:
+ *relocSite64 = targetAddr;
+ break;
+ case llvm::COFF::IMAGE_REL_AMD64_ADDR32:
+ *relocSite32 = targetAddr;
+ break;
case llvm::COFF::IMAGE_REL_AMD64_ADDR32NB:
*relocSite32 = targetAddr - imageBase;
break;
@@ -569,6 +583,13 @@ void AtomChunk::applyRelocations64(uint8
REL32(5);
#undef CASE
+ case llvm::COFF::IMAGE_REL_AMD64_SECTION:
+ *relocSite16 = getSectionIndex(targetAddr, sectionRva);
+ break;
+ case llvm::COFF::IMAGE_REL_AMD64_SECREL:
+ *relocSite32 = targetAddr - getSectionStartAddr(targetAddr, sectionRva);
+ break;
+
default:
llvm::errs() << "Kind: " << (int)ref->kindValue() << "\n";
llvm_unreachable("Unsupported relocation kind");
More information about the llvm-commits
mailing list