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