00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #include <stdio.h>
00059 #include <unistd.h>
00060 #include <fcntl.h>
00061 #include <sys/stat.h>
00062 #include <errno.h>
00063 #include <bstring.h>
00064 #include "elf_stuff.h"
00065 #include <elfaccess.h>
00066 #include "libelf/libelf.h"
00067 #include <stamp.h>
00068 #include <alloca.h>
00069 #include <assert.h>
00070 #include <cmplrs/leb128.h>
00071 #include <cmplrs/elf_interfaces.h>
00072
00073 #define USE_STANDARD_TYPES 1
00074 #include "defs.h"
00075 #include "erlib.h"
00076 #include "erglob.h"
00077 #include "config.h"
00078 #include "targ_const.h"
00079 #include "glob.h"
00080 #include "config.h"
00081 #include "config_elf_targ.h"
00082 #include "em_elf.h"
00083 #include "targ_em_elf.h"
00084
00085
00086
00087 static SCNINFO Shstrtab_Info;
00088 static SCNINFO Strtab_Info;
00089 static SCNINFO Symtab_Info_struct;
00090
00091 pSCNINFO Symtab_Info = &Symtab_Info_struct;
00092
00093 static pSCNINFO Comment_Scn;
00094 static char *object_file_name;
00095
00096
00097
00098
00099 static Elf *Elf_Ptr;
00100
00101 pSCNINFO Options_Scn;
00102 BOOL Sixtyfour_Bit;
00103
00104
00105
00106 static BOOL Big_Endian;
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 static void
00124 Increase_Data_Buffer_Size ( pSCNINFO scninfo, Elf64_Xword newsize )
00125 {
00126 char *newbuf;
00127 Elf64_Word newsize32 = newsize;
00128
00129
00130 if (newsize == 0) return;
00131
00132
00133 if ( newsize32 != newsize ) {
00134 ErrMsg ( EC_Elf_Size64, newsize, "Increase_Data_Buffer_Size" );
00135 }
00136
00137 if ( SCNINFO_buffer(scninfo) == NULL ) {
00138 newbuf = (char *) malloc ( newsize32 );
00139 } else {
00140 newbuf = (char *) realloc ( SCNINFO_buffer(scninfo), newsize32 );
00141 }
00142 if ( newbuf == NULL ) {
00143 ErrMsg ( EC_No_Mem, "Increase_Data_Buffer_Size" );
00144 }
00145 BZERO ( newbuf + (INTPS) SCNINFO_limit(scninfo),
00146 newsize32 - (INT32) SCNINFO_limit(scninfo) );
00147
00148 SCNINFO_buffer(scninfo) = newbuf;
00149 SCNINFO_limit(scninfo) = newsize32;
00150 }
00151
00152
00153 void
00154 Em_Change_Section_Origin ( pSCNINFO scn, Elf64_Xword scn_ofst )
00155 {
00156 SCNINFO_offset(scn) = scn_ofst;
00157 }
00158
00159
00160 void
00161 Em_Change_Section_Alignment (pSCNINFO scn, Elf64_Word scn_align)
00162 {
00163 if (SCNINFO_align(scn) < scn_align) SCNINFO_align (scn) = scn_align;
00164 }
00165
00166
00167
00168
00169 Elf64_Xword
00170 Em_Add_Bytes_To_Scn (
00171 pSCNINFO scninfo,
00172 const void *input_buf,
00173 Elf64_Xword length,
00174 Elf64_Word align)
00175 {
00176 Elf64_Xword index;
00177 Elf64_Xword newoffset;
00178 Elf64_Xword newsize;
00179
00180 index = SCNINFO_offset(scninfo);
00181
00182 index = Roundup (index, align);
00183 if (SCNINFO_align(scninfo) < align) SCNINFO_align(scninfo) = align;
00184
00185 newoffset = index + length;
00186 if (newoffset > SCNINFO_size(scninfo)) {
00187 SCNINFO_size(scninfo) = newoffset;
00188 }
00189
00190
00191
00192
00193 if (input_buf != NULL) {
00194
00195
00196 newsize = newoffset + BUFSIZ;
00197 if ( (INT32)newsize != newsize ) {
00198 ErrMsg ( EC_Elf_Size64, newsize, "Em_Add_Bytes_To_Scn" );
00199 }
00200
00201 if (newoffset > SCNINFO_limit(scninfo)) {
00202 Increase_Data_Buffer_Size (scninfo, newoffset + BUFSIZ);
00203 }
00204 if (length > 0)
00205 memcpy(SCNINFO_buffer(scninfo) + index, input_buf, length);
00206
00207 }
00208
00209 SCNINFO_offset(scninfo) = newoffset;
00210 return index;
00211 }
00212
00213
00214
00215
00216 Elf64_Xword
00217 Em_Add_Zeros_To_Scn (
00218 pSCNINFO scninfo,
00219 Elf64_Word length,
00220 Elf64_Word align)
00221 {
00222 Elf64_Xword index;
00223 static char *buf = NULL;
00224 static Elf64_Sword buflen = 0;
00225
00226 if ( buflen < length ) {
00227 if ( buf != NULL ) free ( buf );
00228 buflen = length + 128;
00229 buf = (char *) calloc (buflen, 1);
00230 if (buf == NULL)
00231 ErrMsg ( EC_No_Mem, "Em_Add_Zeros_To_Scn" );
00232 }
00233 index = Em_Add_Bytes_To_Scn (scninfo, buf, length, align);
00234 return index;
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244 Elf64_Xword
00245 Em_Add_Address_To_Scn (
00246 pSCNINFO scninfo,
00247 Elf64_Word symindex,
00248 Elf64_Sxword addend,
00249 Elf64_Word align)
00250 {
00251 Elf64_Xword index;
00252
00253 if (Sixtyfour_Bit) {
00254 INT64 value = addend;
00255 Elf64_Shdr *scn_hdr64 = elf64_getshdr (SCNINFO_scnptr(scninfo));
00256
00257 if (scn_hdr64->sh_flags & SHF_MERGE) {
00258 index = Em_Add_Zeros_To_Scn (scninfo, sizeof(value), align);
00259 Em_Add_New_Rela (symindex, R_WORD64, index, addend, scninfo);
00260 }
00261 else {
00262 index = Em_Add_Bytes_To_Scn (scninfo, &value, sizeof(value), align);
00263 Em_Add_New_Rel (symindex, R_WORD64, index, scninfo);
00264 }
00265 }
00266 else {
00267 INT32 value = addend;
00268 Elf32_Shdr *scn_hdr32 = elf32_getshdr (SCNINFO_scnptr(scninfo));
00269
00270 if (scn_hdr32->sh_flags & SHF_MERGE) {
00271 index = Em_Add_Zeros_To_Scn (scninfo, sizeof(value), align);
00272 Em_Add_New_Rela (symindex, R_WORD32, index, addend, scninfo);
00273 }
00274 else {
00275 index = Em_Add_Bytes_To_Scn (scninfo, &value, sizeof(value), align);
00276 Em_Add_New_Rel (symindex, R_WORD32, index, scninfo);
00277 }
00278 }
00279 return index;
00280 }
00281
00282
00283
00284
00285
00286
00287 Elf64_Xword
00288 Em_Add_Displacement_To_Scn (
00289 pSCNINFO scninfo,
00290 Elf64_Word symindex,
00291 Elf64_Sxword addend,
00292 Elf64_Word align)
00293 {
00294 Elf64_Xword index;
00295 INT32 value = addend;
00296
00297 index = Em_Add_Bytes_To_Scn (scninfo, &value, sizeof(value), align);
00298 Em_Add_New_Rel (symindex, R_SCN_DISP, index, scninfo);
00299 return index;
00300 }
00301
00302
00303
00304
00305
00306
00307 static Elf64_Word
00308 String_To_Index (pSCNINFO strinfo, const char *scn_name)
00309 {
00310 Elf64_Word i;
00311 char *buf;
00312
00313
00314 if (scn_name == NULL) return 0;
00315
00316 buf = SCNINFO_buffer(strinfo);
00317 for (i = 0; i < SCNINFO_size(strinfo); i += strlen(&buf[i]) + 1) {
00318 if (strcmp (&buf[i], scn_name) == 0) return i;
00319 }
00320 return Em_Add_Bytes_To_Scn (strinfo, scn_name, strlen(scn_name) + 1, 1);
00321 }
00322
00323 static char *
00324 Index_To_String (pSCNINFO strinfo, Elf64_Word index)
00325 {
00326 return SCNINFO_buffer(strinfo) + index;
00327 }
00328
00329
00330
00331 static void
00332 print_elf_error (void)
00333 {
00334 int err;
00335
00336 err = elf_errno();
00337 if (err != 0) ErrMsg (EC_Elf_Error, elf_errmsg (err));
00338 }
00339
00340
00341
00342
00343
00344 static Elf_Scn *
00345 Create_New_Section (
00346 const char *scn_name,
00347 Elf64_Word scn_type,
00348 Elf64_Xword scn_flags,
00349 Elf64_Xword scn_entsize)
00350 {
00351 Elf_Scn *scn_ptr;
00352 Elf64_Word string_index;
00353
00354 if ((scn_ptr = elf_newscn(Elf_Ptr)) == 0) {
00355 print_elf_error ();
00356 assert(FALSE);
00357 }
00358
00359 string_index = String_To_Index (&Shstrtab_Info, scn_name);
00360 if (Sixtyfour_Bit)
00361 {
00362 Elf64_Shdr *scn_hdr64;
00363
00364 if ((scn_hdr64 = elf64_getshdr(scn_ptr)) == 0) {
00365 print_elf_error ();
00366 assert(FALSE);
00367 }
00368 scn_hdr64->sh_name = string_index;
00369 scn_hdr64->sh_type = scn_type;
00370 scn_hdr64->sh_flags = scn_flags;
00371 scn_hdr64->sh_addr = 0;
00372 scn_hdr64->sh_entsize = scn_entsize;
00373 }
00374 else {
00375 Elf32_Shdr *scn_hdr32;
00376
00377 if ((scn_hdr32 = elf32_getshdr(scn_ptr)) == 0) {
00378 print_elf_error ();
00379 assert(FALSE);
00380 }
00381 scn_hdr32->sh_name = string_index;
00382 scn_hdr32->sh_type = scn_type;
00383 scn_hdr32->sh_flags = scn_flags;
00384 scn_hdr32->sh_addr = 0;
00385 scn_hdr32->sh_entsize = scn_entsize;
00386 }
00387 return scn_ptr;
00388 }
00389
00390
00391 void
00392 Em_Set_sh_link (pSCNINFO scn, Elf64_Word link)
00393 {
00394 if (Sixtyfour_Bit) {
00395 Elf64_Shdr *sh64;
00396 sh64 = elf64_getshdr (SCNINFO_scnptr(scn));
00397 sh64->sh_link = link;
00398 }
00399 else {
00400 Elf32_Shdr *sh32;
00401 sh32 = elf32_getshdr (SCNINFO_scnptr(scn));
00402 sh32->sh_link = link;
00403 }
00404 }
00405
00406
00407 void
00408 Em_Set_sh_info (pSCNINFO scn, Elf64_Word info)
00409 {
00410 if (Sixtyfour_Bit) {
00411 Elf64_Shdr *sh64;
00412 sh64 = elf64_getshdr (SCNINFO_scnptr(scn));
00413 sh64->sh_info = info;
00414 }
00415 else {
00416 Elf32_Shdr *sh32;
00417 sh32 = elf32_getshdr (SCNINFO_scnptr(scn));
00418 sh32->sh_info = info;
00419 }
00420 }
00421
00422
00423
00424
00425
00426
00427 static void Update_Data (pSCNINFO scninfo, Elf_Type type)
00428 {
00429 Elf_Data *secdata;
00430
00431
00432 if (SCNINFO_size(scninfo) == 0) return;
00433
00434 if ((secdata = elf_newdata (SCNINFO_scnptr(scninfo))) == 0) {
00435 print_elf_error ();
00436 }
00437
00438 secdata->d_buf = SCNINFO_buffer(scninfo);
00439 secdata->d_size = SCNINFO_size(scninfo);
00440 secdata->d_type = type;
00441 secdata->d_align = SCNINFO_align(scninfo);
00442
00443 SCNINFO_buffer(scninfo) = NULL;
00444 SCNINFO_size(scninfo) = 0;
00445 SCNINFO_limit(scninfo) = 0;
00446 SCNINFO_align(scninfo) = 0;
00447 }
00448
00449
00450 size_t
00451 Em_Get_Section_Index (pSCNINFO scn)
00452 {
00453 return SCNINFO_index (scn);
00454 }
00455
00456
00457 Elf64_Xword
00458 Em_Get_Section_Offset (pSCNINFO scn)
00459 {
00460 return SCNINFO_offset(scn);
00461 }
00462
00463
00464 char *
00465 Em_Get_Section_Name (pSCNINFO scninfo)
00466 {
00467 char *scnname;
00468 Elf64_Shdr *sh64;
00469 Elf32_Shdr *sh32;
00470
00471 if (Sixtyfour_Bit) {
00472 sh64 = elf64_getshdr (SCNINFO_scnptr(scninfo));
00473 scnname = Shstrtab_Info.buffer + sh64->sh_name;
00474 }
00475 else {
00476 sh32 = elf32_getshdr (SCNINFO_scnptr(scninfo));
00477 scnname = Shstrtab_Info.buffer + sh32->sh_name;
00478 }
00479 return scnname;
00480 }
00481
00482 Elf64_Word
00483 Em_Get_Section_Type (pSCNINFO scninfo)
00484 {
00485 if (Sixtyfour_Bit) {
00486 return elf64_getshdr(SCNINFO_scnptr(scninfo))->sh_type;
00487 }
00488 else {
00489 return elf32_getshdr(SCNINFO_scnptr(scninfo))->sh_type;
00490 }
00491 }
00492
00493 Elf64_Word
00494 Em_Get_Section_Flags (pSCNINFO scninfo)
00495 {
00496 if (Sixtyfour_Bit) {
00497 return elf64_getshdr(SCNINFO_scnptr(scninfo))->sh_flags;
00498 }
00499 else {
00500 return elf32_getshdr(SCNINFO_scnptr(scninfo))->sh_flags;
00501 }
00502 }
00503
00504 Elf64_Word
00505 Em_Get_Section_Entsize (pSCNINFO scninfo)
00506 {
00507 if (Sixtyfour_Bit) {
00508 return elf64_getshdr(SCNINFO_scnptr(scninfo))->sh_entsize;
00509 }
00510 else {
00511 return elf32_getshdr(SCNINFO_scnptr(scninfo))->sh_entsize;
00512 }
00513 }
00514
00515 Elf64_Word
00516 Em_Get_Section_Align (pSCNINFO scninfo)
00517 {
00518 if (Sixtyfour_Bit) {
00519 return elf64_getshdr(SCNINFO_scnptr(scninfo))->sh_addralign;
00520 }
00521 else {
00522 return elf32_getshdr(SCNINFO_scnptr(scninfo))->sh_addralign;
00523 }
00524 }
00525
00526 Elf64_Word
00527 Em_Get_Section_Info (pSCNINFO scninfo)
00528 {
00529 if (Sixtyfour_Bit) {
00530 return elf64_getshdr(SCNINFO_scnptr(scninfo))->sh_info;
00531 }
00532 else {
00533 return elf32_getshdr(SCNINFO_scnptr(scninfo))->sh_info;
00534 }
00535 }
00536
00537
00538
00539
00540 static void
00541 Create_New_Relocation_Section (BOOL is_rela, pSCNINFO scninfo)
00542 {
00543 char *scnname;
00544 char *relname;
00545 pSCNINFO newscn;
00546
00547 scnname = Em_Get_Section_Name (scninfo);
00548 relname = (char *) alloca (strlen(scnname) + 10);
00549 if (is_rela) {
00550 strcpy (relname, ".rela");
00551 }
00552 else {
00553 strcpy (relname, ".rel");
00554 }
00555 strcpy (relname+strlen(relname), scnname);
00556
00557 if (is_rela) {
00558 newscn = Em_New_Section (relname, SHT_RELA,
00559 0,
00560 Sixtyfour_Bit ? sizeof(Elf64_Rela) : sizeof(Elf32_Rela),
00561 Sixtyfour_Bit ? ELF64_FSZ_XWORD : ELF32_FSZ_WORD);
00562 SCNINFO_relainfo(scninfo) = newscn;
00563 }
00564 else {
00565 newscn = Em_New_Section (relname, SHT_REL,
00566 0,
00567 Sixtyfour_Bit ? sizeof(Elf64_Rel) : sizeof(Elf32_Rel),
00568 Sixtyfour_Bit ? ELF64_FSZ_XWORD : ELF32_FSZ_WORD);
00569 SCNINFO_relinfo(scninfo) = newscn;
00570 }
00571
00572 Em_Set_sh_link (newscn, SCNINFO_index(Symtab_Info));
00573 Em_Set_sh_info (newscn, SCNINFO_index(scninfo));
00574 }
00575
00576
00577
00578 void
00579 Em_Add_New_Rel (
00580 Elf64_Word symindex,
00581 unsigned char reltype,
00582 Elf64_Addr reloffset,
00583 pSCNINFO scninfo)
00584 {
00585 if (symindex == 0) {
00586 ErrMsg (EC_Elf_Idx, symindex, "Em_Add_New_Rel");
00587 }
00588 if (SCNINFO_relinfo(scninfo) == NULL) {
00589 Create_New_Relocation_Section (FALSE, scninfo);
00590 }
00591 if (Sixtyfour_Bit) {
00592 Elf64_AltRel reloc;
00593
00594 REL_offset(reloc) = reloffset;
00595 Set_REL64_info ( reloc, symindex, reltype );
00596 REL64_ssym(reloc) = 0;
00597 REL64_type2(reloc) = 0;
00598 REL64_type3(reloc) = 0;
00599 Em_Add_Bytes_To_Scn (SCNINFO_relinfo(scninfo), &reloc,
00600 sizeof (Elf64_Rel), ELF64_FSZ_XWORD);
00601 }
00602 else {
00603 Elf32_Rel reloc;
00604
00605 REL_offset(reloc) = reloffset;
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 Set_REL32_info ( reloc, symindex, reltype );
00622 Em_Add_Bytes_To_Scn (SCNINFO_relinfo(scninfo), &reloc,
00623 sizeof (Elf32_Rel), ELF32_FSZ_WORD);
00624 }
00625 }
00626
00627
00628
00629 void
00630 Em_Add_New_Rela (
00631 Elf64_Word symindex,
00632 unsigned char reltype,
00633 Elf64_Addr reloffset,
00634 Elf64_Sxword addend,
00635 pSCNINFO scninfo)
00636 {
00637 if (SCNINFO_relainfo(scninfo) == NULL) {
00638 Create_New_Relocation_Section (TRUE, scninfo);
00639 }
00640 if (Sixtyfour_Bit) {
00641 Elf64_AltRela reloc;
00642
00643 Set_REL64_info ( reloc, symindex, reltype );
00644 REL64_ssym(reloc) = 0;
00645 REL64_type2(reloc) = 0;
00646 REL64_type3(reloc) = 0;
00647 REL_offset(reloc) = reloffset;
00648 REL_addend(reloc) = addend;
00649 Em_Add_Bytes_To_Scn (SCNINFO_relainfo(scninfo), &reloc,
00650 sizeof (Elf64_Rela), ELF64_FSZ_XWORD);
00651 }
00652 else {
00653 Elf32_Rela reloc;
00654
00655 REL_offset(reloc) = reloffset;
00656 Set_REL32_info ( reloc, symindex, reltype );
00657 REL_addend(reloc) = addend;
00658 Em_Add_Bytes_To_Scn (SCNINFO_relainfo(scninfo), &reloc,
00659 sizeof (Elf32_Rela), ELF32_FSZ_WORD);
00660 }
00661 }
00662
00663
00664
00665
00666
00667 void
00668 Em_Add_New_Composite_Rela (Elf64_AltRela *preloc, pSCNINFO scninfo)
00669 {
00670
00671 if (REL64_type(*preloc) == R_NONE) return;
00672
00673 if (SCNINFO_relainfo(scninfo) == NULL) {
00674 Create_New_Relocation_Section (TRUE, scninfo);
00675 }
00676
00677 if (Sixtyfour_Bit) {
00678 Em_Add_Bytes_To_Scn (SCNINFO_relainfo(scninfo), preloc,
00679 sizeof (Elf64_Rela), ELF64_FSZ_XWORD);
00680 }
00681 else {
00682 Elf32_Rela reloc;
00683
00684 REL_offset(reloc) = REL_offset(*preloc);
00685 Set_REL32_info ( reloc, REL64_sym(*preloc), REL64_type(*preloc) );
00686 REL_addend(reloc) = REL_addend(*preloc);
00687 Em_Add_Bytes_To_Scn (SCNINFO_relainfo(scninfo), &reloc,
00688 sizeof (Elf32_Rela), ELF32_FSZ_WORD);
00689 if (REL64_type2(*preloc) != 0) {
00690 Set_REL32_info (reloc, 0, REL64_type2(*preloc));
00691 REL_addend(reloc) = 0;
00692 Em_Add_Bytes_To_Scn (SCNINFO_relainfo(scninfo), &reloc,
00693 sizeof (Elf32_Rela), ELF32_FSZ_WORD);
00694 if (REL64_type3(*preloc) != 0) {
00695 Set_REL32_info (reloc, 0, REL64_type3(*preloc));
00696 Em_Add_Bytes_To_Scn (SCNINFO_relainfo(scninfo), &reloc,
00697 sizeof (Elf32_Rela), ELF32_FSZ_WORD);
00698 }
00699 }
00700 }
00701 }
00702
00703
00704
00705
00706
00707
00708 void
00709 Em_Define_Symbol (
00710 Elf64_Word symindex,
00711 Elf64_Addr symvalue,
00712 Elf64_Xword symsize,
00713 pSCNINFO scninfo)
00714 {
00715 Elf64_Half scnindex;
00716
00717 if (symindex == 0) {
00718 ErrMsg (EC_Elf_Idx, symindex, "Em_Define_Symbol");
00719 }
00720 scnindex = SCNINFO_index(scninfo);
00721
00722 if (Sixtyfour_Bit) {
00723 Elf64_Sym *symtable;
00724
00725 symtable = (Elf64_Sym *)SCNINFO_buffer(Symtab_Info);
00726 if (symindex >= (SCNINFO_size(Symtab_Info) / sizeof(Elf64_Sym)))
00727 ErrMsg (EC_Elf_Idx, symindex, "Em_Define_Symbol");
00728 symtable[symindex].st_value = symvalue;
00729 symtable[symindex].st_size = symsize;
00730 symtable[symindex].st_shndx = scnindex;
00731 }
00732 else {
00733 Elf32_Sym *symtable;
00734
00735 symtable = (Elf32_Sym *)SCNINFO_buffer(Symtab_Info);
00736 if (symindex >= (SCNINFO_size(Symtab_Info) / sizeof(Elf32_Sym)))
00737 ErrMsg (EC_Elf_Idx, symindex, "Em_Define_Symbol");
00738 symtable[symindex].st_value = symvalue;
00739 symtable[symindex].st_size = symsize;
00740 symtable[symindex].st_shndx = scnindex;
00741 }
00742 }
00743
00744
00745 void
00746 Em_Undefine_Symbol (Elf64_Word symindex)
00747 {
00748 if (symindex == 0) {
00749 ErrMsg (EC_Elf_Idx, symindex, "Em_Undefine_Symbol");
00750 }
00751 if (Sixtyfour_Bit) {
00752 Elf64_Sym *symtable;
00753
00754 symtable = (Elf64_Sym *)SCNINFO_buffer(Symtab_Info);
00755 if (symindex >= (SCNINFO_size(Symtab_Info) / sizeof(Elf64_Sym)))
00756 ErrMsg (EC_Elf_Idx, symindex, "Em_Undefine_Symbol");
00757 symtable[symindex].st_shndx = SHN_UNDEF;
00758 }
00759 else {
00760 Elf32_Sym *symtable;
00761
00762 symtable = (Elf32_Sym *)SCNINFO_buffer(Symtab_Info);
00763 if (symindex >= (SCNINFO_size(Symtab_Info) / sizeof(Elf32_Sym)))
00764 ErrMsg (EC_Elf_Idx, symindex, "Em_Undefine_Symbol");
00765 symtable[symindex].st_shndx = SHN_UNDEF;
00766 }
00767 }
00768
00769
00770 void
00771 Em_Set_Symbol_Binding (Elf64_Word symindex, unsigned char symbind)
00772 {
00773 if (symindex == 0) {
00774 ErrMsg (EC_Elf_Idx, symindex, "Em_Set_Symbol_Binding");
00775 }
00776 if (Sixtyfour_Bit) {
00777 Elf64_Sym *sym64;
00778 unsigned char symtype;
00779
00780 if (symindex >= (SCNINFO_size(Symtab_Info) / sizeof(Elf64_Sym))) {
00781 ErrMsg (EC_Elf_Idx, symindex, "Em_Set_Symbol_Binding");
00782 }
00783 sym64 = (Elf64_Sym *)SCNINFO_buffer(Symtab_Info) + symindex;
00784 symtype = ELF64_ST_TYPE(sym64->st_info);
00785 sym64->st_info = ELF64_ST_INFO(symbind, symtype);
00786 }
00787 else {
00788 Elf32_Sym *sym32;
00789 unsigned char symtype;
00790
00791 if (symindex >= (SCNINFO_size(Symtab_Info) / sizeof(Elf32_Sym))) {
00792 ErrMsg (EC_Elf_Idx, symindex, "Em_Set_Symbol_Binding");
00793 }
00794 sym32 = (Elf32_Sym *)SCNINFO_buffer(Symtab_Info) + symindex;
00795 symtype = ELF32_ST_TYPE(sym32->st_info);
00796 sym32->st_info = ELF32_ST_INFO(symbind, symtype);
00797 }
00798 }
00799
00800 #ifndef MONGOOSE_BE
00801 Elf64_Addr
00802 Em_Get_Symbol_Value (Elf64_Word symindex)
00803 {
00804 if (Sixtyfour_Bit) {
00805 Elf64_Sym *symtable;
00806
00807 symtable = (Elf64_Sym *)SCNINFO_buffer(Symtab_Info);
00808 if (symindex >= (SCNINFO_size(Symtab_Info) / sizeof(Elf64_Sym)))
00809 ErrMsg (EC_Elf_Idx, symindex, "Em_Get_Symbol_Value");
00810 return symtable[symindex].st_value;
00811 }
00812 else {
00813 Elf32_Sym *symtable;
00814
00815 symtable = (Elf32_Sym *)SCNINFO_buffer(Symtab_Info);
00816 if (symindex >= (SCNINFO_size(Symtab_Info) / sizeof(Elf32_Sym)))
00817 ErrMsg (EC_Elf_Idx, symindex, "Em_Get_Symbol_Value");
00818 return symtable[symindex].st_value;
00819 }
00820 }
00821 #endif
00822
00823 char *
00824 Em_Get_Symbol_Name (Elf64_Word symindex)
00825 {
00826 if (Sixtyfour_Bit) {
00827 Elf64_Sym *symtable;
00828
00829 symtable = (Elf64_Sym *)SCNINFO_buffer(Symtab_Info);
00830 if (symindex >= (SCNINFO_size(Symtab_Info) / sizeof(Elf64_Sym)))
00831 ErrMsg (EC_Elf_Idx, symindex, "Em_Get_Symbol_Name");
00832 return Index_To_String(&Strtab_Info, symtable[symindex].st_name);
00833 }
00834 else {
00835 Elf32_Sym *symtable;
00836
00837 symtable = (Elf32_Sym *)SCNINFO_buffer(Symtab_Info);
00838 if (symindex >= (SCNINFO_size(Symtab_Info) / sizeof(Elf32_Sym)))
00839 ErrMsg (EC_Elf_Idx, symindex, "Em_Get_Symbol_Name");
00840 return Index_To_String(&Strtab_Info, symtable[symindex].st_name);
00841 }
00842 }
00843
00844
00845 Elf64_Word
00846 Em_Add_New_Symbol (
00847 char *symname,
00848 Elf64_Addr symvalue,
00849 Elf64_Xword symsize,
00850 unsigned char symbind,
00851 unsigned char symtype,
00852 unsigned char symother,
00853 Elf64_Half symshndx)
00854 {
00855 Elf64_Word strindex;
00856 Elf64_Word symindex;
00857
00858 strindex = (symname == NULL) ? 0 :
00859 (Elf64_Word) Em_Add_Bytes_To_Scn (&Strtab_Info, symname,
00860 strlen(symname)+1, sizeof(char));
00861 if (Sixtyfour_Bit) {
00862 Elf64_Sym sym64;
00863
00864 sym64.st_name = strindex;
00865 sym64.st_value = symvalue;
00866 sym64.st_size = symsize;
00867 sym64.st_info = ELF64_ST_INFO (symbind, symtype);
00868 sym64.st_other = symother;
00869 sym64.st_shndx = symshndx;
00870 symindex = (Elf64_Word) Em_Add_Bytes_To_Scn (Symtab_Info, &sym64,
00871 sizeof (Elf64_Sym), ELF64_FSZ_XWORD);
00872 symindex /= sizeof (Elf64_Sym);
00873 }
00874 else {
00875 Elf32_Sym sym32;
00876
00877 sym32.st_name = strindex;
00878 sym32.st_value = symvalue;
00879 sym32.st_size = symsize;
00880 sym32.st_info = ELF32_ST_INFO (symbind, symtype);
00881 sym32.st_other = symother;
00882 sym32.st_shndx = symshndx;
00883 symindex = (Elf64_Word) Em_Add_Bytes_To_Scn (Symtab_Info, &sym32,
00884 sizeof (Elf32_Sym), ELF32_FSZ_WORD);
00885 symindex /= sizeof (Elf32_Sym);
00886 }
00887 return symindex;
00888 }
00889
00890
00891 #ifndef MONGOOSE_BE
00892
00893
00894
00895 Elf64_Word
00896 Em_Add_New_Common_Symbol (
00897 char *symname,
00898 Elf64_Xword symsize,
00899 unsigned char symbind,
00900 unsigned char symother)
00901 {
00902 return Em_Add_New_Symbol (symname, 0, symsize, symbind, STT_OBJECT,
00903 symother, SHN_COMMON);
00904 }
00905 #endif
00906
00907
00908
00909
00910 Elf64_Word
00911 Em_Add_New_Undef_Symbol (
00912 char *symname,
00913 unsigned char symbind,
00914 unsigned char symtype,
00915 unsigned char symother)
00916 {
00917 return Em_Add_New_Symbol (symname, 0, 0, symbind, symtype,
00918 symother, SHN_UNDEF);
00919 }
00920
00921
00922
00923
00924
00925 Elf64_Word
00926 Em_Add_New_Weak_Symbol (
00927 char *weakname,
00928 unsigned char symtype,
00929 unsigned char symother,
00930 Elf64_Word symindex)
00931 {
00932 if (symindex == 0) {
00933 ErrMsg (EC_Elf_Idx, symindex, "Em_Add_New_Weak_Symbol");
00934 }
00935 if (Sixtyfour_Bit) {
00936 Elf64_Sym *symtable;
00937
00938 symtable = (Elf64_Sym *)SCNINFO_buffer(Symtab_Info);
00939 if (symindex >= (SCNINFO_size(Symtab_Info) / sizeof(Elf64_Sym)))
00940 ErrMsg (EC_Elf_Idx, symindex, "Em_Add_New_Weak_Symbol");
00941 return Em_Add_New_Symbol (weakname, symtable[symindex].st_value,
00942 symtable[symindex].st_size, STB_WEAK,
00943 symtype, symother,
00944 symtable[symindex].st_shndx);
00945 }
00946 else {
00947 Elf32_Sym *symtable;
00948
00949 symtable = (Elf32_Sym *)SCNINFO_buffer(Symtab_Info);
00950 if (symindex >= (SCNINFO_size(Symtab_Info) / sizeof(Elf32_Sym)))
00951 ErrMsg (EC_Elf_Idx, symindex, "Em_Add_New_Weak_Symbol");
00952 return Em_Add_New_Symbol (weakname, symtable[symindex].st_value,
00953 symtable[symindex].st_size, STB_WEAK,
00954 symtype, symother,
00955 symtable[symindex].st_shndx);
00956 }
00957 }
00958
00959
00960
00961
00962 static void
00963 Update_Addr_Reset_Size (pSCNINFO ev_scn)
00964 {
00965 UINT16 size;
00966 INT size_index;
00967
00968 size = SCNINFO_offset(ev_scn) - SCNINFO_ev_offset(ev_scn);
00969 size_index = SCNINFO_ev_offset(ev_scn) + 5;
00970 SCNINFO_buffer(ev_scn)[size_index] = (size >> 8);
00971 SCNINFO_buffer(ev_scn)[size_index+1] = (size & 0xff);
00972 }
00973
00974
00975
00976
00977 void
00978 Generate_Addr_Reset (pSCNINFO scn, BOOL is_events, Elf64_Xword ev_ofst)
00979 {
00980 Elf64_Xword evscn_ofst;
00981 char opcode = EK_ADDR_RESET;
00982 Elf64_Xword dummy = 0;
00983 pSCNINFO events_scn;
00984 Elf64_Word short_ofst = ev_ofst;
00985
00986 if ( short_ofst != ev_ofst ) {
00987 ErrMsg ( EC_Elf_Ofst64, ev_ofst, "Generate_Addr_Reset" );
00988 }
00989
00990 events_scn = (is_events) ? SCNINFO_events(scn) : SCNINFO_contents(scn);
00991
00992
00993
00994 SCNINFO_ev_offset(events_scn) = (Elf64_Word)
00995 Em_Add_Bytes_To_Scn (events_scn, &opcode, 1, 1);
00996 evscn_ofst = Em_Add_Bytes_To_Scn (events_scn, &short_ofst, 4, 1);
00997 Em_Add_New_Rel (Em_Create_Section_Symbol(scn), R_SCN_DISP,
00998 evscn_ofst, events_scn);
00999
01000 Em_Add_Bytes_To_Scn (events_scn, &dummy, 2, 1);
01001 if (is_events)
01002 SCNINFO_ev_offset(scn) = ev_ofst;
01003 else
01004 SCNINFO_con_offset(scn) = ev_ofst;
01005 }
01006
01007
01008
01009
01010 #define MAX_EV_SIZE 64000
01011
01012 void
01013 Set_Current_Location (pSCNINFO scn, BOOL is_events, Elf64_Word ev_ofst)
01014 {
01015 Elf64_Word cur_ofst, word_ofst;
01016 char opcode;
01017 pSCNINFO ev_scn;
01018 char leb_buf[10];
01019 UINT32 num_bytes;
01020
01021
01022 ev_scn = (is_events) ? SCNINFO_events(scn) : SCNINFO_contents(scn);
01023
01024
01025 if ((SCNINFO_offset(ev_scn) - SCNINFO_ev_offset(ev_scn)) > MAX_EV_SIZE) {
01026 Update_Addr_Reset_Size (ev_scn);
01027 Generate_Addr_Reset ( scn, is_events, (Elf64_Xword)ev_ofst );
01028 return;
01029 }
01030
01031 cur_ofst = (is_events) ? SCNINFO_ev_offset(scn) : SCNINFO_con_offset(scn);
01032 if (ev_ofst < cur_ofst) {
01033
01034 Update_Addr_Reset_Size (ev_scn);
01035 Generate_Addr_Reset ( scn, is_events, (Elf64_Xword)ev_ofst );
01036 return;
01037 }
01038 if ((ev_ofst - cur_ofst) > MAX_EV_SIZE) {
01039
01040 Update_Addr_Reset_Size (ev_scn);
01041 Generate_Addr_Reset ( scn, is_events, (Elf64_Xword)ev_ofst );
01042 return;
01043 }
01044
01045 if (ev_ofst == cur_ofst) return;
01046
01047 word_ofst = (ev_ofst - cur_ofst) >> 2;
01048 if (word_ofst <= 127) {
01049 opcode = EK_INCR_LOC | (word_ofst & 0x7f);
01050 Em_Add_Bytes_To_Scn (ev_scn, &opcode, 1, 1);
01051 } else {
01052 opcode = EK_INCR_LOC_EXT;
01053 Em_Add_Bytes_To_Scn (ev_scn, &opcode, 1, 1);
01054 num_bytes = _leb128_unsigned_encode32 (word_ofst, leb_buf);
01055 Em_Add_Bytes_To_Scn (ev_scn, leb_buf, num_bytes, 1);
01056 }
01057 if ( is_events)
01058 SCNINFO_ev_offset(scn) = ev_ofst;
01059 else
01060 SCNINFO_con_offset(scn) = ev_ofst;
01061 }
01062
01063
01064
01065
01066 void
01067 Em_Add_New_Interface (
01068 Elf64_Word length,
01069 Elf64_Byte *data )
01070 {
01071 if ( Interface_Scn == NULL) {
01072 Interface_Scn = Em_New_Section (SECT_IFACE_NAME, SHT_IRIX_IFACE,
01073 SHF_NOSTRIP, ELF32_FSZ_WORD, ELF32_FSZ_WORD);
01074 Em_Set_sh_link (Interface_Scn, SCNINFO_index(Symtab_Info));
01075 }
01076 Em_Add_Bytes_To_Scn (Interface_Scn, data, length, ELF32_FSZ_WORD);
01077 }
01078
01079
01080
01081
01082
01083
01084
01085 extern void
01086 Em_Add_Comment (char *s)
01087 {
01088 char *buff;
01089 if (Comment_Scn == NULL) {
01090 Comment_Scn = Em_New_Section (ELF_COMMENT, SHT_PROGBITS,
01091 0, 0, sizeof(char));
01092 }
01093 if (strchr(s,':') == NULL) {
01094 buff = (char *) alloca (strlen(s) + sizeof(INCLUDE_STAMP) +
01095 strlen(object_file_name) + 4);
01096 sprintf(buff, "%s::%s:%s", s, INCLUDE_STAMP, object_file_name);
01097 } else {
01098 buff = s;
01099 }
01100 Em_Add_Bytes_To_Scn (Comment_Scn, buff, strlen(buff) + 1, sizeof(char));
01101 }
01102
01103
01104
01105
01106 static void
01107 Create_Elf_Header (INT isa, BOOL old_abi, BOOL big_endian, BOOL pic,
01108 BOOL cpic, BOOL xgot, BOOL gp_groups)
01109 {
01110 unsigned char e_ident_data;
01111 Elf64_Word e_flags;
01112 Elf32_Ehdr *ehdr32;
01113 Elf64_Ehdr *ehdr64;
01114
01115
01116
01117 e_flags = Config_ELF_From_Target (Sixtyfour_Bit, old_abi, isa);
01118
01119
01120 if (pic)
01121 e_flags |= EF_MIPS_PIC;
01122 else if (cpic)
01123 e_flags |= EF_MIPS_CPIC;
01124 if (xgot)
01125 e_flags |= EF_MIPS_XGOT;
01126 if (gp_groups)
01127 e_flags |= EF_MIPS_OPTIONS_FIRST;
01128
01129
01130 e_ident_data = (big_endian ? ELFDATA2MSB : ELFDATA2LSB);
01131
01132 if (Sixtyfour_Bit) {
01133 ehdr64 = elf64_newehdr(Elf_Ptr);
01134 ehdr64->e_ident[EI_DATA] = e_ident_data;
01135 Set_Elf_Version ((unsigned char *) &(ehdr64->e_ident));
01136 ehdr64->e_machine = Get_Elf_Target_Machine();
01137 ehdr64->e_type = ET_REL;
01138 #if ! (defined(linux) || defined(BUILD_OS_DARWIN))
01139 ehdr64->e_flags = e_flags;
01140 #else
01141 ehdr64->e_flags = 0x23000000LL | e_flags;
01142 #endif
01143 }
01144 else {
01145 ehdr32 = elf32_newehdr(Elf_Ptr);
01146 ehdr32->e_ident[EI_DATA] = e_ident_data;
01147 Set_Elf_Version ((unsigned char *) &(ehdr32->e_ident));
01148 ehdr32->e_machine = Get_Elf_Target_Machine();
01149 ehdr32->e_type = ET_REL;
01150 ehdr32->e_flags = e_flags;
01151 }
01152
01153
01154
01155
01156 (void) Em_Add_Bytes_To_Scn (&Shstrtab_Info, "", 1, 1);
01157 (void) Em_Add_Bytes_To_Scn (&Strtab_Info, "", 1, 1);
01158
01159
01160 SCNINFO_scnptr(Symtab_Info) =
01161 Create_New_Section (ELF_SYMTAB, SHT_SYMTAB, SHF_ALLOC ,
01162 Sixtyfour_Bit ? sizeof(Elf64_Sym) : sizeof(Elf32_Sym));
01163
01164
01165 Em_Add_New_Symbol (NULL, 0, 0, STB_LOCAL, STT_NOTYPE, 0, SHN_UNDEF);
01166
01167
01168 Shstrtab_Info.scnptr = Create_New_Section (ELF_SHSTRTAB, SHT_STRTAB,
01169 SHF_ALLOC, sizeof(char));
01170
01171
01172 Strtab_Info.scnptr = Create_New_Section (ELF_STRTAB, SHT_STRTAB,
01173 SHF_ALLOC, sizeof(char));
01174
01175 Em_Set_sh_link (Symtab_Info, SCNINFO_index(&Strtab_Info));
01176 if (Sixtyfour_Bit) {
01177 ehdr64->e_shstrndx = SCNINFO_index(&Shstrtab_Info);
01178 }
01179 else {
01180 ehdr32->e_shstrndx = SCNINFO_index(&Shstrtab_Info);
01181 }
01182 }
01183
01184
01185 static void
01186 Read_Section (pSCNINFO scninfo, Elf64_Word scndx)
01187 {
01188 Elf_Data *scndata;
01189 Elf_Scn *scn;
01190
01191
01192 BZERO (scninfo, sizeof(SCNINFO));
01193 scn = elf_getscn (Elf_Ptr, scndx);
01194 scndata = elf_getdata (scn, (Elf_Data *)0);
01195 elf_flagscn (scn, ELF_C_SET, ELF_F_DIRTY);
01196 elf_flagdata (scndata, ELF_C_SET, ELF_F_DIRTY);
01197 SCNINFO_scnptr(scninfo) = scn;
01198 Em_Add_Bytes_To_Scn (scninfo, scndata->d_buf, scndata->d_size,
01199 scndata->d_align);
01200 scndata->d_buf = NULL;
01201 scndata->d_size = 0;
01202 }
01203
01204
01205 static void
01206 Read_Elf_File (void)
01207 {
01208 Elf64_Word shndx;
01209 Elf64_Word scntype;
01210 Elf_Scn *scn;
01211
01212 shndx = (Sixtyfour_Bit) ? elf64_getehdr(Elf_Ptr)->e_shstrndx :
01213 elf32_getehdr(Elf_Ptr)->e_shstrndx;
01214 Read_Section (&Shstrtab_Info, shndx);
01215
01216 scn = NULL;
01217 while ((scn = elf_nextscn (Elf_Ptr, scn)) != NULL) {
01218 scntype = (Sixtyfour_Bit) ? elf64_getshdr(scn)->sh_type :
01219 elf32_getshdr(scn)->sh_type;
01220 if (scntype == SHT_SYMTAB) {
01221 Read_Section (Symtab_Info, elf_ndxscn(scn));
01222 shndx = (Sixtyfour_Bit) ? elf64_getshdr(scn)->sh_link :
01223 elf32_getshdr(scn)->sh_link;
01224 Read_Section (&Strtab_Info, shndx);
01225 break;
01226 }
01227 }
01228 }
01229
01230
01231
01232 int Em_Begin_File (
01233 char *ofilename,
01234 BOOL update,
01235 BOOL elf64,
01236 BOOL old_abi,
01237 INT isa,
01238 BOOL big_endian,
01239 BOOL pic,
01240 BOOL cpic,
01241 BOOL xgot,
01242 BOOL gp_groups,
01243 BOOL elf_trace)
01244 {
01245 int ofiledes;
01246 Elf_Cmd cmd;
01247
01248
01249 Options_Scn = NULL;
01250 Comment_Scn = NULL;
01251 Interface_Scn = NULL;
01252
01253 Sixtyfour_Bit = elf64;
01254 Big_Endian = big_endian;
01255 if (update) {
01256 ofiledes = open (ofilename, O_RDWR);
01257 }
01258 else {
01259 INT result;
01260 struct stat statstuff;
01261
01262 result = stat (ofilename, &statstuff);
01263
01264 if (result != -1) {
01265
01266 result = unlink (ofilename);
01267 if (result == -1) {
01268 ErrMsg (EC_Obj_Delete, ofilename, errno);
01269 return (int) 0;
01270 }
01271 }
01272 ofiledes = open (ofilename, O_RDWR|O_TRUNC|O_CREAT, 0666);
01273 }
01274 if (ofiledes <= 0) {
01275 ErrMsg (EC_Obj_Create, ofilename, errno);
01276 return (int) 0;
01277 }
01278
01279 object_file_name = ofilename;
01280
01281
01282 (void)elf_errno();
01283
01284 if (elf_version(EV_CURRENT) == EV_NONE) {
01285 print_elf_error ();
01286 }
01287 cmd = update ? ELF_C_RDWR : ELF_C_WRITE;
01288 if ((Elf_Ptr = elf_begin(ofiledes, cmd, (Elf * )0)) == 0) {
01289 print_elf_error ();
01290 }
01291
01292 if (update) {
01293 Read_Elf_File ();
01294 }
01295 else {
01296 Create_Elf_Header (isa, old_abi, big_endian, pic, cpic, xgot, gp_groups);
01297 }
01298 return ofiledes;
01299 }
01300
01301
01302
01303 void
01304 Em_End_File (void)
01305 {
01306
01307 Update_Data (&Shstrtab_Info, ELF_T_BYTE);
01308
01309 Update_Data (&Strtab_Info, ELF_T_BYTE);
01310
01311 Update_Data (Symtab_Info, ELF_T_SYM);
01312
01313
01314 if (Options_Scn != NULL) Em_End_Section (Options_Scn);
01315
01316 if (Comment_Scn != NULL) Em_End_Section (Comment_Scn);
01317
01318 if (Interface_Scn != NULL) Em_End_Section (Interface_Scn);
01319
01320 if (elf_update(Elf_Ptr, ELF_C_WRITE) == -1 ||
01321 elf_end(Elf_Ptr) == 0)
01322 {
01323 print_elf_error ();
01324 }
01325 }
01326
01327
01328 pSCNINFO Em_New_Section (
01329 const char *scnname,
01330 Elf64_Word scntype,
01331 Elf64_Xword scnflags,
01332 Elf64_Xword scnentsize,
01333 Elf64_Xword scnalign)
01334 {
01335 Elf_Scn *scn;
01336 pSCNINFO scninfo;
01337
01338 scninfo = (pSCNINFO) malloc (sizeof (SCNINFO));
01339 if (scninfo == NULL)
01340 ErrMsg ( EC_No_Mem, "Em_New_Section" );
01341 BZERO (scninfo, sizeof(SCNINFO));
01342 scn = Create_New_Section (scnname, scntype, scnflags, scnentsize);
01343 SCNINFO_scnptr(scninfo) = scn;
01344 SCNINFO_align(scninfo) = scnalign;
01345 return scninfo;
01346 }
01347
01348
01349 void
01350 Em_End_Section (pSCNINFO scninfo)
01351 {
01352 Update_Data (scninfo, ELF_T_BYTE);
01353 if (SCNINFO_relinfo(scninfo) != NULL) {
01354 Update_Data (SCNINFO_relinfo(scninfo), ELF_T_REL);
01355 free (SCNINFO_relinfo(scninfo));
01356 }
01357 if (SCNINFO_relainfo(scninfo) != NULL) {
01358 Update_Data (SCNINFO_relainfo(scninfo), ELF_T_RELA);
01359 free (SCNINFO_relainfo(scninfo));
01360 }
01361 if (SCNINFO_events(scninfo) != NULL) {
01362 Update_Addr_Reset_Size (SCNINFO_events(scninfo));
01363 Em_End_Section (SCNINFO_events(scninfo));
01364 }
01365 if (SCNINFO_contents(scninfo) != NULL) {
01366 Update_Addr_Reset_Size (SCNINFO_contents(scninfo));
01367 Em_End_Section (SCNINFO_contents(scninfo));
01368 }
01369 free (scninfo);
01370 }
01371
01372
01373 void Em_New_Data_Buffer (pSCNINFO scninfo, Elf64_Xword size, int alignment)
01374 {
01375 Elf64_Xword newoffset;
01376
01377 newoffset = SCNINFO_size(scninfo);
01378 newoffset = Roundup (newoffset, alignment);
01379 if (SCNINFO_align(scninfo) < alignment)
01380 SCNINFO_align(scninfo) = alignment;
01381 Increase_Data_Buffer_Size ( scninfo, newoffset + size );
01382 }
01383
01384 Elf64_Word
01385 Em_Create_Section_Symbol (pSCNINFO scninfo)
01386 {
01387 Elf64_Word symindex;
01388
01389 symindex = SCNINFO_scnidx(scninfo);
01390 if (symindex == 0) {
01391 symindex = Em_Add_New_Symbol (Em_Get_Section_Name (scninfo),
01392 (Elf64_Addr)0, (Elf64_Xword)0,
01393 STB_LOCAL, STT_SECTION, 0,
01394 SCNINFO_index(scninfo));
01395 SCNINFO_scnidx(scninfo) = symindex;
01396 }
01397 return symindex;
01398 }