<div dir="ltr">Thank you for pointing it out. I've forgotten that each entry has a type in its high bits, though the type doesn't make sense as they are always the same. I'll fix the comment.</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Apr 26, 2017 at 12:33 PM, Peter Collingbourne <span dir="ltr"><<a href="mailto:peter@pcc.me.uk" target="_blank">peter@pcc.me.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Thanks for writing this up.<div><br></div><div>The description does not seem to match the code, though. It looks like relocations are grouped into pages of 4096 bytes, not 65536 bytes.</div><div><br></div><div>Peter</div></div><div class="gmail_extra"><div><div class="h5"><br><div class="gmail_quote">On Mon, Apr 24, 2017 at 8:31 PM, Rui Ueyama via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: ruiu<br>
Date: Mon Apr 24 22:31:10 2017<br>
New Revision: 301287<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=301287&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=301287&view=rev</a><br>
Log:<br>
Add comments about Widnows .reloc section.<br>
<br>
Modified:<br>
lld/trunk/COFF/Chunks.cpp<br>
<br>
Modified: lld/trunk/COFF/Chunks.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=301287&r1=301286&r2=301287&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/lld/trunk/COFF/Chunks.cp<wbr>p?rev=301287&r1=301286&r2=3012<wbr>87&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/COFF/Chunks.cpp (original)<br>
+++ lld/trunk/COFF/Chunks.cpp Mon Apr 24 22:31:10 2017<br>
@@ -319,8 +319,48 @@ void SEHTableChunk::writeTo(uint8_t *Buf<br>
std::sort(Begin, Begin + Cnt);<br>
}<br>
<br>
-// Windows-specific.<br>
-// This class represents a block in .reloc section.<br>
+// Windows-specific. This class represents a block in .reloc section.<br>
+// The format is described here.<br>
+//<br>
+// On Windows, each DLL is linked against a fixed base address and<br>
+// usually loaded to that address. However, if there's already another<br>
+// DLL that overlaps, the loader has to relocate it. To do that, DLLs<br>
+// contain .reloc sections which contain offsets that need to be fixed<br>
+// up at runtime. If the loader find that a DLL cannot be loaded to its<br>
+// desired base address, it loads it to somewhere else, and add <actual<br>
+// base address> - <desired base address> to each offset that is<br>
+// specified by .reloc section.<br>
+//<br>
+// In ELF terms, .reloc sections contain arrays of relocation offsets.<br>
+// All these offsets in the section are implicitly R_*_RELATIVE, and<br>
+// addends are read from section contents (so it is REL as opposed to<br>
+// RELA).<br>
+//<br>
+// This already reduce the size of relocations to 1/3 compared to ELF<br>
+// .dynrel, but Windows does more to reduce it (probably because it was<br>
+// invented for PCs in the late '80s or early '90s.) Offsets in .reloc<br>
+// are grouped by page where page size is 16 bits, and offsets sharing<br>
+// the same page address are stored consecutively to represent them with<br>
+// less space. This is a very similar to the page table which is grouped<br>
+// by (multiple stages of) pages.<br>
+//<br>
+// For example, let's say we have 0x00030, 0x00500, 0x01000, 0x01100,<br>
+// 0x20004, and 0x20008 in a .reloc section. In the section, they are<br>
+// represented like this:<br>
+//<br>
+// 0x00000 -- page address (4 bytes)<br>
+// 16 -- size of this block (4 bytes)<br>
+// 0x0030 -- entries (2 bytes each)<br>
+// 0x0500<br>
+// 0x1000<br>
+// 0x1100<br>
+// 0x20000 -- page address (4 bytes)<br>
+// 12 -- size of this block (4 bytes)<br>
+// 0x0004 -- entries (2 bytes each)<br>
+// 0x0008<br>
+//<br>
+// Usually we have a lot of relocatinos for each page, so the number of<br>
+// bytes for one .reloc entry is close to 2 bytes.<br>
BaserelChunk::BaserelChunk(ui<wbr>nt32_t Page, Baserel *Begin, Baserel *End) {<br>
// Block header consists of 4 byte page RVA and 4 byte block size.<br>
// Each entry is 2 byte. Last entry may be padding.<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div></div></div><span class="HOEnZb"><font color="#888888">-- <br><div class="m_5659965275836422158gmail_signature" data-smartmail="gmail_signature"><div dir="ltr">-- <div>Peter</div></div></div>
</font></span></div>
</blockquote></div><br></div>