From: YAMAMOTO Mitsuharu Date: Sat, 24 Nov 2007 08:51:24 +0000 (+0000) Subject: (copy_data_segment): Also copy __gcc_except_tab and __objc_* sections. X-Git-Tag: emacs-pretest-22.1.90~320 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=b2411edf931941ce5f2de932da8340cea330c15e;p=emacs.git (copy_data_segment): Also copy __gcc_except_tab and __objc_* sections. (unrelocate) [_LP64]: Set relocation base to address of data segment. --- diff --git a/src/ChangeLog b/src/ChangeLog index 918af2c6335..206ded2aaa5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2007-11-24 YAMAMOTO Mitsuharu + + * unexmacosx.c (copy_data_segment): Also copy __gcc_except_tab and + __objc_* sections. + (unrelocate) [_LP64]: Set relocation base to address of data segment. + 2007-11-23 Andreas Schwab * editfns.c (Fformat): Handle %c specially since it requires the diff --git a/src/unexmacosx.c b/src/unexmacosx.c index 3646aec6983..eceffc4af4b 100644 --- a/src/unexmacosx.c +++ b/src/unexmacosx.c @@ -819,7 +819,9 @@ copy_data_segment (struct load_command *lc) || strncmp (sectp->sectname, "__la_sym_ptr2", 16) == 0 || strncmp (sectp->sectname, "__dyld", 16) == 0 || strncmp (sectp->sectname, "__const", 16) == 0 - || strncmp (sectp->sectname, "__cfstring", 16) == 0) + || strncmp (sectp->sectname, "__cfstring", 16) == 0 + || strncmp (sectp->sectname, "__gcc_except_tab", 16) == 0 + || strncmp (sectp->sectname, "__objc_", 7) == 0) { if (!unexec_copy (sectp->offset, old_file_offset, sectp->size)) unexec_error ("cannot copy section %s", sectp->sectname); @@ -904,6 +906,20 @@ unrelocate (const char *name, off_t reloff, int nrel) struct relocation_info reloc_info; struct scattered_relocation_info *sc_reloc_info = (struct scattered_relocation_info *) &reloc_info; + vm_address_t reloc_base, location; + +#ifdef _LP64 +#if __ppc64__ + reloc_base = (data_segment_scp->vmaddr >= 0x100000000 + ? data_segment_scp->vmaddr : 0); +#else + /* First writable segment address. */ + reloc_base = data_segment_scp->vmaddr; +#endif +#else + /* First segment address in the file (unless MH_SPLIT_SEGS set). */ + reloc_base = 0; +#endif for (unreloc_count = 0, i = 0; i < nrel; i++) { @@ -917,14 +933,15 @@ unrelocate (const char *name, off_t reloff, int nrel) switch (reloc_info.r_type) { case GENERIC_RELOC_VANILLA: - if (reloc_info.r_address >= data_segment_scp->vmaddr - && reloc_info.r_address < (data_segment_scp->vmaddr - + data_segment_scp->vmsize)) + location = reloc_base + reloc_info.r_address; + if (location >= data_segment_scp->vmaddr + && location < (data_segment_scp->vmaddr + + data_segment_scp->vmsize)) { off_t src_off = data_segment_old_fileoff - + reloc_info.r_address - data_segment_scp->vmaddr; + + (location - data_segment_scp->vmaddr); off_t dst_off = data_segment_scp->fileoff - + reloc_info.r_address - data_segment_scp->vmaddr; + + (location - data_segment_scp->vmaddr); if (!unexec_copy (dst_off, src_off, 1 << reloc_info.r_length)) unexec_error ("unrelocate: %s:%d cannot copy original value",