Mercurial > hg > CbC > CbC_gcc
comparison libiberty/simple-object-elf.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | 561a7518be6b |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* simple-object-elf.c -- routines to manipulate ELF object files. | 1 /* simple-object-elf.c -- routines to manipulate ELF object files. |
2 Copyright 2010 Free Software Foundation, Inc. | 2 Copyright (C) 2010-2017 Free Software Foundation, Inc. |
3 Written by Ian Lance Taylor, Google. | 3 Written by Ian Lance Taylor, Google. |
4 | 4 |
5 This program is free software; you can redistribute it and/or modify it | 5 This program is free software; you can redistribute it and/or modify it |
6 under the terms of the GNU General Public License as published by the | 6 under the terms of the GNU General Public License as published by the |
7 Free Software Foundation; either version 2, or (at your option) any | 7 Free Software Foundation; either version 2, or (at your option) any |
120 #define EM_SPARC 2 /* SUN SPARC */ | 120 #define EM_SPARC 2 /* SUN SPARC */ |
121 #define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ | 121 #define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ |
122 | 122 |
123 /* Special section index values. */ | 123 /* Special section index values. */ |
124 | 124 |
125 #define SHN_UNDEF 0 /* Undefined section */ | |
125 #define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */ | 126 #define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */ |
127 #define SHN_COMMON 0xFFF2 /* Associated symbol is in common */ | |
126 #define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */ | 128 #define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */ |
129 | |
127 | 130 |
128 /* 32-bit ELF program header. */ | 131 /* 32-bit ELF program header. */ |
129 | 132 |
130 typedef struct { | 133 typedef struct { |
131 unsigned char p_type[4]; /* Identifies program segment type */ | 134 unsigned char p_type[4]; /* Identifies program segment type */ |
181 unsigned char sh_entsize[8]; /* Entry size if section holds table */ | 184 unsigned char sh_entsize[8]; /* Entry size if section holds table */ |
182 } Elf64_External_Shdr; | 185 } Elf64_External_Shdr; |
183 | 186 |
184 /* Values for sh_type field. */ | 187 /* Values for sh_type field. */ |
185 | 188 |
189 #define SHT_NULL 0 /* Section header table entry unused */ | |
186 #define SHT_PROGBITS 1 /* Program data */ | 190 #define SHT_PROGBITS 1 /* Program data */ |
191 #define SHT_SYMTAB 2 /* Link editing symbol table */ | |
187 #define SHT_STRTAB 3 /* A string table */ | 192 #define SHT_STRTAB 3 /* A string table */ |
193 #define SHT_RELA 4 /* Relocation entries with addends */ | |
194 #define SHT_REL 9 /* Relocation entries, no addends */ | |
195 #define SHT_GROUP 17 /* Section contains a section group */ | |
196 | |
197 /* Values for sh_flags field. */ | |
198 | |
199 #define SHF_EXECINSTR 0x00000004 /* Executable section. */ | |
200 #define SHF_EXCLUDE 0x80000000 /* Link editor is to exclude this | |
201 section from executable and | |
202 shared library that it builds | |
203 when those objects are not to be | |
204 further relocated. */ | |
205 /* Symbol table entry. */ | |
206 | |
207 typedef struct | |
208 { | |
209 unsigned char st_name[4]; /* Symbol name (string tbl index) */ | |
210 unsigned char st_value[4]; /* Symbol value */ | |
211 unsigned char st_size[4]; /* Symbol size */ | |
212 unsigned char st_info; /* Symbol type and binding */ | |
213 unsigned char st_other; /* Symbol visibility */ | |
214 unsigned char st_shndx[2]; /* Section index */ | |
215 } Elf32_External_Sym; | |
216 | |
217 typedef struct | |
218 { | |
219 unsigned char st_name[4]; /* Symbol name (string tbl index) */ | |
220 unsigned char st_info; /* Symbol type and binding */ | |
221 unsigned char st_other; /* Symbol visibility */ | |
222 unsigned char st_shndx[2]; /* Section index */ | |
223 unsigned char st_value[8]; /* Symbol value */ | |
224 unsigned char st_size[8]; /* Symbol size */ | |
225 } Elf64_External_Sym; | |
226 | |
227 #define ELF_ST_BIND(val) (((unsigned char) (val)) >> 4) | |
228 #define ELF_ST_TYPE(val) ((val) & 0xf) | |
229 #define ELF_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) | |
230 | |
231 #define STT_NOTYPE 0 /* Symbol type is unspecified */ | |
232 #define STT_OBJECT 1 /* Symbol is a data object */ | |
233 #define STT_FUNC 2 /* Symbol is a code object */ | |
234 #define STT_TLS 6 /* Thread local data object */ | |
235 #define STT_GNU_IFUNC 10 /* Symbol is an indirect code object */ | |
236 | |
237 #define STB_LOCAL 0 /* Local symbol */ | |
238 #define STB_GLOBAL 1 /* Global symbol */ | |
239 #define STB_WEAK 2 /* Weak global */ | |
240 | |
241 #define STV_DEFAULT 0 /* Visibility is specified by binding type */ | |
242 #define STV_HIDDEN 2 /* Can only be seen inside currect component */ | |
188 | 243 |
189 /* Functions to fetch and store different ELF types, depending on the | 244 /* Functions to fetch and store different ELF types, depending on the |
190 endianness and size. */ | 245 endianness and size. */ |
191 | 246 |
192 struct elf_type_functions | 247 struct elf_type_functions |
346 unsigned short machine; | 401 unsigned short machine; |
347 /* Processor specific flags. */ | 402 /* Processor specific flags. */ |
348 unsigned int flags; | 403 unsigned int flags; |
349 }; | 404 }; |
350 | 405 |
406 /* Private data for an simple_object_write. */ | |
407 | |
408 struct simple_object_elf_write | |
409 { | |
410 struct simple_object_elf_attributes attrs; | |
411 unsigned char *shdrs; | |
412 }; | |
413 | |
351 /* See if we have an ELF file. */ | 414 /* See if we have an ELF file. */ |
352 | 415 |
353 static void * | 416 static void * |
354 simple_object_elf_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN], | 417 simple_object_elf_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN], |
355 int descriptor, off_t offset, | 418 int descriptor, off_t offset, |
673 const char **errmsg ATTRIBUTE_UNUSED, | 736 const char **errmsg ATTRIBUTE_UNUSED, |
674 int *err ATTRIBUTE_UNUSED) | 737 int *err ATTRIBUTE_UNUSED) |
675 { | 738 { |
676 struct simple_object_elf_attributes *attrs = | 739 struct simple_object_elf_attributes *attrs = |
677 (struct simple_object_elf_attributes *) attributes_data; | 740 (struct simple_object_elf_attributes *) attributes_data; |
678 struct simple_object_elf_attributes *ret; | 741 struct simple_object_elf_write *ret; |
679 | 742 |
680 /* We're just going to record the attributes, but we need to make a | 743 /* We're just going to record the attributes, but we need to make a |
681 copy because the user may delete them. */ | 744 copy because the user may delete them. */ |
682 ret = XNEW (struct simple_object_elf_attributes); | 745 ret = XNEW (struct simple_object_elf_write); |
683 *ret = *attrs; | 746 ret->attrs = *attrs; |
747 ret->shdrs = NULL; | |
684 return ret; | 748 return ret; |
685 } | 749 } |
686 | 750 |
687 /* Write out an ELF ehdr. */ | 751 /* Write out an ELF ehdr. */ |
688 | 752 |
696 unsigned char cl; | 760 unsigned char cl; |
697 size_t ehdr_size; | 761 size_t ehdr_size; |
698 unsigned char buf[sizeof (Elf64_External_Ehdr)]; | 762 unsigned char buf[sizeof (Elf64_External_Ehdr)]; |
699 simple_object_write_section *section; | 763 simple_object_write_section *section; |
700 unsigned int shnum; | 764 unsigned int shnum; |
765 unsigned int shstrndx; | |
701 | 766 |
702 fns = attrs->type_functions; | 767 fns = attrs->type_functions; |
703 cl = attrs->ei_class; | 768 cl = attrs->ei_class; |
704 | 769 |
705 shnum = 0; | 770 shnum = 0; |
741 /* e_phnum left as zero. */ | 806 /* e_phnum left as zero. */ |
742 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shentsize, Elf_Half, | 807 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shentsize, Elf_Half, |
743 (cl == ELFCLASS32 | 808 (cl == ELFCLASS32 |
744 ? sizeof (Elf32_External_Shdr) | 809 ? sizeof (Elf32_External_Shdr) |
745 : sizeof (Elf64_External_Shdr))); | 810 : sizeof (Elf64_External_Shdr))); |
746 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shnum, Elf_Half, shnum); | 811 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shnum, Elf_Half, |
747 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shstrndx, Elf_Half, | 812 shnum >= SHN_LORESERVE ? 0 : shnum); |
748 shnum == 0 ? 0 : shnum - 1); | 813 if (shnum == 0) |
814 shstrndx = 0; | |
815 else | |
816 { | |
817 shstrndx = shnum - 1; | |
818 if (shstrndx >= SHN_LORESERVE) | |
819 shstrndx = SHN_XINDEX; | |
820 } | |
821 ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shstrndx, Elf_Half, shstrndx); | |
749 | 822 |
750 return simple_object_internal_write (descriptor, 0, buf, ehdr_size, | 823 return simple_object_internal_write (descriptor, 0, buf, ehdr_size, |
751 errmsg, err); | 824 errmsg, err); |
752 } | 825 } |
753 | 826 |
755 | 828 |
756 static int | 829 static int |
757 simple_object_elf_write_shdr (simple_object_write *sobj, int descriptor, | 830 simple_object_elf_write_shdr (simple_object_write *sobj, int descriptor, |
758 off_t offset, unsigned int sh_name, | 831 off_t offset, unsigned int sh_name, |
759 unsigned int sh_type, unsigned int sh_flags, | 832 unsigned int sh_type, unsigned int sh_flags, |
833 off_t sh_addr, | |
760 unsigned int sh_offset, unsigned int sh_size, | 834 unsigned int sh_offset, unsigned int sh_size, |
761 unsigned int sh_addralign, const char **errmsg, | 835 unsigned int sh_link, unsigned int sh_info, |
762 int *err) | 836 size_t sh_addralign, |
837 size_t sh_entsize, | |
838 const char **errmsg, int *err) | |
763 { | 839 { |
764 struct simple_object_elf_attributes *attrs = | 840 struct simple_object_elf_attributes *attrs = |
765 (struct simple_object_elf_attributes *) sobj->data; | 841 (struct simple_object_elf_attributes *) sobj->data; |
766 const struct elf_type_functions* fns; | 842 const struct elf_type_functions* fns; |
767 unsigned char cl; | 843 unsigned char cl; |
777 memset (buf, 0, sizeof (Elf64_External_Shdr)); | 853 memset (buf, 0, sizeof (Elf64_External_Shdr)); |
778 | 854 |
779 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_name, Elf_Word, sh_name); | 855 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_name, Elf_Word, sh_name); |
780 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_type, Elf_Word, sh_type); | 856 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_type, Elf_Word, sh_type); |
781 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_flags, Elf_Addr, sh_flags); | 857 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_flags, Elf_Addr, sh_flags); |
858 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_addr, Elf_Addr, sh_addr); | |
782 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_offset, Elf_Addr, sh_offset); | 859 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_offset, Elf_Addr, sh_offset); |
783 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_size, Elf_Addr, sh_size); | 860 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_size, Elf_Addr, sh_size); |
784 /* sh_link left as zero. */ | 861 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_link, Elf_Word, sh_link); |
785 /* sh_info left as zero. */ | 862 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_info, Elf_Word, sh_info); |
786 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_addralign, Elf_Addr, sh_addralign); | 863 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_addralign, Elf_Addr, sh_addralign); |
787 /* sh_entsize left as zero. */ | 864 ELF_SET_FIELD (fns, cl, Shdr, buf, sh_entsize, Elf_Addr, sh_entsize); |
788 | 865 |
789 return simple_object_internal_write (descriptor, offset, buf, shdr_size, | 866 return simple_object_internal_write (descriptor, offset, buf, shdr_size, |
790 errmsg, err); | 867 errmsg, err); |
791 } | 868 } |
792 | 869 |
800 | 877 |
801 static const char * | 878 static const char * |
802 simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor, | 879 simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor, |
803 int *err) | 880 int *err) |
804 { | 881 { |
805 struct simple_object_elf_attributes *attrs = | 882 struct simple_object_elf_write *eow = |
806 (struct simple_object_elf_attributes *) sobj->data; | 883 (struct simple_object_elf_write *) sobj->data; |
884 struct simple_object_elf_attributes *attrs = &eow->attrs; | |
807 unsigned char cl; | 885 unsigned char cl; |
808 size_t ehdr_size; | 886 size_t ehdr_size; |
809 size_t shdr_size; | 887 size_t shdr_size; |
810 const char *errmsg; | 888 const char *errmsg; |
811 simple_object_write_section *section; | 889 simple_object_write_section *section; |
812 unsigned int shnum; | 890 unsigned int shnum; |
813 size_t shdr_offset; | 891 size_t shdr_offset; |
814 size_t sh_offset; | 892 size_t sh_offset; |
893 unsigned int first_sh_size; | |
894 unsigned int first_sh_link; | |
815 size_t sh_name; | 895 size_t sh_name; |
816 unsigned char zero; | 896 unsigned char zero; |
897 unsigned secnum; | |
817 | 898 |
818 if (!simple_object_elf_write_ehdr (sobj, descriptor, &errmsg, err)) | 899 if (!simple_object_elf_write_ehdr (sobj, descriptor, &errmsg, err)) |
819 return errmsg; | 900 return errmsg; |
820 | 901 |
821 cl = attrs->ei_class; | 902 cl = attrs->ei_class; |
840 shnum += 2; | 921 shnum += 2; |
841 | 922 |
842 shdr_offset = ehdr_size; | 923 shdr_offset = ehdr_size; |
843 sh_offset = shdr_offset + shnum * shdr_size; | 924 sh_offset = shdr_offset + shnum * shdr_size; |
844 | 925 |
926 if (shnum < SHN_LORESERVE) | |
927 first_sh_size = 0; | |
928 else | |
929 first_sh_size = shnum; | |
930 if (shnum - 1 < SHN_LORESERVE) | |
931 first_sh_link = 0; | |
932 else | |
933 first_sh_link = shnum - 1; | |
845 if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset, | 934 if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset, |
846 0, 0, 0, 0, 0, 0, &errmsg, err)) | 935 0, 0, 0, 0, 0, first_sh_size, first_sh_link, |
936 0, 0, 0, &errmsg, err)) | |
847 return errmsg; | 937 return errmsg; |
848 | 938 |
849 shdr_offset += shdr_size; | 939 shdr_offset += shdr_size; |
850 | 940 |
851 sh_name = 1; | 941 sh_name = 1; |
942 secnum = 0; | |
852 for (section = sobj->sections; section != NULL; section = section->next) | 943 for (section = sobj->sections; section != NULL; section = section->next) |
853 { | 944 { |
854 size_t mask; | 945 size_t mask; |
855 size_t new_sh_offset; | 946 size_t new_sh_offset; |
856 size_t sh_size; | 947 size_t sh_size; |
857 struct simple_object_write_section_buffer *buffer; | 948 struct simple_object_write_section_buffer *buffer; |
858 | 949 unsigned int sh_type = SHT_PROGBITS; |
859 mask = (1U << section->align) - 1; | 950 unsigned int sh_flags = 0; |
951 off_t sh_addr = 0; | |
952 unsigned int sh_link = 0; | |
953 unsigned int sh_info = 0; | |
954 size_t sh_addralign = 1U << section->align; | |
955 size_t sh_entsize = 0; | |
956 if (eow->shdrs) | |
957 { | |
958 sh_type = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr, | |
959 eow->shdrs + secnum * shdr_size, | |
960 sh_type, Elf_Word); | |
961 sh_flags = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr, | |
962 eow->shdrs + secnum * shdr_size, | |
963 sh_flags, Elf_Addr); | |
964 sh_addr = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr, | |
965 eow->shdrs + secnum * shdr_size, | |
966 sh_addr, Elf_Addr); | |
967 sh_link = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr, | |
968 eow->shdrs + secnum * shdr_size, | |
969 sh_link, Elf_Word); | |
970 sh_info = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr, | |
971 eow->shdrs + secnum * shdr_size, | |
972 sh_info, Elf_Word); | |
973 sh_addralign = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr, | |
974 eow->shdrs + secnum * shdr_size, | |
975 sh_addralign, Elf_Addr); | |
976 sh_entsize = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr, | |
977 eow->shdrs + secnum * shdr_size, | |
978 sh_entsize, Elf_Addr); | |
979 secnum++; | |
980 } | |
981 | |
982 mask = sh_addralign - 1; | |
860 new_sh_offset = sh_offset + mask; | 983 new_sh_offset = sh_offset + mask; |
861 new_sh_offset &= ~ mask; | 984 new_sh_offset &= ~ mask; |
862 while (new_sh_offset > sh_offset) | 985 while (new_sh_offset > sh_offset) |
863 { | 986 { |
864 unsigned char zeroes[16]; | 987 unsigned char zeroes[16]; |
884 return errmsg; | 1007 return errmsg; |
885 sh_size += buffer->size; | 1008 sh_size += buffer->size; |
886 } | 1009 } |
887 | 1010 |
888 if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset, | 1011 if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset, |
889 sh_name, SHT_PROGBITS, 0, sh_offset, | 1012 sh_name, sh_type, sh_flags, |
890 sh_size, 1U << section->align, | 1013 sh_addr, sh_offset, |
1014 sh_size, sh_link, sh_info, | |
1015 sh_addralign, sh_entsize, | |
891 &errmsg, err)) | 1016 &errmsg, err)) |
892 return errmsg; | 1017 return errmsg; |
893 | 1018 |
894 shdr_offset += shdr_size; | 1019 shdr_offset += shdr_size; |
895 sh_name += strlen (section->name) + 1; | 1020 sh_name += strlen (section->name) + 1; |
896 sh_offset += sh_size; | 1021 sh_offset += sh_size; |
897 } | 1022 } |
898 | 1023 |
899 if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset, | 1024 if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset, |
900 sh_name, SHT_STRTAB, 0, sh_offset, | 1025 sh_name, SHT_STRTAB, 0, 0, sh_offset, |
901 sh_name + strlen (".shstrtab") + 1, | 1026 sh_name + strlen (".shstrtab") + 1, 0, 0, |
902 1, &errmsg, err)) | 1027 1, 0, &errmsg, err)) |
903 return errmsg; | 1028 return errmsg; |
904 | 1029 |
905 /* .shstrtab has a leading zero byte. */ | 1030 /* .shstrtab has a leading zero byte. */ |
906 zero = 0; | 1031 zero = 0; |
907 if (!simple_object_internal_write (descriptor, sh_offset, &zero, 1, | 1032 if (!simple_object_internal_write (descriptor, sh_offset, &zero, 1, |
932 /* Release the private data for an simple_object_write structure. */ | 1057 /* Release the private data for an simple_object_write structure. */ |
933 | 1058 |
934 static void | 1059 static void |
935 simple_object_elf_release_write (void *data) | 1060 simple_object_elf_release_write (void *data) |
936 { | 1061 { |
1062 struct simple_object_elf_write *eow = (struct simple_object_elf_write *) data; | |
1063 if (eow->shdrs) | |
1064 XDELETE (eow->shdrs); | |
937 XDELETE (data); | 1065 XDELETE (data); |
938 } | 1066 } |
1067 | |
1068 /* Copy all sections in an ELF file. */ | |
1069 | |
1070 static const char * | |
1071 simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, | |
1072 simple_object_write *dobj, | |
1073 int (*pfn) (const char **), | |
1074 int *err) | |
1075 { | |
1076 struct simple_object_elf_read *eor = | |
1077 (struct simple_object_elf_read *) sobj->data; | |
1078 const struct elf_type_functions *type_functions = eor->type_functions; | |
1079 struct simple_object_elf_write *eow = | |
1080 (struct simple_object_elf_write *) dobj->data; | |
1081 unsigned char ei_class = eor->ei_class; | |
1082 size_t shdr_size; | |
1083 unsigned int shnum; | |
1084 unsigned char *shdrs; | |
1085 const char *errmsg; | |
1086 unsigned char *shstrhdr; | |
1087 size_t name_size; | |
1088 off_t shstroff; | |
1089 unsigned char *names; | |
1090 unsigned int i; | |
1091 int changed; | |
1092 int *pfnret; | |
1093 const char **pfnname; | |
1094 | |
1095 shdr_size = (ei_class == ELFCLASS32 | |
1096 ? sizeof (Elf32_External_Shdr) | |
1097 : sizeof (Elf64_External_Shdr)); | |
1098 | |
1099 /* Read the section headers. We skip section 0, which is not a | |
1100 useful section. */ | |
1101 | |
1102 shnum = eor->shnum; | |
1103 shdrs = XNEWVEC (unsigned char, shdr_size * (shnum - 1)); | |
1104 | |
1105 if (!simple_object_internal_read (sobj->descriptor, | |
1106 sobj->offset + eor->shoff + shdr_size, | |
1107 shdrs, | |
1108 shdr_size * (shnum - 1), | |
1109 &errmsg, err)) | |
1110 { | |
1111 XDELETEVEC (shdrs); | |
1112 return errmsg; | |
1113 } | |
1114 | |
1115 /* Read the section names. */ | |
1116 | |
1117 shstrhdr = shdrs + (eor->shstrndx - 1) * shdr_size; | |
1118 name_size = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1119 shstrhdr, sh_size, Elf_Addr); | |
1120 shstroff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1121 shstrhdr, sh_offset, Elf_Addr); | |
1122 names = XNEWVEC (unsigned char, name_size); | |
1123 if (!simple_object_internal_read (sobj->descriptor, | |
1124 sobj->offset + shstroff, | |
1125 names, name_size, &errmsg, err)) | |
1126 { | |
1127 XDELETEVEC (names); | |
1128 XDELETEVEC (shdrs); | |
1129 return errmsg; | |
1130 } | |
1131 | |
1132 eow->shdrs = XNEWVEC (unsigned char, shdr_size * (shnum - 1)); | |
1133 pfnret = XNEWVEC (int, shnum); | |
1134 pfnname = XNEWVEC (const char *, shnum); | |
1135 | |
1136 /* First perform the callbacks to know which sections to preserve and | |
1137 what name to use for those. */ | |
1138 for (i = 1; i < shnum; ++i) | |
1139 { | |
1140 unsigned char *shdr; | |
1141 unsigned int sh_name; | |
1142 const char *name; | |
1143 int ret; | |
1144 | |
1145 shdr = shdrs + (i - 1) * shdr_size; | |
1146 sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1147 shdr, sh_name, Elf_Word); | |
1148 if (sh_name >= name_size) | |
1149 { | |
1150 *err = 0; | |
1151 XDELETEVEC (names); | |
1152 XDELETEVEC (shdrs); | |
1153 return "ELF section name out of range"; | |
1154 } | |
1155 | |
1156 name = (const char *) names + sh_name; | |
1157 | |
1158 ret = (*pfn) (&name); | |
1159 pfnret[i - 1] = ret == 1 ? 0 : -1; | |
1160 pfnname[i - 1] = name; | |
1161 } | |
1162 | |
1163 /* Mark sections as preserved that are required by to be preserved | |
1164 sections. */ | |
1165 do | |
1166 { | |
1167 changed = 0; | |
1168 for (i = 1; i < shnum; ++i) | |
1169 { | |
1170 unsigned char *shdr; | |
1171 unsigned int sh_type, sh_info, sh_link; | |
1172 off_t offset; | |
1173 off_t length; | |
1174 | |
1175 shdr = shdrs + (i - 1) * shdr_size; | |
1176 sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1177 shdr, sh_type, Elf_Word); | |
1178 sh_info = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1179 shdr, sh_info, Elf_Word); | |
1180 sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1181 shdr, sh_link, Elf_Word); | |
1182 if (sh_type == SHT_GROUP) | |
1183 { | |
1184 /* Mark groups containing copied sections. */ | |
1185 unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class, | |
1186 Shdr, shdr, sh_entsize, | |
1187 Elf_Addr); | |
1188 unsigned char *ent, *buf; | |
1189 int keep = 0; | |
1190 offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1191 shdr, sh_offset, Elf_Addr); | |
1192 length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1193 shdr, sh_size, Elf_Addr); | |
1194 buf = XNEWVEC (unsigned char, length); | |
1195 if (!simple_object_internal_read (sobj->descriptor, | |
1196 sobj->offset + offset, buf, | |
1197 (size_t) length, &errmsg, err)) | |
1198 { | |
1199 XDELETEVEC (buf); | |
1200 XDELETEVEC (names); | |
1201 XDELETEVEC (shdrs); | |
1202 return errmsg; | |
1203 } | |
1204 for (ent = buf + entsize; ent < buf + length; ent += entsize) | |
1205 { | |
1206 unsigned sec = type_functions->fetch_Elf_Word (ent); | |
1207 if (pfnret[sec - 1] == 0) | |
1208 keep = 1; | |
1209 } | |
1210 if (keep) | |
1211 { | |
1212 changed |= (pfnret[sh_link - 1] == -1 | |
1213 || pfnret[i - 1] == -1); | |
1214 pfnret[sh_link - 1] = 0; | |
1215 pfnret[i - 1] = 0; | |
1216 } | |
1217 } | |
1218 if (sh_type == SHT_RELA | |
1219 || sh_type == SHT_REL) | |
1220 { | |
1221 /* Mark relocation sections and symtab of copied sections. */ | |
1222 if (pfnret[sh_info - 1] == 0) | |
1223 { | |
1224 changed |= (pfnret[sh_link - 1] == -1 | |
1225 || pfnret[i - 1] == -1); | |
1226 pfnret[sh_link - 1] = 0; | |
1227 pfnret[i - 1] = 0; | |
1228 } | |
1229 } | |
1230 if (sh_type == SHT_SYMTAB) | |
1231 { | |
1232 /* Mark strings sections of copied symtabs. */ | |
1233 if (pfnret[i - 1] == 0) | |
1234 { | |
1235 changed |= pfnret[sh_link - 1] == -1; | |
1236 pfnret[sh_link - 1] = 0; | |
1237 } | |
1238 } | |
1239 } | |
1240 } | |
1241 while (changed); | |
1242 | |
1243 /* Then perform the actual copying. */ | |
1244 for (i = 1; i < shnum; ++i) | |
1245 { | |
1246 unsigned char *shdr; | |
1247 unsigned int sh_name, sh_type; | |
1248 const char *name; | |
1249 off_t offset; | |
1250 off_t length; | |
1251 int ret; | |
1252 simple_object_write_section *dest; | |
1253 off_t flags; | |
1254 unsigned char *buf; | |
1255 | |
1256 shdr = shdrs + (i - 1) * shdr_size; | |
1257 sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1258 shdr, sh_name, Elf_Word); | |
1259 if (sh_name >= name_size) | |
1260 { | |
1261 *err = 0; | |
1262 XDELETEVEC (names); | |
1263 XDELETEVEC (shdrs); | |
1264 return "ELF section name out of range"; | |
1265 } | |
1266 | |
1267 name = (const char *) names + sh_name; | |
1268 offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1269 shdr, sh_offset, Elf_Addr); | |
1270 length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1271 shdr, sh_size, Elf_Addr); | |
1272 sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1273 shdr, sh_type, Elf_Word); | |
1274 | |
1275 ret = pfnret[i - 1]; | |
1276 name = ret == 0 ? pfnname[i - 1] : ""; | |
1277 | |
1278 dest = simple_object_write_create_section (dobj, name, 0, &errmsg, err); | |
1279 if (dest == NULL) | |
1280 { | |
1281 XDELETEVEC (names); | |
1282 XDELETEVEC (shdrs); | |
1283 return errmsg; | |
1284 } | |
1285 | |
1286 /* Record the SHDR of the source. */ | |
1287 memcpy (eow->shdrs + (i - 1) * shdr_size, shdr, shdr_size); | |
1288 shdr = eow->shdrs + (i - 1) * shdr_size; | |
1289 | |
1290 /* Copy the data. | |
1291 ??? This is quite wasteful and ideally would be delayed until | |
1292 write_to_file (). Thus it questions the interfacing | |
1293 which eventually should contain destination creation plus | |
1294 writing. */ | |
1295 /* Keep empty sections for sections we should discard. This avoids | |
1296 the need to rewrite section indices in symtab and relocation | |
1297 sections. */ | |
1298 if (ret == 0) | |
1299 { | |
1300 buf = XNEWVEC (unsigned char, length); | |
1301 if (!simple_object_internal_read (sobj->descriptor, | |
1302 sobj->offset + offset, buf, | |
1303 (size_t) length, &errmsg, err)) | |
1304 { | |
1305 XDELETEVEC (buf); | |
1306 XDELETEVEC (names); | |
1307 XDELETEVEC (shdrs); | |
1308 return errmsg; | |
1309 } | |
1310 | |
1311 /* If we are processing .symtab purge __gnu_lto_v1 and | |
1312 __gnu_lto_slim symbols from it. */ | |
1313 if (sh_type == SHT_SYMTAB) | |
1314 { | |
1315 unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1316 shdr, sh_entsize, Elf_Addr); | |
1317 unsigned strtab = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1318 shdr, sh_link, Elf_Word); | |
1319 unsigned char *strshdr = shdrs + (strtab - 1) * shdr_size; | |
1320 off_t stroff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1321 strshdr, sh_offset, Elf_Addr); | |
1322 size_t strsz = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1323 strshdr, sh_size, Elf_Addr); | |
1324 char *strings = XNEWVEC (char, strsz); | |
1325 unsigned char *ent; | |
1326 simple_object_internal_read (sobj->descriptor, | |
1327 sobj->offset + stroff, | |
1328 (unsigned char *)strings, | |
1329 strsz, &errmsg, err); | |
1330 for (ent = buf; ent < buf + length; ent += entsize) | |
1331 { | |
1332 unsigned st_shndx = ELF_FETCH_FIELD (type_functions, ei_class, | |
1333 Sym, ent, | |
1334 st_shndx, Elf_Half); | |
1335 unsigned char *st_info; | |
1336 unsigned char *st_other; | |
1337 int discard = 0; | |
1338 if (ei_class == ELFCLASS32) | |
1339 { | |
1340 st_info = &((Elf32_External_Sym *)ent)->st_info; | |
1341 st_other = &((Elf32_External_Sym *)ent)->st_other; | |
1342 } | |
1343 else | |
1344 { | |
1345 st_info = &((Elf64_External_Sym *)ent)->st_info; | |
1346 st_other = &((Elf64_External_Sym *)ent)->st_other; | |
1347 } | |
1348 /* Eliminate all COMMONs - this includes __gnu_lto_v1 | |
1349 and __gnu_lto_slim which otherwise cause endless | |
1350 LTO plugin invocation. */ | |
1351 if (st_shndx == SHN_COMMON) | |
1352 discard = 1; | |
1353 /* We also need to remove symbols refering to sections | |
1354 we'll eventually remove as with fat LTO objects | |
1355 we otherwise get duplicate symbols at final link | |
1356 (with GNU ld, gold is fine and ignores symbols in | |
1357 sections marked as EXCLUDE). ld/20513 */ | |
1358 else if (st_shndx != SHN_UNDEF | |
1359 && st_shndx < shnum | |
1360 && pfnret[st_shndx - 1] == -1) | |
1361 discard = 1; | |
1362 | |
1363 if (discard) | |
1364 { | |
1365 /* Make discarded symbols undefined and unnamed | |
1366 in case it is local. */ | |
1367 int bind = ELF_ST_BIND (*st_info); | |
1368 int other = STV_DEFAULT; | |
1369 size_t st_name; | |
1370 | |
1371 if (bind == STB_LOCAL) | |
1372 ELF_SET_FIELD (type_functions, ei_class, Sym, | |
1373 ent, st_name, Elf_Word, 0); | |
1374 else | |
1375 { | |
1376 bind = STB_WEAK; | |
1377 st_name = ELF_FETCH_FIELD (type_functions, ei_class, | |
1378 Sym, ent, st_name, | |
1379 Elf_Word); | |
1380 if (st_name < strsz) | |
1381 { | |
1382 char *p = strings + st_name; | |
1383 if (p[0] == '_' | |
1384 && p[1] == '_' | |
1385 && strncmp (p + (p[2] == '_'), | |
1386 "__gnu_lto_", 10) == 0) | |
1387 other = STV_HIDDEN; | |
1388 } | |
1389 } | |
1390 *st_other = other; | |
1391 *st_info = ELF_ST_INFO (bind, STT_NOTYPE); | |
1392 ELF_SET_FIELD (type_functions, ei_class, Sym, | |
1393 ent, st_value, Elf_Addr, 0); | |
1394 ELF_SET_FIELD (type_functions, ei_class, Sym, | |
1395 ent, st_size, Elf_Word, 0); | |
1396 ELF_SET_FIELD (type_functions, ei_class, Sym, | |
1397 ent, st_shndx, Elf_Half, SHN_UNDEF); | |
1398 } | |
1399 } | |
1400 XDELETEVEC (strings); | |
1401 } | |
1402 | |
1403 errmsg = simple_object_write_add_data (dobj, dest, | |
1404 buf, length, 1, err); | |
1405 XDELETEVEC (buf); | |
1406 if (errmsg) | |
1407 { | |
1408 XDELETEVEC (names); | |
1409 XDELETEVEC (shdrs); | |
1410 return errmsg; | |
1411 } | |
1412 } | |
1413 else | |
1414 { | |
1415 /* For deleted sections mark the section header table entry as | |
1416 unused. That allows the link editor to remove it in a partial | |
1417 link. */ | |
1418 ELF_SET_FIELD (type_functions, ei_class, Shdr, | |
1419 shdr, sh_type, Elf_Word, SHT_NULL); | |
1420 } | |
1421 | |
1422 flags = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, | |
1423 shdr, sh_flags, Elf_Addr); | |
1424 if (ret == 0) | |
1425 { | |
1426 /* The debugobj doesn't contain any code, thus no trampolines. | |
1427 Even when the original object needs trampolines, debugobj | |
1428 doesn't. */ | |
1429 if (strcmp (name, ".note.GNU-stack") == 0) | |
1430 flags &= ~SHF_EXECINSTR; | |
1431 flags &= ~SHF_EXCLUDE; | |
1432 } | |
1433 else if (ret == -1) | |
1434 flags = SHF_EXCLUDE; | |
1435 ELF_SET_FIELD (type_functions, ei_class, Shdr, | |
1436 shdr, sh_flags, Elf_Addr, flags); | |
1437 } | |
1438 | |
1439 XDELETEVEC (names); | |
1440 XDELETEVEC (shdrs); | |
1441 XDELETEVEC (pfnret); | |
1442 XDELETEVEC (pfnname); | |
1443 | |
1444 return NULL; | |
1445 } | |
1446 | |
939 | 1447 |
940 /* The ELF functions. */ | 1448 /* The ELF functions. */ |
941 | 1449 |
942 const struct simple_object_functions simple_object_elf_functions = | 1450 const struct simple_object_functions simple_object_elf_functions = |
943 { | 1451 { |
947 simple_object_elf_release_read, | 1455 simple_object_elf_release_read, |
948 simple_object_elf_attributes_merge, | 1456 simple_object_elf_attributes_merge, |
949 simple_object_elf_release_attributes, | 1457 simple_object_elf_release_attributes, |
950 simple_object_elf_start_write, | 1458 simple_object_elf_start_write, |
951 simple_object_elf_write_to_file, | 1459 simple_object_elf_write_to_file, |
952 simple_object_elf_release_write | 1460 simple_object_elf_release_write, |
1461 simple_object_elf_copy_lto_debug_sections | |
953 }; | 1462 }; |