add dysymtab write support to bfd/mach-o.

bfd:

	* mach-o.c (bfd_mach_o_write_symtab): Fill in the string table index
	as the value of an indirect symbol.  Keep the string table index in
	non-indirect syms for reference.
	(bfd_mach_o_write_dysymtab): New.
	(bfd_mach_o_primary_symbol_sort_key): New.
	(bfd_mach_o_cf_symbols): New.
	(bfd_mach_o_sort_symbol_table): New.
	(bfd_mach_o_mangle_symbols): Return early if no symbols.  Sort symbols.
	If we are emitting a dysymtab, process indirect symbols and count the
	number of each other kind.
	(bfd_mach_o_mangle_sections): New.
	(bfd_mach_o_write_contents): Split out some pre-requisite code into
	the command builder. Write dysymtab if the command is present.
	(bfd_mach_o_count_sections_for_seg): New.
	(bfd_mach_o_build_seg_command): New.
	(bfd_mach_o_build_dysymtab_command): New.
	(bfd_mach_o_build_commands): Reorganize to support the fact that some
	commands are optional and should not be emitted if there are no
	sections or symbols.
	(bfd_mach_o_set_section_contents): Amend comment.
	* mach-o.h: Amend and add to comments.
	(mach_o_data_struct): Add fields for dysymtab symbols counts and a
	pointer to the indirects, when present.
	(bfd_mach_o_should_emit_dysymtab): New macro.
	(IS_MACHO_INDIRECT): Likewise.

gas/testsuite:

	* gas/mach-o/dysymtab-1-64.d: New.
	* gas/mach-o/dysymtab-1.d: New.
	* gas/mach-o/symbols-1-64.d: New.
	* gas/mach-o/symbols-1.d: New.
	* gas/mach-o/symbols-base-64.s: New.
	* gas/mach-o/symbols-base.s: New.
This commit is contained in:
Iain Sandoe 2012-01-03 10:54:01 +00:00
parent 3c2d6aff67
commit 7f3072381b
10 changed files with 1167 additions and 108 deletions

View file

@ -1,3 +1,31 @@
2012-01-03 Iain Sandoe <idsandoe@googlemail.com>
* mach-o.c (bfd_mach_o_write_symtab): Fill in the string table index
as the value of an indirect symbol. Keep the string table index in
non-indirect syms for reference.
(bfd_mach_o_write_dysymtab): New.
(bfd_mach_o_primary_symbol_sort_key): New.
(bfd_mach_o_cf_symbols): New.
(bfd_mach_o_sort_symbol_table): New.
(bfd_mach_o_mangle_symbols): Return early if no symbols. Sort symbols.
If we are emitting a dysymtab, process indirect symbols and count the
number of each other kind.
(bfd_mach_o_mangle_sections): New.
(bfd_mach_o_write_contents): Split out some pre-requisite code into
the command builder. Write dysymtab if the command is present.
(bfd_mach_o_count_sections_for_seg): New.
(bfd_mach_o_build_seg_command): New.
(bfd_mach_o_build_dysymtab_command): New.
(bfd_mach_o_build_commands): Reorganize to support the fact that some
commands are optional and should not be emitted if there are no
sections or symbols.
(bfd_mach_o_set_section_contents): Amend comment.
* mach-o.h: Amend and add to comments.
(mach_o_data_struct): Add fields for dysymtab symbols counts and a
pointer to the indirects, when present.
(bfd_mach_o_should_emit_dysymtab): New macro.
(IS_MACHO_INDIRECT): Likewise.
2011-12-24 Jan Kratochvil <jan.kratochvil@redhat.com>
* elf32-rl78.c (rl78_elf_relocate_section, rl78_dump_symtab)

View file

