diff options
| author | Karl Heuer | 1999-08-25 16:15:29 +0000 |
|---|---|---|
| committer | Karl Heuer | 1999-08-25 16:15:29 +0000 |
| commit | bc597cc7be83a24e93ee9c032993389003d6ff5f (patch) | |
| tree | c43494ae333ebd96113326b69ac72d3b6c001205 /src | |
| parent | 3bc0ab9fdd82e52ce98ff01abb3ee40e780bde5b (diff) | |
| download | emacs-bc597cc7be83a24e93ee9c032993389003d6ff5f.tar.gz emacs-bc597cc7be83a24e93ee9c032993389003d6ff5f.zip | |
Merge IRIX debugging info patch from unexsgi.c
Auto-detect .sbss section.
(round_up): Make it static.
(unexec): Declare alignment as Elf Word. Skip ``Program
segment above .bss'' test on MIPS without .sbss.
Copy sections .got and .sdata1 sections. Adjust offsets in
sections .sdata, .lit4, .lit8, .got and .sdata1.
Diffstat (limited to 'src')
| -rw-r--r-- | src/unexelf.c | 145 |
1 files changed, 96 insertions, 49 deletions
diff --git a/src/unexelf.c b/src/unexelf.c index bf4f40cca0c..7fa8eb00ce0 100644 --- a/src/unexelf.c +++ b/src/unexelf.c | |||
| @@ -427,16 +427,10 @@ Filesz Memsz Flags Align | |||
| 427 | #if defined (__sony_news) && defined (_SYSTYPE_SYSV) | 427 | #if defined (__sony_news) && defined (_SYSTYPE_SYSV) |
| 428 | #include <sys/elf_mips.h> | 428 | #include <sys/elf_mips.h> |
| 429 | #include <sym.h> | 429 | #include <sym.h> |
| 430 | #define HAS_SBSS_SECTION | ||
| 431 | #endif /* __sony_news && _SYSTYPE_SYSV */ | 430 | #endif /* __sony_news && _SYSTYPE_SYSV */ |
| 432 | 431 | #if __sgi | |
| 433 | #if defined (__NetBSD__) && defined (__powerpc__) | 432 | #include <sym.h> /* for HDRR declaration */ |
| 434 | #define HAS_SBSS_SECTION | 433 | #endif /* __sgi */ |
| 435 | #endif | ||
| 436 | |||
| 437 | #if defined (__linux__) && defined (__alpha__) | ||
| 438 | #define HAS_SBSS_SECTION | ||
| 439 | #endif | ||
| 440 | 434 | ||
| 441 | #if defined (__alpha__) && !defined (__NetBSD__) && !defined (__OpenBSD__) | 435 | #if defined (__alpha__) && !defined (__NetBSD__) && !defined (__OpenBSD__) |
| 442 | /* Declare COFF debugging symbol table. This used to be in | 436 | /* Declare COFF debugging symbol table. This used to be in |
| @@ -543,7 +537,7 @@ extern void fatal (char *, ...); | |||
| 543 | /* Get the address of a particular section or program header entry, | 537 | /* Get the address of a particular section or program header entry, |
| 544 | * accounting for the size of the entries. | 538 | * accounting for the size of the entries. |
| 545 | */ | 539 | */ |
| 546 | /* | 540 | /* |
| 547 | On PPC Reference Platform running Solaris 2.5.1 | 541 | On PPC Reference Platform running Solaris 2.5.1 |
| 548 | the plt section is also of type NOBI like the bss section. | 542 | the plt section is also of type NOBI like the bss section. |
| 549 | (not really stored) and therefore sections after the bss | 543 | (not really stored) and therefore sections after the bss |
| @@ -552,7 +546,7 @@ extern void fatal (char *, ...); | |||
| 552 | Thus, we modify the test from | 546 | Thus, we modify the test from |
| 553 | if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset) | 547 | if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset) |
| 554 | to | 548 | to |
| 555 | if (NEW_SECTION_H (nn).sh_offset >= | 549 | if (NEW_SECTION_H (nn).sh_offset >= |
| 556 | OLD_SECTION_H (old_bss_index-1).sh_offset) | 550 | OLD_SECTION_H (old_bss_index-1).sh_offset) |
| 557 | This is just a hack. We should put the new data section | 551 | This is just a hack. We should put the new data section |
| 558 | before the .plt section. | 552 | before the .plt section. |
| @@ -584,7 +578,7 @@ typedef unsigned char byte; | |||
| 584 | 578 | ||
| 585 | /* Round X up to a multiple of Y. */ | 579 | /* Round X up to a multiple of Y. */ |
| 586 | 580 | ||
| 587 | ElfW(Addr) | 581 | static ElfW(Addr) |
| 588 | round_up (x, y) | 582 | round_up (x, y) |
| 589 | ElfW(Addr) x, y; | 583 | ElfW(Addr) x, y; |
| 590 | { | 584 | { |
| @@ -629,9 +623,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 629 | ElfW(Addr) new_data2_addr; | 623 | ElfW(Addr) new_data2_addr; |
| 630 | 624 | ||
| 631 | int n, nn, old_bss_index, old_data_index, new_data2_index; | 625 | int n, nn, old_bss_index, old_data_index, new_data2_index; |
| 632 | #if defined (HAS_SBSS_SECTION) | ||
| 633 | int old_sbss_index, old_mdebug_index; | 626 | int old_sbss_index, old_mdebug_index; |
| 634 | #endif /* HAS_SBSS_SECTION */ | ||
| 635 | struct stat stat_buf; | 627 | struct stat stat_buf; |
| 636 | 628 | ||
| 637 | /* Open the old file & map it into the address space. */ | 629 | /* Open the old file & map it into the address space. */ |
| @@ -681,7 +673,6 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 681 | if (old_bss_index == old_file_h->e_shnum) | 673 | if (old_bss_index == old_file_h->e_shnum) |
| 682 | fatal ("Can't find .bss in %s.\n", old_name, 0); | 674 | fatal ("Can't find .bss in %s.\n", old_name, 0); |
| 683 | 675 | ||
| 684 | #if defined (HAS_SBSS_SECTION) | ||
| 685 | for (old_sbss_index = 1; old_sbss_index < (int) old_file_h->e_shnum; | 676 | for (old_sbss_index = 1; old_sbss_index < (int) old_file_h->e_shnum; |
| 686 | old_sbss_index++) | 677 | old_sbss_index++) |
| 687 | { | 678 | { |
| @@ -695,6 +686,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 695 | } | 686 | } |
| 696 | if (old_sbss_index == old_file_h->e_shnum) | 687 | if (old_sbss_index == old_file_h->e_shnum) |
| 697 | { | 688 | { |
| 689 | old_sbss_index = -1; | ||
| 698 | old_bss_addr = OLD_SECTION_H(old_bss_index).sh_addr; | 690 | old_bss_addr = OLD_SECTION_H(old_bss_index).sh_addr; |
| 699 | old_bss_size = OLD_SECTION_H(old_bss_index).sh_size; | 691 | old_bss_size = OLD_SECTION_H(old_bss_index).sh_size; |
| 700 | new_data2_offset = OLD_SECTION_H(old_bss_index).sh_offset; | 692 | new_data2_offset = OLD_SECTION_H(old_bss_index).sh_offset; |
| @@ -722,10 +714,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 722 | } | 714 | } |
| 723 | if (old_mdebug_index == old_file_h->e_shnum) | 715 | if (old_mdebug_index == old_file_h->e_shnum) |
| 724 | old_mdebug_index = 0; | 716 | old_mdebug_index = 0; |
| 725 | #else /* not HAS_SBSS_SECTION */ | 717 | |
| 726 | old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; | ||
| 727 | old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; | ||
| 728 | #endif /* not HAS_SBSS_SECTION */ | ||
| 729 | #if defined (emacs) || !defined (DEBUG) | 718 | #if defined (emacs) || !defined (DEBUG) |
| 730 | new_bss_addr = (ElfW(Addr)) sbrk (0); | 719 | new_bss_addr = (ElfW(Addr)) sbrk (0); |
| 731 | #else | 720 | #else |
| @@ -733,9 +722,6 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 733 | #endif | 722 | #endif |
| 734 | new_data2_addr = old_bss_addr; | 723 | new_data2_addr = old_bss_addr; |
| 735 | new_data2_size = new_bss_addr - old_bss_addr; | 724 | new_data2_size = new_bss_addr - old_bss_addr; |
| 736 | #if !defined (HAS_SBSS_SECTION) | ||
| 737 | new_data2_offset = OLD_SECTION_H (old_bss_index).sh_offset; | ||
| 738 | #endif /* not HAS_SBSS_SECTION */ | ||
| 739 | 725 | ||
| 740 | #ifdef DEBUG | 726 | #ifdef DEBUG |
| 741 | fprintf (stderr, "old_bss_index %d\n", old_bss_index); | 727 | fprintf (stderr, "old_bss_index %d\n", old_bss_index); |
| @@ -816,18 +802,22 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 816 | for (n = new_file_h->e_phnum - 1; n >= 0; n--) | 802 | for (n = new_file_h->e_phnum - 1; n >= 0; n--) |
| 817 | { | 803 | { |
| 818 | /* Compute maximum of all requirements for alignment of section. */ | 804 | /* Compute maximum of all requirements for alignment of section. */ |
| 819 | int alignment = (NEW_PROGRAM_H (n)).p_align; | 805 | ElfW(Word) alignment = (NEW_PROGRAM_H (n)).p_align; |
| 820 | if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment) | 806 | if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment) |
| 821 | alignment = OLD_SECTION_H (old_bss_index).sh_addralign; | 807 | alignment = OLD_SECTION_H (old_bss_index).sh_addralign; |
| 822 | 808 | ||
| 823 | #if defined (HAS_SBSS_SECTION) | 809 | #ifdef __mips |
| 810 | /* According to r02kar@x4u2.desy.de (Karsten Kuenne) | ||
| 811 | and oliva@gnu.org (Alexandre Oliva), on IRIX 5.2, we | ||
| 812 | always get "Program segment above .bss" when dumping | ||
| 813 | when the executable doesn't have an sbss section. */ | ||
| 814 | if (old_sbss_index != -1) | ||
| 815 | #endif /* __mips */ | ||
| 824 | if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz | 816 | if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz |
| 825 | > round_up (old_bss_addr, alignment)) | 817 | > (old_sbss_index == -1 |
| 826 | fatal ("Program segment above .bss in %s\n", old_name, 0); | 818 | ? old_bss_addr |
| 827 | #else /* not HAS_SBSS_SECTION */ | 819 | : round_up (old_bss_addr, alignment))) |
| 828 | if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz > old_bss_addr) | 820 | fatal ("Program segment above .bss in %s\n", old_name, 0); |
| 829 | fatal ("Program segment above .bss in %s\n", old_name, 0); | ||
| 830 | #endif /* not HAS_SBSS_SECTION */ | ||
| 831 | 821 | ||
| 832 | if (NEW_PROGRAM_H (n).p_type == PT_LOAD | 822 | if (NEW_PROGRAM_H (n).p_type == PT_LOAD |
| 833 | && (round_up ((NEW_PROGRAM_H (n)).p_vaddr | 823 | && (round_up ((NEW_PROGRAM_H (n)).p_vaddr |
| @@ -875,17 +865,10 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 875 | for (n = 1, nn = 1; n < (int) old_file_h->e_shnum; n++, nn++) | 865 | for (n = 1, nn = 1; n < (int) old_file_h->e_shnum; n++, nn++) |
| 876 | { | 866 | { |
| 877 | caddr_t src; | 867 | caddr_t src; |
| 878 | int temp_index; | ||
| 879 | #if defined (HAS_SBSS_SECTION) | ||
| 880 | /* If it is (s)bss section, insert the new data2 section before it. */ | 868 | /* If it is (s)bss section, insert the new data2 section before it. */ |
| 881 | /* new_data2_index is the index of either old_sbss or old_bss, that was | 869 | /* new_data2_index is the index of either old_sbss or old_bss, that was |
| 882 | chosen as a section for new_data2. */ | 870 | chosen as a section for new_data2. */ |
| 883 | temp_index = new_data2_index; | 871 | if (n == new_data2_index) |
| 884 | #else /* not HAS_SBSS_SECTION */ | ||
| 885 | /* If it is bss section, insert the new data2 section before it. */ | ||
| 886 | temp_index = old_bss_index; | ||
| 887 | #endif /* not HAS_SBSS_SECTION */ | ||
| 888 | if (n == temp_index) | ||
| 889 | { | 872 | { |
| 890 | /* Steal the data section header for this data2 section. */ | 873 | /* Steal the data section header for this data2 section. */ |
| 891 | memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index), | 874 | memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index), |
| @@ -910,16 +893,16 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 910 | old_file_h->e_shentsize); | 893 | old_file_h->e_shentsize); |
| 911 | 894 | ||
| 912 | if (n == old_bss_index | 895 | if (n == old_bss_index |
| 913 | #if defined (HAS_SBSS_SECTION) | ||
| 914 | /* The new bss and sbss section's size is zero, and its file offset | 896 | /* The new bss and sbss section's size is zero, and its file offset |
| 915 | and virtual address should be off by NEW_DATA2_SIZE. */ | 897 | and virtual address should be off by NEW_DATA2_SIZE. */ |
| 916 | || n == old_sbss_index | 898 | || n == old_sbss_index |
| 917 | #endif /* HAS_SBSS_SECTION */ | ||
| 918 | ) | 899 | ) |
| 919 | { | 900 | { |
| 920 | /* NN should be `old_bss_index + 1' at this point. */ | 901 | /* NN should be `old_s?bss_index + 1' at this point. */ |
| 921 | NEW_SECTION_H (nn).sh_offset += new_data2_size; | 902 | NEW_SECTION_H (nn).sh_offset = |
| 922 | NEW_SECTION_H (nn).sh_addr += new_data2_size; | 903 | NEW_SECTION_H (new_data2_index).sh_offset + new_data2_size; |
| 904 | NEW_SECTION_H (nn).sh_addr = | ||
| 905 | NEW_SECTION_H (new_data2_index).sh_addr + new_data2_size; | ||
| 923 | /* Let the new bss section address alignment be the same as the | 906 | /* Let the new bss section address alignment be the same as the |
| 924 | section address alignment followed the old bss section, so | 907 | section address alignment followed the old bss section, so |
| 925 | this section will be placed in exactly the same place. */ | 908 | this section will be placed in exactly the same place. */ |
| @@ -975,18 +958,16 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 975 | ".data" in the strings table) get copied from the current process | 958 | ".data" in the strings table) get copied from the current process |
| 976 | instead of the old file. */ | 959 | instead of the old file. */ |
| 977 | if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data") | 960 | if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data") |
| 978 | #ifdef _nec_ews_svr4 /* hir, 1994.6.13 */ | ||
| 979 | || !strcmp ((old_section_names + NEW_SECTION_H(n).sh_name), | ||
| 980 | ".sdata") | ||
| 981 | #endif | ||
| 982 | #if defined (HAS_SBSS_SECTION) | ||
| 983 | || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), | 961 | || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), |
| 984 | ".sdata") | 962 | ".sdata") |
| 985 | || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), | 963 | || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), |
| 986 | ".lit4") | 964 | ".lit4") |
| 987 | || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), | 965 | || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), |
| 988 | ".lit8") | 966 | ".lit8") |
| 989 | #endif /* HAS_SBSS_SECTION */ | 967 | || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), |
| 968 | ".got") | ||
| 969 | || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), | ||
| 970 | ".sdata1") | ||
| 990 | || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), | 971 | || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name), |
| 991 | ".data1")) | 972 | ".data1")) |
| 992 | src = (caddr_t) OLD_SECTION_H (n).sh_addr; | 973 | src = (caddr_t) OLD_SECTION_H (n).sh_addr; |
| @@ -1040,6 +1021,62 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 1040 | } | 1021 | } |
| 1041 | } | 1022 | } |
| 1042 | #endif /* __sony_news && _SYSTYPE_SYSV */ | 1023 | #endif /* __sony_news && _SYSTYPE_SYSV */ |
| 1024 | |||
| 1025 | #if __sgi | ||
| 1026 | /* Adjust the HDRR offsets in .mdebug and copy the | ||
| 1027 | line data if it's in its usual 'hole' in the object. | ||
| 1028 | Makes the new file debuggable with dbx. | ||
| 1029 | patches up two problems: the absolute file offsets | ||
| 1030 | in the HDRR record of .mdebug (see /usr/include/syms.h), and | ||
| 1031 | the ld bug that gets the line table in a hole in the | ||
| 1032 | elf file rather than in the .mdebug section proper. | ||
| 1033 | David Anderson. davea@sgi.com Jan 16,1994. */ | ||
| 1034 | if (n == old_mdebug_index) | ||
| 1035 | { | ||
| 1036 | #define MDEBUGADJUST(__ct,__fileaddr) \ | ||
| 1037 | if (n_phdrr->__ct > 0) \ | ||
| 1038 | { \ | ||
| 1039 | n_phdrr->__fileaddr += movement; \ | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | HDRR * o_phdrr = (HDRR *)((byte *)old_base + OLD_SECTION_H (n).sh_offset); | ||
| 1043 | HDRR * n_phdrr = (HDRR *)((byte *)new_base + NEW_SECTION_H (nn).sh_offset); | ||
| 1044 | unsigned movement = new_data2_size; | ||
| 1045 | |||
| 1046 | MDEBUGADJUST (idnMax, cbDnOffset); | ||
| 1047 | MDEBUGADJUST (ipdMax, cbPdOffset); | ||
| 1048 | MDEBUGADJUST (isymMax, cbSymOffset); | ||
| 1049 | MDEBUGADJUST (ioptMax, cbOptOffset); | ||
| 1050 | MDEBUGADJUST (iauxMax, cbAuxOffset); | ||
| 1051 | MDEBUGADJUST (issMax, cbSsOffset); | ||
| 1052 | MDEBUGADJUST (issExtMax, cbSsExtOffset); | ||
| 1053 | MDEBUGADJUST (ifdMax, cbFdOffset); | ||
| 1054 | MDEBUGADJUST (crfd, cbRfdOffset); | ||
| 1055 | MDEBUGADJUST (iextMax, cbExtOffset); | ||
| 1056 | /* The Line Section, being possible off in a hole of the object, | ||
| 1057 | requires special handling. */ | ||
| 1058 | if (n_phdrr->cbLine > 0) | ||
| 1059 | { | ||
| 1060 | if (o_phdrr->cbLineOffset > (OLD_SECTION_H (n).sh_offset | ||
| 1061 | + OLD_SECTION_H (n).sh_size)) | ||
| 1062 | { | ||
| 1063 | /* line data is in a hole in elf. do special copy and adjust | ||
| 1064 | for this ld mistake. | ||
| 1065 | */ | ||
| 1066 | n_phdrr->cbLineOffset += movement; | ||
| 1067 | |||
| 1068 | memcpy (n_phdrr->cbLineOffset + new_base, | ||
| 1069 | o_phdrr->cbLineOffset + old_base, n_phdrr->cbLine); | ||
| 1070 | } | ||
| 1071 | else | ||
| 1072 | { | ||
| 1073 | /* somehow line data is in .mdebug as it is supposed to be. */ | ||
| 1074 | MDEBUGADJUST (cbLine, cbLineOffset); | ||
| 1075 | } | ||
| 1076 | } | ||
| 1077 | } | ||
| 1078 | #endif /* __sgi */ | ||
| 1079 | |||
| 1043 | /* If it is the symbol table, its st_shndx field needs to be patched. */ | 1080 | /* If it is the symbol table, its st_shndx field needs to be patched. */ |
| 1044 | if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB | 1081 | if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB |
| 1045 | || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) | 1082 | || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) |
| @@ -1099,6 +1136,16 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) | |||
| 1099 | nn = section.sh_info; | 1136 | nn = section.sh_info; |
| 1100 | if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data") | 1137 | if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data") |
| 1101 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | 1138 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), |
| 1139 | ".sdata") | ||
| 1140 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | ||
| 1141 | ".lit4") | ||
| 1142 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | ||
| 1143 | ".lit8") | ||
| 1144 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | ||
| 1145 | ".got") | ||
| 1146 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | ||
| 1147 | ".sdata1") | ||
| 1148 | || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), | ||
| 1102 | ".data1")) | 1149 | ".data1")) |
| 1103 | { | 1150 | { |
| 1104 | ElfW(Addr) offset = NEW_SECTION_H (nn).sh_addr - | 1151 | ElfW(Addr) offset = NEW_SECTION_H (nn).sh_addr - |