-
- 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");
-}
-
-\f
-/* Add a function table to the load commands to call a function
- on initiation or termination of the process. */
-
-static void
-add_func_table (hdr_p, load_array, sym, type)
- mo_header_t *hdr_p; /* pointer to global header */
- load_all_t *load_array; /* array of ptrs to load cmds */
- symbol_info_t *sym; /* pointer to symbol entry */
- int type; /* fntc_type value */
-{
- /* 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++)