#undef CATS_BUG_FIX1
#ifdef SHLIB
#include "shlib.h"
#endif
#ifdef RLD
#include <stdlib.h>
#if !(defined(KLD) && defined(__STATIC__))
#include <stdio.h>
#include <mach/mach.h>
#else
#include <mach/kern_return.h>
#include <mach/vm_map.h>
#include <mach/mach.h>
#endif
#include <stdarg.h>
#include <string.h>
#include "stuff/openstep_mach.h"
#include <mach-o/loader.h>
#include "stuff/bool.h"
#include "stuff/bytesex.h"
#include "ld.h"
#include "live_refs.h"
#include "objects.h"
#include "sets.h"
#define NSETS_INCREMENT 10
__private_extern__ struct set *sets = NULL;
static long nsets = 0;
__private_extern__ long cur_set = -1;
__private_extern__
void
new_set(void)
{
long i;
if(cur_set + 2 > nsets){
sets = reallocate(sets,
(nsets + NSETS_INCREMENT) * sizeof(struct set));
for(i = 0; i < NSETS_INCREMENT; i++){
memset(sets + nsets + i, '\0', sizeof(struct set));
sets[nsets + i].link_edit_common_object =
allocate(sizeof(struct object_file));
memset(sets[nsets + i].link_edit_common_object, '\0',
sizeof(struct object_file));
sets[nsets + i].link_edit_section_maps =
allocate(sizeof(struct section_map));
memset(sets[nsets + i].link_edit_section_maps, '\0',
sizeof(struct section_map));
sets[nsets + i].link_edit_common_section =
allocate(sizeof(struct section));
memset(sets[nsets + i].link_edit_common_section, '\0',
sizeof(struct section));
}
nsets += NSETS_INCREMENT;
}
cur_set++;
}
__private_extern__
void
new_archive_or_fat(
char *file_name,
char *file_addr,
unsigned long file_size)
{
sets[cur_set].archives = reallocate(sets[cur_set].archives,
(sets[cur_set].narchives + 1) *
sizeof(struct archive));
sets[cur_set].archives[sets[cur_set].narchives].file_name =
allocate(strlen(file_name) + 1);
strcpy(sets[cur_set].archives[sets[cur_set].narchives].file_name,
file_name);
sets[cur_set].archives[sets[cur_set].narchives].file_addr = file_addr;
sets[cur_set].archives[sets[cur_set].narchives].file_size = file_size;
sets[cur_set].narchives++;
}
__private_extern__
void
clean_archives_and_fats(void)
{
#ifndef SA_RLD
unsigned long i;
kern_return_t r;
char *file_addr, *file_name;
long file_size;
if(sets != NULL && cur_set != -1){
for(i = 0; i < sets[cur_set].narchives; i++){
file_addr = sets[cur_set].archives[i].file_addr;
file_size = sets[cur_set].archives[i].file_size;
file_name = sets[cur_set].archives[i].file_name;
if((r = vm_deallocate(mach_task_self(), (vm_address_t)file_addr,
file_size)) != KERN_SUCCESS)
mach_fatal(r, "can't vm_deallocate() memory for "
"mapped file %s", file_name);
#ifdef RLD_VM_ALLOC_DEBUG
print("rld() vm_deallocate: addr = 0x%0x size = 0x%x\n",
(unsigned int)file_addr,
(unsigned int)file_size);
#endif
free(file_name);
}
if(sets[cur_set].archives != NULL)
free(sets[cur_set].archives);
sets[cur_set].archives = NULL;
sets[cur_set].narchives = 0;
}
#endif
}
__private_extern__
void
remove_set(void)
{
if(cur_set >= 0){
sets[cur_set].output_addr = NULL;
sets[cur_set].output_size = 0;
memset(sets[cur_set].link_edit_common_object, '\0',
sizeof(struct object_file));
memset(sets[cur_set].link_edit_section_maps, '\0',
sizeof(struct section_map));
memset(sets[cur_set].link_edit_common_section, '\0',
sizeof(struct section));
cur_set--;
}
}
__private_extern__
void
free_sets(void)
{
long i;
if(sets != NULL){
for(i = 0; i < nsets; i++){
if(sets[i].link_edit_common_object != NULL){
free(sets[i].link_edit_common_object);
}
if(sets[i].link_edit_section_maps != NULL){
free(sets[i].link_edit_section_maps);
}
if(sets[i].link_edit_common_section != NULL){
free(sets[i].link_edit_common_section);
}
}
free(sets);
}
sets = NULL;
nsets = 0;
cur_set = -1;
}
#endif