mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-05 01:34:12 +08:00
target-def.h: Remove usage of OBJECT_FORMAT_ROSE.
* target-def.h: Remove usage of OBJECT_FORMAT_ROSE. * system.h: Poison OBJ_FORMAT_ROSE. * doc/tm.texi (Macros for Initialization): Remove documentatin of OBJECT_FORMAT_ROSE. * config/rs6000/lynx.h: Remove undef of OBJECT_FORMAT_ROSE. * collect2.c: Remove usage of OBJECT_FORMAT_ROSE. From-SVN: r68678
This commit is contained in:
parent
5fad1c24db
commit
4a023207ac
@ -1,3 +1,11 @@
|
||||
2003-06-29 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* target-def.h: Remove usage of OBJECT_FORMAT_ROSE.
|
||||
* system.h: Poison OBJ_FORMAT_ROSE.
|
||||
* doc/tm.texi (Macros for Initialization): Remove documentatin of
|
||||
OBJECT_FORMAT_ROSE.
|
||||
* config/rs6000/lynx.h: Remove undef of OBJECT_FORMAT_ROSE.
|
||||
* collect2.c: Remove usage of OBJECT_FORMAT_ROSE.
|
||||
|
||||
2003-06-29 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
|
||||
|
||||
|
676
gcc/collect2.c
676
gcc/collect2.c
@ -69,7 +69,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#ifdef CROSS_COMPILE
|
||||
#undef SUNOS4_SHARED_LIBRARIES
|
||||
#undef OBJECT_FORMAT_COFF
|
||||
#undef OBJECT_FORMAT_ROSE
|
||||
#undef MD_EXEC_PREFIX
|
||||
#undef REAL_LD_FILE_NAME
|
||||
#undef REAL_NM_FILE_NAME
|
||||
@ -81,7 +80,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
In a cross-compiler, this means you need a cross nm,
|
||||
but that is not quite as unpleasant as special headers. */
|
||||
|
||||
#if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
|
||||
#if !defined (OBJECT_FORMAT_COFF)
|
||||
#define OBJECT_FORMAT_NONE
|
||||
#endif
|
||||
|
||||
@ -113,24 +112,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
|
||||
#endif /* OBJECT_FORMAT_COFF */
|
||||
|
||||
#ifdef OBJECT_FORMAT_ROSE
|
||||
|
||||
#ifdef _OSF_SOURCE
|
||||
#define USE_MMAP
|
||||
#endif
|
||||
|
||||
#ifdef USE_MMAP
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <mach_o_format.h>
|
||||
#include <mach_o_header.h>
|
||||
#include <mach_o_vals.h>
|
||||
#include <mach_o_types.h>
|
||||
|
||||
#endif /* OBJECT_FORMAT_ROSE */
|
||||
|
||||
#ifdef OBJECT_FORMAT_NONE
|
||||
|
||||
/* Default flags to pass to nm. */
|
||||
@ -2856,658 +2837,3 @@ if (debug) fprintf (stderr, "found: %s\n", lib_buf);
|
||||
return (NULL);
|
||||
}
|
||||
#endif /* COLLECT_EXPORT_LIST */
|
||||
|
||||
|
||||
/*
|
||||
* OSF/rose specific stuff.
|
||||
*/
|
||||
|
||||
#ifdef OBJECT_FORMAT_ROSE
|
||||
|
||||
/* Union of the various load commands */
|
||||
|
||||
typedef union load_union
|
||||
{
|
||||
ldc_header_t hdr; /* common header */
|
||||
load_cmd_map_command_t map; /* map indexing other load cmds */
|
||||
interpreter_command_t iprtr; /* interpreter pathname */
|
||||
strings_command_t str; /* load commands strings section */
|
||||
region_command_t region; /* region load command */
|
||||
reloc_command_t reloc; /* relocation section */
|
||||
package_command_t pkg; /* package load command */
|
||||
symbols_command_t sym; /* symbol sections */
|
||||
entry_command_t ent; /* program start section */
|
||||
gen_info_command_t info; /* object information */
|
||||
func_table_command_t func; /* function constructors/destructors */
|
||||
} load_union_t;
|
||||
|
||||
/* Structure to point to load command and data section in memory. */
|
||||
|
||||
typedef struct load_all
|
||||
{
|
||||
load_union_t *load; /* load command */
|
||||
char *section; /* pointer to section */
|
||||
} load_all_t;
|
||||
|
||||
/* Structure to contain information about a file mapped into memory. */
|
||||
|
||||
struct file_info
|
||||
{
|
||||
char *start; /* start of map */
|
||||
char *name; /* filename */
|
||||
long size; /* size of the file */
|
||||
long rounded_size; /* size rounded to page boundary */
|
||||
int fd; /* file descriptor */
|
||||
int rw; /* != 0 if opened read/write */
|
||||
int use_mmap; /* != 0 if mmap'ed */
|
||||
};
|
||||
|
||||
extern int decode_mach_o_hdr (void);
|
||||
extern int encode_mach_o_hdr (void);
|
||||
|
||||
static void add_func_table (mo_header_t *, load_all_t *, symbol_info_t *,
|
||||
int);
|
||||
static void print_header (mo_header_t *);
|
||||
static void print_load_command (load_union_t *, size_t, int);
|
||||
static void bad_header (int);
|
||||
static struct file_info *read_file (const char *, int, int);
|
||||
static void end_file (struct file_info *);
|
||||
|
||||
/* OSF/rose specific version to scan the name list of the loaded
|
||||
program for the symbols g++ uses for static constructors and
|
||||
destructors.
|
||||
|
||||
The constructor table begins at __CTOR_LIST__ and contains a count
|
||||
of the number of pointers (or -1 if the constructors are built in a
|
||||
separate section by the linker), followed by the pointers to the
|
||||
constructor functions, terminated with a null pointer. The
|
||||
destructor table has the same format, and begins at __DTOR_LIST__. */
|
||||
|
||||
static void
|
||||
scan_prog_file (const char *prog_name, enum pass which_pass)
|
||||
{
|
||||
char *obj;
|
||||
mo_header_t hdr;
|
||||
load_all_t *load_array;
|
||||
load_all_t *load_end;
|
||||
load_all_t *load_cmd;
|
||||
int symbol_load_cmds;
|
||||
off_t offset;
|
||||
int i;
|
||||
int num_syms;
|
||||
int status;
|
||||
char *str_sect;
|
||||
struct file_info *obj_file;
|
||||
int prog_fd;
|
||||
mo_lcid_t cmd_strings = -1;
|
||||
symbol_info_t *main_sym = 0;
|
||||
int rw = (which_pass != PASS_FIRST);
|
||||
|
||||
prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
|
||||
if (prog_fd < 0)
|
||||
fatal_perror ("open %s", prog_name);
|
||||
|
||||
obj_file = read_file (prog_name, prog_fd, rw);
|
||||
obj = obj_file->start;
|
||||
|
||||
status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
|
||||
if (status != MO_HDR_CONV_SUCCESS)
|
||||
bad_header (status);
|
||||
|
||||
|
||||
/* Do some basic sanity checks. Note we explicitly use the big endian magic number,
|
||||
since the hardware will automatically swap bytes for us on loading little endian
|
||||
integers. */
|
||||
|
||||
#ifndef CROSS_COMPILE
|
||||
if (hdr.moh_magic != MOH_MAGIC_MSB
|
||||
|| hdr.moh_header_version != MOH_HEADER_VERSION
|
||||
|| hdr.moh_byte_order != OUR_BYTE_ORDER
|
||||
|| hdr.moh_data_rep_id != OUR_DATA_REP_ID
|
||||
|| hdr.moh_cpu_type != OUR_CPU_TYPE
|
||||
|| hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
|
||||
|| hdr.moh_vendor_type != OUR_VENDOR_TYPE)
|
||||
{
|
||||
fatal ("incompatibilities between object file & expected values");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (debug)
|
||||
print_header (&hdr);
|
||||
|
||||
offset = hdr.moh_first_cmd_off;
|
||||
load_end = load_array
|
||||
= (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
|
||||
|
||||
/* Build array of load commands, calculating the offsets */
|
||||
for (i = 0; i < hdr.moh_n_load_cmds; i++)
|
||||
{
|
||||
load_union_t *load_hdr; /* load command header */
|
||||
|
||||
load_cmd = load_end++;
|
||||
load_hdr = (load_union_t *) (obj + offset);
|
||||
|
||||
/* If modifying the program file, copy the header. */
|
||||
if (rw)
|
||||
{
|
||||
load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
|
||||
memcpy ((char *)ptr, (char *)load_hdr, load_hdr->hdr.ldci_cmd_size);
|
||||
load_hdr = ptr;
|
||||
|
||||
/* null out old command map, because we will rewrite at the end. */
|
||||
if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
|
||||
{
|
||||
cmd_strings = ptr->map.lcm_ld_cmd_strings;
|
||||
ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
load_cmd->load = load_hdr;
|
||||
if (load_hdr->hdr.ldci_section_off > 0)
|
||||
load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
|
||||
|
||||
if (debug)
|
||||
print_load_command (load_hdr, offset, i);
|
||||
|
||||
offset += load_hdr->hdr.ldci_cmd_size;
|
||||
}
|
||||
|
||||
/* If the last command is the load command map and is not undefined,
|
||||
decrement the count of load commands. */
|
||||
if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
|
||||
{
|
||||
load_end--;
|
||||
hdr.moh_n_load_cmds--;
|
||||
}
|
||||
|
||||
/* Go through and process each symbol table section. */
|
||||
symbol_load_cmds = 0;
|
||||
for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
|
||||
{
|
||||
load_union_t *load_hdr = load_cmd->load;
|
||||
|
||||
if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
|
||||
{
|
||||
symbol_load_cmds++;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
const char *kind = "unknown";
|
||||
|
||||
switch (load_hdr->sym.symc_kind)
|
||||
{
|
||||
case SYMC_IMPORTS: kind = "imports"; break;
|
||||
case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
|
||||
case SYMC_STABS: kind = "stabs"; break;
|
||||
}
|
||||
|
||||
notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
|
||||
symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
|
||||
}
|
||||
|
||||
if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
|
||||
continue;
|
||||
|
||||
str_sect = load_array[load_hdr->sym.symc_strings_section].section;
|
||||
if (str_sect == (char *) 0)
|
||||
fatal ("string section missing");
|
||||
|
||||
if (load_cmd->section == (char *) 0)
|
||||
fatal ("section pointer missing");
|
||||
|
||||
num_syms = load_hdr->sym.symc_nentries;
|
||||
for (i = 0; i < num_syms; i++)
|
||||
{
|
||||
symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
|
||||
char *name = sym->si_name.symbol_name + str_sect;
|
||||
|
||||
if (name[0] != '_')
|
||||
continue;
|
||||
|
||||
if (rw)
|
||||
{
|
||||
char *n = name + strlen (name) - strlen (NAME__MAIN);
|
||||
|
||||
if ((n - name) < 0 || strcmp (n, NAME__MAIN))
|
||||
continue;
|
||||
while (n != name)
|
||||
if (*--n != '_')
|
||||
continue;
|
||||
|
||||
main_sym = sym;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (is_ctor_dtor (name))
|
||||
{
|
||||
case 1:
|
||||
add_to_list (&constructors, name);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
add_to_list (&destructors, name);
|
||||
break;
|
||||
|
||||
default: /* not a constructor or destructor */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
|
||||
sym->si_type, sym->si_sc_type, sym->si_flags, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (symbol_load_cmds == 0)
|
||||
fatal ("no symbol table found");
|
||||
|
||||
/* Update the program file now, rewrite header and load commands. At present,
|
||||
we assume that there is enough space after the last load command to insert
|
||||
one more. Since the first section written out is page aligned, and the
|
||||
number of load commands is small, this is ok for the present. */
|
||||
|
||||
if (rw)
|
||||
{
|
||||
load_union_t *load_map;
|
||||
size_t size;
|
||||
|
||||
if (cmd_strings == -1)
|
||||
fatal ("no cmd_strings found");
|
||||
|
||||
/* Add __main to initializer list.
|
||||
If we are building a program instead of a shared library, do not
|
||||
do anything, since in the current version, you cannot do mallocs
|
||||
and such in the constructors. */
|
||||
|
||||
if (main_sym != (symbol_info_t *) 0
|
||||
&& ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
|
||||
add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
|
||||
|
||||
if (debug)
|
||||
notice ("\nUpdating header and load commands.\n\n");
|
||||
|
||||
hdr.moh_n_load_cmds++;
|
||||
size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
|
||||
|
||||
/* Create new load command map. */
|
||||
if (debug)
|
||||
notice ("load command map, %d cmds, new size %ld.\n",
|
||||
(int) hdr.moh_n_load_cmds, (long) size);
|
||||
|
||||
load_map = (load_union_t *) xcalloc (1, size);
|
||||
load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
|
||||
load_map->map.ldc_header.ldci_cmd_size = size;
|
||||
load_map->map.lcm_ld_cmd_strings = cmd_strings;
|
||||
load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
|
||||
load_array[hdr.moh_n_load_cmds-1].load = load_map;
|
||||
|
||||
offset = hdr.moh_first_cmd_off;
|
||||
for (i = 0; i < hdr.moh_n_load_cmds; i++)
|
||||
{
|
||||
load_map->map.lcm_map[i] = offset;
|
||||
if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
|
||||
hdr.moh_load_map_cmd_off = offset;
|
||||
|
||||
offset += load_array[i].load->hdr.ldci_cmd_size;
|
||||
}
|
||||
|
||||
hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
|
||||
|
||||
if (debug)
|
||||
print_header (&hdr);
|
||||
|
||||
/* Write header. */
|
||||
status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
|
||||
if (status != MO_HDR_CONV_SUCCESS)
|
||||
bad_header (status);
|
||||
|
||||
if (debug)
|
||||
notice ("writing load commands.\n\n");
|
||||
|
||||
/* Write load commands. */
|
||||
offset = hdr.moh_first_cmd_off;
|
||||
for (i = 0; i < hdr.moh_n_load_cmds; i++)
|
||||
{
|
||||
load_union_t *load_hdr = load_array[i].load;
|
||||
size_t size = load_hdr->hdr.ldci_cmd_size;
|
||||
|
||||
if (debug)
|
||||
print_load_command (load_hdr, offset, i);
|
||||
|
||||
bcopy ((char *) load_hdr, (char *) (obj + offset), size);
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
|
||||
end_file (obj_file);
|
||||
|
||||
if (close (prog_fd))
|
||||
fatal_perror ("close %s", prog_name);
|
||||
|
||||
if (debug)
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
|
||||
/* Add a function table to the load commands to call a function on
|
||||
initiation or termination of the process. The function takes HDR_P
|
||||
as pointer to the global header, LOAD_ARRAY as array of pointers to
|
||||
load commands, SYM as pointer to symbol entry and the fntc_type
|
||||
value TYPE. */
|
||||
|
||||
static void
|
||||
add_func_table (mo_header_t *hdr_p, load_all_t *load_array,
|
||||
symbol_info_t *sym, int type)
|
||||
{
|
||||
/* Add a new load command. */
|
||||
int num_cmds = ++hdr_p->moh_n_load_cmds;
|
||||
int load_index = num_cmds - 1;
|
||||
size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
|
||||
load_union_t *ptr = xcalloc (1, size);
|
||||
load_all_t *load_cmd;
|
||||
int i;
|
||||
|
||||
/* Set the unresolved address bit in the header to force the loader to be
|
||||
used, since kernel exec does not call the initialization functions. */
|
||||
hdr_p->moh_flags |= MOH_UNRESOLVED_F;
|
||||
|
||||
load_cmd = &load_array[load_index];
|
||||
load_cmd->load = ptr;
|
||||
load_cmd->section = (char *) 0;
|
||||
|
||||
/* Fill in func table load command. */
|
||||
ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
|
||||
ptr->func.ldc_header.ldci_cmd_size = size;
|
||||
ptr->func.ldc_header.ldci_section_off = 0;
|
||||
ptr->func.ldc_header.ldci_section_len = 0;
|
||||
ptr->func.fntc_type = type;
|
||||
ptr->func.fntc_nentries = 1;
|
||||
|
||||
/* copy address, turn it from abs. address to (region,offset) if necessary. */
|
||||
/* Is the symbol already expressed as (region, offset)? */
|
||||
if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
|
||||
{
|
||||
ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
|
||||
ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
|
||||
}
|
||||
|
||||
/* If not, figure out which region it's in. */
|
||||
else
|
||||
{
|
||||
mo_vm_addr_t addr = sym->si_value.abs_val;
|
||||
int found = 0;
|
||||
|
||||
for (i = 0; i < load_index; i++)
|
||||
{
|
||||
if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
|
||||
{
|
||||
region_command_t *region_ptr = &load_array[i].load->region;
|
||||
|
||||
if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
|
||||
&& addr >= region_ptr->regc_addr.vm_addr
|
||||
&& addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
|
||||
{
|
||||
ptr->func.fntc_entry_loc[0].adr_lcid = i;
|
||||
ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
|
||||
found++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
fatal ("could not convert 0x%l.8x into a region", addr);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
notice ("%s function, region %d, offset = %ld (0x%.8lx)\n",
|
||||
type == FNTC_INITIALIZATION ? "init" : "term",
|
||||
(int) ptr->func.fntc_entry_loc[i].adr_lcid,
|
||||
(long) ptr->func.fntc_entry_loc[i].adr_sctoff,
|
||||
(long) ptr->func.fntc_entry_loc[i].adr_sctoff);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Print the global header for an OSF/rose object. */
|
||||
|
||||
static void
|
||||
print_header (mo_header_t *hdr_ptr)
|
||||
{
|
||||
fprintf (stderr, "\nglobal header:\n");
|
||||
fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
|
||||
fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
|
||||
fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
|
||||
fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
|
||||
fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
|
||||
fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
|
||||
fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
|
||||
fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
|
||||
fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
|
||||
fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
|
||||
fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
|
||||
fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
|
||||
fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
|
||||
fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
|
||||
fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
|
||||
|
||||
if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
|
||||
fprintf (stderr, ", relocatable");
|
||||
|
||||
if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
|
||||
fprintf (stderr, ", linkable");
|
||||
|
||||
if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
|
||||
fprintf (stderr, ", execable");
|
||||
|
||||
if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
|
||||
fprintf (stderr, ", executable");
|
||||
|
||||
if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
|
||||
fprintf (stderr, ", unresolved");
|
||||
|
||||
fprintf (stderr, "\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Print a short summary of a load command. */
|
||||
|
||||
static void
|
||||
print_load_command (load_union_t *load_hdr, size_t offset, int number)
|
||||
{
|
||||
mo_long_t type = load_hdr->hdr.ldci_cmd_type;
|
||||
const char *type_str = (char *) 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
|
||||
case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
|
||||
case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
|
||||
case LDC_STRINGS: type_str = "STRINGS"; break;
|
||||
case LDC_REGION: type_str = "REGION"; break;
|
||||
case LDC_RELOC: type_str = "RELOC"; break;
|
||||
case LDC_PACKAGE: type_str = "PACKAGE"; break;
|
||||
case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
|
||||
case LDC_ENTRY: type_str = "ENTRY"; break;
|
||||
case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
|
||||
case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
|
||||
}
|
||||
|
||||
fprintf (stderr,
|
||||
"cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
|
||||
number,
|
||||
(long) load_hdr->hdr.ldci_cmd_size,
|
||||
(long) offset,
|
||||
(long) load_hdr->hdr.ldci_section_off,
|
||||
(long) load_hdr->hdr.ldci_section_len);
|
||||
|
||||
if (type_str == (char *) 0)
|
||||
fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
|
||||
|
||||
else if (type != LDC_REGION)
|
||||
fprintf (stderr, ", ty: %s\n", type_str);
|
||||
|
||||
else
|
||||
{
|
||||
const char *region = "";
|
||||
switch (load_hdr->region.regc_usage_type)
|
||||
{
|
||||
case REG_TEXT_T: region = ", .text"; break;
|
||||
case REG_DATA_T: region = ", .data"; break;
|
||||
case REG_BSS_T: region = ", .bss"; break;
|
||||
case REG_GLUE_T: region = ", .glue"; break;
|
||||
#if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
|
||||
case REG_RDATA_T: region = ", .rdata"; break;
|
||||
case REG_SDATA_T: region = ", .sdata"; break;
|
||||
case REG_SBSS_T: region = ", .sbss"; break;
|
||||
#endif
|
||||
}
|
||||
|
||||
fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
|
||||
type_str,
|
||||
(long) load_hdr->region.regc_vm_addr,
|
||||
(long) load_hdr->region.regc_vm_size,
|
||||
region);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Fatal error when {en,de}code_mach_o_header fails. */
|
||||
|
||||
static void
|
||||
bad_header (int status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case MO_ERROR_BAD_MAGIC: fatal ("bad magic number");
|
||||
case MO_ERROR_BAD_HDR_VERS: fatal ("bad header version");
|
||||
case MO_ERROR_BAD_RAW_HDR_VERS: fatal ("bad raw header version");
|
||||
case MO_ERROR_BUF2SML: fatal ("raw header buffer too small");
|
||||
case MO_ERROR_OLD_RAW_HDR_FILE: fatal ("old raw header file");
|
||||
case MO_ERROR_UNSUPPORTED_VERS: fatal ("unsupported version");
|
||||
default:
|
||||
fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Read a file into a memory buffer. The file has filename NAME and is
|
||||
opened with the file descriptor FD for read or write according to
|
||||
RW. */
|
||||
|
||||
static struct file_info *
|
||||
read_file (const char *name, int fd, int rw)
|
||||
{
|
||||
struct stat stat_pkt;
|
||||
struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
|
||||
#ifdef USE_MMAP
|
||||
static int page_size;
|
||||
#endif
|
||||
|
||||
if (fstat (fd, &stat_pkt) < 0)
|
||||
fatal_perror ("fstat %s", name);
|
||||
|
||||
p->name = name;
|
||||
p->size = stat_pkt.st_size;
|
||||
p->rounded_size = stat_pkt.st_size;
|
||||
p->fd = fd;
|
||||
p->rw = rw;
|
||||
|
||||
#ifdef USE_MMAP
|
||||
if (debug)
|
||||
fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
|
||||
|
||||
if (page_size == 0)
|
||||
page_size = sysconf (_SC_PAGE_SIZE);
|
||||
|
||||
p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
|
||||
p->start = mmap ((caddr_t) 0,
|
||||
(rw) ? p->rounded_size : p->size,
|
||||
(rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
|
||||
MAP_FILE | MAP_VARIABLE | MAP_SHARED,
|
||||
fd,
|
||||
0L);
|
||||
|
||||
if (p->start != (char *) 0 && p->start != (char *) -1)
|
||||
p->use_mmap = 1;
|
||||
|
||||
else
|
||||
#endif /* USE_MMAP */
|
||||
{
|
||||
long len;
|
||||
|
||||
if (debug)
|
||||
fprintf (stderr, "read %s\n", name);
|
||||
|
||||
p->use_mmap = 0;
|
||||
p->start = xmalloc (p->size);
|
||||
if (lseek (fd, 0L, SEEK_SET) < 0)
|
||||
fatal_perror ("lseek %s 0", name);
|
||||
|
||||
len = read (fd, p->start, p->size);
|
||||
if (len < 0)
|
||||
fatal_perror ("read %s", name);
|
||||
|
||||
if (len != p->size)
|
||||
fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Do anything necessary to write a file back from memory. */
|
||||
|
||||
static void
|
||||
end_file (struct file_info *pt)
|
||||
{
|
||||
#ifdef USE_MMAP
|
||||
if (ptr->use_mmap)
|
||||
{
|
||||
if (ptr->rw)
|
||||
{
|
||||
if (debug)
|
||||
fprintf (stderr, "msync %s\n", ptr->name);
|
||||
|
||||
if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
|
||||
fatal_perror ("msync %s", ptr->name);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
fprintf (stderr, "munmap %s\n", ptr->name);
|
||||
|
||||
if (munmap (ptr->start, ptr->size))
|
||||
fatal_perror ("munmap %s", ptr->name);
|
||||
}
|
||||
else
|
||||
#endif /* USE_MMAP */
|
||||
{
|
||||
if (ptr->rw)
|
||||
{
|
||||
long len;
|
||||
|
||||
if (debug)
|
||||
fprintf (stderr, "write %s\n", ptr->name);
|
||||
|
||||
if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
|
||||
fatal_perror ("lseek %s 0", ptr->name);
|
||||
|
||||
len = write (ptr->fd, ptr->start, ptr->size);
|
||||
if (len < 0)
|
||||
fatal_perror ("write %s", ptr->name);
|
||||
|
||||
if (len != ptr->size)
|
||||
fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
|
||||
}
|
||||
|
||||
free (ptr->start);
|
||||
}
|
||||
|
||||
free (ptr);
|
||||
}
|
||||
|
||||
#endif /* OBJECT_FORMAT_ROSE */
|
||||
|
@ -103,7 +103,6 @@ do { \
|
||||
/* For collect2 */
|
||||
#define OBJECT_FORMAT_NONE
|
||||
#undef OBJECT_FORMAT_COFF
|
||||
#undef OBJECT_FORMAT_ROSE
|
||||
#undef MD_EXEC_PREFIX
|
||||
#undef REAL_LD_FILE_NAME
|
||||
#undef REAL_STRIP_FILE_NAME
|
||||
|
@ -7118,21 +7118,15 @@ If your system uses @command{collect2} as the means of processing
|
||||
constructors, then that program normally uses @command{nm} to scan
|
||||
an object file for constructor functions to be called.
|
||||
|
||||
On certain kinds of systems, you can define these macros to make
|
||||
On certain kinds of systems, you can define this macro to make
|
||||
@command{collect2} work faster (and, in some cases, make it work at all):
|
||||
|
||||
@defmac OBJECT_FORMAT_COFF
|
||||
Define this macro if the system uses COFF (Common Object File Format)
|
||||
object files, so that @command{collect2} can assume this format and scan
|
||||
object files directly for dynamic constructor/destructor functions.
|
||||
@end defmac
|
||||
|
||||
@defmac OBJECT_FORMAT_ROSE
|
||||
Define this macro if the system uses ROSE format object files, so that
|
||||
@command{collect2} can assume this format and scan object files directly
|
||||
for dynamic constructor/destructor functions.
|
||||
|
||||
These macros are effective only in a native compiler; @command{collect2} as
|
||||
This macro is effective only in a native compiler; @command{collect2} as
|
||||
part of a cross compiler always uses @command{nm} for the target machine.
|
||||
@end defmac
|
||||
|
||||
|
@ -621,7 +621,7 @@ typedef char _Bool;
|
||||
DBX_LBRAC_FIRST DBX_OUTPUT_ENUM DBX_OUTPUT_SOURCE_FILENAME \
|
||||
DBX_WORKING_DIRECTORY INSN_CACHE_DEPTH INSN_CACHE_SIZE \
|
||||
INSN_CACHE_LINE_WIDTH INIT_SECTION_PREAMBLE NEED_ATEXIT ON_EXIT \
|
||||
EXIT_BODY
|
||||
EXIT_BODY OBJECT_FORMAT_ROSE
|
||||
|
||||
/* Hooks that are no longer used. */
|
||||
#pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \
|
||||
|
@ -40,7 +40,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#define TARGET_ASM_ALIGNED_TI_OP NULL
|
||||
|
||||
/* GAS and SYSV4 assemblers accept these. */
|
||||
#if defined (OBJECT_FORMAT_ELF) || defined (OBJECT_FORMAT_ROSE)
|
||||
#if defined (OBJECT_FORMAT_ELF)
|
||||
#define TARGET_ASM_UNALIGNED_HI_OP "\t.2byte\t"
|
||||
#define TARGET_ASM_UNALIGNED_SI_OP "\t.4byte\t"
|
||||
#define TARGET_ASM_UNALIGNED_DI_OP "\t.8byte\t"
|
||||
@ -50,7 +50,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#define TARGET_ASM_UNALIGNED_SI_OP NULL
|
||||
#define TARGET_ASM_UNALIGNED_DI_OP NULL
|
||||
#define TARGET_ASM_UNALIGNED_TI_OP NULL
|
||||
#endif /* OBJECT_FORMAT_ELF || OBJECT_FORMAT_ROSE */
|
||||
#endif /* OBJECT_FORMAT_ELF */
|
||||
|
||||
#define TARGET_ASM_INTEGER default_assemble_integer
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user