This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] COFF/PE offset ajdustment (for Interix)


Hello,

in my quest to get rid of the xm-interix.h file, I am looking at a macro
that Donn Terry added, and used in coffread.c: ADJUST_OBJFILE_OFFSETS.

What happens is that, COFF/PE stores the offset of the symbols using
a base address that is non-zero: In the PE case, the offset is relative
to the imageBase (the prefered-address to load the executable).

The solution that Donn Terry came up with was to call a function
before reading the symbol that would adjust the objfile offsets array
by the right amount - Once the symbols are read, he then call this
function to restore this array. Something like this:

        *************** coff_symfile_read (struct objfile *objfi
        *** 635,641 ****
        --- 634,648 ----
            /* Now that the executable file is positioned at symbol table,
               process it and define symbols accordingly.  */
          
        +   /* Some implementations (e.g. PE) have their symbols stored as
        +      relative to some base other than zero.  Adjust the offset
        +      array to compensate.  (And then put things back like we found
        +      them.)   (Doing this here saves lots of execution time while
        +      reading the symbols, because it's automatic.) */
        + 
        +   ADJUST_OBJFILE_OFFSETS(objfile, adjust_for_symtab);
            coff_symtab_read ((long) symtab_offset, num_symbols, objfile);
        +   ADJUST_OBJFILE_OFFSETS(objfile, adjust_for_symtab_restore);
          
            /* Sort symbols alphabetically within each block.  */
  
Here, the adjust_for_* are just 2 values of an enum type (discussed
below). It is not absolutely necessary, but was introduced by Donn
as an effort to do it "right".

For the sake of completness, here is a copy of the function that the
ADJUST_OBJFILE_OFFSETS is defined to on Interix (NONZERO_LINK_BASE
returns the imageBase here):
        void
        pei_adjust_objfile_offsets (struct objfile *objfile,
                                    enum objfile_adjusts type)
        {
          int i;
          CORE_ADDR symbols_offset;
        
          switch (type)
            {
            case adjust_for_symtab:
              symbols_offset = NONZERO_LINK_BASE (objfile->obfd);
              break;
            case adjust_for_symtab_restore:
              symbols_offset = -NONZERO_LINK_BASE (objfile->obfd);
              break;
            }
            
          for (i = 0; i < SECT_OFF_MAX; i++)
            {
              (objfile->section_offsets)->offsets[i] += symbols_offset;
            }
        }

This change was written some time ago, without thinking about the
multi-arching capabilities. I don't think you will want to integrate
this change as it is at the moment. But I think that the approach itself
is sensible. Donn reported that modifying ANOFFSET to make it
imageBase-aware was too intrusive to be interesting).

What I suggest, on the other hand, is to define a new gdbarch method
called for instance ADJUST_COFF_SYMTAB_OFFSETS, with the profile above
(param1 = objfile, param2 = either enum or int to tell in which
direction to adjust). By default, this method would do nothing, but we
would set this method to pei_adjust_objfile_offsets inside
i386-interix-tdep.c. Or maybe a target method? Alternatively, we could
define 2 methods (one for each adjustment direction), but I think this
not really necessary.

About the enum type, this enum type was defined by Donn in symfile.h
with 6 values: 3 pairs to adjust the offsets for either symtab, stabs,
and dwarf2. So far, the stabs and dwarf2 information don't need this
little tap-dance, so ADJUST_OBJFILE_OFFSETS with stabs or dwarf2 is a
no-op. According to Donn, this may become useful in the future:

<<
        Since (gcc) Interix executables don't have a .reloc section,
        they will ALWAYS run at the location they were linked for.
        However, if a .reloc section is present, they can be relocated
        at runtime.  (For the "base" .exe (in Windows parlance) that's
        higly unlikely to happen anyway, but is *theoretically*
        possible.)
>>

My feeling is that this enum is not really mandate. If one day stabs
and/or dwarf2 need to be relocated too, I'd create a separate function
for that.

So to summarize: my suggestion is to enhance a bit the approach taken by
Donn to promote his ADJUST_OBJFILE_OFFSETS macro as a gdbarch method,
called ADJUST_COFF_SYMTAB_OFFSETS.  By default, this method would do
nothing. The profile of this method would be "(struct objfile *objfile,
int adjust)". I will then wrap the call to coff_symtab_read with calls to
this new method.

Does this sound like a sensible plan?

Thanks,
-- 
Joel


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]