On Sun, Mar 13, 2011 at 11:59:33AM -0700, Chris Lattner wrote:
> On Mar 13, 2011, at 11:55 AM, Chris Lattner wrote:
> > On Mar 13, 2011, at 11:26 AM, Jack Howarth wrote:
> > 
> >>> Yes, I agree that this is a better solution.  This error was put into the 
> >>> linker to detect some overflow conditions for part of the code that 
> >>> expected the section number to only be a byte.  It is likely that "things 
> >>> worked" only out of luck before.
> >>> 
> >>> -Chris
> >> 
> >> Chris,
> >>  Is there any documentation or example code on how to properly use 
> >> subsections in mach-o?
> >> My fear is that we are moving from one poorly documented technique to 
> >> another which may well
> >> have it own slate of hidden bugs.
> > 
> > I'm not sure what you mean here Jack.  ld64 is open source on the darwin 
> > page, and if you have all the developer bits installed, the format is 
> > "documented" in /usr/include/mach-o/.  It's pretty clear all around that 
> > you can only have 256 sections.
> 
> Sorry, I actually mean 255 of course, because of the NO_SECT sentinel.  Here 
> are the relevant bits from nlist.h.  I'm not sure how you expect the 
> toolchain to store more than 256 sections in a uint8_t.
> 
> This is not the conspiracy you are looking for.
> 
> -Chris

Chris,
   Nick's most recent comments to me on this were...

mach-o has always had a restriction on the number of sections.  The mach-o 
nlist struct has a one byte n_sect field which is the index of the section that 
symbol is in.  Previously,
+the assembler did not validate that the n_sect field was not overflowed.  Now 
it does validate.

He left us with the impression that only sections actually containing symbols 
were validated
and that our original design (based on his recommendations) of placing all of 
the symbol-less
GNU_LTO sections at the end of the file was still okay.
             Jack

> 
> 
> 
> /*
>  * Format of a symbol table entry of a Mach-O file for 32-bit architectures.
>  * Modified from the BSD format.  The modifications from the original format
>  * were changing n_other (an unused field) to n_sect and the addition of the
>  * N_SECT type.  These modifications are required to support symbols in a 
> larger
>  * number of sections not just the three sections (text, data and bss) in a 
> BSD
>  * file.
>  */
> struct nlist {
>         union {
> #ifndef __LP64__
>                 char *n_name;   /* for use when in-core */
> #endif
>                 int32_t n_strx; /* index into the string table */
>         } n_un;
>         uint8_t n_type;         /* type flag, see below */
>         uint8_t n_sect;         /* section number or NO_SECT */
>         int16_t n_desc;         /* see <mach-o/stab.h> */
>         uint32_t n_value;       /* value of this symbol (or stab offset) */
> };
> 
> /*
>  * This is the symbol table entry structure for 64-bit architectures.
>  */
> struct nlist_64 {
>     union {
>         uint32_t  n_strx; /* index into the string table */
>     } n_un;
>     uint8_t n_type;        /* type flag, see below */
>     uint8_t n_sect;        /* section number or NO_SECT */
>     uint16_t n_desc;       /* see <mach-o/stab.h> */
>     uint64_t n_value;      /* value of this symbol (or stab offset) */
> };
> 
> /*
>  * If the type is N_SECT then the n_sect field contains an ordinal of the
>  * section the symbol is defined in.  The sections are numbered from 1 and 
>  * refer to sections in order they appear in the load commands for the file
>  * they are in.  This means the same ordinal may very well refer to different
>  * sections in different files.
>  *
>  * The n_value field for all symbol table entries (including N_STAB's) gets
>  * updated by the link editor based on the value of it's n_sect field and 
> where
>  * the section n_sect references gets relocated.  If the value of the n_sect 
>  * field is NO_SECT then it's n_value field is not changed by the link editor.
>  */
> #define NO_SECT         0       /* symbol is not in any section */
> #define MAX_SECT        255     /* 1 thru 255 inclusive */

Reply via email to