diff options
| author | Richard M. Stallman | 1997-01-10 02:53:35 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1997-01-10 02:53:35 +0000 |
| commit | acacb2920929152a02f5836d39189b04cea08202 (patch) | |
| tree | ac3c27a848aece275d542c9e1d675570ec46ab63 /src | |
| parent | 1c626aaf749003439929908143e519befd64eb53 (diff) | |
| download | emacs-acacb2920929152a02f5836d39189b04cea08202.tar.gz emacs-acacb2920929152a02f5836d39189b04cea08202.zip | |
Include <mach-o/reloc.h>.
(fgrowth): Initialize to zero.
(vmaddr_growth, dataseg_vmaddr, dataseg_vmend): New variables.
[NS_TARGET] (extreloff, nextrel, dysymtab, reloc_info): New variables.
(unexec_doit): Adjust file offsets of segments that follow the
enlarged data segment. Adjust vmaddr of the SEG_LINKEDIT segment that
follows the data segment.
[NS_TARGET] (unexec_doit): Adjust file offsets in the LC_DYSYMTAB load
command that follows the data segment. Zero out relocation entries
that fall within the data segment.
Diffstat (limited to 'src')
| -rw-r--r-- | src/unexnext.c | 80 |
1 files changed, 79 insertions, 1 deletions
diff --git a/src/unexnext.c b/src/unexnext.c index 66f52fa0352..1cf41ca05a1 100644 --- a/src/unexnext.c +++ b/src/unexnext.c | |||
| @@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA. */ | |||
| 27 | #include <stdarg.h> | 27 | #include <stdarg.h> |
| 28 | #include <mach/mach.h> | 28 | #include <mach/mach.h> |
| 29 | #include <mach-o/loader.h> | 29 | #include <mach-o/loader.h> |
| 30 | #include <mach-o/reloc.h> | ||
| 30 | #include <sys/file.h> | 31 | #include <sys/file.h> |
| 31 | #include <sys/stat.h> | 32 | #include <sys/stat.h> |
| 32 | #include <libc.h> | 33 | #include <libc.h> |
| @@ -243,7 +244,7 @@ unexec_doit( | |||
| 243 | struct load_command **the_commands = NULL; | 244 | struct load_command **the_commands = NULL; |
| 244 | unsigned the_commands_len; | 245 | unsigned the_commands_len; |
| 245 | struct mach_header the_header; | 246 | struct mach_header the_header; |
| 246 | int fgrowth; | 247 | int fgrowth = 0; |
| 247 | int fdatastart; | 248 | int fdatastart; |
| 248 | int fdatasize; | 249 | int fdatasize; |
| 249 | int size; | 250 | int size; |
| @@ -251,9 +252,18 @@ unexec_doit( | |||
| 251 | char *buf; | 252 | char *buf; |
| 252 | vm_address_t data_address; | 253 | vm_address_t data_address; |
| 253 | vm_size_t data_size; | 254 | vm_size_t data_size; |
| 255 | vm_size_t vmaddr_growth = 0; | ||
| 256 | vm_size_t dataseg_vmaddr, dataseg_vmend; | ||
| 254 | 257 | ||
| 255 | struct segment_command *segment; | 258 | struct segment_command *segment; |
| 256 | 259 | ||
| 260 | #ifdef NS_TARGET | ||
| 261 | unsigned long extreloff = 0; | ||
| 262 | unsigned long nextrel = 0; | ||
| 263 | struct dysymtab_command *dysymtab; | ||
| 264 | struct relocation_info reloc_info; | ||
| 265 | #endif | ||
| 266 | |||
| 257 | if (!read_macho(infd, &the_header, &the_commands, &the_commands_len)) { | 267 | if (!read_macho(infd, &the_header, &the_commands, &the_commands_len)) { |
| 258 | return (0); | 268 | return (0); |
| 259 | } | 269 | } |
| @@ -284,7 +294,17 @@ unexec_doit( | |||
| 284 | segment->filesize); | 294 | segment->filesize); |
| 285 | segment->vmsize = data_size; | 295 | segment->vmsize = data_size; |
| 286 | segment->filesize = data_size; | 296 | segment->filesize = data_size; |
| 297 | dataseg_vmaddr = segment->vmaddr; | ||
| 298 | dataseg_vmend = segment->vmaddr + segment->vmsize; | ||
| 299 | vmaddr_growth = segment->vmaddr + segment->vmsize; | ||
| 300 | } else { | ||
| 301 | ((struct segment_command *)the_commands[i])->fileoff += fgrowth; | ||
| 302 | } | ||
| 303 | |||
| 304 | if( strcmp( segment->segname, SEG_LINKEDIT ) == 0 ) { | ||
| 305 | segment->vmaddr = vmaddr_growth; | ||
| 287 | } | 306 | } |
| 307 | |||
| 288 | break; | 308 | break; |
| 289 | case LC_SYMTAB: | 309 | case LC_SYMTAB: |
| 290 | ((struct symtab_command *) | 310 | ((struct symtab_command *) |
| @@ -296,6 +316,15 @@ unexec_doit( | |||
| 296 | ((struct symseg_command *) | 316 | ((struct symseg_command *) |
| 297 | the_commands[i])->offset += fgrowth; | 317 | the_commands[i])->offset += fgrowth; |
| 298 | break; | 318 | break; |
| 319 | #ifdef NS_TARGET | ||
| 320 | case LC_DYSYMTAB: | ||
| 321 | dysymtab = ((struct dysymtab_command *)the_commands[i]); | ||
| 322 | extreloff = dysymtab->extreloff; | ||
| 323 | nextrel = dysymtab->nextrel; | ||
| 324 | dysymtab->indirectsymoff += fgrowth; | ||
| 325 | dysymtab->extreloff += fgrowth; | ||
| 326 | break; | ||
| 327 | #endif | ||
| 299 | default: | 328 | default: |
| 300 | break; | 329 | break; |
| 301 | } | 330 | } |
| @@ -382,6 +411,55 @@ unexec_doit( | |||
| 382 | return (0); | 411 | return (0); |
| 383 | } | 412 | } |
| 384 | free(buf); | 413 | free(buf); |
| 414 | |||
| 415 | #ifdef NS_TARGET | ||
| 416 | /* | ||
| 417 | * Fix up relocation entries in the data segment. | ||
| 418 | */ | ||
| 419 | |||
| 420 | if (lseek(infd, extreloff, L_SET) < 0) { | ||
| 421 | fatal_unexec("cannot seek input file"); | ||
| 422 | return (0); | ||
| 423 | } | ||
| 424 | |||
| 425 | for (i = 0; i < nextrel; i++) | ||
| 426 | { | ||
| 427 | long zeroval = 0; | ||
| 428 | |||
| 429 | if (read(infd, &reloc_info, sizeof (reloc_info)) != sizeof (reloc_info)) { | ||
| 430 | fatal_unexec("cannot read input file"); | ||
| 431 | return (0); | ||
| 432 | } | ||
| 433 | if (reloc_info.r_address >= dataseg_vmaddr && reloc_info.r_address < dataseg_vmend) | ||
| 434 | { | ||
| 435 | if (lseek (outfd, fdatastart + reloc_info.r_address - dataseg_vmaddr, L_SET) < 0 ) { | ||
| 436 | fatal_unexec("cannot seek input file"); | ||
| 437 | return (0); | ||
| 438 | } | ||
| 439 | switch (reloc_info.r_length) { | ||
| 440 | case 0: | ||
| 441 | if (write(outfd, &zeroval, 1) != 1) { | ||
| 442 | fatal_unexec("cannot write output file"); | ||
| 443 | return (0); | ||
| 444 | } | ||
| 445 | break; | ||
| 446 | case 1: | ||
| 447 | if (write(outfd, &zeroval, 2) != 2) { | ||
| 448 | fatal_unexec("cannot write output file"); | ||
| 449 | return (0); | ||
| 450 | } | ||
| 451 | break; | ||
| 452 | case 2: | ||
| 453 | if (write(outfd, &zeroval, 4) != 4) { | ||
| 454 | fatal_unexec("cannot write output file"); | ||
| 455 | return (0); | ||
| 456 | } | ||
| 457 | break; | ||
| 458 | } | ||
| 459 | } | ||
| 460 | } | ||
| 461 | #endif | ||
| 462 | |||
| 385 | return (1); | 463 | return (1); |
| 386 | } | 464 | } |
| 387 | 465 | ||