+ /* Some other BSD systems use this file.
+ We don't know whether this change is right for them. */
+#ifdef UNDO_RELOCATION
+ /* Undo the relocations done at startup by ld.so.
+ It will do these relocations again when we start the dumped Emacs.
+ Doing them twice gives incorrect results. */
+ {
+ unsigned long daddr = N_DATADDR (ohdr);
+ unsigned long rel, erel;
+#ifdef SUNOS4
+#ifdef SUNOS4_SHARED_LIBRARIES
+ extern struct link_dynamic _DYNAMIC;
+
+ /* SunOS4.x's ld_rel is relative to N_TXTADDR. */
+ if (!ohdr.a_dynamic)
+ /* This was statically linked. */
+ rel = erel = 0;
+ else if (_DYNAMIC.ld_version < 2)
+ {
+ rel = _DYNAMIC.ld_un.ld_1->ld_rel + N_TXTADDR (ohdr);
+ erel = _DYNAMIC.ld_un.ld_1->ld_hash + N_TXTADDR (ohdr);
+ }
+ else
+ {
+ rel = _DYNAMIC.ld_un.ld_2->ld_rel + N_TXTADDR (ohdr);
+ erel = _DYNAMIC.ld_un.ld_2->ld_hash + N_TXTADDR (ohdr);
+ }
+#else /* not SUNOS4_SHARED_LIBRARIES */
+ rel = erel = 0;
+#endif /* not SUNOS4_SHARED_LIBRARIES */
+#ifdef sparc
+#define REL_INFO_TYPE struct reloc_info_sparc
+#else
+#define REL_INFO_TYPE struct relocation_info
+#endif /* sparc */
+#define REL_TARGET_ADDRESS(r) (((REL_INFO_TYPE *)(r))->r_address)
+#endif /* SUNOS4 */
+#if defined (__FreeBSD__) || defined (__NetBSD__)
+ extern struct _dynamic _DYNAMIC;
+
+ /* FreeBSD's LD_REL is a virtual address itself. */
+ rel = LD_REL (&_DYNAMIC);
+ erel = rel + LD_RELSZ (&_DYNAMIC);
+#define REL_INFO_TYPE struct relocation_info
+#define REL_TARGET_ADDRESS(r) (((REL_INFO_TYPE *)(r))->r_address)
+#endif
+
+ for (; rel < erel; rel += sizeof (REL_INFO_TYPE))
+ {
+ /* This is the virtual address where ld.so will do relocation. */
+ unsigned long target = REL_TARGET_ADDRESS (rel);
+ /* This is the offset in the data segment. */
+ unsigned long segoffset = target - daddr;
+
+ /* If it is located below data_start, we have to do nothing here,
+ because the old data has been already written to the location. */
+ if (target < (unsigned long)&data_start)
+ continue;
+
+ lseek (new, N_DATOFF (nhdr) + segoffset, L_SET);
+ write (new, old + N_DATOFF (ohdr) + segoffset, sizeof (unsigned long));
+ }
+ }
+#endif /* UNDO_RELOCATION */
+