1 1.1 christos /* simple-object-elf.c -- routines to manipulate ELF object files. 2 1.10 christos Copyright (C) 2010-2025 Free Software Foundation, Inc. 3 1.1 christos Written by Ian Lance Taylor, Google. 4 1.1 christos 5 1.1 christos This program is free software; you can redistribute it and/or modify it 6 1.1 christos under the terms of the GNU General Public License as published by the 7 1.1 christos Free Software Foundation; either version 2, or (at your option) any 8 1.1 christos later version. 9 1.1 christos 10 1.1 christos This program is distributed in the hope that it will be useful, 11 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 12 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 1.1 christos GNU General Public License for more details. 14 1.1 christos 15 1.1 christos You should have received a copy of the GNU General Public License 16 1.1 christos along with this program; if not, write to the Free Software 17 1.1 christos Foundation, 51 Franklin Street - Fifth Floor, 18 1.1 christos Boston, MA 02110-1301, USA. */ 19 1.1 christos 20 1.1 christos #include "config.h" 21 1.1 christos #include "libiberty.h" 22 1.1 christos #include "simple-object.h" 23 1.1 christos 24 1.1 christos #include <errno.h> 25 1.7 christos /* mingw.org's MinGW doesn't have ENOTSUP. */ 26 1.7 christos #ifndef ENOTSUP 27 1.7 christos # define ENOTSUP ENOSYS 28 1.7 christos #endif 29 1.1 christos #include <stddef.h> 30 1.1 christos 31 1.1 christos #ifdef HAVE_STDLIB_H 32 1.1 christos #include <stdlib.h> 33 1.1 christos #endif 34 1.1 christos 35 1.1 christos #ifdef HAVE_STDINT_H 36 1.1 christos #include <stdint.h> 37 1.1 christos #endif 38 1.1 christos 39 1.1 christos #ifdef HAVE_STRING_H 40 1.1 christos #include <string.h> 41 1.1 christos #endif 42 1.1 christos 43 1.1 christos #ifdef HAVE_INTTYPES_H 44 1.1 christos #include <inttypes.h> 45 1.1 christos #endif 46 1.1 christos 47 1.1 christos #include "simple-object-common.h" 48 1.1 christos 49 1.1 christos /* ELF structures and constants. */ 50 1.1 christos 51 1.1 christos /* 32-bit ELF file header. */ 52 1.1 christos 53 1.1 christos typedef struct { 54 1.1 christos unsigned char e_ident[16]; /* ELF "magic number" */ 55 1.1 christos unsigned char e_type[2]; /* Identifies object file type */ 56 1.1 christos unsigned char e_machine[2]; /* Specifies required architecture */ 57 1.1 christos unsigned char e_version[4]; /* Identifies object file version */ 58 1.1 christos unsigned char e_entry[4]; /* Entry point virtual address */ 59 1.1 christos unsigned char e_phoff[4]; /* Program header table file offset */ 60 1.1 christos unsigned char e_shoff[4]; /* Section header table file offset */ 61 1.1 christos unsigned char e_flags[4]; /* Processor-specific flags */ 62 1.1 christos unsigned char e_ehsize[2]; /* ELF header size in bytes */ 63 1.1 christos unsigned char e_phentsize[2]; /* Program header table entry size */ 64 1.1 christos unsigned char e_phnum[2]; /* Program header table entry count */ 65 1.1 christos unsigned char e_shentsize[2]; /* Section header table entry size */ 66 1.1 christos unsigned char e_shnum[2]; /* Section header table entry count */ 67 1.1 christos unsigned char e_shstrndx[2]; /* Section header string table index */ 68 1.1 christos } Elf32_External_Ehdr; 69 1.1 christos 70 1.1 christos /* 64-bit ELF file header. */ 71 1.1 christos 72 1.1 christos typedef struct { 73 1.1 christos unsigned char e_ident[16]; /* ELF "magic number" */ 74 1.1 christos unsigned char e_type[2]; /* Identifies object file type */ 75 1.1 christos unsigned char e_machine[2]; /* Specifies required architecture */ 76 1.1 christos unsigned char e_version[4]; /* Identifies object file version */ 77 1.1 christos unsigned char e_entry[8]; /* Entry point virtual address */ 78 1.1 christos unsigned char e_phoff[8]; /* Program header table file offset */ 79 1.1 christos unsigned char e_shoff[8]; /* Section header table file offset */ 80 1.1 christos unsigned char e_flags[4]; /* Processor-specific flags */ 81 1.1 christos unsigned char e_ehsize[2]; /* ELF header size in bytes */ 82 1.1 christos unsigned char e_phentsize[2]; /* Program header table entry size */ 83 1.1 christos unsigned char e_phnum[2]; /* Program header table entry count */ 84 1.1 christos unsigned char e_shentsize[2]; /* Section header table entry size */ 85 1.1 christos unsigned char e_shnum[2]; /* Section header table entry count */ 86 1.1 christos unsigned char e_shstrndx[2]; /* Section header string table index */ 87 1.1 christos } Elf64_External_Ehdr; 88 1.1 christos 89 1.1 christos /* Indexes and values in e_ident field of Ehdr. */ 90 1.1 christos 91 1.1 christos #define EI_MAG0 0 /* File identification byte 0 index */ 92 1.1 christos #define ELFMAG0 0x7F /* Magic number byte 0 */ 93 1.1 christos 94 1.1 christos #define EI_MAG1 1 /* File identification byte 1 index */ 95 1.1 christos #define ELFMAG1 'E' /* Magic number byte 1 */ 96 1.1 christos 97 1.1 christos #define EI_MAG2 2 /* File identification byte 2 index */ 98 1.1 christos #define ELFMAG2 'L' /* Magic number byte 2 */ 99 1.1 christos 100 1.1 christos #define EI_MAG3 3 /* File identification byte 3 index */ 101 1.1 christos #define ELFMAG3 'F' /* Magic number byte 3 */ 102 1.1 christos 103 1.1 christos #define EI_CLASS 4 /* File class */ 104 1.1 christos #define ELFCLASSNONE 0 /* Invalid class */ 105 1.1 christos #define ELFCLASS32 1 /* 32-bit objects */ 106 1.1 christos #define ELFCLASS64 2 /* 64-bit objects */ 107 1.1 christos 108 1.1 christos #define EI_DATA 5 /* Data encoding */ 109 1.1 christos #define ELFDATANONE 0 /* Invalid data encoding */ 110 1.1 christos #define ELFDATA2LSB 1 /* 2's complement, little endian */ 111 1.1 christos #define ELFDATA2MSB 2 /* 2's complement, big endian */ 112 1.1 christos 113 1.1 christos #define EI_VERSION 6 /* File version */ 114 1.1 christos #define EV_CURRENT 1 /* Current version */ 115 1.1 christos 116 1.1 christos #define EI_OSABI 7 /* Operating System/ABI indication */ 117 1.1 christos 118 1.1 christos /* Values for e_type field of Ehdr. */ 119 1.1 christos 120 1.1 christos #define ET_REL 1 /* Relocatable file */ 121 1.1 christos 122 1.1 christos /* Values for e_machine field of Ehdr. */ 123 1.1 christos 124 1.1 christos #define EM_SPARC 2 /* SUN SPARC */ 125 1.1 christos #define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ 126 1.1 christos 127 1.1 christos /* Special section index values. */ 128 1.1 christos 129 1.6 christos #define SHN_UNDEF 0 /* Undefined section */ 130 1.1 christos #define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */ 131 1.10 christos #define SHN_COMMON 0xFFF2 /* Associated symbol is in common */ 132 1.1 christos #define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */ 133 1.10 christos #define SHN_HIRESERVE 0xFFFF /* End of reserved indices */ 134 1.6 christos 135 1.1 christos 136 1.1 christos /* 32-bit ELF program header. */ 137 1.1 christos 138 1.1 christos typedef struct { 139 1.1 christos unsigned char p_type[4]; /* Identifies program segment type */ 140 1.1 christos unsigned char p_offset[4]; /* Segment file offset */ 141 1.1 christos unsigned char p_vaddr[4]; /* Segment virtual address */ 142 1.1 christos unsigned char p_paddr[4]; /* Segment physical address */ 143 1.1 christos unsigned char p_filesz[4]; /* Segment size in file */ 144 1.1 christos unsigned char p_memsz[4]; /* Segment size in memory */ 145 1.1 christos unsigned char p_flags[4]; /* Segment flags */ 146 1.1 christos unsigned char p_align[4]; /* Segment alignment, file & memory */ 147 1.1 christos } Elf32_External_Phdr; 148 1.1 christos 149 1.1 christos /* 64-bit ELF program header. */ 150 1.1 christos 151 1.1 christos typedef struct { 152 1.1 christos unsigned char p_type[4]; /* Identifies program segment type */ 153 1.1 christos unsigned char p_flags[4]; /* Segment flags */ 154 1.1 christos unsigned char p_offset[8]; /* Segment file offset */ 155 1.1 christos unsigned char p_vaddr[8]; /* Segment virtual address */ 156 1.1 christos unsigned char p_paddr[8]; /* Segment physical address */ 157 1.1 christos unsigned char p_filesz[8]; /* Segment size in file */ 158 1.1 christos unsigned char p_memsz[8]; /* Segment size in memory */ 159 1.1 christos unsigned char p_align[8]; /* Segment alignment, file & memory */ 160 1.1 christos } Elf64_External_Phdr; 161 1.1 christos 162 1.1 christos /* 32-bit ELF section header */ 163 1.1 christos 164 1.1 christos typedef struct { 165 1.1 christos unsigned char sh_name[4]; /* Section name, index in string tbl */ 166 1.1 christos unsigned char sh_type[4]; /* Type of section */ 167 1.1 christos unsigned char sh_flags[4]; /* Miscellaneous section attributes */ 168 1.1 christos unsigned char sh_addr[4]; /* Section virtual addr at execution */ 169 1.1 christos unsigned char sh_offset[4]; /* Section file offset */ 170 1.1 christos unsigned char sh_size[4]; /* Size of section in bytes */ 171 1.1 christos unsigned char sh_link[4]; /* Index of another section */ 172 1.1 christos unsigned char sh_info[4]; /* Additional section information */ 173 1.1 christos unsigned char sh_addralign[4]; /* Section alignment */ 174 1.1 christos unsigned char sh_entsize[4]; /* Entry size if section holds table */ 175 1.1 christos } Elf32_External_Shdr; 176 1.1 christos 177 1.1 christos /* 64-bit ELF section header. */ 178 1.1 christos 179 1.1 christos typedef struct { 180 1.1 christos unsigned char sh_name[4]; /* Section name, index in string tbl */ 181 1.1 christos unsigned char sh_type[4]; /* Type of section */ 182 1.1 christos unsigned char sh_flags[8]; /* Miscellaneous section attributes */ 183 1.1 christos unsigned char sh_addr[8]; /* Section virtual addr at execution */ 184 1.1 christos unsigned char sh_offset[8]; /* Section file offset */ 185 1.1 christos unsigned char sh_size[8]; /* Size of section in bytes */ 186 1.1 christos unsigned char sh_link[4]; /* Index of another section */ 187 1.1 christos unsigned char sh_info[4]; /* Additional section information */ 188 1.1 christos unsigned char sh_addralign[8]; /* Section alignment */ 189 1.1 christos unsigned char sh_entsize[8]; /* Entry size if section holds table */ 190 1.1 christos } Elf64_External_Shdr; 191 1.1 christos 192 1.1 christos /* Values for sh_type field. */ 193 1.1 christos 194 1.6 christos #define SHT_NULL 0 /* Section header table entry unused */ 195 1.1 christos #define SHT_PROGBITS 1 /* Program data */ 196 1.6 christos #define SHT_SYMTAB 2 /* Link editing symbol table */ 197 1.1 christos #define SHT_STRTAB 3 /* A string table */ 198 1.6 christos #define SHT_RELA 4 /* Relocation entries with addends */ 199 1.6 christos #define SHT_REL 9 /* Relocation entries, no addends */ 200 1.6 christos #define SHT_GROUP 17 /* Section contains a section group */ 201 1.6 christos #define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ 202 1.6 christos 203 1.6 christos /* Values for sh_flags field. */ 204 1.6 christos 205 1.6 christos #define SHF_INFO_LINK 0x00000040 /* `sh_info' contains SHT index */ 206 1.6 christos #define SHF_EXECINSTR 0x00000004 /* Executable section. */ 207 1.6 christos #define SHF_EXCLUDE 0x80000000 /* Link editor is to exclude this 208 1.6 christos section from executable and 209 1.6 christos shared library that it builds 210 1.6 christos when those objects are not to be 211 1.6 christos further relocated. */ 212 1.6 christos /* Symbol table entry. */ 213 1.6 christos 214 1.6 christos typedef struct 215 1.6 christos { 216 1.6 christos unsigned char st_name[4]; /* Symbol name (string tbl index) */ 217 1.6 christos unsigned char st_value[4]; /* Symbol value */ 218 1.6 christos unsigned char st_size[4]; /* Symbol size */ 219 1.6 christos unsigned char st_info; /* Symbol type and binding */ 220 1.6 christos unsigned char st_other; /* Symbol visibility */ 221 1.6 christos unsigned char st_shndx[2]; /* Section index */ 222 1.6 christos } Elf32_External_Sym; 223 1.6 christos 224 1.6 christos typedef struct 225 1.6 christos { 226 1.6 christos unsigned char st_name[4]; /* Symbol name (string tbl index) */ 227 1.6 christos unsigned char st_info; /* Symbol type and binding */ 228 1.6 christos unsigned char st_other; /* Symbol visibility */ 229 1.6 christos unsigned char st_shndx[2]; /* Section index */ 230 1.6 christos unsigned char st_value[8]; /* Symbol value */ 231 1.6 christos unsigned char st_size[8]; /* Symbol size */ 232 1.6 christos } Elf64_External_Sym; 233 1.6 christos 234 1.6 christos #define ELF_ST_BIND(val) (((unsigned char) (val)) >> 4) 235 1.6 christos #define ELF_ST_TYPE(val) ((val) & 0xf) 236 1.6 christos #define ELF_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) 237 1.6 christos 238 1.6 christos #define STT_NOTYPE 0 /* Symbol type is unspecified */ 239 1.6 christos #define STT_OBJECT 1 /* Symbol is a data object */ 240 1.6 christos #define STT_FUNC 2 /* Symbol is a code object */ 241 1.6 christos #define STT_TLS 6 /* Thread local data object */ 242 1.6 christos #define STT_GNU_IFUNC 10 /* Symbol is an indirect code object */ 243 1.6 christos 244 1.6 christos #define STB_LOCAL 0 /* Local symbol */ 245 1.6 christos #define STB_GLOBAL 1 /* Global symbol */ 246 1.6 christos #define STB_WEAK 2 /* Weak global */ 247 1.6 christos 248 1.6 christos #define STV_DEFAULT 0 /* Visibility is specified by binding type */ 249 1.6 christos #define STV_HIDDEN 2 /* Can only be seen inside currect component */ 250 1.1 christos 251 1.1 christos /* Functions to fetch and store different ELF types, depending on the 252 1.1 christos endianness and size. */ 253 1.1 christos 254 1.1 christos struct elf_type_functions 255 1.1 christos { 256 1.1 christos unsigned short (*fetch_Elf_Half) (const unsigned char *); 257 1.1 christos unsigned int (*fetch_Elf_Word) (const unsigned char *); 258 1.1 christos ulong_type (*fetch_Elf_Addr) (const unsigned char *); 259 1.1 christos void (*set_Elf_Half) (unsigned char *, unsigned short); 260 1.1 christos void (*set_Elf_Word) (unsigned char *, unsigned int); 261 1.1 christos void (*set_Elf_Addr) (unsigned char *, ulong_type); 262 1.1 christos }; 263 1.1 christos 264 1.1 christos static const struct elf_type_functions elf_big_32_functions = 265 1.1 christos { 266 1.1 christos simple_object_fetch_big_16, 267 1.1 christos simple_object_fetch_big_32, 268 1.1 christos simple_object_fetch_big_32_ulong, 269 1.1 christos simple_object_set_big_16, 270 1.1 christos simple_object_set_big_32, 271 1.1 christos simple_object_set_big_32_ulong 272 1.1 christos }; 273 1.1 christos 274 1.1 christos static const struct elf_type_functions elf_little_32_functions = 275 1.1 christos { 276 1.1 christos simple_object_fetch_little_16, 277 1.1 christos simple_object_fetch_little_32, 278 1.1 christos simple_object_fetch_little_32_ulong, 279 1.1 christos simple_object_set_little_16, 280 1.1 christos simple_object_set_little_32, 281 1.1 christos simple_object_set_little_32_ulong 282 1.1 christos }; 283 1.1 christos 284 1.1 christos #ifdef UNSIGNED_64BIT_TYPE 285 1.1 christos 286 1.1 christos static const struct elf_type_functions elf_big_64_functions = 287 1.1 christos { 288 1.1 christos simple_object_fetch_big_16, 289 1.1 christos simple_object_fetch_big_32, 290 1.1 christos simple_object_fetch_big_64, 291 1.1 christos simple_object_set_big_16, 292 1.1 christos simple_object_set_big_32, 293 1.1 christos simple_object_set_big_64 294 1.1 christos }; 295 1.1 christos 296 1.1 christos static const struct elf_type_functions elf_little_64_functions = 297 1.1 christos { 298 1.1 christos simple_object_fetch_little_16, 299 1.1 christos simple_object_fetch_little_32, 300 1.1 christos simple_object_fetch_little_64, 301 1.1 christos simple_object_set_little_16, 302 1.1 christos simple_object_set_little_32, 303 1.1 christos simple_object_set_little_64 304 1.1 christos }; 305 1.1 christos 306 1.1 christos #endif 307 1.1 christos 308 1.1 christos /* Hideous macro to fetch the value of a field from an external ELF 309 1.1 christos struct of some sort. TYPEFUNCS is the set of type functions. 310 1.1 christos BUFFER points to the external data. STRUCTTYPE is the appropriate 311 1.1 christos struct type. FIELD is a field within the struct. TYPE is the type 312 1.1 christos of the field in the struct: Elf_Half, Elf_Word, or Elf_Addr. */ 313 1.1 christos 314 1.1 christos #define ELF_FETCH_STRUCT_FIELD(TYPEFUNCS, STRUCTTYPE, FIELD, BUFFER, TYPE) \ 315 1.1 christos ((TYPEFUNCS)->fetch_ ## TYPE ((BUFFER) + offsetof (STRUCTTYPE, FIELD))) 316 1.1 christos 317 1.1 christos /* Even more hideous macro to fetch the value of FIELD from BUFFER. 318 1.1 christos SIZE is 32 or 64. STRUCTTYPE is the name of the struct from 319 1.1 christos elf/external.h: Ehdr, Shdr, etc. FIELD is the name of a field in 320 1.1 christos the struct. TYPE is the type of the field in the struct: Elf_Half, 321 1.1 christos Elf_Word, or Elf_Addr. */ 322 1.1 christos 323 1.1 christos #define ELF_FETCH_SIZED_FIELD(TYPEFUNCS, SIZE, STRUCTTYPE, BUFFER, \ 324 1.1 christos FIELD, TYPE) \ 325 1.1 christos ELF_FETCH_STRUCT_FIELD (TYPEFUNCS, \ 326 1.1 christos Elf ## SIZE ## _External_ ## STRUCTTYPE, \ 327 1.1 christos FIELD, BUFFER, TYPE) 328 1.1 christos 329 1.1 christos /* Like ELF_FETCH_SIZED_FIELD but taking an ELFCLASS value. */ 330 1.1 christos 331 1.1 christos #define ELF_FETCH_FIELD(TYPEFUNCS, CLASS, STRUCTTYPE, BUFFER, \ 332 1.1 christos FIELD, TYPE) \ 333 1.1 christos ((CLASS) == ELFCLASS32 \ 334 1.1 christos ? ELF_FETCH_SIZED_FIELD (TYPEFUNCS, 32, STRUCTTYPE, BUFFER, FIELD, \ 335 1.1 christos TYPE) \ 336 1.1 christos : ELF_FETCH_SIZED_FIELD (TYPEFUNCS, 64, STRUCTTYPE, BUFFER, FIELD, \ 337 1.1 christos TYPE)) 338 1.1 christos 339 1.1 christos /* Hideous macro to set the value of a field in an external ELF 340 1.1 christos structure to VAL. TYPEFUNCS is the set of type functions. BUFFER 341 1.1 christos points to the external data. STRUCTTYPE is the appropriate 342 1.1 christos structure type. FIELD is a field within the struct. TYPE is the 343 1.1 christos type of the field in the struct: Elf_Half, Elf_Word, or 344 1.1 christos Elf_Addr. */ 345 1.1 christos 346 1.1 christos #define ELF_SET_STRUCT_FIELD(TYPEFUNCS, STRUCTTYPE, FIELD, BUFFER, TYPE, VAL) \ 347 1.1 christos (TYPEFUNCS)->set_ ## TYPE ((BUFFER) + offsetof (STRUCTTYPE, FIELD), (VAL)) 348 1.1 christos 349 1.1 christos /* Even more hideous macro to set the value of FIELD in BUFFER to VAL. 350 1.1 christos SIZE is 32 or 64. STRUCTTYPE is the name of the struct from 351 1.1 christos elf/external.h: Ehdr, Shdr, etc. FIELD is the name of a field in 352 1.1 christos the struct. TYPE is the type of the field in the struct: Elf_Half, 353 1.1 christos Elf_Word, or Elf_Addr. */ 354 1.1 christos 355 1.1 christos #define ELF_SET_SIZED_FIELD(TYPEFUNCS, SIZE, STRUCTTYPE, BUFFER, FIELD, \ 356 1.1 christos TYPE, VAL) \ 357 1.1 christos ELF_SET_STRUCT_FIELD (TYPEFUNCS, \ 358 1.1 christos Elf ## SIZE ## _External_ ## STRUCTTYPE, \ 359 1.1 christos FIELD, BUFFER, TYPE, VAL) 360 1.1 christos 361 1.1 christos /* Like ELF_SET_SIZED_FIELD but taking an ELFCLASS value. */ 362 1.1 christos 363 1.1 christos #define ELF_SET_FIELD(TYPEFUNCS, CLASS, STRUCTTYPE, BUFFER, FIELD, \ 364 1.1 christos TYPE, VAL) \ 365 1.1 christos ((CLASS) == ELFCLASS32 \ 366 1.1 christos ? ELF_SET_SIZED_FIELD (TYPEFUNCS, 32, STRUCTTYPE, BUFFER, FIELD, \ 367 1.1 christos TYPE, VAL) \ 368 1.1 christos : ELF_SET_SIZED_FIELD (TYPEFUNCS, 64, STRUCTTYPE, BUFFER, FIELD, \ 369 1.1 christos TYPE, VAL)) 370 1.1 christos 371 1.1 christos /* Private data for an simple_object_read. */ 372 1.1 christos 373 1.1 christos struct simple_object_elf_read 374 1.1 christos { 375 1.1 christos /* Type functions. */ 376 1.1 christos const struct elf_type_functions* type_functions; 377 1.1 christos /* Elf data. */ 378 1.1 christos unsigned char ei_data; 379 1.1 christos /* Elf class. */ 380 1.1 christos unsigned char ei_class; 381 1.1 christos /* ELF OS ABI. */ 382 1.1 christos unsigned char ei_osabi; 383 1.1 christos /* Elf machine number. */ 384 1.1 christos unsigned short machine; 385 1.1 christos /* Processor specific flags. */ 386 1.1 christos unsigned int flags; 387 1.1 christos /* File offset of section headers. */ 388 1.1 christos ulong_type shoff; 389 1.1 christos /* Number of sections. */ 390 1.1 christos unsigned int shnum; 391 1.1 christos /* Index of string table section header. */ 392 1.1 christos unsigned int shstrndx; 393 1.1 christos }; 394 1.1 christos 395 1.1 christos /* Private data for an simple_object_attributes. */ 396 1.1 christos 397 1.1 christos struct simple_object_elf_attributes 398 1.1 christos { 399 1.1 christos /* Type functions. */ 400 1.1 christos const struct elf_type_functions* type_functions; 401 1.1 christos /* Elf data. */ 402 1.1 christos unsigned char ei_data; 403 1.1 christos /* Elf class. */ 404 1.1 christos unsigned char ei_class; 405 1.1 christos /* ELF OS ABI. */ 406 1.1 christos unsigned char ei_osabi; 407 1.1 christos /* Elf machine number. */ 408 1.1 christos unsigned short machine; 409 1.1 christos /* Processor specific flags. */ 410 1.1 christos unsigned int flags; 411 1.1 christos }; 412 1.1 christos 413 1.6 christos /* Private data for an simple_object_write. */ 414 1.6 christos 415 1.6 christos struct simple_object_elf_write 416 1.6 christos { 417 1.6 christos struct simple_object_elf_attributes attrs; 418 1.6 christos unsigned char *shdrs; 419 1.6 christos }; 420 1.6 christos 421 1.1 christos /* See if we have an ELF file. */ 422 1.1 christos 423 1.1 christos static void * 424 1.1 christos simple_object_elf_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN], 425 1.1 christos int descriptor, off_t offset, 426 1.1 christos const char *segment_name ATTRIBUTE_UNUSED, 427 1.1 christos const char **errmsg, int *err) 428 1.1 christos { 429 1.1 christos unsigned char ei_data; 430 1.1 christos unsigned char ei_class; 431 1.1 christos const struct elf_type_functions *type_functions; 432 1.1 christos unsigned char ehdr[sizeof (Elf64_External_Ehdr)]; 433 1.1 christos struct simple_object_elf_read *eor; 434 1.1 christos 435 1.1 christos if (header[EI_MAG0] != ELFMAG0 436 1.1 christos || header[EI_MAG1] != ELFMAG1 437 1.1 christos || header[EI_MAG2] != ELFMAG2 438 1.1 christos || header[EI_MAG3] != ELFMAG3 439 1.1 christos || header[EI_VERSION] != EV_CURRENT) 440 1.1 christos { 441 1.1 christos *errmsg = NULL; 442 1.1 christos *err = 0; 443 1.1 christos return NULL; 444 1.1 christos } 445 1.1 christos 446 1.1 christos ei_data = header[EI_DATA]; 447 1.1 christos if (ei_data != ELFDATA2LSB && ei_data != ELFDATA2MSB) 448 1.1 christos { 449 1.1 christos *errmsg = "unknown ELF endianness"; 450 1.1 christos *err = 0; 451 1.1 christos return NULL; 452 1.1 christos } 453 1.1 christos 454 1.1 christos ei_class = header[EI_CLASS]; 455 1.1 christos switch (ei_class) 456 1.1 christos { 457 1.1 christos case ELFCLASS32: 458 1.1 christos type_functions = (ei_data == ELFDATA2LSB 459 1.1 christos ? &elf_little_32_functions 460 1.1 christos : &elf_big_32_functions); 461 1.1 christos break; 462 1.1 christos 463 1.1 christos case ELFCLASS64: 464 1.1 christos #ifndef UNSIGNED_64BIT_TYPE 465 1.1 christos *errmsg = "64-bit ELF objects not supported"; 466 1.1 christos *err = 0; 467 1.1 christos return NULL; 468 1.1 christos #else 469 1.1 christos type_functions = (ei_data == ELFDATA2LSB 470 1.1 christos ? &elf_little_64_functions 471 1.1 christos : &elf_big_64_functions); 472 1.1 christos break; 473 1.1 christos #endif 474 1.1 christos 475 1.1 christos default: 476 1.1 christos *errmsg = "unrecognized ELF size"; 477 1.1 christos *err = 0; 478 1.1 christos return NULL; 479 1.1 christos } 480 1.1 christos 481 1.1 christos if (!simple_object_internal_read (descriptor, offset, ehdr, sizeof ehdr, 482 1.1 christos errmsg, err)) 483 1.1 christos return NULL; 484 1.1 christos 485 1.1 christos eor = XNEW (struct simple_object_elf_read); 486 1.1 christos eor->type_functions = type_functions; 487 1.1 christos eor->ei_data = ei_data; 488 1.1 christos eor->ei_class = ei_class; 489 1.1 christos eor->ei_osabi = header[EI_OSABI]; 490 1.1 christos eor->machine = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr, 491 1.1 christos e_machine, Elf_Half); 492 1.1 christos eor->flags = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr, 493 1.1 christos e_flags, Elf_Word); 494 1.1 christos eor->shoff = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr, 495 1.1 christos e_shoff, Elf_Addr); 496 1.1 christos eor->shnum = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr, 497 1.1 christos e_shnum, Elf_Half); 498 1.1 christos eor->shstrndx = ELF_FETCH_FIELD (type_functions, ei_class, Ehdr, ehdr, 499 1.1 christos e_shstrndx, Elf_Half); 500 1.1 christos 501 1.1 christos if ((eor->shnum == 0 || eor->shstrndx == SHN_XINDEX) 502 1.1 christos && eor->shoff != 0) 503 1.1 christos { 504 1.1 christos unsigned char shdr[sizeof (Elf64_External_Shdr)]; 505 1.1 christos 506 1.1 christos /* Object file has more than 0xffff sections. */ 507 1.1 christos 508 1.1 christos if (!simple_object_internal_read (descriptor, offset + eor->shoff, shdr, 509 1.1 christos (ei_class == ELFCLASS32 510 1.1 christos ? sizeof (Elf32_External_Shdr) 511 1.1 christos : sizeof (Elf64_External_Shdr)), 512 1.1 christos errmsg, err)) 513 1.1 christos { 514 1.1 christos XDELETE (eor); 515 1.1 christos return NULL; 516 1.1 christos } 517 1.1 christos 518 1.1 christos if (eor->shnum == 0) 519 1.1 christos eor->shnum = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 520 1.1 christos shdr, sh_size, Elf_Addr); 521 1.1 christos 522 1.1 christos if (eor->shstrndx == SHN_XINDEX) 523 1.1 christos { 524 1.1 christos eor->shstrndx = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 525 1.1 christos shdr, sh_link, Elf_Word); 526 1.1 christos 527 1.1 christos /* Versions of the GNU binutils between 2.12 and 2.18 did 528 1.1 christos not handle objects with more than SHN_LORESERVE sections 529 1.1 christos correctly. All large section indexes were offset by 530 1.1 christos 0x100. There is more information at 531 1.8 christos https://sourceware.org/PR5900 . 532 1.1 christos Fortunately these object files are easy to detect, as the 533 1.1 christos GNU binutils always put the section header string table 534 1.1 christos near the end of the list of sections. Thus if the 535 1.1 christos section header string table index is larger than the 536 1.1 christos number of sections, then we know we have to subtract 537 1.1 christos 0x100 to get the real section index. */ 538 1.1 christos if (eor->shstrndx >= eor->shnum 539 1.1 christos && eor->shstrndx >= SHN_LORESERVE + 0x100) 540 1.1 christos eor->shstrndx -= 0x100; 541 1.1 christos } 542 1.1 christos } 543 1.1 christos 544 1.1 christos if (eor->shstrndx >= eor->shnum) 545 1.1 christos { 546 1.1 christos *errmsg = "invalid ELF shstrndx >= shnum"; 547 1.1 christos *err = 0; 548 1.1 christos XDELETE (eor); 549 1.1 christos return NULL; 550 1.1 christos } 551 1.7 christos 552 1.7 christos if (eor->shstrndx == 0) 553 1.7 christos { 554 1.7 christos *errmsg = "invalid ELF shstrndx == 0"; 555 1.7 christos *err = 0; 556 1.7 christos XDELETE (eor); 557 1.7 christos return NULL; 558 1.7 christos } 559 1.7 christos 560 1.1 christos return (void *) eor; 561 1.1 christos } 562 1.1 christos 563 1.1 christos /* Find all sections in an ELF file. */ 564 1.1 christos 565 1.1 christos static const char * 566 1.1 christos simple_object_elf_find_sections (simple_object_read *sobj, 567 1.1 christos int (*pfn) (void *, const char *, 568 1.1 christos off_t offset, off_t length), 569 1.1 christos void *data, 570 1.1 christos int *err) 571 1.1 christos { 572 1.10 christos struct simple_object_elf_read *eor 573 1.10 christos = (struct simple_object_elf_read *) sobj->data; 574 1.1 christos const struct elf_type_functions *type_functions = eor->type_functions; 575 1.1 christos unsigned char ei_class = eor->ei_class; 576 1.1 christos size_t shdr_size; 577 1.1 christos unsigned int shnum; 578 1.1 christos unsigned char *shdrs; 579 1.1 christos const char *errmsg; 580 1.1 christos unsigned char *shstrhdr; 581 1.1 christos size_t name_size; 582 1.1 christos off_t shstroff; 583 1.1 christos unsigned char *names; 584 1.1 christos unsigned int i; 585 1.1 christos 586 1.1 christos shdr_size = (ei_class == ELFCLASS32 587 1.1 christos ? sizeof (Elf32_External_Shdr) 588 1.1 christos : sizeof (Elf64_External_Shdr)); 589 1.1 christos 590 1.1 christos /* Read the section headers. We skip section 0, which is not a 591 1.1 christos useful section. */ 592 1.1 christos 593 1.1 christos shnum = eor->shnum; 594 1.1 christos shdrs = XNEWVEC (unsigned char, shdr_size * (shnum - 1)); 595 1.1 christos 596 1.1 christos if (!simple_object_internal_read (sobj->descriptor, 597 1.1 christos sobj->offset + eor->shoff + shdr_size, 598 1.1 christos shdrs, 599 1.1 christos shdr_size * (shnum - 1), 600 1.1 christos &errmsg, err)) 601 1.1 christos { 602 1.1 christos XDELETEVEC (shdrs); 603 1.1 christos return errmsg; 604 1.1 christos } 605 1.1 christos 606 1.1 christos /* Read the section names. */ 607 1.1 christos 608 1.1 christos shstrhdr = shdrs + (eor->shstrndx - 1) * shdr_size; 609 1.1 christos name_size = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 610 1.1 christos shstrhdr, sh_size, Elf_Addr); 611 1.1 christos shstroff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 612 1.1 christos shstrhdr, sh_offset, Elf_Addr); 613 1.1 christos names = XNEWVEC (unsigned char, name_size); 614 1.1 christos if (!simple_object_internal_read (sobj->descriptor, 615 1.1 christos sobj->offset + shstroff, 616 1.1 christos names, name_size, &errmsg, err)) 617 1.1 christos { 618 1.1 christos XDELETEVEC (names); 619 1.1 christos XDELETEVEC (shdrs); 620 1.1 christos return errmsg; 621 1.1 christos } 622 1.1 christos 623 1.1 christos for (i = 1; i < shnum; ++i) 624 1.1 christos { 625 1.1 christos unsigned char *shdr; 626 1.1 christos unsigned int sh_name; 627 1.1 christos const char *name; 628 1.1 christos off_t offset; 629 1.1 christos off_t length; 630 1.1 christos 631 1.1 christos shdr = shdrs + (i - 1) * shdr_size; 632 1.1 christos sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 633 1.1 christos shdr, sh_name, Elf_Word); 634 1.1 christos if (sh_name >= name_size) 635 1.1 christos { 636 1.1 christos *err = 0; 637 1.1 christos XDELETEVEC (names); 638 1.1 christos XDELETEVEC (shdrs); 639 1.1 christos return "ELF section name out of range"; 640 1.1 christos } 641 1.1 christos 642 1.1 christos name = (const char *) names + sh_name; 643 1.1 christos offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 644 1.1 christos shdr, sh_offset, Elf_Addr); 645 1.1 christos length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 646 1.1 christos shdr, sh_size, Elf_Addr); 647 1.1 christos 648 1.1 christos if (!(*pfn) (data, name, offset, length)) 649 1.1 christos break; 650 1.1 christos } 651 1.1 christos 652 1.1 christos XDELETEVEC (names); 653 1.1 christos XDELETEVEC (shdrs); 654 1.1 christos 655 1.1 christos return NULL; 656 1.1 christos } 657 1.1 christos 658 1.1 christos /* Fetch the attributes for an simple_object_read. */ 659 1.1 christos 660 1.1 christos static void * 661 1.1 christos simple_object_elf_fetch_attributes (simple_object_read *sobj, 662 1.1 christos const char **errmsg ATTRIBUTE_UNUSED, 663 1.1 christos int *err ATTRIBUTE_UNUSED) 664 1.1 christos { 665 1.10 christos struct simple_object_elf_read *eor 666 1.10 christos = (struct simple_object_elf_read *) sobj->data; 667 1.1 christos struct simple_object_elf_attributes *ret; 668 1.1 christos 669 1.1 christos ret = XNEW (struct simple_object_elf_attributes); 670 1.1 christos ret->type_functions = eor->type_functions; 671 1.1 christos ret->ei_data = eor->ei_data; 672 1.1 christos ret->ei_class = eor->ei_class; 673 1.1 christos ret->ei_osabi = eor->ei_osabi; 674 1.1 christos ret->machine = eor->machine; 675 1.1 christos ret->flags = eor->flags; 676 1.1 christos return ret; 677 1.1 christos } 678 1.1 christos 679 1.1 christos /* Release the privata data for an simple_object_read. */ 680 1.1 christos 681 1.1 christos static void 682 1.1 christos simple_object_elf_release_read (void *data) 683 1.1 christos { 684 1.1 christos XDELETE (data); 685 1.1 christos } 686 1.1 christos 687 1.1 christos /* Compare two attributes structures. */ 688 1.1 christos 689 1.1 christos static const char * 690 1.1 christos simple_object_elf_attributes_merge (void *todata, void *fromdata, int *err) 691 1.1 christos { 692 1.10 christos struct simple_object_elf_attributes *to 693 1.10 christos = (struct simple_object_elf_attributes *) todata; 694 1.10 christos struct simple_object_elf_attributes *from 695 1.10 christos = (struct simple_object_elf_attributes *) fromdata; 696 1.1 christos 697 1.1 christos if (to->ei_data != from->ei_data || to->ei_class != from->ei_class) 698 1.1 christos { 699 1.1 christos *err = 0; 700 1.1 christos return "ELF object format mismatch"; 701 1.1 christos } 702 1.1 christos 703 1.1 christos if (to->machine != from->machine) 704 1.1 christos { 705 1.1 christos int ok; 706 1.1 christos 707 1.1 christos /* EM_SPARC and EM_SPARC32PLUS are compatible and force an 708 1.1 christos output of EM_SPARC32PLUS. */ 709 1.1 christos ok = 0; 710 1.1 christos switch (to->machine) 711 1.1 christos { 712 1.1 christos case EM_SPARC: 713 1.1 christos if (from->machine == EM_SPARC32PLUS) 714 1.1 christos { 715 1.1 christos to->machine = from->machine; 716 1.1 christos ok = 1; 717 1.1 christos } 718 1.1 christos break; 719 1.1 christos 720 1.1 christos case EM_SPARC32PLUS: 721 1.1 christos if (from->machine == EM_SPARC) 722 1.1 christos ok = 1; 723 1.1 christos break; 724 1.1 christos 725 1.1 christos default: 726 1.1 christos break; 727 1.1 christos } 728 1.1 christos 729 1.1 christos if (!ok) 730 1.1 christos { 731 1.1 christos *err = 0; 732 1.1 christos return "ELF machine number mismatch"; 733 1.1 christos } 734 1.1 christos } 735 1.1 christos 736 1.1 christos return NULL; 737 1.1 christos } 738 1.1 christos 739 1.1 christos /* Release the private data for an attributes structure. */ 740 1.1 christos 741 1.1 christos static void 742 1.1 christos simple_object_elf_release_attributes (void *data) 743 1.1 christos { 744 1.1 christos XDELETE (data); 745 1.1 christos } 746 1.1 christos 747 1.1 christos /* Prepare to write out a file. */ 748 1.1 christos 749 1.1 christos static void * 750 1.1 christos simple_object_elf_start_write (void *attributes_data, 751 1.1 christos const char **errmsg ATTRIBUTE_UNUSED, 752 1.1 christos int *err ATTRIBUTE_UNUSED) 753 1.1 christos { 754 1.10 christos struct simple_object_elf_attributes *attrs 755 1.10 christos = (struct simple_object_elf_attributes *) attributes_data; 756 1.6 christos struct simple_object_elf_write *ret; 757 1.1 christos 758 1.1 christos /* We're just going to record the attributes, but we need to make a 759 1.1 christos copy because the user may delete them. */ 760 1.6 christos ret = XNEW (struct simple_object_elf_write); 761 1.6 christos ret->attrs = *attrs; 762 1.6 christos ret->shdrs = NULL; 763 1.1 christos return ret; 764 1.1 christos } 765 1.1 christos 766 1.1 christos /* Write out an ELF ehdr. */ 767 1.1 christos 768 1.1 christos static int 769 1.1 christos simple_object_elf_write_ehdr (simple_object_write *sobj, int descriptor, 770 1.1 christos const char **errmsg, int *err) 771 1.1 christos { 772 1.10 christos struct simple_object_elf_attributes *attrs 773 1.10 christos = (struct simple_object_elf_attributes *) sobj->data; 774 1.1 christos const struct elf_type_functions* fns; 775 1.1 christos unsigned char cl; 776 1.1 christos size_t ehdr_size; 777 1.1 christos unsigned char buf[sizeof (Elf64_External_Ehdr)]; 778 1.1 christos simple_object_write_section *section; 779 1.1 christos unsigned int shnum; 780 1.3 christos unsigned int shstrndx; 781 1.1 christos 782 1.1 christos fns = attrs->type_functions; 783 1.1 christos cl = attrs->ei_class; 784 1.1 christos 785 1.1 christos shnum = 0; 786 1.1 christos for (section = sobj->sections; section != NULL; section = section->next) 787 1.1 christos ++shnum; 788 1.1 christos if (shnum > 0) 789 1.1 christos { 790 1.1 christos /* Add a section header for the dummy section and one for 791 1.1 christos .shstrtab. */ 792 1.1 christos shnum += 2; 793 1.1 christos } 794 1.1 christos 795 1.1 christos ehdr_size = (cl == ELFCLASS32 796 1.1 christos ? sizeof (Elf32_External_Ehdr) 797 1.1 christos : sizeof (Elf64_External_Ehdr)); 798 1.1 christos memset (buf, 0, sizeof (Elf64_External_Ehdr)); 799 1.1 christos 800 1.1 christos buf[EI_MAG0] = ELFMAG0; 801 1.1 christos buf[EI_MAG1] = ELFMAG1; 802 1.1 christos buf[EI_MAG2] = ELFMAG2; 803 1.1 christos buf[EI_MAG3] = ELFMAG3; 804 1.1 christos buf[EI_CLASS] = cl; 805 1.1 christos buf[EI_DATA] = attrs->ei_data; 806 1.1 christos buf[EI_VERSION] = EV_CURRENT; 807 1.1 christos buf[EI_OSABI] = attrs->ei_osabi; 808 1.1 christos 809 1.1 christos ELF_SET_FIELD (fns, cl, Ehdr, buf, e_type, Elf_Half, ET_REL); 810 1.1 christos ELF_SET_FIELD (fns, cl, Ehdr, buf, e_machine, Elf_Half, attrs->machine); 811 1.1 christos ELF_SET_FIELD (fns, cl, Ehdr, buf, e_version, Elf_Word, EV_CURRENT); 812 1.1 christos /* e_entry left as zero. */ 813 1.1 christos /* e_phoff left as zero. */ 814 1.1 christos ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shoff, Elf_Addr, ehdr_size); 815 1.1 christos ELF_SET_FIELD (fns, cl, Ehdr, buf, e_flags, Elf_Word, attrs->flags); 816 1.1 christos ELF_SET_FIELD (fns, cl, Ehdr, buf, e_ehsize, Elf_Half, ehdr_size); 817 1.1 christos ELF_SET_FIELD (fns, cl, Ehdr, buf, e_phentsize, Elf_Half, 818 1.1 christos (cl == ELFCLASS32 819 1.1 christos ? sizeof (Elf32_External_Phdr) 820 1.1 christos : sizeof (Elf64_External_Phdr))); 821 1.1 christos /* e_phnum left as zero. */ 822 1.1 christos ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shentsize, Elf_Half, 823 1.1 christos (cl == ELFCLASS32 824 1.1 christos ? sizeof (Elf32_External_Shdr) 825 1.1 christos : sizeof (Elf64_External_Shdr))); 826 1.3 christos ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shnum, Elf_Half, 827 1.3 christos shnum >= SHN_LORESERVE ? 0 : shnum); 828 1.3 christos if (shnum == 0) 829 1.3 christos shstrndx = 0; 830 1.3 christos else 831 1.3 christos { 832 1.3 christos shstrndx = shnum - 1; 833 1.3 christos if (shstrndx >= SHN_LORESERVE) 834 1.3 christos shstrndx = SHN_XINDEX; 835 1.3 christos } 836 1.3 christos ELF_SET_FIELD (fns, cl, Ehdr, buf, e_shstrndx, Elf_Half, shstrndx); 837 1.1 christos 838 1.1 christos return simple_object_internal_write (descriptor, 0, buf, ehdr_size, 839 1.1 christos errmsg, err); 840 1.1 christos } 841 1.1 christos 842 1.1 christos /* Write out an ELF shdr. */ 843 1.1 christos 844 1.1 christos static int 845 1.1 christos simple_object_elf_write_shdr (simple_object_write *sobj, int descriptor, 846 1.1 christos off_t offset, unsigned int sh_name, 847 1.1 christos unsigned int sh_type, unsigned int sh_flags, 848 1.6 christos off_t sh_addr, 849 1.1 christos unsigned int sh_offset, unsigned int sh_size, 850 1.6 christos unsigned int sh_link, unsigned int sh_info, 851 1.6 christos size_t sh_addralign, 852 1.6 christos size_t sh_entsize, 853 1.3 christos const char **errmsg, int *err) 854 1.1 christos { 855 1.10 christos struct simple_object_elf_attributes *attrs 856 1.10 christos = (struct simple_object_elf_attributes *) sobj->data; 857 1.1 christos const struct elf_type_functions* fns; 858 1.1 christos unsigned char cl; 859 1.1 christos size_t shdr_size; 860 1.1 christos unsigned char buf[sizeof (Elf64_External_Shdr)]; 861 1.1 christos 862 1.1 christos fns = attrs->type_functions; 863 1.1 christos cl = attrs->ei_class; 864 1.1 christos 865 1.1 christos shdr_size = (cl == ELFCLASS32 866 1.1 christos ? sizeof (Elf32_External_Shdr) 867 1.1 christos : sizeof (Elf64_External_Shdr)); 868 1.1 christos memset (buf, 0, sizeof (Elf64_External_Shdr)); 869 1.1 christos 870 1.1 christos ELF_SET_FIELD (fns, cl, Shdr, buf, sh_name, Elf_Word, sh_name); 871 1.1 christos ELF_SET_FIELD (fns, cl, Shdr, buf, sh_type, Elf_Word, sh_type); 872 1.1 christos ELF_SET_FIELD (fns, cl, Shdr, buf, sh_flags, Elf_Addr, sh_flags); 873 1.6 christos ELF_SET_FIELD (fns, cl, Shdr, buf, sh_addr, Elf_Addr, sh_addr); 874 1.1 christos ELF_SET_FIELD (fns, cl, Shdr, buf, sh_offset, Elf_Addr, sh_offset); 875 1.1 christos ELF_SET_FIELD (fns, cl, Shdr, buf, sh_size, Elf_Addr, sh_size); 876 1.3 christos ELF_SET_FIELD (fns, cl, Shdr, buf, sh_link, Elf_Word, sh_link); 877 1.6 christos ELF_SET_FIELD (fns, cl, Shdr, buf, sh_info, Elf_Word, sh_info); 878 1.1 christos ELF_SET_FIELD (fns, cl, Shdr, buf, sh_addralign, Elf_Addr, sh_addralign); 879 1.6 christos ELF_SET_FIELD (fns, cl, Shdr, buf, sh_entsize, Elf_Addr, sh_entsize); 880 1.1 christos 881 1.1 christos return simple_object_internal_write (descriptor, offset, buf, shdr_size, 882 1.1 christos errmsg, err); 883 1.1 christos } 884 1.1 christos 885 1.1 christos /* Write out a complete ELF file. 886 1.1 christos Ehdr 887 1.1 christos initial dummy Shdr 888 1.1 christos user-created Shdrs 889 1.1 christos .shstrtab Shdr 890 1.1 christos user-created section data 891 1.1 christos .shstrtab data */ 892 1.1 christos 893 1.1 christos static const char * 894 1.1 christos simple_object_elf_write_to_file (simple_object_write *sobj, int descriptor, 895 1.1 christos int *err) 896 1.1 christos { 897 1.10 christos struct simple_object_elf_write *eow 898 1.10 christos = (struct simple_object_elf_write *) sobj->data; 899 1.6 christos struct simple_object_elf_attributes *attrs = &eow->attrs; 900 1.1 christos unsigned char cl; 901 1.1 christos size_t ehdr_size; 902 1.1 christos size_t shdr_size; 903 1.1 christos const char *errmsg; 904 1.1 christos simple_object_write_section *section; 905 1.1 christos unsigned int shnum; 906 1.1 christos size_t shdr_offset; 907 1.1 christos size_t sh_offset; 908 1.3 christos unsigned int first_sh_size; 909 1.3 christos unsigned int first_sh_link; 910 1.1 christos size_t sh_name; 911 1.1 christos unsigned char zero; 912 1.6 christos unsigned secnum; 913 1.1 christos 914 1.1 christos if (!simple_object_elf_write_ehdr (sobj, descriptor, &errmsg, err)) 915 1.1 christos return errmsg; 916 1.1 christos 917 1.1 christos cl = attrs->ei_class; 918 1.1 christos if (cl == ELFCLASS32) 919 1.1 christos { 920 1.1 christos ehdr_size = sizeof (Elf32_External_Ehdr); 921 1.1 christos shdr_size = sizeof (Elf32_External_Shdr); 922 1.1 christos } 923 1.1 christos else 924 1.1 christos { 925 1.1 christos ehdr_size = sizeof (Elf64_External_Ehdr); 926 1.1 christos shdr_size = sizeof (Elf64_External_Shdr); 927 1.1 christos } 928 1.1 christos 929 1.1 christos shnum = 0; 930 1.1 christos for (section = sobj->sections; section != NULL; section = section->next) 931 1.1 christos ++shnum; 932 1.1 christos if (shnum == 0) 933 1.1 christos return NULL; 934 1.1 christos 935 1.1 christos /* Add initial dummy Shdr and .shstrtab. */ 936 1.1 christos shnum += 2; 937 1.1 christos 938 1.1 christos shdr_offset = ehdr_size; 939 1.1 christos sh_offset = shdr_offset + shnum * shdr_size; 940 1.1 christos 941 1.3 christos if (shnum < SHN_LORESERVE) 942 1.3 christos first_sh_size = 0; 943 1.3 christos else 944 1.3 christos first_sh_size = shnum; 945 1.3 christos if (shnum - 1 < SHN_LORESERVE) 946 1.3 christos first_sh_link = 0; 947 1.3 christos else 948 1.3 christos first_sh_link = shnum - 1; 949 1.1 christos if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset, 950 1.6 christos 0, 0, 0, 0, 0, first_sh_size, first_sh_link, 951 1.6 christos 0, 0, 0, &errmsg, err)) 952 1.1 christos return errmsg; 953 1.1 christos 954 1.1 christos shdr_offset += shdr_size; 955 1.1 christos 956 1.1 christos sh_name = 1; 957 1.6 christos secnum = 0; 958 1.1 christos for (section = sobj->sections; section != NULL; section = section->next) 959 1.1 christos { 960 1.1 christos size_t mask; 961 1.1 christos size_t new_sh_offset; 962 1.1 christos size_t sh_size; 963 1.1 christos struct simple_object_write_section_buffer *buffer; 964 1.6 christos unsigned int sh_type = SHT_PROGBITS; 965 1.6 christos unsigned int sh_flags = 0; 966 1.6 christos off_t sh_addr = 0; 967 1.6 christos unsigned int sh_link = 0; 968 1.6 christos unsigned int sh_info = 0; 969 1.6 christos size_t sh_addralign = 1U << section->align; 970 1.6 christos size_t sh_entsize = 0; 971 1.6 christos if (eow->shdrs) 972 1.6 christos { 973 1.6 christos sh_type = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr, 974 1.6 christos eow->shdrs + secnum * shdr_size, 975 1.6 christos sh_type, Elf_Word); 976 1.6 christos sh_flags = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr, 977 1.6 christos eow->shdrs + secnum * shdr_size, 978 1.6 christos sh_flags, Elf_Addr); 979 1.6 christos sh_addr = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr, 980 1.6 christos eow->shdrs + secnum * shdr_size, 981 1.6 christos sh_addr, Elf_Addr); 982 1.6 christos sh_link = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr, 983 1.6 christos eow->shdrs + secnum * shdr_size, 984 1.6 christos sh_link, Elf_Word); 985 1.6 christos sh_info = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr, 986 1.6 christos eow->shdrs + secnum * shdr_size, 987 1.6 christos sh_info, Elf_Word); 988 1.6 christos sh_addralign = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr, 989 1.6 christos eow->shdrs + secnum * shdr_size, 990 1.6 christos sh_addralign, Elf_Addr); 991 1.6 christos sh_entsize = ELF_FETCH_FIELD (attrs->type_functions, attrs->ei_class, Shdr, 992 1.6 christos eow->shdrs + secnum * shdr_size, 993 1.6 christos sh_entsize, Elf_Addr); 994 1.6 christos secnum++; 995 1.6 christos } 996 1.1 christos 997 1.6 christos mask = sh_addralign - 1; 998 1.1 christos new_sh_offset = sh_offset + mask; 999 1.1 christos new_sh_offset &= ~ mask; 1000 1.1 christos while (new_sh_offset > sh_offset) 1001 1.1 christos { 1002 1.1 christos unsigned char zeroes[16]; 1003 1.1 christos size_t write; 1004 1.1 christos 1005 1.1 christos memset (zeroes, 0, sizeof zeroes); 1006 1.1 christos write = new_sh_offset - sh_offset; 1007 1.1 christos if (write > sizeof zeroes) 1008 1.1 christos write = sizeof zeroes; 1009 1.1 christos if (!simple_object_internal_write (descriptor, sh_offset, zeroes, 1010 1.1 christos write, &errmsg, err)) 1011 1.1 christos return errmsg; 1012 1.1 christos sh_offset += write; 1013 1.1 christos } 1014 1.1 christos 1015 1.1 christos sh_size = 0; 1016 1.1 christos for (buffer = section->buffers; buffer != NULL; buffer = buffer->next) 1017 1.1 christos { 1018 1.1 christos if (!simple_object_internal_write (descriptor, sh_offset + sh_size, 1019 1.1 christos ((const unsigned char *) 1020 1.1 christos buffer->buffer), 1021 1.1 christos buffer->size, &errmsg, err)) 1022 1.1 christos return errmsg; 1023 1.1 christos sh_size += buffer->size; 1024 1.1 christos } 1025 1.1 christos 1026 1.1 christos if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset, 1027 1.6 christos sh_name, sh_type, sh_flags, 1028 1.6 christos sh_addr, sh_offset, 1029 1.6 christos sh_size, sh_link, sh_info, 1030 1.6 christos sh_addralign, sh_entsize, 1031 1.1 christos &errmsg, err)) 1032 1.1 christos return errmsg; 1033 1.1 christos 1034 1.1 christos shdr_offset += shdr_size; 1035 1.1 christos sh_name += strlen (section->name) + 1; 1036 1.1 christos sh_offset += sh_size; 1037 1.1 christos } 1038 1.1 christos 1039 1.1 christos if (!simple_object_elf_write_shdr (sobj, descriptor, shdr_offset, 1040 1.6 christos sh_name, SHT_STRTAB, 0, 0, sh_offset, 1041 1.6 christos sh_name + strlen (".shstrtab") + 1, 0, 0, 1042 1.6 christos 1, 0, &errmsg, err)) 1043 1.1 christos return errmsg; 1044 1.1 christos 1045 1.1 christos /* .shstrtab has a leading zero byte. */ 1046 1.1 christos zero = 0; 1047 1.1 christos if (!simple_object_internal_write (descriptor, sh_offset, &zero, 1, 1048 1.1 christos &errmsg, err)) 1049 1.1 christos return errmsg; 1050 1.1 christos ++sh_offset; 1051 1.1 christos 1052 1.1 christos for (section = sobj->sections; section != NULL; section = section->next) 1053 1.1 christos { 1054 1.1 christos size_t len; 1055 1.1 christos 1056 1.1 christos len = strlen (section->name) + 1; 1057 1.1 christos if (!simple_object_internal_write (descriptor, sh_offset, 1058 1.1 christos (const unsigned char *) section->name, 1059 1.1 christos len, &errmsg, err)) 1060 1.1 christos return errmsg; 1061 1.1 christos sh_offset += len; 1062 1.1 christos } 1063 1.1 christos 1064 1.1 christos if (!simple_object_internal_write (descriptor, sh_offset, 1065 1.1 christos (const unsigned char *) ".shstrtab", 1066 1.1 christos strlen (".shstrtab") + 1, &errmsg, err)) 1067 1.1 christos return errmsg; 1068 1.1 christos 1069 1.1 christos return NULL; 1070 1.1 christos } 1071 1.1 christos 1072 1.1 christos /* Release the private data for an simple_object_write structure. */ 1073 1.1 christos 1074 1.1 christos static void 1075 1.1 christos simple_object_elf_release_write (void *data) 1076 1.1 christos { 1077 1.6 christos struct simple_object_elf_write *eow = (struct simple_object_elf_write *) data; 1078 1.6 christos if (eow->shdrs) 1079 1.6 christos XDELETE (eow->shdrs); 1080 1.1 christos XDELETE (data); 1081 1.1 christos } 1082 1.1 christos 1083 1.6 christos /* Copy all sections in an ELF file. */ 1084 1.6 christos 1085 1.6 christos static const char * 1086 1.6 christos simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj, 1087 1.6 christos simple_object_write *dobj, 1088 1.6 christos char *(*pfn) (const char *), 1089 1.6 christos int *err) 1090 1.6 christos { 1091 1.10 christos struct simple_object_elf_read *eor 1092 1.10 christos = (struct simple_object_elf_read *) sobj->data; 1093 1.6 christos const struct elf_type_functions *type_functions = eor->type_functions; 1094 1.10 christos struct simple_object_elf_write *eow 1095 1.10 christos = (struct simple_object_elf_write *) dobj->data; 1096 1.6 christos unsigned char ei_class = eor->ei_class; 1097 1.6 christos size_t shdr_size; 1098 1.6 christos unsigned int shnum; 1099 1.6 christos unsigned char *shdrs; 1100 1.6 christos const char *errmsg; 1101 1.6 christos unsigned char *shstrhdr; 1102 1.6 christos size_t name_size; 1103 1.6 christos off_t shstroff; 1104 1.6 christos unsigned char *names; 1105 1.6 christos unsigned int i; 1106 1.6 christos int changed; 1107 1.6 christos int *pfnret; 1108 1.6 christos const char **pfnname; 1109 1.10 christos unsigned new_i, new_count; 1110 1.6 christos unsigned *sh_map; 1111 1.6 christos unsigned first_shndx = 0; 1112 1.6 christos unsigned int *symtab_indices_shndx; 1113 1.10 christos int pass_symtab_indices_shndx; 1114 1.10 christos unsigned int first_symtab_indices_shndx; 1115 1.10 christos unsigned char **symtab_indices_shndx_buf; 1116 1.6 christos 1117 1.6 christos shdr_size = (ei_class == ELFCLASS32 1118 1.6 christos ? sizeof (Elf32_External_Shdr) 1119 1.6 christos : sizeof (Elf64_External_Shdr)); 1120 1.6 christos 1121 1.6 christos /* Read the section headers. We skip section 0, which is not a 1122 1.6 christos useful section. */ 1123 1.6 christos 1124 1.6 christos shnum = eor->shnum; 1125 1.6 christos shdrs = XNEWVEC (unsigned char, shdr_size * (shnum - 1)); 1126 1.6 christos 1127 1.6 christos if (!simple_object_internal_read (sobj->descriptor, 1128 1.6 christos sobj->offset + eor->shoff + shdr_size, 1129 1.6 christos shdrs, 1130 1.6 christos shdr_size * (shnum - 1), 1131 1.6 christos &errmsg, err)) 1132 1.6 christos { 1133 1.6 christos XDELETEVEC (shdrs); 1134 1.6 christos return errmsg; 1135 1.6 christos } 1136 1.6 christos 1137 1.6 christos /* Read the section names. */ 1138 1.6 christos 1139 1.6 christos shstrhdr = shdrs + (eor->shstrndx - 1) * shdr_size; 1140 1.6 christos name_size = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1141 1.6 christos shstrhdr, sh_size, Elf_Addr); 1142 1.6 christos shstroff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1143 1.6 christos shstrhdr, sh_offset, Elf_Addr); 1144 1.6 christos names = XNEWVEC (unsigned char, name_size); 1145 1.6 christos if (!simple_object_internal_read (sobj->descriptor, 1146 1.6 christos sobj->offset + shstroff, 1147 1.6 christos names, name_size, &errmsg, err)) 1148 1.6 christos { 1149 1.6 christos XDELETEVEC (names); 1150 1.6 christos XDELETEVEC (shdrs); 1151 1.6 christos return errmsg; 1152 1.6 christos } 1153 1.6 christos 1154 1.6 christos pfnret = XNEWVEC (int, shnum); 1155 1.6 christos pfnname = XNEWVEC (const char *, shnum); 1156 1.6 christos 1157 1.6 christos /* Map of symtab to index section. */ 1158 1.6 christos symtab_indices_shndx = XCNEWVEC (unsigned int, shnum - 1); 1159 1.6 christos 1160 1.6 christos /* First perform the callbacks to know which sections to preserve and 1161 1.6 christos what name to use for those. */ 1162 1.6 christos for (i = 1; i < shnum; ++i) 1163 1.6 christos { 1164 1.6 christos unsigned char *shdr; 1165 1.6 christos unsigned int sh_name, sh_type; 1166 1.6 christos const char *name; 1167 1.6 christos char *ret; 1168 1.6 christos 1169 1.6 christos shdr = shdrs + (i - 1) * shdr_size; 1170 1.6 christos sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1171 1.6 christos shdr, sh_name, Elf_Word); 1172 1.6 christos if (sh_name >= name_size) 1173 1.6 christos { 1174 1.6 christos *err = 0; 1175 1.6 christos XDELETEVEC (names); 1176 1.6 christos XDELETEVEC (shdrs); 1177 1.6 christos return "ELF section name out of range"; 1178 1.6 christos } 1179 1.6 christos 1180 1.6 christos name = (const char *) names + sh_name; 1181 1.6 christos 1182 1.6 christos ret = (*pfn) (name); 1183 1.6 christos pfnret[i - 1] = ret == NULL ? -1 : 0; 1184 1.6 christos pfnname[i - 1] = ret == NULL ? name : ret; 1185 1.10 christos if (first_shndx == 0 && pfnret[i - 1] == 0) 1186 1.6 christos first_shndx = i; 1187 1.6 christos 1188 1.6 christos /* Remember the indexes of existing SHT_SYMTAB_SHNDX sections. */ 1189 1.6 christos sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1190 1.6 christos shdr, sh_type, Elf_Word); 1191 1.6 christos if (sh_type == SHT_SYMTAB_SHNDX) 1192 1.6 christos { 1193 1.6 christos unsigned int sh_link; 1194 1.6 christos sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1195 1.6 christos shdr, sh_link, Elf_Word); 1196 1.10 christos symtab_indices_shndx[sh_link - 1] = i; 1197 1.10 christos /* Discard the extended index sections, after copying it will not 1198 1.10 christos be needed, unless we need more than SHN_LORESERVE - 1 sections 1199 1.10 christos in the output. This way we don't need to update it and deal with 1200 1.10 christos the ordering constraints of processing the existing symtab and 1201 1.10 christos changing the index. */ 1202 1.6 christos pfnret[i - 1] = -1; 1203 1.6 christos } 1204 1.6 christos } 1205 1.6 christos 1206 1.6 christos /* Mark sections as preserved that are required by to be preserved 1207 1.6 christos sections. */ 1208 1.6 christos do 1209 1.6 christos { 1210 1.6 christos changed = 0; 1211 1.6 christos for (i = 1; i < shnum; ++i) 1212 1.6 christos { 1213 1.6 christos unsigned char *shdr; 1214 1.6 christos unsigned int sh_type, sh_info, sh_link; 1215 1.6 christos off_t offset; 1216 1.6 christos off_t length; 1217 1.6 christos 1218 1.6 christos shdr = shdrs + (i - 1) * shdr_size; 1219 1.6 christos sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1220 1.6 christos shdr, sh_type, Elf_Word); 1221 1.6 christos sh_info = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1222 1.6 christos shdr, sh_info, Elf_Word); 1223 1.6 christos sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1224 1.6 christos shdr, sh_link, Elf_Word); 1225 1.6 christos if (sh_type == SHT_GROUP) 1226 1.6 christos { 1227 1.6 christos /* Mark groups containing copied sections. */ 1228 1.6 christos unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class, 1229 1.6 christos Shdr, shdr, sh_entsize, 1230 1.6 christos Elf_Addr); 1231 1.6 christos unsigned char *ent, *buf; 1232 1.6 christos int keep = 0; 1233 1.6 christos offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1234 1.6 christos shdr, sh_offset, Elf_Addr); 1235 1.6 christos length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1236 1.6 christos shdr, sh_size, Elf_Addr); 1237 1.6 christos buf = XNEWVEC (unsigned char, length); 1238 1.6 christos if (!simple_object_internal_read (sobj->descriptor, 1239 1.6 christos sobj->offset + offset, buf, 1240 1.6 christos (size_t) length, &errmsg, err)) 1241 1.6 christos { 1242 1.6 christos XDELETEVEC (buf); 1243 1.6 christos XDELETEVEC (names); 1244 1.6 christos XDELETEVEC (shdrs); 1245 1.6 christos return errmsg; 1246 1.6 christos } 1247 1.6 christos for (ent = buf + entsize; ent < buf + length; ent += entsize) 1248 1.6 christos { 1249 1.6 christos unsigned sec = type_functions->fetch_Elf_Word (ent); 1250 1.6 christos if (pfnret[sec - 1] == 0) 1251 1.6 christos keep = 1; 1252 1.6 christos } 1253 1.6 christos if (keep) 1254 1.6 christos { 1255 1.6 christos changed |= (pfnret[sh_link - 1] == -1 1256 1.6 christos || pfnret[i - 1] == -1); 1257 1.6 christos pfnret[sh_link - 1] = 0; 1258 1.6 christos pfnret[i - 1] = 0; 1259 1.6 christos } 1260 1.6 christos } 1261 1.6 christos if (sh_type == SHT_RELA 1262 1.6 christos || sh_type == SHT_REL) 1263 1.6 christos { 1264 1.6 christos /* Mark relocation sections and symtab of copied sections. */ 1265 1.6 christos if (pfnret[sh_info - 1] == 0) 1266 1.6 christos { 1267 1.6 christos changed |= (pfnret[sh_link - 1] == -1 1268 1.6 christos || pfnret[i - 1] == -1); 1269 1.6 christos pfnret[sh_link - 1] = 0; 1270 1.6 christos pfnret[i - 1] = 0; 1271 1.6 christos } 1272 1.6 christos } 1273 1.6 christos if (sh_type == SHT_SYMTAB) 1274 1.6 christos { 1275 1.6 christos /* Mark strings sections of copied symtabs. */ 1276 1.6 christos if (pfnret[i - 1] == 0) 1277 1.6 christos { 1278 1.6 christos changed |= pfnret[sh_link - 1] == -1; 1279 1.6 christos pfnret[sh_link - 1] = 0; 1280 1.6 christos } 1281 1.6 christos } 1282 1.6 christos } 1283 1.6 christos } 1284 1.6 christos while (changed); 1285 1.6 christos 1286 1.6 christos /* Compute a mapping of old -> new section numbers. */ 1287 1.6 christos sh_map = XNEWVEC (unsigned, shnum); 1288 1.6 christos sh_map[0] = 0; 1289 1.6 christos new_i = 1; 1290 1.6 christos for (i = 1; i < shnum; ++i) 1291 1.6 christos { 1292 1.6 christos if (pfnret[i - 1] == -1) 1293 1.6 christos sh_map[i] = 0; 1294 1.6 christos else 1295 1.6 christos sh_map[i] = new_i++; 1296 1.6 christos } 1297 1.10 christos first_symtab_indices_shndx = new_i; 1298 1.10 christos symtab_indices_shndx_buf = NULL; 1299 1.6 christos if (new_i - 1 >= SHN_LORESERVE) 1300 1.10 christos for (i = 1; i < shnum; ++i) 1301 1.10 christos if (pfnret[i - 1] == 0 && symtab_indices_shndx[i - 1] != 0) 1302 1.10 christos { 1303 1.10 christos pfnret[symtab_indices_shndx[i - 1] - 1] = 0; 1304 1.10 christos sh_map[symtab_indices_shndx[i - 1]] = new_i++; 1305 1.10 christos } 1306 1.10 christos new_count = new_i; 1307 1.10 christos if (new_count != first_symtab_indices_shndx) 1308 1.10 christos symtab_indices_shndx_buf 1309 1.10 christos = XNEWVEC (unsigned char *, new_count - first_symtab_indices_shndx); 1310 1.10 christos eow->shdrs = XNEWVEC (unsigned char, shdr_size * (new_count - 1)); 1311 1.6 christos 1312 1.6 christos /* Then perform the actual copying. */ 1313 1.6 christos new_i = 0; 1314 1.10 christos pass_symtab_indices_shndx = 0; 1315 1.10 christos for (i = 1; i <= shnum; ++i) 1316 1.6 christos { 1317 1.6 christos unsigned char *shdr; 1318 1.6 christos unsigned int sh_name, sh_type; 1319 1.6 christos const char *name; 1320 1.6 christos off_t offset; 1321 1.6 christos off_t length; 1322 1.6 christos simple_object_write_section *dest; 1323 1.6 christos off_t flags; 1324 1.6 christos unsigned char *buf; 1325 1.6 christos 1326 1.10 christos if (i == shnum) 1327 1.10 christos { 1328 1.10 christos if (new_count - 1 < SHN_LORESERVE || pass_symtab_indices_shndx) 1329 1.10 christos break; 1330 1.10 christos i = 0; 1331 1.10 christos pass_symtab_indices_shndx = 1; 1332 1.10 christos continue; 1333 1.10 christos } 1334 1.10 christos 1335 1.6 christos if (pfnret[i - 1]) 1336 1.6 christos continue; 1337 1.6 christos 1338 1.10 christos shdr = shdrs + (i - 1) * shdr_size; 1339 1.10 christos sh_type = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1340 1.10 christos shdr, sh_type, Elf_Word); 1341 1.10 christos if (sh_type == SHT_SYMTAB_SHNDX) 1342 1.10 christos { 1343 1.10 christos if (!pass_symtab_indices_shndx) 1344 1.10 christos continue; 1345 1.10 christos } 1346 1.10 christos else if (pass_symtab_indices_shndx) 1347 1.10 christos continue; 1348 1.10 christos 1349 1.6 christos new_i++; 1350 1.6 christos sh_name = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1351 1.6 christos shdr, sh_name, Elf_Word); 1352 1.6 christos if (sh_name >= name_size) 1353 1.6 christos { 1354 1.6 christos *err = 0; 1355 1.6 christos XDELETEVEC (names); 1356 1.6 christos XDELETEVEC (shdrs); 1357 1.6 christos XDELETEVEC (symtab_indices_shndx); 1358 1.10 christos XDELETEVEC (symtab_indices_shndx_buf); 1359 1.6 christos return "ELF section name out of range"; 1360 1.6 christos } 1361 1.6 christos 1362 1.6 christos name = pfnname[i - 1]; 1363 1.6 christos offset = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1364 1.6 christos shdr, sh_offset, Elf_Addr); 1365 1.6 christos length = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1366 1.6 christos shdr, sh_size, Elf_Addr); 1367 1.6 christos 1368 1.10 christos dest = simple_object_write_create_section (dobj, name, 0, &errmsg, err); 1369 1.6 christos if (dest == NULL) 1370 1.6 christos { 1371 1.6 christos XDELETEVEC (names); 1372 1.6 christos XDELETEVEC (shdrs); 1373 1.6 christos XDELETEVEC (symtab_indices_shndx); 1374 1.10 christos XDELETEVEC (symtab_indices_shndx_buf); 1375 1.6 christos return errmsg; 1376 1.6 christos } 1377 1.6 christos 1378 1.6 christos /* Record the SHDR of the source. */ 1379 1.6 christos memcpy (eow->shdrs + (new_i - 1) * shdr_size, shdr, shdr_size); 1380 1.6 christos shdr = eow->shdrs + (new_i - 1) * shdr_size; 1381 1.6 christos 1382 1.6 christos /* Copy the data. 1383 1.6 christos ??? This is quite wasteful and ideally would be delayed until 1384 1.6 christos write_to_file (). Thus it questions the interfacing 1385 1.6 christos which eventually should contain destination creation plus 1386 1.6 christos writing. */ 1387 1.6 christos buf = XNEWVEC (unsigned char, length); 1388 1.6 christos if (!simple_object_internal_read (sobj->descriptor, 1389 1.6 christos sobj->offset + offset, buf, 1390 1.6 christos (size_t) length, &errmsg, err)) 1391 1.6 christos { 1392 1.6 christos XDELETEVEC (buf); 1393 1.6 christos XDELETEVEC (names); 1394 1.6 christos XDELETEVEC (shdrs); 1395 1.6 christos XDELETEVEC (symtab_indices_shndx); 1396 1.10 christos XDELETEVEC (symtab_indices_shndx_buf); 1397 1.6 christos return errmsg; 1398 1.6 christos } 1399 1.6 christos 1400 1.7 christos /* If we are processing .symtab purge any symbols 1401 1.7 christos in discarded sections. */ 1402 1.6 christos if (sh_type == SHT_SYMTAB) 1403 1.6 christos { 1404 1.6 christos unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1405 1.6 christos shdr, sh_entsize, Elf_Addr); 1406 1.7 christos size_t prevailing_name_idx = 0; 1407 1.6 christos unsigned char *ent; 1408 1.6 christos unsigned *shndx_table = NULL; 1409 1.6 christos /* Read the section index table if present. */ 1410 1.6 christos if (symtab_indices_shndx[i - 1] != 0) 1411 1.6 christos { 1412 1.10 christos unsigned char *sidxhdr 1413 1.10 christos = shdrs + (symtab_indices_shndx[i - 1] - 1) * shdr_size; 1414 1.6 christos off_t sidxoff = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1415 1.6 christos sidxhdr, sh_offset, Elf_Addr); 1416 1.6 christos size_t sidxsz = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1417 1.6 christos sidxhdr, sh_size, Elf_Addr); 1418 1.8 christos unsigned int shndx_type 1419 1.8 christos = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1420 1.8 christos sidxhdr, sh_type, Elf_Word); 1421 1.8 christos if (shndx_type != SHT_SYMTAB_SHNDX) 1422 1.8 christos return "Wrong section type of a SYMTAB SECTION INDICES section"; 1423 1.10 christos shndx_table = (unsigned *) XNEWVEC (char, sidxsz); 1424 1.10 christos if (!simple_object_internal_read (sobj->descriptor, 1425 1.10 christos sobj->offset + sidxoff, 1426 1.10 christos (unsigned char *) shndx_table, 1427 1.10 christos sidxsz, &errmsg, err)) 1428 1.10 christos { 1429 1.10 christos XDELETEVEC (buf); 1430 1.10 christos XDELETEVEC (names); 1431 1.10 christos XDELETEVEC (shdrs); 1432 1.10 christos XDELETEVEC (symtab_indices_shndx); 1433 1.10 christos XDELETEVEC (shndx_table); 1434 1.10 christos XDELETEVEC (symtab_indices_shndx_buf); 1435 1.10 christos return errmsg; 1436 1.10 christos } 1437 1.6 christos } 1438 1.7 christos 1439 1.7 christos /* Find a WEAK HIDDEN symbol which name we will use for removed 1440 1.7 christos symbols. We know there's a prevailing weak hidden symbol 1441 1.7 christos at the start of the .debug_info section. */ 1442 1.7 christos for (ent = buf; ent < buf + length; ent += entsize) 1443 1.7 christos { 1444 1.7 christos unsigned st_shndx = ELF_FETCH_FIELD (type_functions, ei_class, 1445 1.7 christos Sym, ent, 1446 1.7 christos st_shndx, Elf_Half); 1447 1.7 christos unsigned char *st_info; 1448 1.7 christos unsigned char *st_other; 1449 1.7 christos if (ei_class == ELFCLASS32) 1450 1.7 christos { 1451 1.10 christos st_info = &((Elf32_External_Sym *) ent)->st_info; 1452 1.10 christos st_other = &((Elf32_External_Sym *) ent)->st_other; 1453 1.7 christos } 1454 1.7 christos else 1455 1.7 christos { 1456 1.10 christos st_info = &((Elf64_External_Sym *) ent)->st_info; 1457 1.10 christos st_other = &((Elf64_External_Sym *) ent)->st_other; 1458 1.7 christos } 1459 1.7 christos if (st_shndx == SHN_XINDEX) 1460 1.10 christos { 1461 1.10 christos unsigned char *ndx_ptr 1462 1.10 christos = (unsigned char *) (shndx_table + (ent - buf) / entsize); 1463 1.10 christos st_shndx = type_functions->fetch_Elf_Word (ndx_ptr); 1464 1.10 christos } 1465 1.7 christos 1466 1.7 christos if (st_shndx != SHN_COMMON 1467 1.7 christos && !(st_shndx != SHN_UNDEF 1468 1.7 christos && st_shndx < shnum 1469 1.7 christos && pfnret[st_shndx - 1] == -1) 1470 1.7 christos && ELF_ST_BIND (*st_info) == STB_WEAK 1471 1.7 christos && *st_other == STV_HIDDEN) 1472 1.7 christos { 1473 1.7 christos prevailing_name_idx = ELF_FETCH_FIELD (type_functions, 1474 1.7 christos ei_class, Sym, ent, 1475 1.7 christos st_name, Elf_Word); 1476 1.7 christos break; 1477 1.7 christos } 1478 1.7 christos } 1479 1.7 christos 1480 1.6 christos for (ent = buf; ent < buf + length; ent += entsize) 1481 1.6 christos { 1482 1.6 christos unsigned st_shndx = ELF_FETCH_FIELD (type_functions, ei_class, 1483 1.6 christos Sym, ent, 1484 1.6 christos st_shndx, Elf_Half); 1485 1.6 christos unsigned raw_st_shndx = st_shndx; 1486 1.6 christos unsigned char *st_info; 1487 1.6 christos unsigned char *st_other; 1488 1.6 christos int discard = 0; 1489 1.10 christos unsigned char *ndx_ptr = NULL; 1490 1.6 christos if (ei_class == ELFCLASS32) 1491 1.6 christos { 1492 1.10 christos st_info = &((Elf32_External_Sym *) ent)->st_info; 1493 1.10 christos st_other = &((Elf32_External_Sym *) ent)->st_other; 1494 1.6 christos } 1495 1.6 christos else 1496 1.6 christos { 1497 1.10 christos st_info = &((Elf64_External_Sym *) ent)->st_info; 1498 1.10 christos st_other = &((Elf64_External_Sym *) ent)->st_other; 1499 1.6 christos } 1500 1.10 christos if (shndx_table) 1501 1.10 christos ndx_ptr 1502 1.10 christos = (unsigned char *) (shndx_table + (ent - buf) / entsize); 1503 1.10 christos 1504 1.6 christos if (st_shndx == SHN_XINDEX) 1505 1.10 christos { 1506 1.10 christos st_shndx = type_functions->fetch_Elf_Word (ndx_ptr); 1507 1.10 christos type_functions->set_Elf_Word (ndx_ptr, SHN_UNDEF); 1508 1.10 christos } 1509 1.7 christos /* Eliminate all COMMONs - this includes __gnu_lto_slim 1510 1.7 christos which otherwise cause endless LTO plugin invocation. 1511 1.7 christos FIXME: remove the condition once we remove emission 1512 1.7 christos of __gnu_lto_slim symbol. */ 1513 1.6 christos if (st_shndx == SHN_COMMON) 1514 1.6 christos discard = 1; 1515 1.6 christos /* We also need to remove symbols refering to sections 1516 1.6 christos we'll eventually remove as with fat LTO objects 1517 1.6 christos we otherwise get duplicate symbols at final link 1518 1.6 christos (with GNU ld, gold is fine and ignores symbols in 1519 1.6 christos sections marked as EXCLUDE). ld/20513 */ 1520 1.6 christos else if (st_shndx != SHN_UNDEF 1521 1.6 christos && st_shndx < shnum 1522 1.6 christos && pfnret[st_shndx - 1] == -1) 1523 1.6 christos discard = 1; 1524 1.8 christos /* We also need to remove global UNDEFs which can 1525 1.8 christos cause link fails later. */ 1526 1.8 christos else if (st_shndx == SHN_UNDEF 1527 1.8 christos && ELF_ST_BIND (*st_info) == STB_GLOBAL) 1528 1.8 christos discard = 1; 1529 1.6 christos 1530 1.6 christos if (discard) 1531 1.6 christos { 1532 1.6 christos /* Make discarded symbols undefined and unnamed 1533 1.6 christos in case it is local. */ 1534 1.6 christos int bind = ELF_ST_BIND (*st_info); 1535 1.6 christos int other = STV_DEFAULT; 1536 1.6 christos if (bind == STB_LOCAL) 1537 1.6 christos { 1538 1.6 christos /* Make discarded local symbols unnamed and 1539 1.6 christos defined in the first prevailing section. */ 1540 1.6 christos ELF_SET_FIELD (type_functions, ei_class, Sym, 1541 1.6 christos ent, st_name, Elf_Word, 0); 1542 1.10 christos st_shndx = sh_map[first_shndx]; 1543 1.10 christos if (st_shndx >= SHN_LORESERVE) 1544 1.10 christos { 1545 1.10 christos type_functions->set_Elf_Word (ndx_ptr, st_shndx); 1546 1.10 christos st_shndx = SHN_XINDEX; 1547 1.10 christos } 1548 1.6 christos ELF_SET_FIELD (type_functions, ei_class, Sym, 1549 1.10 christos ent, st_shndx, Elf_Half, st_shndx); 1550 1.6 christos } 1551 1.6 christos else 1552 1.6 christos { 1553 1.6 christos /* Make discarded global symbols hidden weak 1554 1.7 christos undefined and sharing a name of a prevailing 1555 1.7 christos symbol. */ 1556 1.6 christos bind = STB_WEAK; 1557 1.6 christos other = STV_HIDDEN; 1558 1.7 christos ELF_SET_FIELD (type_functions, ei_class, Sym, 1559 1.7 christos ent, st_name, Elf_Word, 1560 1.7 christos prevailing_name_idx); 1561 1.6 christos ELF_SET_FIELD (type_functions, ei_class, Sym, 1562 1.6 christos ent, st_shndx, Elf_Half, SHN_UNDEF); 1563 1.6 christos } 1564 1.6 christos *st_other = other; 1565 1.6 christos *st_info = ELF_ST_INFO (bind, STT_NOTYPE); 1566 1.6 christos ELF_SET_FIELD (type_functions, ei_class, Sym, 1567 1.6 christos ent, st_value, Elf_Addr, 0); 1568 1.6 christos ELF_SET_FIELD (type_functions, ei_class, Sym, 1569 1.6 christos ent, st_size, Elf_Word, 0); 1570 1.6 christos } 1571 1.6 christos else if (raw_st_shndx < SHN_LORESERVE 1572 1.6 christos || raw_st_shndx == SHN_XINDEX) 1573 1.10 christos { 1574 1.10 christos /* Remap the section reference. */ 1575 1.10 christos st_shndx = sh_map[st_shndx]; 1576 1.10 christos if (st_shndx >= SHN_LORESERVE) 1577 1.10 christos { 1578 1.10 christos type_functions->set_Elf_Word (ndx_ptr, st_shndx); 1579 1.10 christos st_shndx = SHN_XINDEX; 1580 1.10 christos } 1581 1.10 christos ELF_SET_FIELD (type_functions, ei_class, Sym, 1582 1.10 christos ent, st_shndx, Elf_Half, st_shndx); 1583 1.10 christos } 1584 1.6 christos } 1585 1.10 christos if (symtab_indices_shndx_buf) 1586 1.10 christos symtab_indices_shndx_buf[sh_map[symtab_indices_shndx[i - 1]] 1587 1.10 christos - first_symtab_indices_shndx] 1588 1.10 christos = (unsigned char *) shndx_table; 1589 1.10 christos else 1590 1.10 christos XDELETEVEC (shndx_table); 1591 1.6 christos } 1592 1.6 christos else if (sh_type == SHT_GROUP) 1593 1.6 christos { 1594 1.6 christos /* Remap section indices in groups and remove removed members. */ 1595 1.6 christos unsigned char *ent, *dst; 1596 1.6 christos for (dst = ent = buf + 4; ent < buf + length; ent += 4) 1597 1.6 christos { 1598 1.6 christos unsigned shndx = type_functions->fetch_Elf_Word (ent); 1599 1.6 christos if (pfnret[shndx - 1] == -1) 1600 1.6 christos ; 1601 1.6 christos else 1602 1.6 christos { 1603 1.6 christos type_functions->set_Elf_Word (dst, sh_map[shndx]); 1604 1.6 christos dst += 4; 1605 1.6 christos } 1606 1.6 christos } 1607 1.6 christos /* Adjust the length. */ 1608 1.6 christos length = dst - buf; 1609 1.6 christos } 1610 1.10 christos else if (sh_type == SHT_SYMTAB_SHNDX) 1611 1.10 christos { 1612 1.10 christos XDELETEVEC (buf); 1613 1.10 christos buf = symtab_indices_shndx_buf[new_i - first_symtab_indices_shndx]; 1614 1.10 christos symtab_indices_shndx_buf[new_i - first_symtab_indices_shndx] = NULL; 1615 1.10 christos } 1616 1.6 christos 1617 1.10 christos errmsg = simple_object_write_add_data (dobj, dest, buf, length, 1, err); 1618 1.6 christos XDELETEVEC (buf); 1619 1.6 christos if (errmsg) 1620 1.6 christos { 1621 1.6 christos XDELETEVEC (names); 1622 1.6 christos XDELETEVEC (shdrs); 1623 1.6 christos XDELETEVEC (symtab_indices_shndx); 1624 1.10 christos XDELETEVEC (symtab_indices_shndx_buf); 1625 1.6 christos return errmsg; 1626 1.6 christos } 1627 1.6 christos 1628 1.6 christos flags = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1629 1.6 christos shdr, sh_flags, Elf_Addr); 1630 1.6 christos /* Remap the section references. */ 1631 1.6 christos { 1632 1.6 christos unsigned int sh_info, sh_link; 1633 1.6 christos if (flags & SHF_INFO_LINK || sh_type == SHT_REL || sh_type == SHT_RELA) 1634 1.6 christos { 1635 1.6 christos sh_info = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1636 1.6 christos shdr, sh_info, Elf_Word); 1637 1.8 christos sh_info = sh_map[sh_info]; 1638 1.6 christos ELF_SET_FIELD (type_functions, ei_class, Shdr, 1639 1.6 christos shdr, sh_info, Elf_Word, sh_info); 1640 1.6 christos } 1641 1.6 christos sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr, 1642 1.6 christos shdr, sh_link, Elf_Word); 1643 1.8 christos sh_link = sh_map[sh_link]; 1644 1.6 christos ELF_SET_FIELD (type_functions, ei_class, Shdr, 1645 1.6 christos shdr, sh_link, Elf_Word, sh_link); 1646 1.6 christos } 1647 1.6 christos /* The debugobj doesn't contain any code, thus no trampolines. 1648 1.6 christos Even when the original object needs trampolines, debugobj 1649 1.6 christos doesn't. */ 1650 1.6 christos if (strcmp (name, ".note.GNU-stack") == 0) 1651 1.6 christos flags &= ~SHF_EXECINSTR; 1652 1.6 christos /* Clear SHF_EXCLUDE on to be preserved sections. */ 1653 1.6 christos flags &= ~SHF_EXCLUDE; 1654 1.6 christos ELF_SET_FIELD (type_functions, ei_class, Shdr, 1655 1.6 christos shdr, sh_flags, Elf_Addr, flags); 1656 1.6 christos } 1657 1.6 christos 1658 1.6 christos XDELETEVEC (names); 1659 1.6 christos XDELETEVEC (shdrs); 1660 1.6 christos XDELETEVEC (pfnret); 1661 1.6 christos XDELETEVEC (pfnname); 1662 1.6 christos XDELETEVEC (symtab_indices_shndx); 1663 1.6 christos XDELETEVEC (sh_map); 1664 1.10 christos XDELETEVEC (symtab_indices_shndx_buf); 1665 1.6 christos 1666 1.6 christos return NULL; 1667 1.6 christos } 1668 1.6 christos 1669 1.6 christos 1670 1.1 christos /* The ELF functions. */ 1671 1.1 christos 1672 1.1 christos const struct simple_object_functions simple_object_elf_functions = 1673 1.1 christos { 1674 1.1 christos simple_object_elf_match, 1675 1.1 christos simple_object_elf_find_sections, 1676 1.1 christos simple_object_elf_fetch_attributes, 1677 1.1 christos simple_object_elf_release_read, 1678 1.1 christos simple_object_elf_attributes_merge, 1679 1.1 christos simple_object_elf_release_attributes, 1680 1.1 christos simple_object_elf_start_write, 1681 1.1 christos simple_object_elf_write_to_file, 1682 1.6 christos simple_object_elf_release_write, 1683 1.6 christos simple_object_elf_copy_lto_debug_sections 1684 1.1 christos }; 1685