aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1996-03-07 20:17:45 +0000
committerRichard M. Stallman1996-03-07 20:17:45 +0000
commit4a438fc5174459a044df208373a43e737c2c714b (patch)
tree7ef759b7ff2407cba5a20947134a697a3b109d2a /src
parente024a2f4ab5c253fe040d3fd2edf7be902e21823 (diff)
downloademacs-4a438fc5174459a044df208373a43e737c2c714b.tar.gz
emacs-4a438fc5174459a044df208373a43e737c2c714b.zip
Handle both AIX 3.2 and 4.1 bind output.
(make_hdr): Handle data_start being non-zero for 4.1. Padding sections are omitted in 4.1, but padding bytes can still be present. Calculate bias directly from first real section following bss. (copy_text_and_data): Correct data section starting point for 4.1. (adjust_lnnoptrs): Adjust line number pointers correctly for both 3.2 and 4.1, based on published IBM documentation. (unrelocate_symbols): Compute and subtract relocation offsets for text and data sections. Handle data_start being non-zero for 4.1. Skip unnecessary writes.
Diffstat (limited to 'src')
-rw-r--r--src/unexaix.c191
1 files changed, 95 insertions, 96 deletions
diff --git a/src/unexaix.c b/src/unexaix.c
index 69b19d2dc54..445f01886dd 100644
--- a/src/unexaix.c
+++ b/src/unexaix.c
@@ -33,6 +33,14 @@ what you give them. Help stamp out software-hoarding! */
33 * Date: Tue Mar 2 1982 33 * Date: Tue Mar 2 1982
34 * Modified heavily since then. 34 * Modified heavily since then.
35 * 35 *
36 * Updated for AIX 4.1.3 by Bill_Mann @ PraxisInt.com, Feb 1996
37 * As of AIX 4.1, text, data, and bss are pre-relocated by the binder in
38 * such a way that the file can be mapped with code in one segment and
39 * data/bss in another segment, without reading or copying the file, by
40 * the AIX exec loader. Padding sections are omitted, nevertheless
41 * small amounts of 'padding' still occurs between sections in the file.
42 * As modified, this code handles both 3.2 and 4.1 conventions.
43 *
36 * Synopsis: 44 * Synopsis:
37 * unexec (new_name, a_name, data_start, bss_start, entry_address) 45 * unexec (new_name, a_name, data_start, bss_start, entry_address)
38 * char *new_name, *a_name; 46 * char *new_name, *a_name;
@@ -203,21 +211,20 @@ extern int _end;
203#endif /* not UMAX */ 211#endif /* not UMAX */
204#endif /* Not STRIDE */ 212#endif /* Not STRIDE */
205#endif /* not USG */ 213#endif /* not USG */
206static long block_copy_start; /* Old executable start point */
207static struct filehdr f_hdr; /* File header */ 214static struct filehdr f_hdr; /* File header */
208static struct aouthdr f_ohdr; /* Optional file header (a.out) */ 215static struct aouthdr f_ohdr; /* Optional file header (a.out) */
209long bias; /* Bias to add for growth */ 216long bias; /* Bias to add for growth */
210long lnnoptr; /* Pointer to line-number info within file */ 217long lnnoptr; /* Pointer to line-number info within file */
211#define SYMS_START block_copy_start
212 218
213static long text_scnptr; 219static long text_scnptr;
214static long data_scnptr; 220static long data_scnptr;
215#ifdef XCOFF 221#ifdef XCOFF
222#define ALIGN(val, pwr) (((val) + ((1L<<(pwr))-1)) & ~((1L<<(pwr))-1))
216static long load_scnptr; 223static long load_scnptr;
217static long orig_load_scnptr; 224static long orig_load_scnptr;
218static long orig_data_scnptr; 225static long orig_data_scnptr;
219#endif 226#endif
220static long data_st; 227static ulong data_st; /* start of data area written out */
221 228
222#ifndef MAX_SECTIONS 229#ifndef MAX_SECTIONS
223#define MAX_SECTIONS 10 230#define MAX_SECTIONS 10
@@ -381,7 +388,6 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
381 388
382#ifdef COFF 389#ifdef COFF
383 /* Salvage as much info from the existing file as possible */ 390 /* Salvage as much info from the existing file as possible */
384 block_copy_start = 0;
385 f_thdr = NULL; f_dhdr = NULL; f_bhdr = NULL; 391 f_thdr = NULL; f_dhdr = NULL; f_bhdr = NULL;
386 f_lhdr = NULL; f_tchdr = NULL; f_dbhdr = NULL; f_xhdr = NULL; 392 f_lhdr = NULL; f_tchdr = NULL; f_dbhdr = NULL; f_xhdr = NULL;
387 if (a_out >= 0) 393 if (a_out >= 0)
@@ -390,14 +396,12 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
390 { 396 {
391 PERROR (a_name); 397 PERROR (a_name);
392 } 398 }
393 block_copy_start += sizeof (f_hdr);
394 if (f_hdr.f_opthdr > 0) 399 if (f_hdr.f_opthdr > 0)
395 { 400 {
396 if (read (a_out, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) 401 if (read (a_out, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr))
397 { 402 {
398 PERROR (a_name); 403 PERROR (a_name);
399 } 404 }
400 block_copy_start += sizeof (f_ohdr);
401 } 405 }
402 if (f_hdr.f_nscns > MAX_SECTIONS) 406 if (f_hdr.f_nscns > MAX_SECTIONS)
403 { 407 {
@@ -410,11 +414,6 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
410 { 414 {
411 PERROR (a_name); 415 PERROR (a_name);
412 } 416 }
413 if (s->s_scnptr > 0L)
414 {
415 if (block_copy_start < s->s_scnptr + s->s_size)
416 block_copy_start = s->s_scnptr + s->s_size;
417 }
418 417
419#define CHECK_SCNHDR(ptr, name, flags) \ 418#define CHECK_SCNHDR(ptr, name, flags) \
420 if (strcmp(s->s_name, name) == 0) { \ 419 if (strcmp(s->s_name, name) == 0) { \
@@ -459,7 +458,11 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
459 458
460 /* Now we alter the contents of all the f_*hdr variables 459 /* Now we alter the contents of all the f_*hdr variables
461 to correspond to what we want to dump. */ 460 to correspond to what we want to dump. */
462 f_hdr.f_flags |= (F_RELFLG | F_EXEC); /* Why? */ 461
462 /* Indicate that the reloc information is no longer valid for ld (bind);
463 we only update it enough to fake out the exec-time loader. */
464 f_hdr.f_flags |= (F_RELFLG | F_EXEC);
465
463#ifdef EXEC_MAGIC 466#ifdef EXEC_MAGIC
464 f_ohdr.magic = EXEC_MAGIC; 467 f_ohdr.magic = EXEC_MAGIC;
465#endif 468#endif
@@ -467,73 +470,77 @@ make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
467 f_ohdr.tsize = data_start - f_ohdr.text_start; 470 f_ohdr.tsize = data_start - f_ohdr.text_start;
468 f_ohdr.text_start = (long) start_of_text (); 471 f_ohdr.text_start = (long) start_of_text ();
469#endif 472#endif
470 f_ohdr.dsize = bss_start - ((unsigned) &_data); 473 data_st = f_ohdr.data_start ? f_ohdr.data_start : (ulong) &_data;
474 f_ohdr.dsize = bss_start - data_st;
471 f_ohdr.bsize = bss_end - bss_start; 475 f_ohdr.bsize = bss_end - bss_start;
472 476
473 f_dhdr->s_size = f_ohdr.dsize; 477 f_dhdr->s_size = f_ohdr.dsize;
474 f_bhdr->s_size = f_ohdr.bsize; 478 f_bhdr->s_size = f_ohdr.bsize;
475 f_bhdr->s_paddr = f_ohdr.dsize; 479 f_bhdr->s_paddr = f_ohdr.data_start + f_ohdr.dsize;
476 f_bhdr->s_vaddr = f_ohdr.dsize; 480 f_bhdr->s_vaddr = f_ohdr.data_start + f_ohdr.dsize;
477 481
478 /* fix scnptr's */ 482 /* fix scnptr's */
479 { 483 {
480 long ptr; 484 ulong ptr = section[0].s_scnptr;
481 485
482 for (scns = 0; scns < f_hdr.f_nscns; scns++) { 486 bias = -1;
483 struct scnhdr *s = &section[scns]; 487 for (scns = 0; scns < f_hdr.f_nscns; scns++)
484 if (scns == 0) 488 {
485 ptr = s->s_scnptr; 489 struct scnhdr *s = &section[scns];
486 490
487 if (s->s_scnptr != 0) 491 if (s->s_flags & STYP_PAD) /* .pad sections omitted in AIX 4.1 */
488 { 492 {
493 /*
494 * the text_start should probably be o_algntext but that doesn't
495 * seem to change
496 */
497 if (f_ohdr.text_start != 0) /* && scns != 0 */
498 {
499 s->s_size = 512 - (ptr % 512);
500 if (s->s_size == 512)
501 s->s_size = 0;
502 }
503 s->s_scnptr = ptr;
504 }
505 else if (s->s_flags & STYP_DATA)
489 s->s_scnptr = ptr; 506 s->s_scnptr = ptr;
490 } 507 else if (!(s->s_flags & (STYP_TEXT | STYP_BSS)))
491 508 {
492 if ((s->s_flags & 0xffff) == STYP_PAD) 509 if (bias == -1) /* if first section after bss */
493 { 510 bias = ptr - s->s_scnptr;
494 /*
495 * the text_start should probably be o_algntext but that doesn't
496 * seem to change
497 */
498 if (f_ohdr.text_start != 0) /* && scns != 0 */
499 {
500 s->s_size = 512 - (s->s_scnptr % 512);
501 if (s->s_size == 512)
502 s->s_size = 0;
503 }
504 }
505
506 ptr = ptr + s->s_size;
507 }
508 511
509 bias = ptr - block_copy_start; 512 s->s_scnptr += bias;
513 ptr = s->s_scnptr;
514 }
515
516 ptr = ptr + s->s_size;
517 }
510 } 518 }
511 519
512 /* fix other pointers */ 520 /* fix other pointers */
513 for (scns = 0; scns < f_hdr.f_nscns; scns++) { 521 for (scns = 0; scns < f_hdr.f_nscns; scns++)
514 struct scnhdr *s = &section[scns]; 522 {
523 struct scnhdr *s = &section[scns];
515 524
516 if (s->s_relptr != 0) 525 if (s->s_relptr != 0)
517 { 526 {
518 s->s_relptr += bias; 527 s->s_relptr += bias;
519 } 528 }
520 if (s->s_lnnoptr != 0) 529 if (s->s_lnnoptr != 0)
521 { 530 {
522 if (lnnoptr == 0) lnnoptr = s->s_lnnoptr; 531 if (lnnoptr == 0) lnnoptr = s->s_lnnoptr;
523 s->s_lnnoptr += bias; 532 s->s_lnnoptr += bias;
524 } 533 }
525 } 534 }
526 535
527 if (f_hdr.f_symptr > 0L) 536 if (f_hdr.f_symptr > 0L)
528 { 537 {
529 f_hdr.f_symptr += bias; 538 f_hdr.f_symptr += bias;
530 } 539 }
531 540
532 data_st = data_start;
533 text_scnptr = f_thdr->s_scnptr; 541 text_scnptr = f_thdr->s_scnptr;
534 data_scnptr = f_dhdr->s_scnptr; 542 data_scnptr = f_dhdr->s_scnptr;
535 load_scnptr = f_lhdr ? f_lhdr->s_scnptr : 0; 543 load_scnptr = f_lhdr ? f_lhdr->s_scnptr : 0;
536 block_copy_start = orig_load_scnptr;
537 544
538#ifdef ADJUST_EXEC_HEADER 545#ifdef ADJUST_EXEC_HEADER
539 ADJUST_EXEC_HEADER 546 ADJUST_EXEC_HEADER
@@ -583,7 +590,7 @@ copy_text_and_data (new)
583 write_segment (new, ptr, end); 590 write_segment (new, ptr, end);
584 591
585 lseek (new, (long) data_scnptr, 0); 592 lseek (new, (long) data_scnptr, 0);
586 ptr = (char *) &_data; 593 ptr = (char *) data_st;
587 end = ptr + f_ohdr.dsize; 594 end = ptr + f_ohdr.dsize;
588 write_segment (new, ptr, end); 595 write_segment (new, ptr, end);
589 596
@@ -644,13 +651,13 @@ copy_sym (new, a_out, a_name, new_name)
644 if (a_out < 0) 651 if (a_out < 0)
645 return 0; 652 return 0;
646 653
647 if (SYMS_START == 0L) 654 if (orig_load_scnptr == 0L)
648 return 0; 655 return 0;
649 656
650 if (lnnoptr && lnnoptr < SYMS_START) /* if there is line number info */ 657 if (lnnoptr && lnnoptr < orig_load_scnptr) /* if there is line number info */
651 lseek (a_out, lnnoptr, 0); /* start copying from there */ 658 lseek (a_out, lnnoptr, 0); /* start copying from there */
652 else 659 else
653 lseek (a_out, SYMS_START, 0); /* Position a.out to symtab. */ 660 lseek (a_out, orig_load_scnptr, 0); /* Position a.out to symtab. */
654 661
655 while ((n = read (a_out, page, sizeof page)) > 0) 662 while ((n = read (a_out, page, sizeof page)) > 0)
656 { 663 {
@@ -703,6 +710,8 @@ mark_x (name)
703 * the auxiliary entries that need adjustment, this routine will 710 * the auxiliary entries that need adjustment, this routine will
704 * be fixed. As it is now, all such entries are wrong and sdb 711 * be fixed. As it is now, all such entries are wrong and sdb
705 * will complain. Fred Fish, UniSoft Systems Inc. 712 * will complain. Fred Fish, UniSoft Systems Inc.
713 *
714 * I believe this is now fixed correctly. Bill Mann
706 */ 715 */
707 716
708#ifdef COFF 717#ifdef COFF
@@ -743,15 +752,17 @@ adjust_lnnoptrs (writedesc, readdesc, new_name)
743 for (nsyms = 0; nsyms < f_hdr.f_nsyms; nsyms++) 752 for (nsyms = 0; nsyms < f_hdr.f_nsyms; nsyms++)
744 { 753 {
745 read (new, &symentry, SYMESZ); 754 read (new, &symentry, SYMESZ);
746 for (naux = 0; naux < symentry.n_numaux; naux++) 755 for (naux = symentry.n_numaux; naux-- != 0; )
747 { 756 {
748 read (new, &auxentry, AUXESZ); 757 read (new, &auxentry, AUXESZ);
749 nsyms++; 758 nsyms++;
750 if (ISFCN (symentry.n_type)) { 759 if (naux != 0 /* skip csect auxentry (last entry) */
751 auxentry.x_sym.x_fcnary.x_fcn.x_lnnoptr += bias; 760 && (symentry.n_sclass == C_EXT || symentry.n_sclass == C_HIDEXT))
752 lseek (new, -AUXESZ, 1); 761 {
753 write (new, &auxentry, AUXESZ); 762 auxentry.x_sym.x_fcnary.x_fcn.x_lnnoptr += bias;
754 } 763 lseek (new, -AUXESZ, 1);
764 write (new, &auxentry, AUXESZ);
765 }
755 } 766 }
756 } 767 }
757 close (new); 768 close (new);
@@ -774,8 +785,8 @@ unrelocate_symbols (new, a_out, a_name, new_name)
774 register LDREL *ldrel; 785 register LDREL *ldrel;
775 LDHDR ldhdr; 786 LDHDR ldhdr;
776 LDREL ldrel_buf [20]; 787 LDREL ldrel_buf [20];
777 ulong t_start = (ulong) &_text; 788 ulong t_reloc = (ulong) &_text - f_ohdr.text_start;
778 ulong d_start = (ulong) &_data; 789 ulong d_reloc = (ulong) &_data - ALIGN(f_ohdr.data_start, 2);
779 int * p; 790 int * p;
780 int dirty; 791 int dirty;
781 792
@@ -837,49 +848,37 @@ unrelocate_symbols (new, a_out, a_name, new_name)
837 { 848 {
838 int orig_int; 849 int orig_int;
839 850
840#ifdef AIX4_1 851 lseek (a_out,
841 lseek (a_out, orig_data_scnptr + (ldrel->l_vaddr - d_start), 0); 852 orig_data_scnptr + (ldrel->l_vaddr - f_ohdr.data_start), 0);
842#else
843 lseek (a_out, orig_data_scnptr + ldrel->l_vaddr, 0);
844#endif
845 853
846 if (read (a_out, (void *) &orig_int, sizeof (orig_int)) != sizeof (orig_int)) 854 if (read (a_out, (void *) &orig_int, sizeof (orig_int)) != sizeof (orig_int))
847 { 855 {
848 PERROR (a_name); 856 PERROR (a_name);
849 } 857 }
850 858
859 p = (int *) (ldrel->l_vaddr + d_reloc);
860
851 switch (ldrel->l_symndx) { 861 switch (ldrel->l_symndx) {
852 case SYMNDX_TEXT: 862 case SYMNDX_TEXT:
853#ifdef AIX4_1 863 orig_int = * p - t_reloc;
854 p = (int *) (ldrel->l_vaddr);
855 orig_int = * p;
856#else
857 p = (int *) (d_start + ldrel->l_vaddr);
858 orig_int = * p - (t_start - f_ohdr.text_start);
859#endif
860 break; 864 break;
861 865
862 case SYMNDX_DATA: 866 case SYMNDX_DATA:
863 case SYMNDX_BSS: 867 case SYMNDX_BSS:
864#ifdef AIX4_1 868 orig_int = * p - d_reloc;
865 p = (int *) (ldrel->l_vaddr);
866 orig_int = * p;
867#else
868 p = (int *) (d_start + ldrel->l_vaddr);
869 orig_int = * p - (d_start - f_ohdr.data_start);
870#endif
871 break; 869 break;
872 } 870 }
873 871
874#ifdef AIX4_1 872 if (orig_int != * p)
875 lseek (new, data_scnptr + (ldrel->l_vaddr - d_start), 0); 873 {
876#else 874 lseek (new,
877 lseek (new, data_scnptr + ldrel->l_vaddr, 0); 875 data_scnptr + (ldrel->l_vaddr - f_ohdr.data_start), 0);
878#endif 876 if (write (new, (void *) &orig_int, sizeof (orig_int))
879 if (write (new, (void *) &orig_int, sizeof (orig_int)) != sizeof (orig_int)) 877 != sizeof (orig_int))
880 { 878 {
881 PERROR (new_name); 879 PERROR (new_name);
882 } 880 }
881 }
883 } 882 }
884 } 883 }
885} 884}