Greetings, and thanks so much for looking into this! Richard Harke <[EMAIL PROTECTED]> writes:
> On Tue November 14 2006 18:43, you wrote: > > > This would be most appreciated, and I'd be happy to lend assistance. > > Knowledge of the ia64 reloc definitions is obviously key, though I put > > together the alpha version mostly as a guesswork based on the mips > > example. If ia64 were done, we could also share with the lush > > project, on which the original sfaslbfd_mips was inspired. And > > someday it would be great to get this back into bfd upstream. > > > > The basic idea is that each section of the .o file has a got table > > appended to handle the relocs that refer to the special gp register > > value. > I have been studying ld.so and also Xorg as that has a loader function. > Its not clear to me that they handle just the same set of relocs. > The R_IA64_ defines in elf.h have two bit fields for the ia64 and > these are used in ld.so but that info seems not to be used in Xorg. > And bfd uses an enum so such structuring of the values isn't > possible. > I notice some comments about a standalone version of the loader > code. That should be very helpful if it works. It might -- haven't tried it in a while. I will do so if you still need it after the following. > You said something about the heap having to do with the dlopen version > not working but I noticed some things that made me think that > dynamic linking, ie letting the lisp code access vars by name > was an issue. Can you provide more detail? > Any suggestions would be helpful. > The standard ia64 build uses dlopen somewhat successfully. In addition to limiting the number of loads to ~ 1024, another weakness stems from the typical usage of loading a .o file into an image, dumping the image with unexec, and reexecuting later where we left off. Many lisp programs are built using this paradigm. dlopen does not allow a fixed address to be assigned to the relocated functions across multiple image executions, and so foils GCL's very fast function calling mechanism. This essentially means that either all loads must be redone on image startup, or the image needs to be written by a special call to ld via compiler::link, in which the .o files are relocated and initialized a second time 'by hand'. This will probably be clearer if you examine how axiom is built on this platform in contrast with say x86. I think the way to start would be to look at a compiled .o file on ia64: ============================================================================= [EMAIL PROTECTED]:~/hol88-2.02.19940316/lisp$ objdump -r hol-writ.o hol-writ.o: file format elf64-ia64-little RELOCATION RECORDS FOR [.text]: OFFSET TYPE VALUE 0000000000000010 LTOFF22X .data.rel.local 0000000000000020 LDXMOV .data.rel.local 0000000000000022 PCREL21B do_init 0000000000000051 LTOFF22X vs_base 0000000000000052 LTOFF22X vs_top 0000000000000060 LTOFF22X vs_limit 0000000000000062 LTOFF22X small_fixnum_table+0x0000000000004000 0000000000000070 LDXMOV vs_base 0000000000000071 LDXMOV vs_top 0000000000000080 LTOFF22X Cnil_body 0000000000000081 LDXMOV vs_limit 0000000000000090 LDXMOV small_fixnum_table+0x0000000000004000 00000000000000b0 LDXMOV Cnil_body 00000000000000c1 GPREL22 .sdata+0x0000000000000228 0000000000000150 GPREL22 .sdata+0x0000000000000230 0000000000000161 GPREL22 .sdata+0x0000000000000238 0000000000000162 LTOFF22X Ct_body 0000000000000191 LDXMOV Ct_body 0000000000000240 LTOFF22X .data.rel.local 0000000000000241 GPREL22 .sdata+0x00000000000001e8 0000000000000242 GPREL22 .sdata+0x00000000000001d8 0000000000000252 GPREL22 .sdata 0000000000000261 LDXMOV .data.rel.local 0000000000000282 GPREL22 .sdata+0x0000000000000010 0000000000000442 GPREL22 .sdata+0x0000000000000008 00000000000004d1 GPREL22 .sdata+0x00000000000001e0 0000000000000601 GPREL22 .sdata+0x00000000000001f8 0000000000000652 PCREL21B vs_overflow 0000000000000670 LTOFF22X small_fixnum_table+0x0000000000004000 0000000000000671 GPREL22 .sdata+0x0000000000000228 0000000000000681 LTOFF22X Cnil_body 0000000000000691 LDXMOV small_fixnum_table+0x0000000000004000 00000000000006b0 LDXMOV Cnil_body 0000000000000700 LTOFF22X .data.rel.local 0000000000000701 GPREL22 .sdata+0x00000000000001e0 0000000000000702 GPREL22 .sdata+0x0000000000000230 0000000000000710 GPREL22 .sdata+0x0000000000000238 0000000000000711 LTOFF22X Ct_body 0000000000000720 LDXMOV .data.rel.local 0000000000000731 LDXMOV Ct_body 0000000000000851 GPREL22 .sdata+0x00000000000001f8 00000000000008a1 LTOFF22X .data.rel.local 00000000000008a2 GPREL22 .sdata+0x00000000000001e8 00000000000008b2 GPREL22 .sdata+0x00000000000001d8 00000000000008c0 LDXMOV .data.rel.local 00000000000008e1 GPREL22 .sdata+0x0000000000000008 0000000000000971 LTOFF22X vs_base 0000000000000980 LTOFF22X vs_top 0000000000000981 LTOFF22X vs_limit 0000000000000990 LDXMOV vs_base 0000000000000991 LDXMOV vs_top 00000000000009a0 LDXMOV vs_limit 00000000000009d0 GPREL22 .sdata+0x0000000000000248 0000000000000a72 PCREL21B vs_overflow 0000000000000a92 GPREL22 .sdata+0x0000000000000248 0000000000000b21 LTOFF22X vs_top 0000000000000b30 LTOFF22X vs_limit 0000000000000b31 LTOFF22X vs_base 0000000000000b40 LDXMOV vs_top 0000000000000b41 LDXMOV vs_limit 0000000000000b50 LDXMOV vs_base 0000000000000b70 LTOFF22X .data.rel.local 0000000000000b80 LDXMOV .data.rel.local 0000000000000be0 LTOFF22X Cnil_body ============================================================================= We just have a handful of relocs that need handling in practice, and of these, several are probably already correctly handled by bfd_get_relocated_section_contents. Typically, the ones that aren't are those referring to the gp register, which in this case appears to be GPREL22, to my untutored guess. These relocs should be handled in analogy with the GP relocs in sfasl_alpha.c -- i.e. they are rewritten to refer to a special .got table that is constructed at the end of each loaded section. They key functions are alphaelf_create_got and alphaelf_fix_relocs, the comments to which are somwhat useful: ============================================================================= static asection * alphaelf_create_got(bfd *b,asymbol **syms, alphaelf_got_info *info) { bfd_vma offset; asection *p; int i; /* Check that there are no GOT section */ info->sgot = bfd_get_section_by_name(b, ".got"); assert(!info->sgot); /* Compute GOT hash table */ offset = 0; for (p=b->sections; p; p=p->next) if ((p->flags & SEC_ALLOC) && (p->flags & SEC_RELOC)) { int sz,reloc_count; arelent **reloc; /* ALPHA native relocs: This section and analogs below have been modified to avoid orelocation in favor of relocation itself. bfd_canonicalize_reloc reads in the relocation table to the latter as an array and makes a pointer list to it in the supplied argument. We will call bfd_get_relocated_section_contents, which will call bfd_canonicalize_reloc internally, on all sections, including the new .got section. If no relocation array exists, this will fail when bfd_cannicalize_reloc attempts to read in the non-existent table. 20050409 CM*/ sz = bfd_get_reloc_upper_bound(b, p); assert(sz>0); reloc=ZALLOCA(sz); reloc_count = bfd_canonicalize_reloc(b, p, reloc, syms); assert(reloc_count>0); assert(p->reloc_count==0 || p->reloc_count==reloc_count); assert(p->relocation); for (i=0; i<p->reloc_count; i++) { arelent *reloc = p->relocation+i; if ((reloc->howto==info->reloc_literal)) { const char *name = msymbol_name(b,*reloc->sym_ptr_ptr,reloc->addend); alphaelf_got_entry *gotent = (alphaelf_got_entry*) bfd_hash_lookup(&info->got_table, name, TRUE, TRUE ); if (!gotent->reloc) { gotent->index = info->gotsize; gotent->offset = offset; gotent->reloc = xballoc(b, sizeof(arelent)); gotent->reloc->sym_ptr_ptr = reloc->sym_ptr_ptr; gotent->reloc->address = offset; gotent->reloc->addend = reloc->addend; gotent->reloc->howto = info->reloc_64; offset += sizeof(void*); info->gotsize += 1; } } } } if (offset >= 0x8000) FEerror("Too many entries in GOT (GOT full, merci ALPHA)",0); if (info->gotsize > 0) { info->sgot = bfd_make_section(b, ".got"); assert(info->sgot); info->sgot->flags = SEC_ALLOC|SEC_RELOC|SEC_LOAD; if (!bfd_set_section_size(b,info->sgot,offset)) FEerror("Cannot set got section size",0); if (info->sgot->alignment_power < 4) info->sgot->alignment_power = 4; /* Set GOT relocations */ info->sgot->relocation = xballoc(b, info->gotsize*sizeof(*info->sgot->relocation)); bfd_hash_traverse(&info->got_table, (void*)alphaelf_got_traverse, info->sgot); info->sgot->reloc_count = info->gotsize; } return info->sgot; } /* alphaelf_fix_relocs -- patches the relocation for GOT */ static void alphaelf_fix_relocs(bfd *b,asymbol ** symbols,int symbol_count, alphaelf_got_info *info) { int i; asymbol **gpdisp_ptr = NULL; asection *p; /* Make a gpdisp symbol at the top of the .got section */ gpdisp = xballoc(b, sizeof(*gpdisp)); gpdisp->value = 0; gpdisp->name="gpdisp"; gpdisp->flags = BSF_LOCAL|BSF_SECTION_SYM; gpdisp->section = info->sgot ? info->sgot : bfd_abs_section_ptr; gpdisp->udata.p = NULL; gp=0; if (!info->sgot) return; gpdisp_ptr = xballoc(b, sizeof(asymbol*)); *gpdisp_ptr = gpdisp; /* Iterate on sections and relocations */ for (p=b->sections; p; p=p->next) if ((p->flags & SEC_ALLOC) && (p->flags & SEC_RELOC)) { assert(p->relocation); for (i=0; i<p->reloc_count; i++) { arelent *reloc = p->relocation+i; if (reloc->howto==info->reloc_literal) { const char *name = msymbol_name(b,*reloc->sym_ptr_ptr,reloc->addend); alphaelf_got_entry *gotent = (alphaelf_got_entry*) bfd_hash_lookup(&info->got_table, name, FALSE, FALSE ); assert(gotent); /* ELF_LITERAL relocations will refer * to the GPDISP symbol and have the GOT index * in the addend */ reloc->addend = gotent->offset; reloc->sym_ptr_ptr = gpdisp_ptr; } } } } ============================================================================= mips is still more involved if a hairier example is needed :-). So I think that all we need is to identify how to 1) capture the gp symbol value and 2) rewrite the relocs referring thereto to refer to a got table entry which is then constructed to point to the right address. Hopefully this will ring some bells in your mind given its familiarity with ia64. The way to debug this is to make a saved_pre_gcl image in unixport with a new sfaslbfd_ia64.c compiled in (the ia64-linux.h needs to be modified following the alpha-linux.h), and debugging enabled (--enable-debug on the configure command line). Then fire up gdb on saved_pre_gcl, and try loading a .o file, breaking at fasload and stepping through each of the routines, especially bfd_get_relocated_section_contents). Take care, and thanks again, > Richard > > > -- Camm Maguire [EMAIL PROTECTED] ========================================================================== "The earth is but one country, and mankind its citizens." -- Baha'u'llah _______________________________________________ Gcl-devel mailing list Gcl-devel@gnu.org http://lists.gnu.org/mailman/listinfo/gcl-devel