delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1998/08/12/07:57:26

Date: Wed, 12 Aug 1998 11:08:25 +0000 ( )
From: "Gurunandan R. Bhat" <grbhat AT unigoa DOT ernet DOT in>
To: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
Cc: djgpp-workers AT delorie DOT com
Subject: Re: [grbhat AT unigoa DOT ernet DOT in: Problem with process_coff()]
In-Reply-To: <Pine.SUN.3.91.980812114947.16932M-100000@is>
Message-Id: <Pine.LNX.3.91.980812110803.5978A-100000@aditya.unigoa.ernet.in>
Mime-Version: 1.0

On Wed, 12 Aug 1998, Eli Zaretskii wrote:

> I have never really dug deep enough into syms.c, so the following is
> based on a very limited study, and only at the source level.  So
> please check my assertions carefully, do not take them for granted ;-).

The same for me too, infact more so. I spell things below, more to 
clarify to myself and make it easier for you to pick holes in my logic, 

> That's not what I think goes on here.  The total number of elements in
> the array l[] is the number of lines in the function to which those
> lines belong.  

Line number info table pertains to a section of a coff file as a whole 
and begins at f_lnno[i][0] where i is the section number. l points  
somewhere into this table. The symbol table entry for a function 
*declaration* (which is a symbol) says where l must point to, inside the
array f_lnno[i].

When l is set in this manner, l.l_nno = 0. That is, the relative
line number of the function declaration symbol is zero. The next entry 
in the line number table will correspond to the line containing the 
opening brace (the ".bf"). This will have l.l_nno = 1.  And....

> l[k] holds the information about k'th
> ``breakpointable'' line of the function.  

Yes, I agree. 

> So l++ just advances from
> the first line of the function to the next:

Yes.
However, may I add here that modules which are compiled without -g have a
line number table entry only for the first line (the opening brace) and the
last line (the closing brace). There are no entries corresponding to lines
in the body of the function. I mention this for reference later.

> The way I see it, the problem might be in the termination condition of
> the ensuing loop:
> 
> >           for (i2=0; l[i2].l_lnno; i2++)
> >             l[i2].l_lnno += lbase;

That it is. But only for the function whose entries comes last in the 
line number info table. Not for others. For functions before the last
entry, there is always an  line number entry for the next function 
declaration  for which l[i2].l_nno = 0. (Function declaration symbols
always have l[].l_nno = 0. It is the opening brace that has l[].l_nno = 1.)
So for any function the loop will stop when it encounters the declaration
of the next function. For the last function.....?

> This assumes that the lines' info for the function being processed is
> terminated by an entry whose l_lnno member is zero.  

In the sense described above. The "entry whose l_nno member is zero" is 
in fact the declaration of the next function. Please confirm this. Thank you.

> This only promises that each entry will *begin* with a zero l_lnno,
> but it says nothing about how the last entry *ends*.  This might cause
> problems when processing the last entry.  Checking l[i2] against the
> end of f_lnno[] might help.

Yes that is what I thought. Moreover the auxent structure contains info about 
the location of the last index in a table. (If some Guru may kindly confirm) 
which also could be used.. ...

> There's also something else that bothers me.  Earlier, you said that
> in the case where FSDB crashed, lbase was -1.  This seems like a bug,
> right there, even before l[i2] is dereferenced: lbase should be a
> non-negative number, right?

Only if the function was compiled with -g. If line number info for a 
module is not available, lbase will always be -1. Nothing wrong since the 
next entry in that case will be the declaration of the next function and
the loop will stop anyway. However the point that lbase = -1 may be used as 
a flag to stop processing for line numbers may be the safest way to handle
this.  In fact I did that and found that fsdb works as expected and no 
crash happens.

> This leads me to another aspect of the code that I find unsafe.  Look
> how lbase is computed:
> 
> >           int lbase = f_aux[i+1].x_sym.x_misc.x_lnsz.x_lnno - 1;
> 
> I'm worried about the f_aux[i+1] thing.  Here's how f_aux is defined:
> 
>   f_symtab = (SYMENT *)malloc(f_fh.f_nsyms * SYMESZ);
>   fread(f_symtab, SYMESZ, f_fh.f_nsyms, fd);
>   f_aux = (AUXENT *)f_symtab;
> 
> In other words, f_aux is an array of f_fh.f_nsyms elements, exactly
> like f_symtab is.  So f_aux[i+1] looks beyond the end of f_symtab[]
> array on the last pass through the loop, since then the index i has
> the value f_fh.f_nsyms.

Not to worry! The loop index is deviously modified here:
 
                i += f_symtab[i].e_numaux

> Maybe that's how that negative lbase is born?  

I am afraid that is quite unlikely.


> Could you tell what is
> the value of i when the offending loop corrupts the pointer maintained
> by `malloc'?

Sure. But the value depends on the manner in which the code was compiled.
In my case (-g, without optimisations) the last line number entry corresponds
to the the module "___udivdi3" in libgcc2.a. and is symbol number i = 2005.
The opening brace for this module is symbol number i = 2007, because
of one auxillary entry for the previous symbol and the closing brace
for this function has symbol number i = 2009, again one aux entry for 
the previous symbol. As expected (since this is the symbol whose line number 
entry is last), mallocs tables get corrupted exactly after process_coff 
reads this module.

Thank you very much for your interest. I hope that you will excuse 
my inarticulateness in matters C. For example I could not find any other
term for "function declaration" for which I mean the line that is the 
function declaration, but without the trailing ";"

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019