aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKarl Heuer1999-08-25 16:15:29 +0000
committerKarl Heuer1999-08-25 16:15:29 +0000
commitbc597cc7be83a24e93ee9c032993389003d6ff5f (patch)
treec43494ae333ebd96113326b69ac72d3b6c001205 /src
parent3bc0ab9fdd82e52ce98ff01abb3ee40e780bde5b (diff)
downloademacs-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.c145
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
587ElfW(Addr) 581static ElfW(Addr)
588round_up (x, y) 582round_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 -