/* Support for the generic parts of most COFF variants, for BFD.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ Copyright 1990-2013 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
The Microsoft PE variants of the Coff object file format add
an extension to support the use of long section names. This
- extension is defined in section 4 of the Microsoft PE/COFF
+ extension is defined in section 4 of the Microsoft PE/COFF
specification (rev 8.1). If a section name is too long to fit
into the section header's @code{s_name} field, it is instead
placed into the string table, and the @code{s_name} field is
- filled with a slash ("/") followed by the ASCII decimal
+ filled with a slash ("/") followed by the ASCII decimal
representation of the offset of the full name relative to the
string table base.
expecting the MS standard format may become confused; @file{PEview} is
one known example.
- The functionality is supported in BFD by code implemented under
+ The functionality is supported in BFD by code implemented under
the control of the macro @code{COFF_LONG_SECTION_NAMES}. If not
defined, the format does not support long section names in any way.
- If defined, it is used to initialise a flag,
- @code{_bfd_coff_long_section_names}, and a hook function pointer,
+ If defined, it is used to initialise a flag,
+ @code{_bfd_coff_long_section_names}, and a hook function pointer,
@code{_bfd_coff_set_long_section_names}, in the Coff backend data
structure. The flag controls the generation of long section names
in output BFDs at runtime; if it is false, as it will be by default
points to a function that allows the value of the flag to be altered
at runtime, on formats that support long section names at all; on
other formats it points to a stub that returns an error indication.
-
+
With input BFDs, the flag is set according to whether any long section
names are detected while reading the section headers. For a completely
new BFD, the flag is set to the default for the target format. This
#define STRING_SIZE_SIZE 4
#define DOT_DEBUG ".debug"
+#define DOT_ZDEBUG ".zdebug"
#define GNU_LINKONCE_WI ".gnu.linkonce.wi."
#define GNU_LINKONCE_WT ".gnu.linkonce.wt."
#define DOT_RELOC ".reloc"
styp_flags = STYP_LIT;
#endif /* _LIT */
}
- else if (CONST_STRNEQ (sec_name, DOT_DEBUG))
+ else if (CONST_STRNEQ (sec_name, DOT_DEBUG)
+ || CONST_STRNEQ (sec_name, DOT_ZDEBUG))
{
/* Handle the XCOFF debug section and DWARF2 debug sections. */
if (!sec_name[6])
{
styp_flags = STYP_TYPCHK;
}
+ else if (sec_flags & SEC_DEBUGGING)
+ {
+ int i;
+
+ for (i = 0; i < XCOFF_DWSECT_NBR_NAMES; i++)
+ if (!strcmp (sec_name, xcoff_dwsect_names[i].name))
+ {
+ styp_flags = STYP_DWARF | xcoff_dwsect_names[i].flag;
+ break;
+ }
+ }
#endif
/* Try and figure out what it should be */
else if (sec_flags & SEC_CODE)
bfd_boolean is_dbg = FALSE;
if (CONST_STRNEQ (sec_name, DOT_DEBUG)
+ || CONST_STRNEQ (sec_name, DOT_ZDEBUG)
#ifdef COFF_LONG_SECTION_NAMES
|| CONST_STRNEQ (sec_name, GNU_LINKONCE_WI)
|| CONST_STRNEQ (sec_name, GNU_LINKONCE_WT)
/* FIXME: There is no gas syntax to specify the debug section flag. */
if (is_dbg)
- sec_flags = SEC_DEBUGGING | SEC_READONLY;
+ {
+ sec_flags &= (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
+ | SEC_LINK_DUPLICATES_SAME_CONTENTS
+ | SEC_LINK_DUPLICATES_SAME_SIZE);
+ sec_flags |= SEC_DEBUGGING | SEC_READONLY;
+ }
/* skip LOAD */
/* READONLY later */
/* skip SORT */
if (sec_flags & SEC_LINK_ONCE)
styp_flags |= IMAGE_SCN_LNK_COMDAT;
- /* skip LINK_DUPLICATES */
+ if ((sec_flags
+ & (SEC_LINK_DUPLICATES_DISCARD | SEC_LINK_DUPLICATES_SAME_CONTENTS
+ | SEC_LINK_DUPLICATES_SAME_SIZE)) != 0)
+ styp_flags |= IMAGE_SCN_LNK_COMDAT;
+
/* skip LINKER_CREATED */
if ((sec_flags & SEC_COFF_NOREAD) == 0)
}
else if (styp_flags & STYP_PAD)
sec_flags = 0;
+#ifdef RS6000COFF_C
+ else if (styp_flags & STYP_EXCEPT)
+ sec_flags |= SEC_LOAD;
+ else if (styp_flags & STYP_LOADER)
+ sec_flags |= SEC_LOAD;
+ else if (styp_flags & STYP_TYPCHK)
+ sec_flags |= SEC_LOAD;
+ else if (styp_flags & STYP_DWARF)
+ sec_flags |= SEC_DEBUGGING;
+#endif
else if (strcmp (name, _TEXT) == 0)
{
if (sec_flags & SEC_NEVER_LOAD)
sec_flags |= SEC_ALLOC;
}
else if (CONST_STRNEQ (name, DOT_DEBUG)
+ || CONST_STRNEQ (name, DOT_ZDEBUG)
#ifdef _COMMENT
|| strcmp (name, _COMMENT) == 0
#endif
bfd_boolean is_dbg = FALSE;
if (CONST_STRNEQ (name, DOT_DEBUG)
+ || CONST_STRNEQ (name, DOT_ZDEBUG)
#ifdef COFF_LONG_SECTION_NAMES
|| CONST_STRNEQ (name, GNU_LINKONCE_WI)
|| CONST_STRNEQ (name, GNU_LINKONCE_WT)
. bfd_boolean _bfd_coff_long_section_names;
. bfd_boolean (*_bfd_coff_set_long_section_names)
. (bfd *, int);
-.
+.
. unsigned int _bfd_coff_default_section_alignment_power;
. bfd_boolean _bfd_coff_force_symnames_in_strings;
. unsigned int _bfd_coff_debug_string_prefix_length;
{
combined_entry_type *native;
bfd_size_type amt;
+ unsigned char sclass = C_STAT;
section->alignment_power = COFF_DEFAULT_SECTION_ALIGNMENT_POWER;
if (bfd_xcoff_text_align_power (abfd) != 0
&& strcmp (bfd_get_section_name (abfd, section), ".text") == 0)
section->alignment_power = bfd_xcoff_text_align_power (abfd);
- if (bfd_xcoff_data_align_power (abfd) != 0
+ else if (bfd_xcoff_data_align_power (abfd) != 0
&& strcmp (bfd_get_section_name (abfd, section), ".data") == 0)
section->alignment_power = bfd_xcoff_data_align_power (abfd);
+ else
+ {
+ int i;
+
+ for (i = 0; i < XCOFF_DWSECT_NBR_NAMES; i++)
+ if (strcmp (bfd_get_section_name (abfd, section),
+ xcoff_dwsect_names[i].name) == 0)
+ {
+ section->alignment_power = 0;
+ sclass = C_DWARF;
+ break;
+ }
+ }
#endif
/* Set up the section symbol. */
for n_numaux is already correct. */
native->u.syment.n_type = T_NULL;
- native->u.syment.n_sclass = C_STAT;
+ native->u.syment.n_sclass = sclass;
coffsymbol (section->symbol)->native = native;
padding the previous section up if necessary. */
old_sofar = sofar;
+ sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+
#ifdef RS6000COFF_C
- /* AIX loader checks the text section alignment of (vma - filepos)
- So even though the filepos may be aligned wrt the o_algntext, for
- AIX executables, this check fails. This shows up when a native
- AIX executable is stripped with gnu strip because the default vma
- of native is 0x10000150 but default for gnu is 0x10000140. Gnu
- stripped gnu excutable passes this check because the filepos is
- 0x0140. This problem also show up with 64 bit shared objects. The
- data section must also be aligned. */
+ /* Make sure the file offset and the vma of .text/.data are at the
+ same page offset, so that the file can be mmap'ed without being
+ relocated. Failing that, AIX is able to load and execute the
+ program, but it will be silently relocated (possible as
+ executables are PIE). But the relocation is slightly costly and
+ complexify the use of addr2line or gdb. So better to avoid it,
+ like does the native linker. Usually gnu ld makes sure that
+ the vma of .text is the file offset so this issue shouldn't
+ appear unless you are stripping such an executable.
+
+ AIX loader checks the text section alignment of (vma - filepos),
+ and the native linker doesn't try to align the text sections.
+ For example:
+
+ 0 .text 000054cc 10000128 10000128 00000128 2**5
+ CONTENTS, ALLOC, LOAD, CODE
+ */
+
if (!strcmp (current->name, _TEXT)
|| !strcmp (current->name, _DATA))
{
- bfd_vma pad;
- bfd_vma align;
-
- sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
-
- align = 1 << current->alignment_power;
- pad = abs (current->vma - sofar) % align;
-
- if (pad)
- {
- pad = align - pad;
- sofar += pad;
- }
- }
- else
-#else
- {
- sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+ bfd_vma align = 4096;
+ bfd_vma sofar_off = sofar % align;
+ bfd_vma vma_off = current->vma % align;
+
+ if (vma_off > sofar_off)
+ sofar += vma_off - sofar_off;
+ else if (vma_off < sofar_off)
+ sofar += align + vma_off - sofar_off;
}
#endif
if (previous != NULL)
incremented in coff_set_section_contents. This is right for
SVR3.2. */
if (strcmp (current->name, _LIB) == 0)
- bfd_set_section_vma (abfd, current, 0);
+ (void) bfd_set_section_vma (abfd, current, 0);
#endif
#ifdef ALIGN_SECTIONS_IN_FILE
bfd_size_type amt;
internal_f.f_nscns++;
- strncpy (&(scnhdr.s_name[0]), current->name, 8);
+ memcpy (scnhdr.s_name, ".ovrflo", 8);
scnhdr.s_paddr = current->reloc_count;
scnhdr.s_vaddr = current->lineno_count;
scnhdr.s_size = 0;
case C_THUMBSTAT: /* Thumb static. */
case C_THUMBLABEL: /* Thumb label. */
case C_THUMBSTATFUNC:/* Thumb static function. */
+#endif
+#ifdef RS6000COFF_C
+ case C_DWARF: /* A label in a dwarf section. */
+ case C_INFO: /* A label in a comment section. */
#endif
case C_LABEL: /* Label. */
if (src->u.syment.n_scnum == N_DEBUG)
#define coff_bfd_gc_sections bfd_generic_gc_sections
#endif
+#ifndef coff_bfd_lookup_section_flags
+#define coff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+#endif
+
#ifndef coff_bfd_merge_sections
#define coff_bfd_merge_sections bfd_generic_merge_sections
#endif
#ifndef coff_section_already_linked
#define coff_section_already_linked \
- _bfd_generic_section_already_linked
+ _bfd_coff_section_already_linked
#endif
#ifndef coff_bfd_define_common_symbol
UNDER, /* Leading symbol underscore. */ \
'/', /* AR_pad_char. */ \
15, /* AR_max_namelen. */ \
+ 0, /* match priority. */ \
\
/* Data conversion functions. */ \
bfd_getb64, bfd_getb_signed_64, bfd_putb64, \
UNDER, /* Leading symbol underscore. */ \
'/', /* AR_pad_char. */ \
15, /* AR_max_namelen. */ \
+ 0, /* match priority. */ \
\
/* Data conversion functions. */ \
bfd_getb64, bfd_getb_signed_64, bfd_putb64, \
UNDER, /* Leading symbol underscore. */ \
'/', /* AR_pad_char. */ \
15, /* AR_max_namelen. */ \
+ 0, /* match priority. */ \
\
/* Data conversion functions. */ \
bfd_getl64, bfd_getl_signed_64, bfd_putl64, \