Linker: Reenable Thumb support
authorBen Gamari <ben@smart-cactus.org>
Sat, 26 Dec 2015 12:32:56 +0000 (13:32 +0100)
committerBen Gamari <ben@smart-cactus.org>
Sun, 27 Dec 2015 00:42:07 +0000 (01:42 +0100)
I believe this ought to be okay now since we only produce ARM-encoded
objects. Added a Note describing the state of things.

rts/Linker.c

index 9905d7d..e411e4d 100644 (file)
@@ -326,6 +326,30 @@ static void m32_allocator_init(struct m32_allocator_t *m32);
 #endif
 
 /*
+  Note [The ARM/Thumb Story]
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+  Support for the ARM architecture is complicated by the fact that ARM has not
+  one but several instruction encodings. The two relevant ones here are the original
+  ARM encoding and Thumb, a more dense variant of ARM supporting only a subset
+  of the instruction set.
+
+  How the CPU decodes a particular instruction is determined by a mode bit. This
+  mode bit is set on jump instructions, the value being determined by the low
+  bit of the target address: An odd address means the target is a procedure
+  encoded in the Thumb encoding whereas an even address means it's a traditional
+  ARM procedure (the actual address jumped to is even regardless of the encoding bit).
+
+  Interoperation between Thumb- and ARM-encoded object code (known as "interworking")
+  is tricky. If the linker needs to link a call by an ARM object into Thumb code
+  (or vice-versa) it will produce a jump island. This, however, is incompatible with
+  GHC's tables-next-to-code. For this reason, it is critical that GHC emit
+  exclusively ARM or Thumb objects for all Haskell code.
+
+  We still do, however, need to worry about foreign code.
+*/
+
+/*
  * Due to the small memory model (see above), on x86_64 we have to map
  * all our non-PIC object files into the low 2Gb of the address space
  * (why 2Gb and not 4Gb?  Because all addresses must be reachable
@@ -5023,10 +5047,6 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
          // Thumb instructions have bit 0 of symbol's st_value set
          is_target_thm = S & 0x1;
 
-         if (is_target_thm)
-            errorBelch( "Symbol `%s' requires Thumb linkage which is not "
-                        "currently supported.\n", symbol );
-
          T = sym.st_info & STT_FUNC && is_target_thm;
 
          // Make sure we clear bit 0. Strictly speaking we should have done