1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29#pragma weak elf32_fsize = _elf32_fsize 30#pragma weak elf_version = _elf_version 31#pragma weak elf32_xlatetof = _elf32_xlatetof 32#pragma weak elf32_xlatetom = _elf32_xlatetom 33 34#include "syn.h" 35#include <memory.h> 36#include <libelf.h> 37#include <link.h> 38#include <sys/elf_SPARC.h> 39#include <sys/elf_amd64.h> 40#include <decl.h> 41#include <msg.h> 42#include <sgs.h> 43 44 45/* 46 * fmsize: Array used to determine what size the the structures 47 * are (for memory image & file image). 48 * 49 * x32: Translation routines - to file & to memory. 50 * 51 * What must be done when adding a new type for conversion: 52 * 53 * The first question is whether you need a new ELF_T_* type 54 * to be created. If you've introduced a new structure - then 55 * it will need to be described - this is done by: 56 * 57 * o adding a new type ELF_T_* to usr/src/head/libelf.h 58 * o Create a new macro to define the bytes contained in the structure. Take a 59 * look at the 'Syminfo_1' macro defined below. The declarations describe 60 * the structure based off of the field size of each element of the structure. 61 * o Add a entry to the fmsize table for the new ELF_T_* type. 62 * o Create a <newtype>_11_tof macro. Take a look at 'syminfo_11_tof'. 63 * o Create a <newtype>_11_tom macro. Take a look at 'syminfo_11_tom'. 64 * o The <newtype>_11_tof & <newtype>_11_tom results in conversion routines 65 * <newtype>_2L11_tof, <newtype>_2L11_tom, <newtype>_2M11_tof, 66 * <newtype>_2M11_tom being created in xlate.c. These routines 67 * need to be added to the 'x32[]' array. 68 * o Add entries to getdata.c::align32[] and getdata.c::align64[]. These 69 * tables define what the alignment requirements for a data type are. 70 * 71 * In order to tie a section header type (SHT_*) to a data 72 * structure you need to update elf32_mtype() so that it can 73 * make the association. If you are introducing a new section built 74 * on a basic datatype (SHT_INIT_ARRAY) then this is all the updating 75 * that needs to be done. 76 * 77 * 78 * ELF translation routines 79 * These routines make a subtle implicit assumption. 80 * The file representations of all structures are "packed," 81 * meaning no implicit padding bytes occur. This might not 82 * be the case for the memory representations. Consequently, 83 * the memory representations ALWAYS contain at least as many 84 * bytes as the file representations. Otherwise, the memory 85 * structures would lose information, meaning they're not 86 * implemented properly. 87 * 88 * The words above apply to structures with the same members. 89 * If a future version changes the number of members, the 90 * relative structure sizes for different version must be 91 * tested with the compiler. 92 */ 93 94#define HI32 0x80000000UL 95#define LO31 0x7fffffffUL 96 97/* 98 * These macros create indexes for accessing the bytes of 99 * words and halfwords for ELFCLASS32 data representations 100 * (currently ELFDATA2LSB and ELFDATA2MSB). In all cases, 101 * 102 * w = (((((X_3 << 8) + X_2) << 8) + X_1) << 8) + X_0 103 * h = (X_1 << 8) + X_0 104 * 105 * These assume the file representations for Addr, Off, 106 * Sword, and Word use 4 bytes, but the memory def's for 107 * the types may differ. 108 * 109 * Naming convention: 110 * ..._L ELFDATA2LSB 111 * ..._M ELFDATA2MSB 112 * 113 * enuma_*(n) define enum names for addr n 114 * enumb_*(n) define enum names for byte n 115 * enumh_*(n) define enum names for half n 116 * enumo_*(n) define enum names for off n 117 * enumw_*(n) define enum names for word n 118 * enuml_*(n) define enum names for Lword n 119 * tofa(d,s,n) xlate addr n from mem s to file d 120 * tofb(d,s,n) xlate byte n from mem s to file d 121 * tofh(d,s,n) xlate half n from mem s to file d 122 * tofo(d,s,n) xlate off n from mem s to file d 123 * tofw(d,s,n) xlate word n from mem s to file d 124 * tofl(d,s,n) xlate Lword n from mem s to file d 125 * toma(s,n) xlate addr n from file s to expression value 126 * tomb(s,n) xlate byte n from file s to expression value 127 * tomh(s,n) xlate half n from file s to expression value 128 * tomo(s,n) xlate off n from file s to expression value 129 * tomw(s,n) xlate word n from file s to expression value 130 * toml(s,n) xlate Lword n from file s to expression value 131 * 132 * tof*() macros must move a multi-byte value into a temporary 133 * because ``in place'' conversions are allowed. If a temp is not 134 * used for multi-byte objects, storing an initial destination byte 135 * may clobber a source byte not yet examined. 136 * 137 * tom*() macros compute an expression value from the source 138 * without touching the destination; so they're safe. 139 */ 140 141define(enuma_L, `$1_L0, $1_L1, $1_L2, $1_L3')dnl 142define(enuma_M, `$1_M3, $1_M2, $1_M1, $1_M0')dnl 143define(enumb_L, `$1_L')dnl 144define(enumb_M, `$1_M')dnl 145define(enumh_L, `$1_L0, $1_L1')dnl 146define(enumh_M, `$1_M1, $1_M0')dnl 147define(enumo_L, `$1_L0, $1_L1, $1_L2, $1_L3')dnl 148define(enumo_M, `$1_M3, $1_M2, $1_M1, $1_M0')dnl 149define(enumw_L, `$1_L0, $1_L1, $1_L2, $1_L3')dnl 150define(enumw_M, `$1_M3, $1_M2, $1_M1, $1_M0')dnl 151define(enuml_L, `$1_L0, $1_L1, $1_L2, $1_L3, $1_L4, $1_L5, $1_L6, $1_L7')dnl 152define(enuml_M, `$1_M7, $1_M6, $1_M5, $1_M4, $1_M3, $1_M2, $1_M1, $1_M0')dnl 153 154define(tofa, `{ register Elf32_Addr _t_ = $2; 155 ($1)[$3`'0] = (unsigned char)_t_, 156 ($1)[$3`'1] = (unsigned char)(_t_>>8), 157 ($1)[$3`'2] = (unsigned char)(_t_>>16), 158 ($1)[$3`'3] = (unsigned char)(_t_>>24); }')dnl 159define(tofb, `($1)[$3] = (unsigned char)($2)')dnl 160define(tofh, `{ register Elf32_Half _t_ = $2; 161 ($1)[$3`'0] = (unsigned char)_t_, 162 ($1)[$3`'1] = (unsigned char)(_t_>>8); }')dnl 163define(tofo, `{ register Elf32_Off _t_ = $2; 164 ($1)[$3`'0] = (unsigned char)_t_, 165 ($1)[$3`'1] = (unsigned char)(_t_>>8), 166 ($1)[$3`'2] = (unsigned char)(_t_>>16), 167 ($1)[$3`'3] = (unsigned char)(_t_>>24); }')dnl 168define(tofw, `{ register Elf32_Word _t_ = $2; 169 ($1)[$3`'0] = (unsigned char)_t_, 170 ($1)[$3`'1] = (unsigned char)(_t_>>8), 171 ($1)[$3`'2] = (unsigned char)(_t_>>16), 172 ($1)[$3`'3] = (unsigned char)(_t_>>24); }')dnl 173define(tofl, `{ Elf32_Lword _t_ = $2; 174 ($1)[$3`'0] = (Byte)_t_, 175 ($1)[$3`'1] = (Byte)(_t_>>8), 176 ($1)[$3`'2] = (Byte)(_t_>>16), 177 ($1)[$3`'3] = (Byte)(_t_>>24), 178 ($1)[$3`'4] = (Byte)(_t_>>32), 179 ($1)[$3`'5] = (Byte)(_t_>>40), 180 ($1)[$3`'6] = (Byte)(_t_>>48), 181 ($1)[$3`'7] = (Byte)(_t_>>56); }')dnl 182 183define(toma, `(((((((Elf32_Addr)($1)[$2`'3]<<8) 184 +($1)[$2`'2])<<8) 185 +($1)[$2`'1])<<8) 186 +($1)[$2`'0])')dnl 187define(tomb, `((unsigned char)($1)[$2])')dnl 188define(tomh, `(((Elf32_Half)($1)[$2`'1]<<8)+($1)[$2`'0])')dnl 189define(tomo, `(((((((Elf32_Off)($1)[$2`'3]<<8) 190 +($1)[$2`'2])<<8) 191 +($1)[$2`'1])<<8) 192 +($1)[$2`'0])')dnl 193define(tomw, `(((((((Elf32_Word)($1)[$2`'3]<<8) 194 +($1)[$2`'2])<<8) 195 +($1)[$2`'1])<<8) 196 +($1)[$2`'0])')dnl 197define(toml, `(((((((((((Elf32_Lword)($1)[$2`'7]<<8) 198 +($1)[$2`'6]<<8) 199 +($1)[$2`'5]<<8) 200 +($1)[$2`'4]<<8) 201 +($1)[$2`'3]<<8) 202 +($1)[$2`'2])<<8) 203 +($1)[$2`'1])<<8) 204 +($1)[$2`'0])')dnl 205 206 207/* 208 * ELF data object indexes 209 * The enums are broken apart to get around deficiencies 210 * in some compilers. 211 */ 212 213define(Addr, ` 214enum 215{ 216 enuma_$1(A)`'ifelse(`$2', `', `', `, 217 A_sizeof') 218};') 219 220Addr(L) 221Addr(M,1) 222 223 224define(Half, ` 225enum 226{ 227 enumh_$1(H)`'ifelse(`$2', `', `', `, 228 H_sizeof') 229};') 230 231Half(L) 232Half(M,1) 233 234define(Lword, ` 235enum 236{ 237 enuml_$1(L)`'ifelse(`$2', `', `', `, 238 L_sizeof') 239};') 240 241Lword(L) 242Lword(M,1) 243 244 245define(Move_1, ` 246enum 247{ 248 enuml_$1(M1_value), 249 enumw_$1(M1_info), 250 enumw_$1(M1_poffset), 251 enumh_$1(M1_repeat), 252 enumh_$1(M1_stride)`'ifelse(`$2', `', `', `, 253 M1_sizeof') 254};') 255 256Move_1(L) 257Move_1(M,1) 258 259 260define(MoveP_1, ` 261enum 262{ 263 enuml_$1(MP1_value), 264 enumw_$1(MP1_info), 265 enumw_$1(MP1_poffset), 266 enumh_$1(MP1_repeat), 267 enumh_$1(MP1_stride), 268 enumw_$1(MP1_padding)`'ifelse(`$2', `', `', `, 269 MP1_sizeof') 270};') 271 272MoveP_1(L) 273MoveP_1(M,1) 274 275 276define(Off, ` 277enum 278{ 279 enumo_$1(O)`'ifelse(`$2', `', `', `, 280 O_sizeof') 281};') 282 283Off(L) 284Off(M,1) 285 286 287define(Word, ` 288enum 289{ 290 enumw_$1(W)`'ifelse(`$2', `', `', `, 291 W_sizeof') 292};') 293 294Word(L) 295Word(M,1) 296 297 298define(Dyn_1, ` 299enum 300{ 301 enumw_$1(D1_tag), 302 enumw_$1(D1_val)`'ifelse(`$2', `', `', `, 303 D1_sizeof') 304};') 305 306Dyn_1(L) 307Dyn_1(M,1) 308 309 310#define E1_Nident 16 311 312define(Ehdr_1, ` 313enum 314{ 315 ifelse(`$2', `', `E1_ident, ')E1_ident_$1_Z = E1_Nident - 1, 316 enumh_$1(E1_type), 317 enumh_$1(E1_machine), 318 enumw_$1(E1_version), 319 enuma_$1(E1_entry), 320 enumo_$1(E1_phoff), 321 enumo_$1(E1_shoff), 322 enumw_$1(E1_flags), 323 enumh_$1(E1_ehsize), 324 enumh_$1(E1_phentsize), 325 enumh_$1(E1_phnum), 326 enumh_$1(E1_shentsize), 327 enumh_$1(E1_shnum), 328 enumh_$1(E1_shstrndx)`'ifelse(`$2', `', `', `, 329 E1_sizeof') 330};') 331 332Ehdr_1(L) 333Ehdr_1(M,1) 334 335define(Nhdr_1, ` 336enum 337{ 338 enumw_$1(N1_namesz), 339 enumw_$1(N1_descsz), 340 enumw_$1(N1_type)`'ifelse(`$2', `', `', `, 341 N1_sizeof') 342};') 343 344Nhdr_1(L) 345Nhdr_1(M,1) 346 347define(Phdr_1, ` 348enum 349{ 350 enumw_$1(P1_type), 351 enumo_$1(P1_offset), 352 enuma_$1(P1_vaddr), 353 enuma_$1(P1_paddr), 354 enumw_$1(P1_filesz), 355 enumw_$1(P1_memsz), 356 enumw_$1(P1_flags), 357 enumw_$1(P1_align)`'ifelse(`$2', `', `', `, 358 P1_sizeof') 359};') 360 361Phdr_1(L) 362Phdr_1(M,1) 363 364 365define(Rel_1, ` 366enum 367{ 368 enuma_$1(R1_offset), 369 enumw_$1(R1_info)`'ifelse(`$2', `', `', `, 370 R1_sizeof') 371};') 372 373Rel_1(L) 374Rel_1(M,1) 375 376 377define(Rela_1, ` 378enum 379{ 380 enuma_$1(RA1_offset), 381 enumw_$1(RA1_info), 382 enumw_$1(RA1_addend)`'ifelse(`$2', `', `', `, 383 RA1_sizeof') 384};') 385 386Rela_1(L) 387Rela_1(M,1) 388 389 390define(Shdr_1, ` 391enum 392{ 393 enumw_$1(SH1_name), 394 enumw_$1(SH1_type), 395 enumw_$1(SH1_flags), 396 enuma_$1(SH1_addr), 397 enumo_$1(SH1_offset), 398 enumw_$1(SH1_size), 399 enumw_$1(SH1_link), 400 enumw_$1(SH1_info), 401 enumw_$1(SH1_addralign), 402 enumw_$1(SH1_entsize)`'ifelse(`$2', `', `', `, 403 SH1_sizeof') 404};') 405 406Shdr_1(L) 407Shdr_1(M,1) 408 409 410define(Sym_1, ` 411enum 412{ 413 enumw_$1(ST1_name), 414 enuma_$1(ST1_value), 415 enumw_$1(ST1_size), 416 enumb_$1(ST1_info), 417 enumb_$1(ST1_other), 418 enumh_$1(ST1_shndx)`'ifelse(`$2', `', `', `, 419 ST1_sizeof') 420};') 421 422Sym_1(L) 423Sym_1(M,1) 424 425 426define(Syminfo_1, ` 427enum 428{ 429 enumh_$1(SI1_boundto), 430 enumh_$1(SI1_flags)`'ifelse(`$2', `', `', `, 431 SI1_sizeof') 432};') 433 434Syminfo_1(L) 435Syminfo_1(M,1) 436 437 438define(Cap_1, ` 439enum 440{ 441 enumw_$1(C1_tag), 442 enumw_$1(C1_val)`'ifelse(`$2', `', `', `, 443 C1_sizeof') 444};') 445 446Cap_1(L) 447Cap_1(M,1) 448 449 450define(Verdef_1, ` 451enum 452{ 453 enumh_$1(VD1_version), 454 enumh_$1(VD1_flags), 455 enumh_$1(VD1_ndx), 456 enumh_$1(VD1_cnt), 457 enumw_$1(VD1_hash), 458 enumw_$1(VD1_aux), 459 enumw_$1(VD1_next)`'ifelse(`$2', `', `', `, 460 VD1_sizeof') 461};') 462 463Verdef_1(L) 464Verdef_1(M,1) 465 466 467define(Verdaux_1, ` 468enum 469{ 470 enuma_$1(VDA1_name), 471 enumw_$1(VDA1_next)`'ifelse(`$2', `', `', `, 472 VDA1_sizeof') 473};') 474 475Verdaux_1(L) 476Verdaux_1(M,1) 477 478 479define(Verneed_1, ` 480enum 481{ 482 enumh_$1(VN1_version), 483 enumh_$1(VN1_cnt), 484 enuma_$1(VN1_file), 485 enumw_$1(VN1_aux), 486 enumw_$1(VN1_next)`'ifelse(`$2', `', `', `, 487 VN1_sizeof') 488};') 489 490Verneed_1(L) 491Verneed_1(M,1) 492 493 494define(Vernaux_1, ` 495enum 496{ 497 enumw_$1(VNA1_hash), 498 enumh_$1(VNA1_flags), 499 enumh_$1(VNA1_other), 500 enuma_$1(VNA1_name), 501 enumw_$1(VNA1_next)`'ifelse(`$2', `', `', `, 502 VNA1_sizeof') 503};') 504 505Vernaux_1(L) 506Vernaux_1(M,1) 507 508 509/* 510 * Translation function declarations. 511 * 512 * <object>_<data><dver><sver>_tof 513 * <object>_<data><dver><sver>_tom 514 * where 515 * <data> 2L ELFDATA2LSB 516 * 2M ELFDATA2MSB 517 */ 518 519static void addr_2L_tof(), addr_2L_tom(), 520 addr_2M_tof(), addr_2M_tom(), 521 byte_to(), 522 dyn_2L11_tof(), dyn_2L11_tom(), 523 dyn_2M11_tof(), dyn_2M11_tom(), 524 ehdr_2L11_tof(), ehdr_2L11_tom(), 525 ehdr_2M11_tof(), ehdr_2M11_tom(), 526 half_2L_tof(), half_2L_tom(), 527 half_2M_tof(), half_2M_tom(), 528 move_2L11_tof(), move_2L11_tom(), 529 move_2M11_tof(), move_2M11_tom(), 530 movep_2L11_tof(), movep_2L11_tom(), 531 movep_2M11_tof(), movep_2M11_tom(), 532 off_2L_tof(), off_2L_tom(), 533 off_2M_tof(), off_2M_tom(), 534 note_2L11_tof(), note_2L11_tom(), 535 note_2M11_tof(), note_2M11_tom(), 536 phdr_2L11_tof(), phdr_2L11_tom(), 537 phdr_2M11_tof(), phdr_2M11_tom(), 538 rel_2L11_tof(), rel_2L11_tom(), 539 rel_2M11_tof(), rel_2M11_tom(), 540 rela_2L11_tof(), rela_2L11_tom(), 541 rela_2M11_tof(), rela_2M11_tom(), 542 shdr_2L11_tof(), shdr_2L11_tom(), 543 shdr_2M11_tof(), shdr_2M11_tom(), 544 sword_2L_tof(), sword_2L_tom(), 545 sword_2M_tof(), sword_2M_tom(), 546 sym_2L11_tof(), sym_2L11_tom(), 547 sym_2M11_tof(), sym_2M11_tom(), 548 syminfo_2L11_tof(), syminfo_2L11_tom(), 549 syminfo_2M11_tof(), syminfo_2M11_tom(), 550 word_2L_tof(), word_2L_tom(), 551 word_2M_tof(), word_2M_tom(), 552 verdef_2L11_tof(), verdef_2L11_tom(), 553 verdef_2M11_tof(), verdef_2M11_tom(), 554 verneed_2L11_tof(), verneed_2L11_tom(), 555 verneed_2M11_tof(), verneed_2M11_tom(), 556 cap_2L11_tof(), cap_2L11_tom(), 557 cap_2M11_tof(), cap_2M11_tom(); 558 559 560/* x32 [dst_version - 1] [src_version - 1] [encode - 1] [type] 561 */ 562 563static struct { 564 void (*x_tof)(), 565 (*x_tom)(); 566} x32 [EV_CURRENT] [EV_CURRENT] [ELFDATANUM - 1] [ELF_T_NUM] = 567{ 568 { 569 { 570 { /* [1-1][1-1][2LSB-1][.] */ 571/* BYTE */ { byte_to, byte_to }, 572/* ADDR */ { addr_2L_tof, addr_2L_tom }, 573/* DYN */ { dyn_2L11_tof, dyn_2L11_tom }, 574/* EHDR */ { ehdr_2L11_tof, ehdr_2L11_tom }, 575/* HALF */ { half_2L_tof, half_2L_tom }, 576/* OFF */ { off_2L_tof, off_2L_tom }, 577/* PHDR */ { phdr_2L11_tof, phdr_2L11_tom }, 578/* RELA */ { rela_2L11_tof, rela_2L11_tom }, 579/* REL */ { rel_2L11_tof, rel_2L11_tom }, 580/* SHDR */ { shdr_2L11_tof, shdr_2L11_tom }, 581/* SWORD */ { sword_2L_tof, sword_2L_tom }, 582/* SYM */ { sym_2L11_tof, sym_2L11_tom }, 583/* WORD */ { word_2L_tof, word_2L_tom }, 584/* VERDEF */ { verdef_2L11_tof, verdef_2L11_tom}, 585/* VERNEED */ { verneed_2L11_tof, verneed_2L11_tom}, 586/* SXWORD */ { 0, 0 }, /* illegal 32-bit op */ 587/* XWORD */ { 0, 0 }, /* illegal 32-bit op */ 588/* SYMINFO */ { syminfo_2L11_tof, syminfo_2L11_tom }, 589/* NOTE */ { note_2L11_tof, note_2L11_tom }, 590/* MOVE */ { move_2L11_tof, move_2L11_tom }, 591/* MOVEP */ { movep_2L11_tof, movep_2L11_tom }, 592/* CAP */ { cap_2L11_tof, cap_2L11_tom }, 593 }, 594 { /* [1-1][1-1][2MSB-1][.] */ 595/* BYTE */ { byte_to, byte_to }, 596/* ADDR */ { addr_2M_tof, addr_2M_tom }, 597/* DYN */ { dyn_2M11_tof, dyn_2M11_tom }, 598/* EHDR */ { ehdr_2M11_tof, ehdr_2M11_tom }, 599/* HALF */ { half_2M_tof, half_2M_tom }, 600/* OFF */ { off_2M_tof, off_2M_tom }, 601/* PHDR */ { phdr_2M11_tof, phdr_2M11_tom }, 602/* RELA */ { rela_2M11_tof, rela_2M11_tom }, 603/* REL */ { rel_2M11_tof, rel_2M11_tom }, 604/* SHDR */ { shdr_2M11_tof, shdr_2M11_tom }, 605/* SWORD */ { sword_2M_tof, sword_2M_tom }, 606/* SYM */ { sym_2M11_tof, sym_2M11_tom }, 607/* WORD */ { word_2M_tof, word_2M_tom }, 608/* VERDEF */ { verdef_2M11_tof, verdef_2M11_tom}, 609/* VERNEED */ { verneed_2M11_tof, verneed_2M11_tom}, 610/* SXWORD */ { 0, 0 }, /* illegal 32-bit op */ 611/* XWORD */ { 0, 0 }, /* illegal 32-bit op */ 612/* SYMINFO */ { syminfo_2M11_tof, syminfo_2M11_tom }, 613/* NOTE */ { note_2M11_tof, note_2M11_tom }, 614/* MOVE */ { move_2M11_tof, move_2M11_tom }, 615/* MOVEP */ { movep_2M11_tof, movep_2M11_tom }, 616/* CAP */ { cap_2M11_tof, cap_2M11_tom }, 617 }, 618 }, 619 }, 620}; 621 622 623/* 624 * size [version - 1] [type] 625 */ 626 627static const struct { 628 size_t s_filesz, 629 s_memsz; 630} fmsize [EV_CURRENT] [ELF_T_NUM] = 631{ 632 { /* [1-1][.] */ 633/* BYTE */ { 1, 1 }, 634/* ADDR */ { A_sizeof, sizeof (Elf32_Addr) }, 635/* DYN */ { D1_sizeof, sizeof (Elf32_Dyn) }, 636/* EHDR */ { E1_sizeof, sizeof (Elf32_Ehdr) }, 637/* HALF */ { H_sizeof, sizeof (Elf32_Half) }, 638/* OFF */ { O_sizeof, sizeof (Elf32_Off) }, 639/* PHDR */ { P1_sizeof, sizeof (Elf32_Phdr) }, 640/* RELA */ { RA1_sizeof, sizeof (Elf32_Rela) }, 641/* REL */ { R1_sizeof, sizeof (Elf32_Rel) }, 642/* SHDR */ { SH1_sizeof, sizeof (Elf32_Shdr) }, 643/* SWORD */ { W_sizeof, sizeof (Elf32_Sword) }, 644/* SYM */ { ST1_sizeof, sizeof (Elf32_Sym) }, 645/* WORD */ { W_sizeof, sizeof (Elf32_Word) }, 646/* VERDEF */ { 1, 1}, /* because bot VERDEF & VERNEED have varying */ 647/* VERNEED */ { 1, 1}, /* sized structures we set their sizes */ 648 /* to 1 byte */ 649/* SXWORD */ { 0, 0 }, /* illegal 32-bit op */ 650/* XWORD */ { 0, 0 }, /* illegal 32-bit op */ 651/* SYMINFO */ { SI1_sizeof, sizeof (Elf32_Syminfo) }, 652/* NOTE */ { 1, 1}, /* NOTE has varying sized data we can't */ 653 /* use the usual table magic. */ 654/* MOVE */ { M1_sizeof, sizeof (Elf32_Move) }, 655/* MOVEP */ { MP1_sizeof, sizeof (Elf32_Move) }, 656/* CAP */ { C1_sizeof, sizeof (Elf32_Cap) }, 657 }, 658}; 659 660 661/* 662 * memory type [version - 1] [section type] 663 */ 664 665static const Elf_Type mtype[EV_CURRENT][SHT_NUM] = 666{ 667 { /* [1-1][.] */ 668/* NULL */ ELF_T_BYTE, 669/* PROGBITS */ ELF_T_BYTE, 670/* SYMTAB */ ELF_T_SYM, 671/* STRTAB */ ELF_T_BYTE, 672/* RELA */ ELF_T_RELA, 673/* HASH */ ELF_T_WORD, 674/* DYNAMIC */ ELF_T_DYN, 675/* NOTE */ ELF_T_NOTE, 676/* NOBITS */ ELF_T_BYTE, 677/* REL */ ELF_T_REL, 678/* SHLIB */ ELF_T_BYTE, 679/* DYNSYM */ ELF_T_SYM, 680/* UNKNOWN12 */ ELF_T_BYTE, 681/* UNKNOWN13 */ ELF_T_BYTE, 682/* INIT_ARRAY */ ELF_T_ADDR, 683/* FINI_ARRAY */ ELF_T_ADDR, 684/* PREINIT_ARRAY */ ELF_T_ADDR, 685/* GROUP */ ELF_T_WORD, 686/* SYMTAB_SHNDX */ ELF_T_WORD 687 }, 688}; 689 690 691size_t 692elf32_fsize(Elf_Type type, size_t count, unsigned ver) 693{ 694 if (--ver >= EV_CURRENT) { 695 _elf_seterr(EREQ_VER, 0); 696 return (0); 697 } 698 if ((unsigned)type >= ELF_T_NUM) { 699 _elf_seterr(EREQ_TYPE, 0); 700 return (0); 701 } 702 return (fmsize[ver][type].s_filesz * count); 703} 704 705 706size_t 707_elf32_msize(Elf_Type type, unsigned ver) 708{ 709 return (fmsize[ver - 1][type].s_memsz); 710} 711 712 713Elf_Type 714_elf32_mtype(Elf * elf, Elf32_Word shtype, unsigned ver) 715{ 716 Elf32_Ehdr * ehdr = (Elf32_Ehdr *)elf->ed_ehdr; 717 718 if (shtype < SHT_NUM) 719 return (mtype[ver - 1][shtype]); 720 721 switch (shtype) { 722 case SHT_SUNW_symsort: 723 case SHT_SUNW_tlssort: 724 return (ELF_T_WORD); 725 case SHT_SUNW_LDYNSYM: 726 return (ELF_T_SYM); 727 case SHT_SUNW_dof: 728 return (ELF_T_BYTE); 729 case SHT_SUNW_cap: 730 return (ELF_T_CAP); 731 case SHT_SUNW_SIGNATURE: 732 return (ELF_T_BYTE); 733 case SHT_SUNW_ANNOTATE: 734 return (ELF_T_BYTE); 735 case SHT_SUNW_DEBUGSTR: 736 return (ELF_T_BYTE); 737 case SHT_SUNW_DEBUG: 738 return (ELF_T_BYTE); 739 case SHT_SUNW_move: 740 /* 741 * 32bit sparc binaries have a padded 742 * MOVE structure. So - return the 743 * appropriate type. 744 */ 745 if ((ehdr->e_machine == EM_SPARC) || 746 (ehdr->e_machine == EM_SPARC32PLUS)) { 747 return (ELF_T_MOVEP); 748 } 749 750 return (ELF_T_MOVE); 751 case SHT_SUNW_COMDAT: 752 return (ELF_T_BYTE); 753 case SHT_SUNW_syminfo: 754 return (ELF_T_SYMINFO); 755 case SHT_SUNW_verdef: 756 return (ELF_T_VDEF); 757 case SHT_SUNW_verneed: 758 return (ELF_T_VNEED); 759 case SHT_SUNW_versym: 760 return (ELF_T_HALF); 761 }; 762 763 /* 764 * Check for the sparc specific section types 765 * below. 766 */ 767 if (((ehdr->e_machine == EM_SPARC) || 768 (ehdr->e_machine == EM_SPARC32PLUS) || 769 (ehdr->e_machine == EM_SPARCV9)) && 770 (shtype == SHT_SPARC_GOTDATA)) 771 return (ELF_T_BYTE); 772 773 /* 774 * Check for the amd64 specific section types 775 * below. 776 */ 777 if ((ehdr->e_machine == EM_AMD64) && 778 (shtype == SHT_AMD64_UNWIND)) 779 return (ELF_T_BYTE); 780 781 /* 782 * And the default is ELF_T_BYTE - but we should 783 * certainly have caught any sections we know about 784 * above. This is for unknown sections to libelf. 785 */ 786 return (ELF_T_BYTE); 787} 788 789 790size_t 791_elf32_entsz(Elf *elf, Elf32_Word shtype, unsigned ver) 792{ 793 Elf_Type ttype; 794 795 ttype = _elf32_mtype(elf, shtype, ver); 796 return ((ttype == ELF_T_BYTE) ? 0 : fmsize[ver - 1][ttype].s_filesz); 797} 798 799 800/* 801 * Determine the data encoding used by the current system. 802 */ 803uint_t 804_elf_sys_encoding(void) 805{ 806 union { 807 Elf32_Word w; 808 unsigned char c[W_sizeof]; 809 } u; 810 811 u.w = 0x10203; 812 /*CONSTANTCONDITION*/ 813 if (~(Elf32_Word)0 == -(Elf32_Sword)1 && tomw(u.c, W_L) == 0x10203) 814 return (ELFDATA2LSB); 815 816 /*CONSTANTCONDITION*/ 817 if (~(Elf32_Word)0 == -(Elf32_Sword)1 && tomw(u.c, W_M) == 0x10203) 818 return (ELFDATA2MSB); 819 820 /* Not expected to occur */ 821 return (ELFDATANONE); 822} 823 824 825/* 826 * XX64 This routine is also used to 'version' interactions with Elf64 827 * applications, but there's no way to figure out if the caller is 828 * asking Elf32 or Elf64 questions, even though it has Elf32 829 * dependencies. Ick. 830 */ 831unsigned 832elf_version(unsigned ver) 833{ 834 register unsigned j; 835 836 if (ver == EV_NONE) 837 return EV_CURRENT; 838 if (ver > EV_CURRENT) 839 { 840 _elf_seterr(EREQ_VER, 0); 841 return EV_NONE; 842 } 843 (void) mutex_lock(&_elf_globals_mutex); 844 if (_elf_work != EV_NONE) 845 { 846 j = _elf_work; 847 _elf_work = ver; 848 (void) mutex_unlock(&_elf_globals_mutex); 849 return j; 850 } 851 _elf_work = ver; 852 853 _elf_encode = _elf_sys_encoding(); 854 855 (void) mutex_unlock(&_elf_globals_mutex); 856 857 return ver; 858} 859 860 861static Elf_Data * 862xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof) 863 /* tof !0 -> xlatetof */ 864{ 865 size_t cnt, dsz, ssz; 866 unsigned type; 867 unsigned dver, sver; 868 void (*f)(); 869 unsigned _encode; 870 871 if (dst == 0 || src == 0) 872 return (0); 873 if (--encode >= (ELFDATANUM - 1)) { 874 _elf_seterr(EREQ_ENCODE, 0); 875 return (0); 876 } 877 if ((dver = dst->d_version - 1) >= EV_CURRENT || 878 (sver = src->d_version - 1) >= EV_CURRENT) { 879 _elf_seterr(EREQ_VER, 0); 880 return (0); 881 } 882 if ((type = src->d_type) >= ELF_T_NUM) { 883 _elf_seterr(EREQ_TYPE, 0); 884 return (0); 885 } 886 887 if (tof) { 888 dsz = fmsize[dver][type].s_filesz; 889 ssz = fmsize[sver][type].s_memsz; 890 f = x32[dver][sver][encode][type].x_tof; 891 } else { 892 dsz = fmsize[dver][type].s_memsz; 893 ssz = fmsize[sver][type].s_filesz; 894 f = x32[dver][sver][encode][type].x_tom; 895 } 896 cnt = src->d_size / ssz; 897 if (dst->d_size < dsz * cnt) { 898 _elf_seterr(EREQ_DSZ, 0); 899 return (0); 900 } 901 902 ELFACCESSDATA(_encode, _elf_encode) 903 if ((_encode == (encode + 1)) && (dsz == ssz)) { 904 /* 905 * ld(1) frequently produces empty sections (eg. .dynsym, 906 * .dynstr, .symtab, .strtab, etc) so that the initial 907 * output image can be created of the correct size. Later 908 * these sections are filled in with the associated data. 909 * So that we don't have to pre-allocate buffers for 910 * these segments, allow for the src destination to be 0. 911 */ 912 if (src->d_buf && src->d_buf != dst->d_buf) 913 (void) memcpy(dst->d_buf, src->d_buf, src->d_size); 914 dst->d_type = src->d_type; 915 dst->d_size = src->d_size; 916 return (dst); 917 } 918 if (cnt) 919 (*f)(dst->d_buf, src->d_buf, cnt); 920 dst->d_size = dsz * cnt; 921 dst->d_type = src->d_type; 922 return (dst); 923} 924 925 926Elf_Data * 927elf32_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned encode) 928{ 929 return (xlate(dst, src, encode, 1)); 930} 931 932 933Elf_Data * 934elf32_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned encode) 935{ 936 return (xlate(dst, src, encode, 0)); 937} 938 939 940/* 941 * xlate to file format 942 * 943 * ..._tof(name, data) -- macros 944 * 945 * Recall that the file format must be no larger than the 946 * memory format (equal versions). Use "forward" copy. 947 * All these routines require non-null, non-zero arguments. 948 */ 949 950define(addr_tof, ` 951static void 952$1(unsigned char *dst, Elf32_Addr *src, size_t cnt) 953{ 954 Elf32_Addr *end = src + cnt; 955 956 do { 957 tofa(dst, *src, A_$2); 958 dst += A_sizeof; 959 } while (++src < end); 960}') 961 962addr_tof(addr_2L_tof,L) 963addr_tof(addr_2M_tof,M) 964 965 966static void 967byte_to(unsigned char *dst, unsigned char *src, size_t cnt) 968{ 969 if (dst != src) 970 (void) memcpy(dst, src, cnt); 971} 972 973 974define(dyn_11_tof, ` 975static void 976$1(unsigned char *dst, Elf32_Dyn *src, size_t cnt) 977{ 978 Elf32_Dyn *end = src + cnt; 979 980 do { 981 tofw(dst, src->d_tag, D1_tag_$2); 982 tofo(dst, src->d_un.d_val, D1_val_$2); 983 dst += D1_sizeof; 984 } while (++src < end); 985}') 986 987dyn_11_tof(dyn_2L11_tof,L) 988dyn_11_tof(dyn_2M11_tof,M) 989 990 991define(ehdr_11_tof, ` 992static void 993$1(unsigned char *dst, Elf32_Ehdr *src, size_t cnt) 994{ 995 Elf32_Ehdr *end = src + cnt; 996 997 do { 998 if (&dst[E1_ident] != src->e_ident) 999 (void) memcpy(&dst[E1_ident], src->e_ident, E1_Nident); 1000 tofh(dst, src->e_type, E1_type_$2); 1001 tofh(dst, src->e_machine, E1_machine_$2); 1002 tofw(dst, src->e_version, E1_version_$2); 1003 tofa(dst, src->e_entry, E1_entry_$2); 1004 tofo(dst, src->e_phoff, E1_phoff_$2); 1005 tofo(dst, src->e_shoff, E1_shoff_$2); 1006 tofw(dst, src->e_flags, E1_flags_$2); 1007 tofh(dst, src->e_ehsize, E1_ehsize_$2); 1008 tofh(dst, src->e_phentsize, E1_phentsize_$2); 1009 tofh(dst, src->e_phnum, E1_phnum_$2); 1010 tofh(dst, src->e_shentsize, E1_shentsize_$2); 1011 tofh(dst, src->e_shnum, E1_shnum_$2); 1012 tofh(dst, src->e_shstrndx, E1_shstrndx_$2); 1013 dst += E1_sizeof; 1014 } while (++src < end); 1015}') 1016 1017ehdr_11_tof(ehdr_2L11_tof,L) 1018ehdr_11_tof(ehdr_2M11_tof,M) 1019 1020 1021define(half_tof, ` 1022static void 1023$1(unsigned char *dst, Elf32_Half *src, size_t cnt) 1024{ 1025 Elf32_Half *end = src + cnt; 1026 1027 do { 1028 tofh(dst, *src, H_$2); 1029 dst += H_sizeof; 1030 } while (++src < end); 1031}') 1032 1033half_tof(half_2L_tof,L) 1034half_tof(half_2M_tof,M) 1035 1036 1037define(move_11_tof, ` 1038static void 1039$1(unsigned char *dst, Elf32_Move *src, size_t cnt) 1040{ 1041 Elf32_Move *end = src + cnt; 1042 1043 do { 1044 tofl(dst, src->m_value, M1_value_$2); 1045 tofw(dst, src->m_info, M1_info_$2); 1046 tofw(dst, src->m_poffset, M1_poffset_$2); 1047 tofh(dst, src->m_repeat, M1_repeat_$2); 1048 tofh(dst, src->m_stride, M1_stride_$2); 1049 dst += M1_sizeof; 1050 } while (++src < end); 1051}') 1052 1053move_11_tof(move_2L11_tof,L) 1054move_11_tof(move_2M11_tof,M) 1055 1056 1057define(movep_11_tof, ` 1058static void 1059$1(unsigned char *dst, Elf32_Move *src, size_t cnt) 1060{ 1061 Elf32_Move *end = src + cnt; 1062 1063 do { 1064 tofl(dst, src->m_value, MP1_value_$2); 1065 tofw(dst, src->m_info, MP1_info_$2); 1066 tofw(dst, src->m_poffset, MP1_poffset_$2); 1067 tofh(dst, src->m_repeat, MP1_repeat_$2); 1068 tofh(dst, src->m_stride, MP1_stride_$2); 1069 dst += MP1_sizeof; 1070 } while (++src < end); 1071}') 1072 1073movep_11_tof(movep_2L11_tof,L) 1074movep_11_tof(movep_2M11_tof,M) 1075 1076 1077define(off_tof, ` 1078static void 1079$1(unsigned char *dst, Elf32_Off *src, size_t cnt) 1080{ 1081 Elf32_Off *end = src + cnt; 1082 1083 do { 1084 tofo(dst, *src, O_$2); 1085 dst += O_sizeof; 1086 } while (++src < end); 1087}') 1088 1089off_tof(off_2L_tof,L) 1090off_tof(off_2M_tof,M) 1091 1092 1093define(note_11_tof, ` 1094static void 1095$1(unsigned char *dst, Elf32_Nhdr *src, size_t cnt) 1096{ 1097 /* LINTED */ 1098 Elf32_Nhdr * end = (Elf32_Nhdr *)((char *)src + cnt); 1099 1100 do { 1101 Elf32_Word descsz, namesz; 1102 1103 /* 1104 * cache size of desc & name fields - while rounding 1105 * up their size. 1106 */ 1107 namesz = S_ROUND(src->n_namesz, sizeof (Elf32_Word)); 1108 descsz = src->n_descsz; 1109 1110 /* 1111 * Copy contents of Elf32_Nhdr 1112 */ 1113 tofw(dst, src->n_namesz, N1_namesz_$2); 1114 tofw(dst, src->n_descsz, N1_descsz_$2); 1115 tofw(dst, src->n_type, N1_type_$2); 1116 1117 /* 1118 * Copy contents of Name field 1119 */ 1120 dst += N1_sizeof; 1121 src++; 1122 (void)memcpy(dst, src, namesz); 1123 1124 /* 1125 * Copy contents of desc field 1126 */ 1127 dst += namesz; 1128 src = (Elf32_Nhdr *)((uintptr_t)src + namesz); 1129 (void)memcpy(dst, src, descsz); 1130 descsz = S_ROUND(descsz, sizeof (Elf32_Word)); 1131 dst += descsz; 1132 src = (Elf32_Nhdr *)((uintptr_t)src + descsz); 1133 } while (src < end); 1134}') 1135 1136note_11_tof(note_2L11_tof,L) 1137note_11_tof(note_2M11_tof,M) 1138 1139 1140define(phdr_11_tof, ` 1141static void 1142$1(unsigned char *dst, Elf32_Phdr *src, size_t cnt) 1143{ 1144 Elf32_Phdr *end = src + cnt; 1145 1146 do { 1147 tofw(dst, src->p_type, P1_type_$2); 1148 tofo(dst, src->p_offset, P1_offset_$2); 1149 tofa(dst, src->p_vaddr, P1_vaddr_$2); 1150 tofa(dst, src->p_paddr, P1_paddr_$2); 1151 tofw(dst, src->p_filesz, P1_filesz_$2); 1152 tofw(dst, src->p_memsz, P1_memsz_$2); 1153 tofw(dst, src->p_flags, P1_flags_$2); 1154 tofw(dst, src->p_align, P1_align_$2); 1155 dst += P1_sizeof; 1156 } while (++src < end); 1157}') 1158 1159phdr_11_tof(phdr_2L11_tof,L) 1160phdr_11_tof(phdr_2M11_tof,M) 1161 1162 1163define(rel_11_tof, ` 1164static void 1165$1(unsigned char *dst, Elf32_Rel *src, size_t cnt) 1166{ 1167 Elf32_Rel *end = src + cnt; 1168 1169 do { 1170 tofa(dst, src->r_offset, R1_offset_$2); 1171 tofw(dst, src->r_info, R1_info_$2); 1172 dst += R1_sizeof; 1173 } while (++src < end); 1174}') 1175 1176rel_11_tof(rel_2L11_tof,L) 1177rel_11_tof(rel_2M11_tof,M) 1178 1179 1180define(rela_11_tof, ` 1181static void 1182$1(unsigned char *dst, Elf32_Rela *src, size_t cnt) 1183{ 1184 Elf32_Rela *end = src + cnt; 1185 1186 do { 1187 tofa(dst, src->r_offset, RA1_offset_$2); 1188 tofw(dst, src->r_info, RA1_info_$2); 1189 /*CONSTANTCONDITION*/ 1190 if (~(Elf32_Word)0 == -(Elf32_Sword)1) { /* 2s comp */ 1191 tofw(dst, src->r_addend, RA1_addend_$2); 1192 } else { 1193 Elf32_Word w; 1194 1195 if (src->r_addend < 0) { 1196 w = - src->r_addend; 1197 w = ~w + 1; 1198 } else 1199 w = src->r_addend; 1200 tofw(dst, w, RA1_addend_$2); 1201 } 1202 dst += RA1_sizeof; 1203 } while (++src < end); 1204}') 1205 1206rela_11_tof(rela_2L11_tof,L) 1207rela_11_tof(rela_2M11_tof,M) 1208 1209 1210define(shdr_11_tof, ` 1211static void 1212$1(unsigned char *dst, Elf32_Shdr *src, size_t cnt) 1213{ 1214 Elf32_Shdr *end = src + cnt; 1215 1216 do { 1217 tofw(dst, src->sh_name, SH1_name_$2); 1218 tofw(dst, src->sh_type, SH1_type_$2); 1219 tofw(dst, src->sh_flags, SH1_flags_$2); 1220 tofa(dst, src->sh_addr, SH1_addr_$2); 1221 tofo(dst, src->sh_offset, SH1_offset_$2); 1222 tofw(dst, src->sh_size, SH1_size_$2); 1223 tofw(dst, src->sh_link, SH1_link_$2); 1224 tofw(dst, src->sh_info, SH1_info_$2); 1225 tofw(dst, src->sh_addralign, SH1_addralign_$2); 1226 tofw(dst, src->sh_entsize, SH1_entsize_$2); 1227 dst += SH1_sizeof; 1228 } while (++src < end); 1229}') 1230 1231shdr_11_tof(shdr_2L11_tof,L) 1232shdr_11_tof(shdr_2M11_tof,M) 1233 1234 1235define(sword_tof, ` 1236static void 1237$1(unsigned char *dst, Elf32_Sword *src, size_t cnt) 1238{ 1239 Elf32_Sword *end = src + cnt; 1240 1241 do { 1242 /*CONSTANTCONDITION*/ 1243 if (~(Elf32_Word)0 == -(Elf32_Sword)1) { /* 2s comp */ 1244 tofw(dst, *src, W_$2); 1245 } else { 1246 Elf32_Word w; 1247 1248 if (*src < 0) { 1249 w = - *src; 1250 w = ~w + 1; 1251 } else 1252 w = *src; 1253 tofw(dst, w, W_$2); 1254 } 1255 dst += W_sizeof; 1256 } while (++src < end); 1257}') 1258 1259sword_tof(sword_2L_tof,L) 1260sword_tof(sword_2M_tof,M) 1261 1262 1263define(cap_11_tof, ` 1264static void 1265$1(unsigned char *dst, Elf32_Cap *src, size_t cnt) 1266{ 1267 Elf32_Cap *end = src + cnt; 1268 1269 do { 1270 tofw(dst, src->c_tag, C1_tag_$2); 1271 tofw(dst, src->c_un.c_val, C1_val_$2); 1272 dst += C1_sizeof; 1273 } while (++src < end); 1274}') 1275 1276cap_11_tof(cap_2L11_tof,L) 1277cap_11_tof(cap_2M11_tof,M) 1278 1279 1280define(syminfo_11_tof, ` 1281static void 1282$1(unsigned char *dst, Elf32_Syminfo *src, size_t cnt) 1283{ 1284 Elf32_Syminfo *end = src + cnt; 1285 1286 do { 1287 tofh(dst, src->si_boundto, SI1_boundto_$2); 1288 tofh(dst, src->si_flags, SI1_flags_$2); 1289 dst += SI1_sizeof; 1290 } while (++src < end); 1291}') 1292 1293syminfo_11_tof(syminfo_2L11_tof,L) 1294syminfo_11_tof(syminfo_2M11_tof,M) 1295 1296 1297define(sym_11_tof, ` 1298static void 1299$1(unsigned char *dst, Elf32_Sym *src, size_t cnt) 1300{ 1301 Elf32_Sym *end = src + cnt; 1302 1303 do { 1304 tofw(dst, src->st_name, ST1_name_$2); 1305 tofa(dst, src->st_value, ST1_value_$2); 1306 tofw(dst, src->st_size, ST1_size_$2); 1307 tofb(dst, src->st_info, ST1_info_$2); 1308 tofb(dst, src->st_other, ST1_other_$2); 1309 tofh(dst, src->st_shndx, ST1_shndx_$2); 1310 dst += ST1_sizeof; 1311 } while (++src < end); 1312}') 1313 1314sym_11_tof(sym_2L11_tof,L) 1315sym_11_tof(sym_2M11_tof,M) 1316 1317 1318define(word_tof, ` 1319static void 1320$1(unsigned char *dst, Elf32_Word *src, size_t cnt) 1321{ 1322 Elf32_Word *end = src + cnt; 1323 1324 do { 1325 tofw(dst, *src, W_$2); 1326 dst += W_sizeof; 1327 } while (++src < end); 1328}') 1329 1330word_tof(word_2L_tof,L) 1331word_tof(word_2M_tof,M) 1332 1333 1334define(verdef_11_tof, ` 1335static void 1336$1(unsigned char *dst, Elf32_Verdef *src, size_t cnt) 1337{ 1338 /* LINTED */ 1339 Elf32_Verdef *end = (Elf32_Verdef *)((char *)src + cnt); 1340 1341 do { 1342 Elf32_Verdef *next_verdef; 1343 Elf32_Verdaux *vaux; 1344 Elf32_Half i; 1345 unsigned char *vaux_dst; 1346 unsigned char *dst_next; 1347 1348 /* LINTED */ 1349 next_verdef = (Elf32_Verdef *)(src->vd_next ? 1350 (char *)src + src->vd_next : (char *)end); 1351 dst_next = dst + src->vd_next; 1352 1353 /* LINTED */ 1354 vaux = (Elf32_Verdaux *)((char *)src + src->vd_aux); 1355 vaux_dst = dst + src->vd_aux; 1356 1357 /* 1358 * Convert auxilary structures 1359 */ 1360 for (i = 0; i < src->vd_cnt; i++) { 1361 Elf32_Verdaux *vaux_next; 1362 unsigned char *vaux_dst_next; 1363 1364 /* 1365 * because our source and destination can be 1366 * the same place we need to figure out the next 1367 * location now. 1368 */ 1369 /* LINTED */ 1370 vaux_next = (Elf32_Verdaux *)((char *)vaux + 1371 vaux->vda_next); 1372 vaux_dst_next = vaux_dst + vaux->vda_next; 1373 1374 tofa(vaux_dst, vaux->vda_name, VDA1_name_$2); 1375 tofw(vaux_dst, vaux->vda_next, VDA1_next_$2); 1376 vaux_dst = vaux_dst_next; 1377 vaux = vaux_next; 1378 } 1379 1380 /* 1381 * Convert Elf32_Verdef structure. 1382 */ 1383 tofh(dst, src->vd_version, VD1_version_$2); 1384 tofh(dst, src->vd_flags, VD1_flags_$2); 1385 tofh(dst, src->vd_ndx, VD1_ndx_$2); 1386 tofh(dst, src->vd_cnt, VD1_cnt_$2); 1387 tofw(dst, src->vd_hash, VD1_hash_$2); 1388 tofw(dst, src->vd_aux, VD1_aux_$2); 1389 tofw(dst, src->vd_next, VD1_next_$2); 1390 src = next_verdef; 1391 dst = dst_next; 1392 } while (src < end); 1393}') 1394 1395verdef_11_tof(verdef_2L11_tof, L) 1396verdef_11_tof(verdef_2M11_tof, M) 1397 1398define(verneed_11_tof, ` 1399static void 1400$1(unsigned char *dst, Elf32_Verneed *src, size_t cnt) 1401{ 1402 /* LINTED */ 1403 Elf32_Verneed *end = (Elf32_Verneed *)((char *)src + cnt); 1404 1405 do { 1406 Elf32_Verneed *next_verneed; 1407 Elf32_Vernaux *vaux; 1408 Elf32_Half i; 1409 unsigned char *vaux_dst; 1410 unsigned char *dst_next; 1411 1412 /* LINTED */ 1413 next_verneed = (Elf32_Verneed *)(src->vn_next ? 1414 (char *)src + src->vn_next : (char *)end); 1415 dst_next = dst + src->vn_next; 1416 1417 /* LINTED */ 1418 vaux = (Elf32_Vernaux *)((char *)src + src->vn_aux); 1419 vaux_dst = dst + src->vn_aux; 1420 1421 /* 1422 * Convert auxilary structures first 1423 */ 1424 for (i = 0; i < src->vn_cnt; i++) { 1425 Elf32_Vernaux * vaux_next; 1426 unsigned char * vaux_dst_next; 1427 1428 /* 1429 * because our source and destination can be 1430 * the same place we need to figure out the 1431 * next location now. 1432 */ 1433 /* LINTED */ 1434 vaux_next = (Elf32_Vernaux *)((char *)vaux + 1435 vaux->vna_next); 1436 vaux_dst_next = vaux_dst + vaux->vna_next; 1437 1438 tofw(vaux_dst, vaux->vna_hash, VNA1_hash_$2); 1439 tofh(vaux_dst, vaux->vna_flags, VNA1_flags_$2); 1440 tofh(vaux_dst, vaux->vna_other, VNA1_other_$2); 1441 tofa(vaux_dst, vaux->vna_name, VNA1_name_$2); 1442 tofw(vaux_dst, vaux->vna_next, VNA1_next_$2); 1443 vaux_dst = vaux_dst_next; 1444 vaux = vaux_next; 1445 } 1446 /* 1447 * Convert Elf32_Verneed structure. 1448 */ 1449 tofh(dst, src->vn_version, VN1_version_$2); 1450 tofh(dst, src->vn_cnt, VN1_cnt_$2); 1451 tofa(dst, src->vn_file, VN1_file_$2); 1452 tofw(dst, src->vn_aux, VN1_aux_$2); 1453 tofw(dst, src->vn_next, VN1_next_$2); 1454 src = next_verneed; 1455 dst = dst_next; 1456 } while (src < end); 1457}') 1458 1459verneed_11_tof(verneed_2L11_tof, L) 1460verneed_11_tof(verneed_2M11_tof, M) 1461 1462 1463/* xlate to memory format 1464 * 1465 * ..._tom(name, data) -- macros 1466 * 1467 * Recall that the memory format may be larger than the 1468 * file format (equal versions). Use "backward" copy. 1469 * All these routines require non-null, non-zero arguments. 1470 */ 1471 1472 1473define(addr_tom, ` 1474static void 1475$1(Elf32_Addr *dst, unsigned char *src, size_t cnt) 1476{ 1477 Elf32_Addr *end = dst; 1478 1479 dst += cnt; 1480 src += cnt * A_sizeof; 1481 while (dst-- > end) { 1482 src -= A_sizeof; 1483 *dst = toma(src, A_$2); 1484 } 1485}') 1486 1487addr_tom(addr_2L_tom,L) 1488addr_tom(addr_2M_tom,M) 1489 1490 1491define(dyn_11_tom, ` 1492static void 1493$1(Elf32_Dyn *dst, unsigned char *src, size_t cnt) 1494{ 1495 Elf32_Dyn *end = dst + cnt; 1496 1497 do { 1498 dst->d_tag = tomw(src, D1_tag_$2); 1499 dst->d_un.d_val = tomw(src, D1_val_$2); 1500 src += D1_sizeof; 1501 } while (++dst < end); 1502}') 1503 1504dyn_11_tom(dyn_2L11_tom,L) 1505dyn_11_tom(dyn_2M11_tom,M) 1506 1507 1508define(ehdr_11_tom, ` 1509static void 1510$1(Elf32_Ehdr *dst, unsigned char *src, size_t cnt) 1511{ 1512 Elf32_Ehdr *end = dst; 1513 1514 dst += cnt; 1515 src += cnt * E1_sizeof; 1516 while (dst-- > end) { 1517 src -= E1_sizeof; 1518 dst->e_shstrndx = tomh(src, E1_shstrndx_$2); 1519 dst->e_shnum = tomh(src, E1_shnum_$2); 1520 dst->e_shentsize = tomh(src, E1_shentsize_$2); 1521 dst->e_phnum = tomh(src, E1_phnum_$2); 1522 dst->e_phentsize = tomh(src, E1_phentsize_$2); 1523 dst->e_ehsize = tomh(src, E1_ehsize_$2); 1524 dst->e_flags = tomw(src, E1_flags_$2); 1525 dst->e_shoff = tomo(src, E1_shoff_$2); 1526 dst->e_phoff = tomo(src, E1_phoff_$2); 1527 dst->e_entry = toma(src, E1_entry_$2); 1528 dst->e_version = tomw(src, E1_version_$2); 1529 dst->e_machine = tomh(src, E1_machine_$2); 1530 dst->e_type = tomh(src, E1_type_$2); 1531 if (dst->e_ident != &src[E1_ident]) 1532 (void) memcpy(dst->e_ident, &src[E1_ident], E1_Nident); 1533 } 1534}') 1535 1536ehdr_11_tom(ehdr_2L11_tom,L) 1537ehdr_11_tom(ehdr_2M11_tom,M) 1538 1539 1540define(half_tom, ` 1541static void 1542$1(Elf32_Half *dst, unsigned char *src, size_t cnt) 1543{ 1544 Elf32_Half *end = dst; 1545 1546 dst += cnt; 1547 src += cnt * H_sizeof; 1548 while (dst-- > end) { 1549 src -= H_sizeof; 1550 *dst = tomh(src, H_$2); 1551 } 1552}') 1553 1554half_tom(half_2L_tom,L) 1555half_tom(half_2M_tom,M) 1556 1557 1558define(move_11_tom, ` 1559static void 1560$1(Elf32_Move *dst, unsigned char *src, size_t cnt) 1561{ 1562 Elf32_Move *end = dst + cnt; 1563 1564 do { 1565 dst->m_value = toml(src, M1_value_$2); 1566 dst->m_info = tomw(src, M1_info_$2); 1567 dst->m_poffset = tomw(src, M1_poffset_$2); 1568 dst->m_repeat = tomh(src, M1_repeat_$2); 1569 dst->m_stride = tomh(src, M1_stride_$2); 1570 src += M1_sizeof; 1571 } while (++dst < end); 1572}') 1573 1574move_11_tom(move_2L11_tom,L) 1575move_11_tom(move_2M11_tom,M) 1576 1577 1578define(movep_11_tom, ` 1579static void 1580$1(Elf32_Move *dst, unsigned char *src, size_t cnt) 1581{ 1582 Elf32_Move *end = dst + cnt; 1583 1584 do 1585 { 1586 dst->m_value = toml(src, MP1_value_$2); 1587 dst->m_info = tomw(src, MP1_info_$2); 1588 dst->m_poffset = tomw(src, MP1_poffset_$2); 1589 dst->m_repeat = tomh(src, MP1_repeat_$2); 1590 dst->m_stride = tomh(src, MP1_stride_$2); 1591 src += MP1_sizeof; 1592 } while (++dst < end); 1593}') 1594 1595movep_11_tom(movep_2L11_tom,L) 1596movep_11_tom(movep_2M11_tom,M) 1597 1598 1599define(note_11_tom, ` 1600static void 1601$1(Elf32_Nhdr *dst, unsigned char *src, size_t cnt) 1602{ 1603 /* LINTED */ 1604 Elf32_Nhdr *end = (Elf32_Nhdr *)((char *)dst + cnt); 1605 1606 while (dst < end) { 1607 Elf32_Nhdr * nhdr; 1608 unsigned char * namestr; 1609 void * desc; 1610 Elf32_Word field_sz; 1611 1612 dst->n_namesz = tomw(src, N1_namesz_$2); 1613 dst->n_descsz = tomw(src, N1_descsz_$2); 1614 dst->n_type = tomw(src, N1_type_$2); 1615 nhdr = dst; 1616 /* LINTED */ 1617 dst = (Elf32_Nhdr *)((char *)dst + sizeof (Elf32_Nhdr)); 1618 namestr = src + N1_sizeof; 1619 field_sz = S_ROUND(nhdr->n_namesz, sizeof (Elf32_Word)); 1620 (void)memcpy((void *)dst, namestr, field_sz); 1621 desc = namestr + field_sz; 1622 /* LINTED */ 1623 dst = (Elf32_Nhdr *)((char *)dst + field_sz); 1624 field_sz = nhdr->n_descsz; 1625 (void)memcpy(dst, desc, field_sz); 1626 field_sz = S_ROUND(field_sz, sizeof (Elf32_Word)); 1627 /* LINTED */ 1628 dst = (Elf32_Nhdr *)((char *)dst + field_sz); 1629 src = (unsigned char *)desc + field_sz; 1630 } 1631}') 1632 1633note_11_tom(note_2L11_tom,L) 1634note_11_tom(note_2M11_tom,M) 1635 1636 1637define(off_tom, ` 1638static void 1639$1(Elf32_Off *dst, unsigned char *src, size_t cnt) 1640{ 1641 Elf32_Off *end = dst; 1642 1643 dst += cnt; 1644 src += cnt * O_sizeof; 1645 while (dst-- > end) { 1646 src -= O_sizeof; 1647 *dst = tomo(src, O_$2); 1648 } 1649}') 1650 1651off_tom(off_2L_tom,L) 1652off_tom(off_2M_tom,M) 1653 1654 1655define(phdr_11_tom, ` 1656static void 1657$1(Elf32_Phdr *dst, unsigned char *src, size_t cnt) 1658{ 1659 Elf32_Phdr *end = dst; 1660 1661 dst += cnt; 1662 src += cnt * P1_sizeof; 1663 while (dst-- > end) { 1664 src -= P1_sizeof; 1665 dst->p_align = tomw(src, P1_align_$2); 1666 dst->p_flags = tomw(src, P1_flags_$2); 1667 dst->p_memsz = tomw(src, P1_memsz_$2); 1668 dst->p_filesz = tomw(src, P1_filesz_$2); 1669 dst->p_paddr = toma(src, P1_paddr_$2); 1670 dst->p_vaddr = toma(src, P1_vaddr_$2); 1671 dst->p_offset = tomo(src, P1_offset_$2); 1672 dst->p_type = tomw(src, P1_type_$2); 1673 } 1674}') 1675 1676phdr_11_tom(phdr_2L11_tom,L) 1677phdr_11_tom(phdr_2M11_tom,M) 1678 1679 1680define(rel_11_tom, ` 1681static void 1682$1(Elf32_Rel *dst, unsigned char *src, size_t cnt) 1683{ 1684 Elf32_Rel *end = dst; 1685 1686 dst += cnt; 1687 src += cnt * R1_sizeof; 1688 while (dst-- > end) { 1689 src -= R1_sizeof; 1690 dst->r_info = tomw(src, R1_info_$2); 1691 dst->r_offset = toma(src, R1_offset_$2); 1692 } 1693}') 1694 1695rel_11_tom(rel_2L11_tom,L) 1696rel_11_tom(rel_2M11_tom,M) 1697 1698 1699define(rela_11_tom, ` 1700static void 1701$1(Elf32_Rela *dst, unsigned char *src, size_t cnt) 1702{ 1703 Elf32_Rela *end = dst; 1704 1705 dst += cnt; 1706 src += cnt * RA1_sizeof; 1707 while (dst-- > end) { 1708 src -= RA1_sizeof; 1709 /*CONSTANTCONDITION*/ 1710 if (~(Elf32_Word)0 == -(Elf32_Sword)1 && /* 2s comp */ 1711 ~(~(Elf32_Word)0 >> 1) == HI32) { 1712 dst->r_addend = tomw(src, RA1_addend_$2); 1713 } else { 1714 union { 1715 Elf32_Word w; 1716 Elf32_Sword sw; 1717 } u; 1718 1719 if ((u.w = tomw(src, RA1_addend_$2)) & HI32) { 1720 u.w |= ~(Elf32_Word)LO31; 1721 u.w = ~u.w + 1; 1722 u.sw = -u.w; 1723 } 1724 dst->r_addend = u.sw; 1725 } 1726 dst->r_info = tomw(src, RA1_info_$2); 1727 dst->r_offset = toma(src, RA1_offset_$2); 1728 } 1729}') 1730 1731rela_11_tom(rela_2L11_tom,L) 1732rela_11_tom(rela_2M11_tom,M) 1733 1734 1735define(shdr_11_tom, ` 1736static void 1737$1(Elf32_Shdr *dst, unsigned char *src, size_t cnt) 1738{ 1739 Elf32_Shdr *end = dst; 1740 1741 dst += cnt; 1742 src += cnt * SH1_sizeof; 1743 while (dst-- > end) { 1744 src -= SH1_sizeof; 1745 dst->sh_entsize = tomw(src, SH1_entsize_$2); 1746 dst->sh_addralign = tomw(src, SH1_addralign_$2); 1747 dst->sh_info = tomw(src, SH1_info_$2); 1748 dst->sh_link = tomw(src, SH1_link_$2); 1749 dst->sh_size = tomw(src, SH1_size_$2); 1750 dst->sh_offset = tomo(src, SH1_offset_$2); 1751 dst->sh_addr = toma(src, SH1_addr_$2); 1752 dst->sh_flags = tomw(src, SH1_flags_$2); 1753 dst->sh_type = tomw(src, SH1_type_$2); 1754 dst->sh_name = tomw(src, SH1_name_$2); 1755 } 1756}') 1757 1758shdr_11_tom(shdr_2L11_tom,L) 1759shdr_11_tom(shdr_2M11_tom,M) 1760 1761 1762 1763define(sword_tom, ` 1764static void 1765$1(Elf32_Sword *dst, unsigned char *src, size_t cnt) 1766{ 1767 Elf32_Sword *end = dst; 1768 1769 dst += cnt; 1770 src += cnt * W_sizeof; 1771 while (dst-- > end) { 1772 src -= W_sizeof; 1773 /*CONSTANTCONDITION*/ 1774 if (~(Elf32_Word)0 == -(Elf32_Sword)1 && /* 2s comp */ 1775 ~(~(Elf32_Word)0 >> 1) == HI32) { 1776 *dst = tomw(src, W_$2); 1777 } else { 1778 union { 1779 Elf32_Word w; 1780 Elf32_Sword sw; 1781 } u; 1782 1783 if ((u.w = tomw(src, W_$2)) & HI32) { 1784 u.w |= ~(Elf32_Word)LO31; 1785 u.w = ~u.w + 1; 1786 u.sw = -u.w; 1787 } 1788 *dst = u.sw; 1789 } 1790 } 1791}') 1792 1793sword_tom(sword_2L_tom,L) 1794sword_tom(sword_2M_tom,M) 1795 1796 1797define(cap_11_tom, ` 1798static void 1799$1(Elf32_Cap *dst, unsigned char *src, size_t cnt) 1800{ 1801 Elf32_Cap *end = dst + cnt; 1802 1803 do { 1804 dst->c_tag = tomw(src, C1_tag_$2); 1805 dst->c_un.c_val = tomw(src, C1_val_$2); 1806 src += C1_sizeof; 1807 } while (++dst < end); 1808}') 1809 1810cap_11_tom(cap_2L11_tom,L) 1811cap_11_tom(cap_2M11_tom,M) 1812 1813 1814define(syminfo_11_tom, ` 1815static void 1816$1(Elf32_Syminfo *dst, unsigned char *src, size_t cnt) 1817{ 1818 Elf32_Syminfo *end = dst; 1819 1820 dst += cnt; 1821 src += cnt * SI1_sizeof; 1822 while (dst-- > end) { 1823 src -= SI1_sizeof; 1824 dst->si_boundto = tomh(src, SI1_boundto_$2); 1825 dst->si_flags = tomh(src, SI1_flags_$2); 1826 } 1827}') 1828 1829syminfo_11_tom(syminfo_2L11_tom,L) 1830syminfo_11_tom(syminfo_2M11_tom,M) 1831 1832 1833define(sym_11_tom, ` 1834static void 1835$1(Elf32_Sym *dst, unsigned char *src, size_t cnt) 1836{ 1837 Elf32_Sym *end = dst; 1838 1839 dst += cnt; 1840 src += cnt * ST1_sizeof; 1841 while (dst-- > end) { 1842 src -= ST1_sizeof; 1843 dst->st_shndx = tomh(src, ST1_shndx_$2); 1844 dst->st_other = tomb(src, ST1_other_$2); 1845 dst->st_info = tomb(src, ST1_info_$2); 1846 dst->st_size = tomw(src, ST1_size_$2); 1847 dst->st_value = toma(src, ST1_value_$2); 1848 dst->st_name = tomw(src, ST1_name_$2); 1849 } 1850}') 1851 1852sym_11_tom(sym_2L11_tom,L) 1853sym_11_tom(sym_2M11_tom,M) 1854 1855 1856define(word_tom, ` 1857static void 1858$1(Elf32_Word *dst, unsigned char *src, size_t cnt) 1859{ 1860 Elf32_Word *end = dst; 1861 1862 dst += cnt; 1863 src += cnt * W_sizeof; 1864 while (dst-- > end) { 1865 src -= W_sizeof; 1866 *dst = tomw(src, W_$2); 1867 } 1868}') 1869 1870word_tom(word_2L_tom,L) 1871word_tom(word_2M_tom,M) 1872 1873 1874define(verdef_11_tom, ` 1875static void 1876$1(Elf32_Verdef *dst, unsigned char *src, size_t cnt) 1877{ 1878 /* LINTED */ 1879 Elf32_Verdef *end = (Elf32_Verdef *)((char *)dst + cnt); 1880 1881 while (dst < end) { 1882 Elf32_Verdaux *vaux; 1883 unsigned char *src_vaux; 1884 Elf32_Half i; 1885 1886 dst->vd_version = tomh(src, VD1_version_$2); 1887 dst->vd_flags = tomh(src, VD1_flags_$2); 1888 dst->vd_ndx = tomh(src, VD1_ndx_$2); 1889 dst->vd_cnt = tomh(src, VD1_cnt_$2); 1890 dst->vd_hash = tomw(src, VD1_hash_$2); 1891 dst->vd_aux = tomw(src, VD1_aux_$2); 1892 dst->vd_next = tomw(src, VD1_next_$2); 1893 1894 src_vaux = src + dst->vd_aux; 1895 /* LINTED */ 1896 vaux = (Elf32_Verdaux*)((char *)dst + dst->vd_aux); 1897 for (i = 0; i < dst->vd_cnt; i++) { 1898 vaux->vda_name = toma(src_vaux, VDA1_name_$2); 1899 vaux->vda_next = toma(src_vaux, VDA1_next_$2); 1900 src_vaux += vaux->vda_next; 1901 /* LINTED */ 1902 vaux = (Elf32_Verdaux *)((char *)vaux + 1903 vaux->vda_next); 1904 } 1905 src += dst->vd_next; 1906 /* LINTED */ 1907 dst = (Elf32_Verdef *)(dst->vd_next ? 1908 (char *)dst + dst->vd_next : (char *)end); 1909 } 1910}') 1911 1912verdef_11_tom(verdef_2L11_tom,L) 1913verdef_11_tom(verdef_2M11_tom,M) 1914 1915 1916define(verneed_11_tom, ` 1917static void 1918$1(Elf32_Verneed *dst, unsigned char *src, size_t cnt) 1919{ 1920 /* LINTED */ 1921 Elf32_Verneed *end = (Elf32_Verneed *)((char *)dst + cnt); 1922 1923 while (dst < end) { 1924 Elf32_Vernaux * vaux; 1925 unsigned char * src_vaux; 1926 Elf32_Half i; 1927 dst->vn_version = tomh(src, VN1_version_$2); 1928 dst->vn_cnt = tomh(src, VN1_cnt_$2); 1929 dst->vn_file = toma(src, VN1_file_$2); 1930 dst->vn_aux = tomw(src, VN1_aux_$2); 1931 dst->vn_next = tomw(src, VN1_next_$2); 1932 1933 src_vaux = src + dst->vn_aux; 1934 /* LINTED */ 1935 vaux = (Elf32_Vernaux *)((char *)dst + dst->vn_aux); 1936 for (i = 0; i < dst->vn_cnt; i++) { 1937 vaux->vna_hash = tomw(src_vaux, VNA1_hash_$2); 1938 vaux->vna_flags = tomh(src_vaux, VNA1_flags_$2); 1939 vaux->vna_other = tomh(src_vaux, VNA1_other_$2); 1940 vaux->vna_name = toma(src_vaux, VNA1_name_$2); 1941 vaux->vna_next = tomw(src_vaux, VNA1_next_$2); 1942 src_vaux += vaux->vna_next; 1943 /* LINTED */ 1944 vaux = (Elf32_Vernaux *)((char *)vaux + 1945 vaux->vna_next); 1946 } 1947 src += dst->vn_next; 1948 /* LINTED */ 1949 dst = (Elf32_Verneed *)(dst->vn_next ? 1950 (char *)dst + dst->vn_next : (char *)end); 1951 } 1952}') 1953 1954verneed_11_tom(verneed_2L11_tom,L) 1955verneed_11_tom(verneed_2M11_tom,M) 1956