This is the mail archive of the cygwin-developers mailing list for the Cygwin 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]

Re: speclib vs. -lc trouble.


Dave Korn wrote:

> If the BFD is flushed, what's to stop us from re-opening the file
> descriptor with the new filename and reading data from offsets
> corresponding to the offsets in the old filename, because those offsets are
> cached in the BFD's archive cache in the filepos members of the ar_cache
> entries.

  Nothing at all.  I just watched with a hardware breakpoint the name of the
BFD change from libc to libcygwin, now I see it reading from libcygwin.a in
FileMon, but the offsets are all still from libc.a.

(gdb) print abfd->filename
$44 = 0xd81aec "cygwin_crt0.o"
(gdb) print abfd->my_archive->filename
$45 = 0xf7a2f8 "/gnu/winsup/obj6/i686-pc-cygwin/winsup/cygwin/libcygwin.a"
(gdb) print *abfd->my_archive->tdata.aout_ar_data
$43 = {first_file_filepos = 53292, cache = 0xd85c18, archive_head = 0x0,
  symdefs = 0xda8480, symdef_count = 3040,
  extended_names = 0xd81a00 "_cygwin_crt0_common.o",
  extended_names_size = 44, armap_timestamp = 0, armap_datepos = 0,
  tdata = 0x0}
(gdb) print abfd->my_archive->tdata.aout_ar_data->symdefs[0]
$46 = {name = 0xdb4280 "__cygwin_crt0_common@8", file_offset = 53292}
(gdb) print abfd->my_archive->tdata.aout_ar_data->symdefs[1]
$47 = {name = 0xdb4297 "_environ", file_offset = 53292}
(gdb) print abfd->my_archive->tdata.aout_ar_data->symdefs[6]
$48 = {name = 0xdb42c2 "__imp__aclcheck", file_offset = 70198}
(gdb) print abfd->my_archive->tdata.aout_ar_data->symdefs[7]
$49 = {name = 0xdb42d2 "_aclfrommode", file_offset = 71062}
(gdb) print abfd->my_archive->tdata.aout_ar_data->symdefs[8]
$50 = {name = 0xdb42df "__imp__aclfrommode", file_offset = 71062}
(gdb) print abfd->my_archive->tdata.aout_ar_data->symdefs[24]
$51 = {name = 0xdb43c9 "_cygwin_crt0", file_offset = 84662}
(gdb)

  Both the first_file_filepos and the symdefs[].file_offset values are all
still right for the original import library.  libcygwin has much more in it
than libc, so the offsets that point to archive members in libc point
somewhere in the (longer) leading string table in libcygwin, and that 0x74
error I was seeing was the letter 't' from an 'idata$4'.

  At offset of 1248 + (84662 + 0x3c = ar member header size) = 0x14FD2 in
libc.a there is this:

014fd0 00 00 15 00 00 00 19 00 00 00 14 00 1e 00 00 00
014fe0 18 00 00 00 06 00 06 00 00 00 0a 00 00 00 0b 00

which is a couple of relocs:

RELOCATION RECORDS FOR [.text]:
OFFSET   TYPE              VALUE
00000015 DISP32            __cygwin_crt0_common@8
0000001e dir32             __imp___dll_crt0@0

[ 24](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __imp___dll_crt0@0
[ 25](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 __cygwin_crt0_common@8

and in libcygwin.a is this:

014fd0 00 00 00 00 00 00 08 00 00 00 2c 01 00 00 50 01
014fe0 00 00 00 00 00 00 01 00 00 00 20 00 30 60 2e 64

which is the bad data I'm seeing here:

(gdb)
_bfd_coff_read_internal_relocs (abfd=0xd85ee0, sec=0xdf83a8, cache=0,
    external_relocs=0xfc8840 "", require_internal=0, internal_relocs=0xfce520)
    at /gnu/binutils/src/bfd/coffgen.c:459
459       for (; erel < erel_end; erel += relsz, irel++)
(gdb) x/32xb external_relocs
0xfc8840:       0x00    0x00    0x00    0x00    0x08    0x00    0x00    0x00
0xfc8848:       0x2c    0x01    0x00    0x00    0x50    0x01    0x00    0x00
0xfc8850:       0x00    0x00    0x00    0x00    0x30    0x00    0x00    0x00
0xfc8858:       0x41    0x00    0x00    0x00    0x0b    0x00    0x34    0x00
(gdb)

and that 0x2c and 0x01 become 0x012c = 300, which is the invalid reloc number
I'm seeing here:

(gdb) c
Continuing.

Breakpoint 5, bfd_set_error (error_tag=bfd_error_bad_value)
    at /gnu/binutils/src/bfd/bfd.c:429
429     {
(gdb) bt
#0  bfd_set_error (error_tag=bfd_error_bad_value)
    at /gnu/binutils/src/bfd/bfd.c:429
#1  0x00435c7e in coff_i386_rtype_to_howto (abfd=0xd85ee0, sec=0xdf83a8,
    rel=0xfce520, h=0x0, sym=0xfaa4c8, addendp=0x22c698)
    at /gnu/binutils/src/bfd/coff-i386.c:459
#2  0x0044adf4 in _bfd_coff_generic_relocate_section (output_bfd=0xb52900,
    info=0x4c41f8, input_bfd=0xd85ee0, input_section=0xdf83a8,
    contents=0xfae190 "", relocs=0xfce520, syms=0xfaa428, sections=0xfabed0)
    at /gnu/binutils/src/bfd/cofflink.c:2930
#3  0x0044dc4d in _bfd_coff_link_input_bfd (finfo=0x22c91c,
    input_bfd=0xd85ee0) at /gnu/binutils/src/bfd/cofflink.c:2384
#4  0x0044eb50 in _bfd_coff_final_link (abfd=0xb52900, info=0x4c41f8)
    at /gnu/binutils/src/bfd/cofflink.c:905
#5  0x0041495e in ldwrite () at /gnu/binutils/src/ld/ldwrite.c:567
#6  0x00413e45 in main (argc=38, argv=0xb49b70)
    at /gnu/binutils/src/ld/ldmain.c:464
(gdb) up
#1  0x00435c7e in coff_i386_rtype_to_howto (abfd=0xd85ee0, sec=0xdf83a8,
    rel=0xfce520, h=0x0, sym=0xfaa4c8, addendp=0x22c698)
    at /gnu/binutils/src/bfd/coff-i386.c:459
459           bfd_set_error (bfd_error_bad_value);
(gdb) print *rel
$55 = {r_vaddr = 0, r_symndx = 8, r_type = 300, r_size = 0 '\0',
  r_extern = 0 '\0', r_offset = 0}
(gdb)


  I always like to know exactly how bad data gets to where it ends up and I'd
say that's fairly conclusive.  Looks like swapping over the parent archive
name like that is not a valid trick, owing to the private data hidden in
bfd_ardata().

    cheers,
      DaveK



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