@ -1,6 +1,6 @@
/* Mach-O support for BFD.
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 2011
2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@ -29,6 +29,8 @@
#include "mach-o/reloc.h"
#include "mach-o/external.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#define bfd_mach_o_object_p bfd_mach_o_gen_object_p
#define bfd_mach_o_core_p bfd_mach_o_gen_core_p
@ -1351,13 +1353,34 @@ bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
bfd_size_type str_index;
bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
/* Compute name index. */
/* An index of 0 always means the empty string. */
/* For a bare indirect symbol, the system tools expect that the symbol
value will be the string table offset for its referenced counterpart.
Normally, indirect syms will not be written this way, but rather as
part of the dysymtab command.
In either case, correct operation depends on the symbol table being
sorted such that the indirect symbols are at the end (since the
string table index is filled in below). */
if (IS_MACHO_INDIRECT (s->n_type))
/* A pointer to the referenced symbol will be stored in the udata
field. Use that to find the string index. */
s->symbol.value =
((bfd_mach_o_asymbol *)s->symbol.udata.p)->symbol.udata.i;
if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
/* An index of 0 always means the empty string. */
str_index = 0;
else
{
str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
/* Record the string index. This can be looked up by an indirect sym
which retains a pointer to its referenced counterpart, until it is
actually output. */
if (IS_MACHO_INDIRECT (s->n_type))
s->symbol.udata.i = str_index;
if (str_index == (bfd_size_type) -1)
goto err;
}
@ -1420,15 +1443,316 @@ bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
return FALSE;
}
/* Process the symbols and generate Mach-O specific fields.
Number them. */
/* Write a dysymtab command.
TODO: Possibly coalesce writes of smaller objects. */
static bfd_boolean
bfd_mach_o_mangle_symbols (bfd *abfd)
bfd_mach_o_write_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
{
bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
if (cmd->nmodtab != 0)
{
unsigned int i;
if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
return FALSE;
for (i = 0; i < cmd->nmodtab; i++)
{
bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
unsigned int iinit;
unsigned int ninit;
iinit = module->iinit & 0xffff;
iinit |= ((module->iterm & 0xffff) << 16);
ninit = module->ninit & 0xffff;
ninit |= ((module->nterm & 0xffff) << 16);
if (bfd_mach_o_wide_p (abfd))
{
struct mach_o_dylib_module_64_external w;
bfd_h_put_32 (abfd, module->module_name_idx, &w.module_name);
bfd_h_put_32 (abfd, module->iextdefsym, &w.iextdefsym);
bfd_h_put_32 (abfd, module->nextdefsym, &w.nextdefsym);
bfd_h_put_32 (abfd, module->irefsym, &w.irefsym);
bfd_h_put_32 (abfd, module->nrefsym, &w.nrefsym);
bfd_h_put_32 (abfd, module->ilocalsym, &w.ilocalsym);
bfd_h_put_32 (abfd, module->nlocalsym, &w.nlocalsym);
bfd_h_put_32 (abfd, module->iextrel, &w.iextrel);
bfd_h_put_32 (abfd, module->nextrel, &w.nextrel);
bfd_h_put_32 (abfd, iinit, &w.iinit_iterm);
bfd_h_put_32 (abfd, ninit, &w.ninit_nterm);
bfd_h_put_64 (abfd, module->objc_module_info_addr,
&w.objc_module_info_addr);
bfd_h_put_32 (abfd, module->objc_module_info_size,
&w.objc_module_info_size);
if (bfd_bwrite ((void *) &w, sizeof (w), abfd) != sizeof (w))
return FALSE;
}
else
{
struct mach_o_dylib_module_external n;
bfd_h_put_32 (abfd, module->module_name_idx, &n.module_name);
bfd_h_put_32 (abfd, module->iextdefsym, &n.iextdefsym);
bfd_h_put_32 (abfd, module->nextdefsym, &n.nextdefsym);
bfd_h_put_32 (abfd, module->irefsym, &n.irefsym);
bfd_h_put_32 (abfd, module->nrefsym, &n.nrefsym);
bfd_h_put_32 (abfd, module->ilocalsym, &n.ilocalsym);
bfd_h_put_32 (abfd, module->nlocalsym, &n.nlocalsym);
bfd_h_put_32 (abfd, module->iextrel, &n.iextrel);
bfd_h_put_32 (abfd, module->nextrel, &n.nextrel);
bfd_h_put_32 (abfd, iinit, &n.iinit_iterm);
bfd_h_put_32 (abfd, ninit, &n.ninit_nterm);
bfd_h_put_32 (abfd, module->objc_module_info_addr,
&n.objc_module_info_addr);
bfd_h_put_32 (abfd, module->objc_module_info_size,
&n.objc_module_info_size);
if (bfd_bwrite ((void *) &n, sizeof (n), abfd) != sizeof (n))
return FALSE;
}
}
}
if (cmd->ntoc != 0)
{
unsigned int i;
if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
return FALSE;
for (i = 0; i < cmd->ntoc; i++)
{
struct mach_o_dylib_table_of_contents_external raw;
bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
bfd_h_put_32 (abfd, toc->symbol_index, &raw.symbol_index);
bfd_h_put_32 (abfd, toc->module_index, &raw.module_index);
if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
}
}
if (cmd->nindirectsyms > 0)
{
unsigned int i;
if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
return FALSE;
for (i = 0; i < cmd->nindirectsyms; ++i)
{
unsigned char raw[4];
bfd_h_put_32 (abfd, cmd->indirect_syms[i], &raw);
if (bfd_bwrite (raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
}
}
if (cmd->nextrefsyms != 0)
{
unsigned int i;
if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
return FALSE;
for (i = 0; i < cmd->nextrefsyms; i++)
{
unsigned long v;
unsigned char raw[4];
bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
/* Fields isym and flags are written as bit-fields, thus we need
a specific processing for endianness. */
if (bfd_big_endian (abfd))
{
v = ((ref->isym & 0xffffff) << 8);
v |= ref->flags & 0xff;
}
else
{
v = ref->isym & 0xffffff;
v |= ((ref->flags & 0xff) << 24);
}
bfd_h_put_32 (abfd, v, raw);
if (bfd_bwrite (raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
}
}
/* The command. */
if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0)
return FALSE;
else
{
struct mach_o_dysymtab_command_external raw;
bfd_h_put_32 (abfd, cmd->ilocalsym, &raw.ilocalsym);
bfd_h_put_32 (abfd, cmd->nlocalsym, &raw.nlocalsym);
bfd_h_put_32 (abfd, cmd->iextdefsym, &raw.iextdefsym);
bfd_h_put_32 (abfd, cmd->nextdefsym, &raw.nextdefsym);
bfd_h_put_32 (abfd, cmd->iundefsym, &raw.iundefsym);
bfd_h_put_32 (abfd, cmd->nundefsym, &raw.nundefsym);
bfd_h_put_32 (abfd, cmd->tocoff, &raw.tocoff);
bfd_h_put_32 (abfd, cmd->ntoc, &raw.ntoc);
bfd_h_put_32 (abfd, cmd->modtaboff, &raw.modtaboff);
bfd_h_put_32 (abfd, cmd->nmodtab, &raw.nmodtab);
bfd_h_put_32 (abfd, cmd->extrefsymoff, &raw.extrefsymoff);
bfd_h_put_32 (abfd, cmd->nextrefsyms, &raw.nextrefsyms);
bfd_h_put_32 (abfd, cmd->indirectsymoff, &raw.indirectsymoff);
bfd_h_put_32 (abfd, cmd->nindirectsyms, &raw.nindirectsyms);
bfd_h_put_32 (abfd, cmd->extreloff, &raw.extreloff);
bfd_h_put_32 (abfd, cmd->nextrel, &raw.nextrel);
bfd_h_put_32 (abfd, cmd->locreloff, &raw.locreloff);
bfd_h_put_32 (abfd, cmd->nlocrel, &raw.nlocrel);
if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
}
return TRUE;
}
static unsigned
bfd_mach_o_primary_symbol_sort_key (unsigned type, unsigned ext)
{
/* TODO: Determine the correct ordering of stabs symbols. */
/* We make indirect symbols a local/synthetic. */
if (type == BFD_MACH_O_N_INDR)
return 3;
/* Local (we should never see an undefined local AFAICT). */
if (! ext)
return 0;
/* Common symbols look like undefined externs. */
if (type == BFD_MACH_O_N_UNDF)
return 2;
/* A defined symbol that's not indirect or extern. */
return 1;
}
static int
bfd_mach_o_cf_symbols (const void *a, const void *b)
{
bfd_mach_o_asymbol *sa = *(bfd_mach_o_asymbol **) a;
bfd_mach_o_asymbol *sb = *(bfd_mach_o_asymbol **) b;
unsigned int soa, sob;
soa = bfd_mach_o_primary_symbol_sort_key
(sa->n_type & BFD_MACH_O_N_TYPE,
sa->n_type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT));
sob = bfd_mach_o_primary_symbol_sort_key
(sb->n_type & BFD_MACH_O_N_TYPE,
sb->n_type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT));
if (soa < sob)
return -1;
if (soa > sob)
return 1;
/* If it's local, just preserve the input order. */
if (soa == 0)
{
if (sa->symbol.udata.i < sb->symbol.udata.i)
return -1;
if (sa->symbol.udata.i > sb->symbol.udata.i)
return 1;
return 0;
}
/* Unless it's an indirect the second sort key is name. */
if (soa < 3)
return strcmp (sa->symbol.name, sb->symbol.name);
/* Here be indirect symbols, which have different sort rules. */
/* Next sort key for indirect, is the section index. */
if (sa->n_sect < sb->n_sect)
return -1;
if (sa->n_sect > sb->n_sect)
return 1;
/* Last sort key is the order of definition - which should be in line with
the value, since a stub size of 0 is meaninglesss. */
if (sa->symbol.value < sb->symbol.value)
return -1;
if (sa->symbol.value > sb->symbol.value)
return 1;
/* In the final analysis, this is probably an error ... but leave it alone
for now. */
return 0;
}
/* When this is finished, return the number of non-indirect symbols. */
static unsigned int
bfd_mach_o_sort_symbol_table (asymbol **symbols, unsigned int nin)
{
qsort (symbols, (size_t) nin, sizeof (void *), bfd_mach_o_cf_symbols);
/* Find the last non-indirect symbol.
There must be at least one non-indirect symbol otherwise there's
nothing for the indirect(s) to refer to. */
do
{
bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[nin - 1];
if (IS_MACHO_INDIRECT (s->n_type))
nin--;
else
break;
} while (nin - 1 > 0);
return nin;
}
/* Process the symbols.
This should be OK for single-module files - but it is not likely to work
for multi-module shared libraries.
(a) If the application has not filled in the relevant mach-o fields, make
an estimate.
(b) Order them, like this:
( i) local.
(unsorted)
( ii) external defined
(by name)
(iii) external undefined
(by name)
( iv) common
(by name)
( v) indirect
(by section)
(by position within section).
(c) Indirect symbols are moved to the end of the list. */
static bfd_boolean
bfd_mach_o_mangle_symbols (bfd *abfd, bfd_mach_o_data_struct *mdata)
{
unsigned long i;
asymbol **symbols = bfd_get_outsymbols (abfd);
if (symbols == NULL || bfd_get_symcount (abfd) == 0)
return TRUE;
for (i = 0; i < bfd_get_symcount (abfd); i++)
{
bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
@ -1445,6 +1769,8 @@ bfd_mach_o_mangle_symbols (bfd *abfd)
s->n_type = BFD_MACH_O_N_UNDF;
if (s->symbol.flags & BSF_WEAK)
s->n_desc |= BFD_MACH_O_N_WEAK_REF;
/* mach-o automatically makes undefined symbols extern. */
s->n_type |= BFD_MACH_O_N_EXT;
}
else if (s->symbol.section == bfd_com_section_ptr)
s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
@ -1455,15 +1781,116 @@ bfd_mach_o_mangle_symbols (bfd *abfd)
s->n_type |= BFD_MACH_O_N_EXT;
}
/* Compute section index. */
/* Put the section index in, where required. */
if (s->symbol.section != bfd_abs_section_ptr
&& s->symbol.section != bfd_und_section_ptr
&& s->symbol.section != bfd_com_section_ptr)
s->n_sect = s->symbol.section->target_index;
/* Number symbols. */
s->symbol.udata.i = i;
/* Unless we're looking at an indirect sym, note the input ordering.
We use this to keep local symbols ordered as per the input. */
if (IS_MACHO_INDIRECT (s->n_type))
s->symbol.udata.i = i;
}
/* Sort the symbols and determine how many will remain in the main symbol
table, and how many will be emitted as indirect (assuming that we will
be emitting a dysymtab). Renumber the sorted symbols so that the right
index will be found during indirection. */
i = bfd_mach_o_sort_symbol_table (symbols, bfd_get_symcount (abfd));
if (bfd_mach_o_should_emit_dysymtab ())
{
/* Point at the first indirect symbol. */
if (i < bfd_get_symcount (abfd))
{
mdata->indirect_syms = &symbols[i];
mdata->nindirect = bfd_get_symcount (abfd) - i;
/* This is, essentially, local to the output section of mach-o,
and therefore should be safe. */
abfd->symcount = i;
}
/* Now setup the counts for each type of symbol. */
for (i = 0; i < bfd_get_symcount (abfd); ++i)
{
bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
s->symbol.udata.i = i; /* renumber. */
if (s->n_type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT))
break;
}
mdata->nlocal = i;
for (; i < bfd_get_symcount (abfd); ++i)
{
bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
s->symbol.udata.i = i; /* renumber. */
if ((s->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_UNDF)
break;
}
mdata->ndefext = i - mdata->nlocal;
mdata->nundefext = bfd_get_symcount (abfd)
- mdata->ndefext
- mdata->nlocal;
for (; i < bfd_get_symcount (abfd); ++i)
{
bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
s->symbol.udata.i = i; /* renumber. */
}
}
return TRUE;
}
/* We build a flat table of sections, which can be re-ordered if necessary.
Fill in the section number and other mach-o-specific data. */
static bfd_boolean
bfd_mach_o_mangle_sections (bfd *abfd, bfd_mach_o_data_struct *mdata)
{
asection *sec;
unsigned target_index;
unsigned nsect;
nsect = bfd_count_sections (abfd);
/* Don't do it if it's already set - assume the application knows what it's
doing. */
if (mdata->nsects == nsect
&& (mdata->nsects == 0 || mdata->sections != NULL))
return TRUE;
mdata->nsects = nsect;
mdata->sections = bfd_alloc (abfd,
mdata->nsects * sizeof (bfd_mach_o_section *));
if (mdata->sections == NULL)
return FALSE;
/* We need to check that this can be done... */
if (nsect > 255)
(*_bfd_error_handler) (_("mach-o: there are too many sections (%d)"
" maximum is 255,\n"), nsect);
/* Create Mach-O sections.
Section type, attribute and align should have been set when the
section was created - either read in or specified. */
target_index = 0;
for (sec = abfd->sections; sec; sec = sec->next)
{
unsigned bfd_align = bfd_get_section_alignment (abfd, sec);
bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec);
mdata->sections[target_index] = msect;
msect->addr = bfd_get_section_vma (abfd, sec);
msect->size = bfd_get_section_size (sec);
/* Use the largest alignment set, in case it was bumped after the
section was created. */
msect->align = msect->align > bfd_align ? msect->align : bfd_align;
msect->offset = 0;
sec->target_index = ++target_index;
}
return TRUE;
}
@ -1473,27 +1900,14 @@ bfd_mach_o_write_contents (bfd *abfd)
unsigned int i;
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
/* Make the commands, if not already present. */
if (mdata->header.ncmds == 0)
if (!bfd_mach_o_build_commands (abfd))
return FALSE;
/* Now write header information. */
if (mdata->header.filetype == 0)
{
if (abfd->flags & EXEC_P)
mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
else if (abfd->flags & DYNAMIC)
mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
else
mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
}
if (!bfd_mach_o_write_header (abfd, &mdata->header))
return FALSE;
/* Assign a number to each symbols. */
if (!bfd_mach_o_mangle_symbols (abfd))
return FALSE;
for (i = 0; i < mdata->header.ncmds; i++)
{
struct mach_o_load_command_external raw;
@ -1523,6 +1937,10 @@ bfd_mach_o_write_contents (bfd *abfd)
if (!bfd_mach_o_write_symtab (abfd, cur))
return FALSE;
break;
case BFD_MACH_O_LC_DYSYMTAB:
if (!bfd_mach_o_write_dysymtab (abfd, cur))
return FALSE;
break;
case BFD_MACH_O_LC_SYMSEG:
break;
case BFD_MACH_O_LC_THREAD:
@ -1535,7 +1953,6 @@ bfd_mach_o_write_contents (bfd *abfd)
case BFD_MACH_O_LC_IDENT:
case BFD_MACH_O_LC_FVMFILE:
case BFD_MACH_O_LC_PREPAGE:
case BFD_MACH_O_LC_DYSYMTAB:
case BFD_MACH_O_LC_LOAD_DYLIB:
case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
case BFD_MACH_O_LC_ID_DYLIB:
@ -1591,7 +2008,171 @@ bfd_mach_o_set_section_flags_from_bfd (bfd *abfd ATTRIBUTE_UNUSED, asection *sec
s->flags = BFD_MACH_O_S_REGULAR;
}
/* Build Mach-O load commands from the sections. */
/* Count the number of sections in the list for the segment named.
The special case of NULL or "" for the segment name is valid for
an MH_OBJECT file and means 'all sections available'.
Requires that the sections table in mdata be filled in.
Returns the number of sections (0 is valid).
Any number > 255 signals an invalid section count, although we will,
perhaps, allow the file to be written (in line with Darwin tools up
to XCode 4).
A section count of (unsigned long) -1 signals a definite error. */
static unsigned long
bfd_mach_o_count_sections_for_seg (const char *segment,
bfd_mach_o_data_struct *mdata)
{
unsigned i,j;
if (mdata == NULL || mdata->sections == NULL)
return (unsigned long) -1;
/* The MH_OBJECT case, all sections are considered; Although nsects is
is an unsigned long, the maximum valid section count is 255 and this
will have been checked already by mangle_sections. */
if (segment == NULL || segment[0] == '\0')
return mdata->nsects;
/* Count the number of sections we see in this segment. */
j = 0;
for (i = 0; i < mdata->nsects; ++i)
{
bfd_mach_o_section *s = mdata->sections[i];
if (strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
j++;
}
return j;
}
static bfd_boolean
bfd_mach_o_build_seg_command (const char *segment,
bfd_mach_o_data_struct *mdata,
bfd_mach_o_segment_command *seg)
{
unsigned i;
int is_mho = (segment == NULL || segment[0] == '\0');
/* Fill segment command. */
if (is_mho)
memset (seg->segname, 0, sizeof (seg->segname));
else
strncpy (seg->segname, segment, sizeof (seg->segname));
/* TODO: fix this up for non-MH_OBJECT cases. */
seg->vmaddr = 0;
seg->fileoff = mdata->filelen;
seg->filesize = 0;
seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
| BFD_MACH_O_PROT_EXECUTE;
seg->initprot = seg->maxprot;
seg->flags = 0;
seg->sect_head = NULL;
seg->sect_tail = NULL;
/* Append sections to the segment. */
for (i = 0; i < mdata->nsects; ++i)
{
bfd_mach_o_section *s = mdata->sections[i];
asection *sec = s->bfdsection;
/* If we're not making an MH_OBJECT, check whether this section is from
our segment, and skip if not. Otherwise, just add all sections. */
if (! is_mho
&& strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) != 0)
continue;
bfd_mach_o_append_section_to_segment (seg, sec);
if (s->size == 0)
s->offset = 0;
else
{
mdata->filelen = FILE_ALIGN (mdata->filelen, s->align);
s->offset = mdata->filelen;
}
sec->filepos = s->offset;
mdata->filelen += s->size;
}
seg->filesize = mdata->filelen - seg->fileoff;
seg->vmsize = seg->filesize;
return TRUE;
}
static bfd_boolean
bfd_mach_o_build_dysymtab_command (bfd *abfd,
bfd_mach_o_data_struct *mdata,
bfd_mach_o_load_command *cmd)
{
bfd_mach_o_dysymtab_command *dsym = &cmd->command.dysymtab;
/* TODO:
We are not going to try and fill these in yet and, moreover, we are
going to bail if they are already set. */
if (dsym->nmodtab != 0
|| dsym->ntoc != 0
|| dsym->nextrefsyms != 0)
{
(*_bfd_error_handler) (_("sorry: modtab, toc and extrefsyms are not yet"
" implemented for dysymtab commands."));
return FALSE;
}
dsym->ilocalsym = 0;
dsym->nlocalsym = mdata->nlocal;
dsym->iextdefsym = dsym->nlocalsym;
dsym->nextdefsym = mdata->ndefext;
dsym->iundefsym = dsym->nextdefsym + dsym->iextdefsym;
dsym->nundefsym = mdata->nundefext;
if (mdata->nindirect > 0)
{
unsigned i, sect;
mdata->filelen = FILE_ALIGN (mdata->filelen, 2);
dsym->indirectsymoff = mdata->filelen;
mdata->filelen += mdata->nindirect * 4;
dsym->indirect_syms = bfd_zalloc (abfd, mdata->nindirect * 4);
if (dsym->indirect_syms == NULL)
return FALSE;
dsym->nindirectsyms = mdata->nindirect;
/* So fill in the indices, and point the section reserved1 fields
at the right one. */
sect = (unsigned) -1;
for (i = 0; i < mdata->nindirect; ++i)
{
bfd_mach_o_asymbol *s =
(bfd_mach_o_asymbol *) mdata->indirect_syms[i];
/* Lookup the index of the referenced symbol. */
dsym->indirect_syms[i] =
((bfd_mach_o_asymbol *) s->symbol.udata.p)->symbol.udata.i;
if (s->n_sect != sect)
{
/* Mach-o sections are 1-based, but the section table
is 0-based. */
bfd_mach_o_section *sc = mdata->sections[s->n_sect-1];
sc->reserved1 = i;
sect = s->n_sect;
}
}
}
return TRUE;
}
/* Build Mach-O load commands (currently assuming an MH_OBJECT file).
TODO: Other file formats, rebuilding symtab/dysymtab commands for strip
and copy functionality. */
bfd_boolean
bfd_mach_o_build_commands (bfd *abfd)
@ -1599,102 +2180,148 @@ bfd_mach_o_build_commands (bfd *abfd)
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
unsigned int wide = mach_o_wide_p (&mdata->header);
bfd_mach_o_segment_command *seg;
asection *sec;
bfd_mach_o_load_command *cmd;
bfd_mach_o_load_command *symtab_cmd;
int target_index;
unsigned symcind;
/* Return now if commands are already built. */
/* Return now if commands are already present. */
if (mdata->header.ncmds)
return FALSE;
/* Very simple version: a command (segment) to contain all the sections and
a command for the symbol table. */
mdata->header.ncmds = 2;
mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
* sizeof (bfd_mach_o_load_command));
if (mdata->commands == NULL)
return FALSE;
cmd = &mdata->commands[0];
seg = &cmd->command.segment;
/* Fill in the file type, if not already set. */
seg->nsects = bfd_count_sections (abfd);
/* Set segment command. */
if (wide)
if (mdata->header.filetype == 0)
{
cmd->type = BFD_MACH_O_LC_SEGMENT_64;
cmd->offset = BFD_MACH_O_HEADER_64_SIZE;
cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
+ BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
if (abfd->flags & EXEC_P)
mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
else if (abfd->flags & DYNAMIC)
mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
else
mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
}
/* If hasn't already been done, flatten sections list, and sort
if/when required. Must be done before the symbol table is adjusted,
since that depends on properly numbered sections. */
if (mdata->nsects == 0 || mdata->sections == NULL)
if (! bfd_mach_o_mangle_sections (abfd, mdata))
return FALSE;
/* Order the symbol table, fill-in/check mach-o specific fields and
partition out any indirect symbols. */
if (!bfd_mach_o_mangle_symbols (abfd, mdata))
return FALSE;
/* It's valid to have a file with only absolute symbols... */
if (mdata->nsects > 0)
{
mdata->header.ncmds = 1;
symcind = 1;
}
else
{
cmd->type = BFD_MACH_O_LC_SEGMENT;
cmd->offset = BFD_MACH_O_HEADER_SIZE;
cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
+ BFD_MACH_O_SECTION_SIZE * seg->nsects;
}
cmd->type_required = FALSE;
mdata->header.sizeofcmds = cmd->len;
mdata->filelen = cmd->offset + cmd->len;
symcind = 0;
/* Set symtab command. */
symtab_cmd = &mdata->commands[1];
symtab_cmd->type = BFD_MACH_O_LC_SYMTAB;
symtab_cmd->offset = cmd->offset + cmd->len;
symtab_cmd->len = 6 * 4;
symtab_cmd->type_required = FALSE;
mdata->header.sizeofcmds += symtab_cmd->len;
mdata->filelen += symtab_cmd->len;
/* It's OK to have a file with only section statements. */
if (bfd_get_symcount (abfd) > 0)
mdata->header.ncmds += 1;
/* Fill segment command. */
memset (seg->segname, 0, sizeof (seg->segname));
seg->vmaddr = 0;
seg->fileoff = mdata->filelen;
seg->filesize = 0;
seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
| BFD_MACH_O_PROT_EXECUTE;
seg->initprot = seg->maxprot;
seg->flags = 0;
seg->sect_head = NULL;
seg->sect_tail = NULL;
/* Very simple version (only really applicable to MH_OBJECTs):
a command (segment) to contain all the sections,
a command for the symbol table
a n (optional) command for the dysymtab.
/* Create Mach-O sections.
Section type, attribute and align should have been set when the
section was created - either read in or specified. */
target_index = 0;
for (sec = abfd->sections; sec; sec = sec->next)
{
unsigned bfd_align = bfd_get_section_alignment (abfd, sec);
bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec);
??? maybe we should assert that this is an MH_OBJECT? */
bfd_mach_o_append_section_to_segment (seg, sec);
if (bfd_mach_o_should_emit_dysymtab ()
&& bfd_get_symcount (abfd) > 0)
mdata->header.ncmds += 1;
msect->addr = bfd_get_section_vma (abfd, sec);
msect->size = bfd_get_section_size (sec);
/* Use the largest alignment set, in case it was bumped after the
section was created. */
msect->align = msect->align > bfd_align ? msect->align : bfd_align;
/* A bit weird, but looks like no content;
as -n empty.s -o empty.o */
if (mdata->header.ncmds == 0)
return TRUE;
if (msect->size != 0)
{
mdata->filelen = FILE_ALIGN (mdata->filelen, msect->align);
msect->offset = mdata->filelen;
}
mdata->commands = bfd_zalloc (abfd, mdata->header.ncmds
* sizeof (bfd_mach_o_load_command));
if (mdata->commands == NULL)
return FALSE;
if (mdata->nsects > 0)
{
cmd = &mdata->commands[0];
seg = &cmd->command.segment;
/* Count the segctions in the special blank segment used for MH_OBJECT. */
seg->nsects = bfd_mach_o_count_sections_for_seg (NULL, mdata);
if (seg->nsects == (unsigned long) -1)
return FALSE;
/* Init segment command. */
if (wide)
{
cmd->type = BFD_MACH_O_LC_SEGMENT_64;
cmd->offset = BFD_MACH_O_HEADER_64_SIZE;
cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
+ BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
}
else
msect->offset = 0;
sec->filepos = msect->offset;
sec->target_index = ++target_index;
mdata->filelen += msect->size;
{
cmd->type = BFD_MACH_O_LC_SEGMENT;
cmd->offset = BFD_MACH_O_HEADER_SIZE;
cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
+ BFD_MACH_O_SECTION_SIZE * seg->nsects;
}
cmd->type_required = FALSE;
mdata->header.sizeofcmds = cmd->len;
mdata->filelen = cmd->offset + cmd->len;
}
seg->filesize = mdata->filelen - seg->fileoff;
seg->vmsize = seg->filesize;
if (bfd_get_symcount (abfd) > 0)
{
/* Init symtab command. */
symtab_cmd = &mdata->commands[symcind];
symtab_cmd->type = BFD_MACH_O_LC_SYMTAB;
if (symcind > 0)
symtab_cmd->offset = mdata->commands[0].offset
+ mdata->commands[0].len;
else
symtab_cmd->offset = 0;
symtab_cmd->len = 6 * 4;
symtab_cmd->type_required = FALSE;
mdata->header.sizeofcmds += symtab_cmd->len;
mdata->filelen += symtab_cmd->len;
}
/* If required, setup symtab command. */
if (bfd_mach_o_should_emit_dysymtab ()
&& bfd_get_symcount (abfd) > 0)
{
cmd = &mdata->commands[symcind+1];
cmd->type = BFD_MACH_O_LC_DYSYMTAB;
cmd->offset = symtab_cmd->offset + symtab_cmd->len;
cmd->type_required = FALSE;
cmd->len = 18 * 4 + BFD_MACH_O_LC_SIZE;
mdata->header.sizeofcmds += cmd->len;
mdata->filelen += cmd->len;
}
/* So, now we have sized the commands and the filelen set to that.
Now we can build the segment command and set the section file offsets. */
if (mdata->nsects > 0
&& ! bfd_mach_o_build_seg_command (NULL, mdata, seg))
return FALSE;
/* If we're doing a dysymtab, cmd points to its load command. */
if (bfd_mach_o_should_emit_dysymtab ()
&& bfd_get_symcount (abfd) > 0
&& ! bfd_mach_o_build_dysymtab_command (abfd, mdata,
&mdata->commands[symcind+1]))
return FALSE;
/* The symtab command is filled in when the symtab is written. */
return TRUE;
}
@ -1709,8 +2336,8 @@ bfd_mach_o_set_section_contents (bfd *abfd,
{
file_ptr pos;
/* This must be done first, because bfd_set_section_contents is
going to set output_has_begun to TRUE. */
/* Trying to write the first section contents will trigger the creation of
the load commands if they are not already present. */
if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
return FALSE;

View file

@ -1,6 +1,6 @@
/* Mach-O support for BFD.
Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008, 2009, 2011
Free Software Foundation, Inc.
Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008, 2009, 2011,
2012 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@ -109,13 +109,24 @@ typedef struct bfd_mach_o_asymbol
/* The actual symbol which the rest of BFD works with. */
asymbol symbol;
/* Fields from Mach-O symbol. */
/* Mach-O symbol fields. */
unsigned char n_type;
unsigned char n_sect;
unsigned short n_desc;
}
bfd_mach_o_asymbol;
/* The symbol table is sorted like this:
(1) local.
(otherwise in order of generation)
(2) external defined
(sorted by name)
(3) external undefined
(sorted by name)
(4) common
(sorted by name)
*/
typedef struct bfd_mach_o_symtab_command
{
unsigned int symoff;
@ -507,7 +518,7 @@ typedef struct mach_o_data_struct
unsigned long nsects;
bfd_mach_o_section **sections;
/* Used while writting: current length of the output file. This is used
/* Used while writing: current length of the output file. This is used
to allocate space in the file. */
ufile_ptr filelen;
@ -517,6 +528,18 @@ typedef struct mach_o_data_struct
bfd_mach_o_symtab_command *symtab;
bfd_mach_o_dysymtab_command *dysymtab;
/* Base values used for building the dysymtab for a single-module object. */
unsigned long nlocal;
unsigned long ndefext;
unsigned long nundefext;
/* If this is non-zero, then the pointer below is populated. */
unsigned long nindirect;
/* A set of synthetic symbols representing the 'indirect' ones in the file.
These should be sorted (a) by the section they represent and (b) by the
order that they appear within each section. */
asymbol **indirect_syms;
/* A place to stash dwarf2 info for this bfd. */
void *dwarf2_find_line_info;
@ -600,6 +623,10 @@ unsigned int bfd_mach_o_section_get_entry_size (bfd *, bfd_mach_o_section *);
bfd_boolean bfd_mach_o_read_symtab_symbols (bfd *);
bfd_boolean bfd_mach_o_read_symtab_strtab (bfd *abfd);
/* A placeholder in case we need to suppress emitting the dysymtab for some
reason (e.g. compatibility with older system versions). */
#define bfd_mach_o_should_emit_dysymtab(x) TRUE
extern const bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[];
extern const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[];
@ -640,4 +667,8 @@ typedef struct bfd_mach_o_backend_data
}
bfd_mach_o_backend_data;
/* Symbol type tests. */
#define IS_MACHO_INDIRECT(x) (((x) & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_INDR)
#endif /* _BFD_MACH_O_H_ */

View file

@ -1,3 +1,12 @@
2012-01-03 Iain Sandoe <idsandoe@googlemail.com>
* gas/mach-o/dysymtab-1-64.d: New.
* gas/mach-o/dysymtab-1.d: New.
* gas/mach-o/symbols-1-64.d: New.
* gas/mach-o/symbols-1.d: New.
* gas/mach-o/symbols-base-64.s: New.
* gas/mach-o/symbols-base.s: New.
2011-12-29 Iain Sandoe <idsandoe@googlemail.com>
* gas/mach-o/sections-1.d: Amend to recognize that bss is not emitted

View file

@ -0,0 +1,15 @@
#objdump: -P dysymtab
#target: x86_64-*-darwin* powerpc64-*-darwin*
#source: symbols-base-64.s
.*: +file format mach-o.*
#...
Load command dysymtab:
local symbols: idx: 0 num: 6.*\(nxtidx: 6\)
external symbols: idx: 6 num: 18.*\(nxtidx: 24\)
undefined symbols: idx: 24 num: 21.*\(nxtidx: 45\)
table of content: off: 0x00000000 num: 0.*\(endoff: 0x00000000\)
module table: off: 0x00000000 num: 0.*\(endoff: 0x00000000\)
external reference table: off: 0x00000000 num: 0.*\(endoff: 0x00000000\)
indirect symbol table: off: 0x00000000 num: 0.*\(endoff: 0x00000000\)
external relocation table: off: 0x00000000 num: 0.*\(endoff: 0x00000000\)
local relocation table: off: 0x00000000 num: 0.*\(endoff: 0x00000000\)

View file

@ -0,0 +1,15 @@
#objdump: -P dysymtab
#target: i?86-*-darwin* powerpc-*-darwin*
#source: symbols-base.s
.*: +file format mach-o.*
#...
Load command dysymtab:
local symbols: idx: 0 num: 6.*\(nxtidx: 6\)
external symbols: idx: 6 num: 18.*\(nxtidx: 24\)
undefined symbols: idx: 24 num: 21.*\(nxtidx: 45\)
table of content: off: 0x00000000 num: 0.*\(endoff: 0x00000000\)
module table: off: 0x00000000 num: 0.*\(endoff: 0x00000000\)
external reference table: off: 0x00000000 num: 0.*\(endoff: 0x00000000\)
indirect symbol table: off: 0x00000000 num: 0.*\(endoff: 0x00000000\)
external relocation table: off: 0x00000000 num: 0.*\(endoff: 0x00000000\)
local relocation table: off: 0x00000000 num: 0.*\(endoff: 0x00000000\)

View file

@ -0,0 +1,70 @@
#as: -L
#objdump: -t
#target: x86_64-*-darwin* powerpc64-*-darwin*
#source: symbols-base-64.s
.*: +file format mach-o.*
#...
SYMBOL TABLE:
0000000000000000 l.*0e SECT 01 0000 \[.text\] Lzt0
0000000000000002 l.*0e SECT 01 0000 \[.text\] Lmt0
0000000000000004 l.*0e SECT 01 0000 \[.text\] Lat0
0000000000000000 l.*0e SECT 02 0000 \[.data\] Lzd0
0000000000000002 l.*0e SECT 02 0000 \[.data\] Lmd0
0000000000000005 l.*0e SECT 02 0000 \[.data\] Lad0
0000000000000000 l.*0e SECT 03 0000 \[.bss\] zlcomm0
0000000000000006 l.*0e SECT 03 0000 \[.bss\] mlcomm0
000000000000000c l.*0e SECT 03 0000 \[.bss\] alcomm0
0000000000000000 l.*0e SECT 04 0000 \[__HERE.__there\] Lzs0
0000000000000002 l.*0e SECT 04 0000 \[__HERE.__there\] Lms0
0000000000000004 l.*0e SECT 04 0000 \[__HERE.__there\] Las0
000000000000001e l.*0e SECT 01 0000 \[.text\] Lzt1
0000000000000021 l.*0e SECT 01 0000 \[.text\] Lmt1
0000000000000023 l.*0e SECT 01 0000 \[.text\] Lat1
000000000000001e l.*0e SECT 02 0000 \[.data\] Lzd1
0000000000000020 l.*0e SECT 02 0000 \[.data\] Lmd1
0000000000000023 l.*0e SECT 02 0000 \[.data\] Lad1
0000000000000012 l.*0e SECT 03 0000 \[.bss\] zlcomm1
0000000000000018 l.*0e SECT 03 0000 \[.bss\] mlcomm1
000000000000001e l.*0e SECT 03 0000 \[.bss\] alcomm1
0000000000000026 l.*0e SECT 04 0000 \[__HERE.__there\] Lzs1
0000000000000032 l.*0e SECT 04 0000 \[__HERE.__there\] Lms1
0000000000000033 l.*0e SECT 04 0000 \[__HERE.__there\] Las1
0000000000000004 g.*0f SECT 02 0000 \[.data\] adg0
0000000000000022 g.*0f SECT 02 0000 \[.data\] adg1
0000000000000005 g.*0f SECT 04 0000 \[__HERE.__there\] asg0
0000000000000031 g.*0f SECT 04 0000 \[__HERE.__there\] asg1
0000000000000005 g.*0f SECT 01 0000 \[.text\] atg0
0000000000000022 g.*0f SECT 01 0000 \[.text\] atg1
0000000000000003 g.*0f SECT 02 0000 \[.data\] mdg0
0000000000000021 g.*0f SECT 02 0000 \[.data\] mdg1
0000000000000003 g.*0f SECT 04 0000 \[__HERE.__there\] msg0
0000000000000030 g.*0f SECT 04 0000 \[__HERE.__there\] msg1
0000000000000003 g.*0f SECT 01 0000 \[.text\] mtg0
0000000000000020 g.*0f SECT 01 0000 \[.text\] mtg1
0000000000000001 g.*0f SECT 02 0000 \[.data\] zdg0
000000000000001f g.*0f SECT 02 0000 \[.data\] zdg1
0000000000000001 g.*0f SECT 04 0000 \[__HERE.__there\] zsg0
0000000000000027 g.*0f SECT 04 0000 \[__HERE.__there\] zsg1
0000000000000001 g.*0f SECT 01 0000 \[.text\] ztg0
000000000000001f g.*0f SECT 01 0000 \[.text\] ztg1
0000000000000000 g.*01 UND 00 0000 _aud0
0000000000000000 g.*01 UND 00 0000 _aud1
0000000000000000 g.*01 UND 00 0000 _aus0
0000000000000000 g.*01 UND 00 0000 _aus1
0000000000000000 g.*01 UND 00 0000 _aut0
0000000000000000 g.*01 UND 00 0000 _mud0
0000000000000000 g.*01 UND 00 0000 _mud1
0000000000000000 g.*01 UND 00 0000 _mus0
0000000000000000 g.*01 UND 00 0000 _mus1
0000000000000000 g.*01 UND 00 0000 _mut0
0000000000000000 g.*01 UND 00 0000 _zud0
0000000000000000 g.*01 UND 00 0000 _zud1
0000000000000000 g.*01 UND 00 0000 _zus0
0000000000000000 g.*01 UND 00 0000 _zus1
0000000000000000 g.*01 UND 00 0000 _zut0
000000000000000a.*01 COM 00 0300 acommon0
000000000000000a.*01 COM 00 0300 acommon1
000000000000000a.*01 COM 00 0300 mcommon0
000000000000000a.*01 COM 00 0300 mcommon1
000000000000000a.*01 COM 00 0300 zcommon0
000000000000000a.*01 COM 00 0300 zcommon1

View file

@ -0,0 +1,70 @@
#as: -L
#objdump: -t
#target: i?86-*-darwin* powerpc-*-darwin*
#source: symbols-base.s
.*: +file format mach-o.*
#...
SYMBOL TABLE:
00000000 l.*0e SECT 01 0000 \[.text\] Lzt0
00000002 l.*0e SECT 01 0000 \[.text\] Lmt0
00000004 l.*0e SECT 01 0000 \[.text\] Lat0
00000000 l.*0e SECT 02 0000 \[.data\] Lzd0
00000002 l.*0e SECT 02 0000 \[.data\] Lmd0
00000005 l.*0e SECT 02 0000 \[.data\] Lad0
00000000 l.*0e SECT 03 0000 \[.bss\] zlcomm0
00000006 l.*0e SECT 03 0000 \[.bss\] mlcomm0
0000000c l.*0e SECT 03 0000 \[.bss\] alcomm0
00000000 l.*0e SECT 04 0000 \[__HERE.__there\] Lzs0
00000002 l.*0e SECT 04 0000 \[__HERE.__there\] Lms0
00000004 l.*0e SECT 04 0000 \[__HERE.__there\] Las0
00000012 l.*0e SECT 01 0000 \[.text\] Lzt1
00000015 l.*0e SECT 01 0000 \[.text\] Lmt1
00000017 l.*0e SECT 01 0000 \[.text\] Lat1
00000012 l.*0e SECT 02 0000 \[.data\] Lzd1
00000014 l.*0e SECT 02 0000 \[.data\] Lmd1
00000017 l.*0e SECT 02 0000 \[.data\] Lad1
00000012 l.*0e SECT 03 0000 \[.bss\] zlcomm1
00000018 l.*0e SECT 03 0000 \[.bss\] mlcomm1
0000001e l.*0e SECT 03 0000 \[.bss\] alcomm1
00000016 l.*0e SECT 04 0000 \[__HERE.__there\] Lzs1
0000001e l.*0e SECT 04 0000 \[__HERE.__there\] Lms1
0000001f l.*0e SECT 04 0000 \[__HERE.__there\] Las1
00000004 g.*0f SECT 02 0000 \[.data\] adg0
00000016 g.*0f SECT 02 0000 \[.data\] adg1
00000005 g.*0f SECT 04 0000 \[__HERE.__there\] asg0
0000001d g.*0f SECT 04 0000 \[__HERE.__there\] asg1
00000005 g.*0f SECT 01 0000 \[.text\] atg0
00000016 g.*0f SECT 01 0000 \[.text\] atg1
00000003 g.*0f SECT 02 0000 \[.data\] mdg0
00000015 g.*0f SECT 02 0000 \[.data\] mdg1
00000003 g.*0f SECT 04 0000 \[__HERE.__there\] msg0
0000001c g.*0f SECT 04 0000 \[__HERE.__there\] msg1
00000003 g.*0f SECT 01 0000 \[.text\] mtg0
00000014 g.*0f SECT 01 0000 \[.text\] mtg1
00000001 g.*0f SECT 02 0000 \[.data\] zdg0
00000013 g.*0f SECT 02 0000 \[.data\] zdg1
00000001 g.*0f SECT 04 0000 \[__HERE.__there\] zsg0
00000017 g.*0f SECT 04 0000 \[__HERE.__there\] zsg1
00000001 g.*0f SECT 01 0000 \[.text\] ztg0
00000013 g.*0f SECT 01 0000 \[.text\] ztg1
00000000 g.*01 UND 00 0000 _aud0
00000000 g.*01 UND 00 0000 _aud1
00000000 g.*01 UND 00 0000 _aus0
00000000 g.*01 UND 00 0000 _aus1
00000000 g.*01 UND 00 0000 _aut0
00000000 g.*01 UND 00 0000 _mud0
00000000 g.*01 UND 00 0000 _mud1
00000000 g.*01 UND 00 0000 _mus0
00000000 g.*01 UND 00 0000 _mus1
00000000 g.*01 UND 00 0000 _mut0
00000000 g.*01 UND 00 0000 _zud0
00000000 g.*01 UND 00 0000 _zud1
00000000 g.*01 UND 00 0000 _zus0
00000000 g.*01 UND 00 0000 _zus1
00000000 g.*01 UND 00 0000 _zut0
0000000a.*01 COM 00 0300 acommon0
0000000a.*01 COM 00 0300 acommon1
0000000a.*01 COM 00 0300 mcommon0
0000000a.*01 COM 00 0300 mcommon1
0000000a.*01 COM 00 0300 zcommon0
0000000a.*01 COM 00 0300 zcommon1

View file

@ -0,0 +1,97 @@
# baseline symbols in sections.
Lzt0: .space 1
.globl ztg0
ztg0: .space 1
Lmt0: .space 1
.globl mtg0
mtg0: .space 1
Lat0: .space 1
.globl atg0
atg0: .space 1
.quad _zut0
.quad _mut0
.quad _aut0
.comm zcommon0, 10, 3
.comm mcommon0, 10, 3
.comm acommon0, 10, 3
.data
Lzd0: .space 1
.globl zdg0
zdg0: .space 1
Lmd0: .space 1
.globl mdg0
mdg0: .space 1
adg0: .space 1
.globl adg0
Lad0: .space 1
.quad _zud0
.quad _mud0
.quad _aud0
.lcomm zlcomm0, 5, 1
.lcomm mlcomm0, 5, 1
.lcomm alcomm0, 5, 1
.section __HERE,__there
Lzs0: .space 1
.globl zsg0
zsg0: .space 1
Lms0: .space 1
.globl msg0
msg0: .space 1
Las0: .space 1
asg0: .space 1
.globl asg0
.quad _zus0
.quad _mus0
.quad _aus0
.text
Lzt1: .space 1
.globl ztg1
ztg1: .space 1
.globl mtg1
mtg1: .space 1
Lmt1: .space 1
atg1: .space 1
.globl atg1
Lat1: .space 1
.comm zcommon1, 10, 3
.comm mcommon1, 10, 3
.comm acommon1, 10, 3
.data
Lzd1: .space 1
.globl zdg1, mdg1, adg1
zdg1: .space 1
Lmd1: .space 1
mdg1: .space 1
adg1: .space 1
Lad1: .space 1
.quad _zud1
.quad _mud1
.quad _aud1
.lcomm zlcomm1, 5, 1
.lcomm mlcomm1, 5, 1
.lcomm alcomm1, 5, 1
.section __HERE,__there
.quad _zus1
Lzs1: .space 1
zsg1: .space 1
.quad _mus1
msg1: .space 1
asg1: .space 1
.globl zsg1, msg1, asg1
Lms1: .space 1
Las1: .space 1
.quad _aus1

View file

@ -0,0 +1,97 @@
# baseline symbols in sections.
Lzt0: .space 1
.globl ztg0
ztg0: .space 1
Lmt0: .space 1
.globl mtg0
mtg0: .space 1
Lat0: .space 1
.globl atg0
atg0: .space 1
.long _zut0
.long _mut0
.long _aut0
.comm zcommon0, 10, 3
.comm mcommon0, 10, 3
.comm acommon0, 10, 3
.data
Lzd0: .space 1
.globl zdg0
zdg0: .space 1
Lmd0: .space 1
.globl mdg0
mdg0: .space 1
adg0: .space 1
.globl adg0
Lad0: .space 1
.long _zud0
.long _mud0
.long _aud0
.lcomm zlcomm0, 5, 1
.lcomm mlcomm0, 5, 1
.lcomm alcomm0, 5, 1
.section __HERE,__there
Lzs0: .space 1
.globl zsg0
zsg0: .space 1
Lms0: .space 1
.globl msg0
msg0: .space 1
Las0: .space 1
asg0: .space 1
.globl asg0
.long _zus0
.long _mus0
.long _aus0
.text
Lzt1: .space 1
.globl ztg1
ztg1: .space 1
.globl mtg1
mtg1: .space 1
Lmt1: .space 1
atg1: .space 1
.globl atg1
Lat1: .space 1
.comm zcommon1, 10, 3
.comm mcommon1, 10, 3
.comm acommon1, 10, 3
.data
Lzd1: .space 1
.globl zdg1, mdg1, adg1
zdg1: .space 1
Lmd1: .space 1
mdg1: .space 1
adg1: .space 1
Lad1: .space 1
.long _zud1
.long _mud1
.long _aud1
.lcomm zlcomm1, 5, 1
.lcomm mlcomm1, 5, 1
.lcomm alcomm1, 5, 1
.section __HERE,__there
.long _zus1
Lzs1: .space 1
zsg1: .space 1
.long _mus1
msg1: .space 1
asg1: .space 1
.globl zsg1, msg1, asg1
Lms1: .space 1
Las1: .space 1
.long _aus1