set_gdbarch_get_siginfo_type (gdbarch, windows_get_siginfo_type);
}
+/* Implement the fetch_tls_load_module_address gdbarch method.
+ Usually this method returns an address representing a load module, but this
+ doesn't exist on Windows. Instead it returns the address of the
+ "_tls_index" variable of OBJFILE, which is then forwarded as LM_ADDR
+ in windows_get_thread_local_address below. */
+
+static CORE_ADDR
+windows_tls_index_address (struct objfile *objfile)
+{
+ bound_minimal_symbol minsym
+ = lookup_minimal_symbol_linkage ("_tls_index", objfile, false);
+ if (minsym.minsym == nullptr)
+ throw_error (TLS_GENERIC_ERROR, _("Cannot find address of _tls_index"));
+
+ return minsym.value_address ();
+}
+
+/* Implement the get_thread_local_address gdbarch method.
+ Each module (with TLS variables) gets its own TLS slot represented by
+ _tls_index, which can be found in TIB->thread_local_storage[_tls_index].
+ The address of _tls_index is provided by the LM_ADDR argument. */
+
+static CORE_ADDR
+windows_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid,
+ CORE_ADDR lm_addr, CORE_ADDR offset)
+{
+ int ptr_bytes;
+ int tls_offset; /* Offset of thread_local_storage in TIB. */
+ if (gdbarch_ptr_bit (gdbarch) == 32)
+ {
+ ptr_bytes = 4;
+ tls_offset = 44;
+ }
+ else
+ {
+ ptr_bytes = 8;
+ tls_offset = 88;
+ }
+
+ gdb_byte buf[8];
+ if (target_read_memory (lm_addr, buf, 4))
+ throw_error (TLS_GENERIC_ERROR, _("Cannot read _tls_index"));
+
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ uint32_t tls_index = extract_unsigned_integer (buf, 4, byte_order);
+
+ CORE_ADDR tlb;
+ if (!target_get_tib_address (ptid, &tlb))
+ throw_error (TLS_GENERIC_ERROR, _("Cannot get tib address"));
+
+ if (target_read_memory (tlb + tls_offset, buf, ptr_bytes))
+ throw_error (TLS_GENERIC_ERROR, _("Cannot read thread_local_storage"));
+
+ CORE_ADDR tls_ptr = extract_unsigned_integer (buf, ptr_bytes, byte_order);
+ if (tls_ptr == 0)
+ throw_error (TLS_NOT_ALLOCATED_YET_ERROR, _("TLS not allocated yet"));
+
+ if (target_read_memory (tls_ptr + tls_index * ptr_bytes, buf, ptr_bytes))
+ throw_error (TLS_GENERIC_ERROR, _("Cannot read TLS slot"));
+
+ CORE_ADDR slot_ptr = extract_unsigned_integer (buf, ptr_bytes, byte_order);
+ if (slot_ptr == 0)
+ throw_error (TLS_NOT_ALLOCATED_YET_ERROR, _("TLS slot not allocated yet"));
+
+ return slot_ptr + offset;
+}
+
/* See windows-tdep.h. */
void
windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* On Windows, "long"s are only 32bit. */
set_gdbarch_long_bit (gdbarch, 32);
+
+ /* Enable TLS support. */
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ windows_tls_index_address);
+ set_gdbarch_get_thread_local_address (gdbarch,
+ windows_get_thread_local_address);
}
/* See windows-tdep.h. */