#ifdef SHLIB
#include "shlib.h"
#endif
#include <stdlib.h>
#if !(defined(KLD) && defined(__STATIC__))
#include <stdio.h>
#include <limits.h>
#include <mach/mach.h>
#else
#include <mach/mach.h>
#include <mach/kern_return.h>
#endif
#include <stdarg.h>
#include <string.h>
#include "stuff/openstep_mach.h"
#include <mach-o/loader.h>
#include <mach-o/nlist.h>
#include <ar.h>
#include "stuff/bool.h"
#include "stuff/bytesex.h"
#include "ld.h"
#include "live_refs.h"
#include "objects.h"
#include "sections.h"
#include "pass1.h"
#include "symbols.h"
#include "sets.h"
__private_extern__ struct object_list *objects = NULL;
__private_extern__ unsigned long nobjects = 0;
__private_extern__ struct object_file *cur_obj = NULL;
__private_extern__ struct object_file *base_obj = NULL;
__private_extern__
struct object_file *
new_object_file(void)
{
struct object_list *object_list, **p;
struct object_file *object_file;
for(p = &objects; *p; p = &(object_list->next)){
object_list = *p;
if(object_list->used == NOBJECTS)
continue;
object_file = &(object_list->object_files[object_list->used]);
object_list->used++;
nobjects++;
#ifdef RLD
object_file->set_num = cur_set;
#endif
return(object_file);
}
*p = allocate(sizeof(struct object_list));
object_list = *p;
memset(object_list, '\0', sizeof(struct object_list));
object_file = &(object_list->object_files[object_list->used]);
object_list->used++;
nobjects++;
#ifdef RLD
object_file->set_num = cur_set;
#endif
return(object_file);
}
#ifndef RLD
__private_extern__
unsigned long
object_index(
struct object_file *obj)
{
unsigned long index, i;
struct object_list *object_list, **p;
struct object_file *cmp_obj;
if(multi_module_dylib == FALSE)
return(0);
index = 0;
for(p = &objects; *p; p = &(object_list->next)){
object_list = *p;
for(i = 0; i < object_list->used; i++){
cmp_obj = &(object_list->object_files[i]);
if(cmp_obj->dylib == TRUE)
continue;
if(cmp_obj->bundle_loader == TRUE)
continue;
if(cmp_obj == obj)
return(index);
index++;
}
}
fatal("internal error: object_index() called with bad object file "
"pointer");
return(0);
}
#endif
__private_extern__
struct object_file *
add_last_object_file(
struct object_file *new_object)
{
struct object_file *last_object;
last_object = new_object_file();
*last_object = *new_object;
return(last_object);
}
__private_extern__
void
remove_last_object_file(
struct object_file *last_object)
{
struct object_list *object_list, **p;
struct object_file *object_file;
object_file = NULL;
object_list = NULL;
for(p = &objects; *p; p = &(object_list->next)){
object_list = *p;
object_file = &(object_list->object_files[object_list->used - 1]);
if(object_list->used == NOBJECTS)
continue;
}
if(object_file == NULL || object_file != last_object)
fatal("internal error: remove_last_object_file() called with "
"object file that was not the last object file");
memset(object_file, '\0', sizeof(struct object_file));
object_list->used--;
}
__private_extern__
void
print_obj_name(
struct object_file *obj)
{
char *strings;
if(obj->ar_hdr != NULL){
print("%s(%.*s) ", obj->file_name, (int)obj->ar_name_size,
obj->ar_name);
}
else if(obj->dylib_module != NULL){
strings = obj->obj_addr + obj->symtab->stroff;
print("%s(%s) ", obj->file_name,
strings + obj->dylib_module->module_name);
}
else
print("%s ", obj->file_name);
}
__private_extern__
unsigned long
size_ar_name(
struct ar_hdr *ar_hdr)
{
long i;
i = sizeof(ar_hdr->ar_name) - 1;
if(ar_hdr->ar_name[i] == ' '){
do{
if(ar_hdr->ar_name[i] != ' ')
break;
i--;
}while(i > 0);
}
return(i + 1);
}
__private_extern__
void
set_obj_resolved_path(
struct object_file *obj)
{
#if !defined (SA_RLD) && !(defined(KLD) && defined(__STATIC__))
char resolved_path[PATH_MAX];
if(obj->resolved_path == NULL){
if(realpath(obj->file_name, resolved_path) == NULL)
system_error("can't get resolved path to: %s", obj->file_name);
if(obj->ar_hdr != NULL){
obj->resolved_path_len = strlen(resolved_path) +
obj->ar_name_size + 2;
obj->resolved_path = allocate(obj->resolved_path_len + 1);
strcpy(obj->resolved_path, resolved_path);
strcat(obj->resolved_path, "(");
strncat(obj->resolved_path, obj->ar_name, obj->ar_name_size);
strcat(obj->resolved_path, ")");
}
else{
obj->resolved_path_len = strlen(resolved_path);
obj->resolved_path = allocate(obj->resolved_path_len + 1);
strcpy(obj->resolved_path, resolved_path);
}
}
#else
obj->resolved_path_len = strlen(obj->file_name + 1);
obj->resolved_path = obj->file_name;
#endif
}
__private_extern__
void
print_whatsloaded(void)
{
unsigned long i;
struct object_list *object_list, **p;
struct object_file *obj;
char *strings;
for(p = &objects; *p; p = &(object_list->next)){
object_list = *p;
for(i = 0; i < object_list->used; i++){
obj = &(object_list->object_files[i]);
if(obj->dylib && obj->dylib_module == NULL)
continue;
if(obj->bundle_loader)
continue;
if(obj->dylinker)
continue;
if(obj->ar_hdr){
print("%s(%.*s)\n",obj->file_name,
(int)obj->ar_name_size, obj->ar_name);
}
else if(obj->dylib_module != NULL){
strings = obj->obj_addr + obj->symtab->stroff;
print("%s(%s)\n", obj->file_name,
strings + obj->dylib_module->module_name);
}
else
print("%s\n", obj->file_name);
}
}
}
__private_extern__
enum bool
is_dylib_module_loaded(
struct dylib_module *dylib_module)
{
unsigned long i;
struct object_list *object_list, **p;
struct object_file *obj;
for(p = &objects; *p; p = &(object_list->next)){
object_list = *p;
for(i = 0; i < object_list->used; i++){
obj = &(object_list->object_files[i]);
if(obj->dylib && obj->dylib_module != NULL){
if(obj->dylib_module == dylib_module)
return(TRUE);
}
}
}
return(FALSE);
}
__private_extern__
unsigned long
fine_reloc_output_offset(
struct section_map *map,
unsigned long input_offset)
{
struct fine_reloc *fine_reloc;
unsigned long section_type;
fine_reloc = fine_reloc_for_input_offset(map, input_offset);
section_type = map->s->flags & SECTION_TYPE;
if(((section_type == S_LAZY_SYMBOL_POINTERS ||
section_type == S_NON_LAZY_SYMBOL_POINTERS ||
section_type == S_SYMBOL_STUBS ||
section_type == S_COALESCED) &&
fine_reloc->use_contents == FALSE) ||
(dead_strip == TRUE && fine_reloc->live == FALSE))
return(map->output_section->s.size +
input_offset - fine_reloc->input_offset);
return(fine_reloc->output_offset +
input_offset - fine_reloc->input_offset);
}
__private_extern__
unsigned long
fine_reloc_output_address(
struct section_map *map,
unsigned long input_offset,
unsigned long output_base_address)
{
struct fine_reloc *fine_reloc;
struct merged_symbol *merged_symbol;
unsigned long index;
struct nlist *nlists;
struct section_map *section_map;
fine_reloc = fine_reloc_for_input_offset(map, input_offset);
if(fine_reloc->local_symbol == TRUE){
if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS){
index = fine_reloc->output_offset;
nlists = (struct nlist *)(cur_obj->obj_addr +
cur_obj->symtab->symoff);
if(nlists[index].n_sect == NO_SECT)
return(nlists[index].n_value);
section_map = &(cur_obj->section_maps[nlists[index].n_sect -1]);
if(section_map->nfine_relocs == 0)
return(nlists[index].n_value - section_map->s->addr +
section_map->output_section->s.addr +
section_map->offset);
else
return(section_map->output_section->s.addr +
fine_reloc_output_offset(section_map,
nlists[index].n_value -
section_map->s->addr));
}
else if((map->s->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS ||
(map->s->flags & SECTION_TYPE) ==
S_NON_LAZY_SYMBOL_POINTERS){
return(output_base_address +
fine_reloc->output_offset +
input_offset - fine_reloc->input_offset);
}
else if((map->s->flags & SECTION_TYPE) == S_COALESCED){
if(fine_reloc->use_contents == TRUE){
return(output_base_address +
fine_reloc->output_offset +
input_offset - fine_reloc->input_offset);
}
else{
merged_symbol = fine_reloc->merged_symbol;
if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR)
merged_symbol = (struct merged_symbol *)
merged_symbol->nlist.n_value;
return(merged_symbol->nlist.n_value);
}
}
else{
fatal("internal error, fine_reloc_output_address() called with "
"an input_offset which maps to a fine_reloc where "
"local_symbol is TRUE but it's not in a S_SYMBOL_STUBS, "
"S_LAZY_SYMBOL_POINTERS or S_COALESCED section");
return(0);
}
}
else if((map->s->flags & SECTION_TYPE) == S_COALESCED){
if(fine_reloc->use_contents == TRUE){
return(output_base_address +
fine_reloc->output_offset +
input_offset - fine_reloc->input_offset);
}
else{
merged_symbol = fine_reloc->merged_symbol;
if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR)
merged_symbol = (struct merged_symbol *)
merged_symbol->nlist.n_value;
return(merged_symbol->nlist.n_value);
}
}
else if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS &&
fine_reloc->indirect_defined == TRUE){
if(filetype != MH_DYLIB ||
(filetype == MH_DYLIB && multi_module_dylib == FALSE) ||
(cur_obj == fine_reloc->merged_symbol->definition_object &&
input_offset - fine_reloc->input_offset == 0)){
if(cur_obj == fine_reloc->merged_symbol->definition_object)
merged_symbol = fine_reloc->merged_symbol;
else
merged_symbol = fine_reloc->merged_symbol;
if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR)
merged_symbol = (struct merged_symbol *)
merged_symbol->nlist.n_value;
return(merged_symbol->nlist.n_value);
}
else{
return(output_base_address +
fine_reloc->output_offset +
input_offset - fine_reloc->input_offset);
}
}
else{
return(output_base_address +
fine_reloc->output_offset +
input_offset - fine_reloc->input_offset);
}
}
__private_extern__
void
fine_reloc_output_ref(
struct section_map *map,
unsigned long input_offset,
struct live_ref *ref)
{
struct fine_reloc *fine_reloc;
struct merged_symbol *merged_symbol;
unsigned long index;
struct nlist *nlists;
fine_reloc = fine_reloc_for_input_offset(map, input_offset);
if(fine_reloc->local_symbol == TRUE){
if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS){
index = fine_reloc->output_offset;
nlists = (struct nlist *)(cur_obj->obj_addr +
cur_obj->symtab->symoff);
ref->ref_type = LIVE_REF_VALUE;
ref->value = nlists[index].n_value;
return;
}
else if((map->s->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS ||
(map->s->flags & SECTION_TYPE) ==
S_NON_LAZY_SYMBOL_POINTERS){
ref->ref_type = LIVE_REF_VALUE;
ref->value = map->s->addr + input_offset;
return;
}
else if((map->s->flags & SECTION_TYPE) == S_COALESCED){
if(fine_reloc->use_contents == TRUE){
ref->ref_type = LIVE_REF_VALUE;
ref->value = map->s->addr + input_offset;
return;
}
else{
merged_symbol = fine_reloc->merged_symbol;
if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR)
merged_symbol = (struct merged_symbol *)
merged_symbol->nlist.n_value;
ref->ref_type = LIVE_REF_SYMBOL;
ref->merged_symbol = merged_symbol;
return;
}
}
else{
fatal("internal error, fine_reloc_output_ref() called with "
"an input_offset which maps to a fine_reloc where "
"local_symbol is TRUE but it's not in a S_SYMBOL_STUBS, "
"S_LAZY_SYMBOL_POINTERS or S_COALESCED section");
return;
}
}
else if((map->s->flags & SECTION_TYPE) == S_COALESCED){
if(fine_reloc->use_contents == TRUE){
ref->ref_type = LIVE_REF_VALUE;
ref->value = map->s->addr + input_offset;
return;
}
else{
merged_symbol = fine_reloc->merged_symbol;
if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR)
merged_symbol = (struct merged_symbol *)
merged_symbol->nlist.n_value;
ref->ref_type = LIVE_REF_SYMBOL;
ref->merged_symbol = merged_symbol;
return;
}
}
else if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS &&
fine_reloc->indirect_defined == TRUE){
if(filetype != MH_DYLIB ||
(filetype == MH_DYLIB && multi_module_dylib == FALSE) ||
(cur_obj == fine_reloc->merged_symbol->definition_object &&
input_offset - fine_reloc->input_offset == 0)){
if(cur_obj == fine_reloc->merged_symbol->definition_object)
merged_symbol = fine_reloc->merged_symbol;
else
merged_symbol = fine_reloc->merged_symbol;
if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR)
merged_symbol = (struct merged_symbol *)
merged_symbol->nlist.n_value;
ref->ref_type = LIVE_REF_SYMBOL;
ref->merged_symbol = merged_symbol;
return;
}
else{
ref->ref_type = LIVE_REF_VALUE;
ref->value = map->s->addr + input_offset;
return;
}
}
else{
ref->ref_type = LIVE_REF_VALUE;
ref->value = map->s->addr + input_offset;
return;
}
}
__private_extern__
enum bool
fine_reloc_offset_in_output(
struct section_map *map,
unsigned long input_offset)
{
struct fine_reloc *fine_reloc;
unsigned long section_type;
fine_reloc = fine_reloc_for_input_offset(map, input_offset);
if(dead_strip == TRUE){
section_type = map->s->flags & SECTION_TYPE;
if(section_type == S_LAZY_SYMBOL_POINTERS ||
section_type == S_NON_LAZY_SYMBOL_POINTERS ||
section_type == S_SYMBOL_STUBS ||
section_type == S_COALESCED){
if(fine_reloc->use_contents == FALSE)
return(FALSE);
}
return((enum bool)(fine_reloc->live));
}
return((enum bool)(fine_reloc->use_contents));
}
__private_extern__
enum bool
fine_reloc_offset_in_output_for_output_offset(
struct section_map *map,
unsigned long output_offset)
{
if(map->nfine_relocs == 0)
fatal("internal error, fine_reloc_offset_in_output_for_output_"
"offset() called with a map->nfine_relocs == 0");
if(output_offset >= map->output_section->s.size)
return(FALSE);
else
return(TRUE);
}
__private_extern__
unsigned long
fine_reloc_output_sectnum(
struct section_map *map,
unsigned long input_offset)
{
struct fine_reloc *fine_reloc;
struct merged_symbol *merged_symbol;
unsigned long index;
unsigned long *indirect_symtab;
struct nlist *nlists;
struct section_map *section_map;
fine_reloc = fine_reloc_for_input_offset(map, input_offset);
if(fine_reloc->local_symbol == TRUE){
if((map->s->flags & SECTION_TYPE) == S_COALESCED){
return(map->output_section->output_sectnum);
}
else if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS){
index = fine_reloc->output_offset;
}
else if((map->s->flags & SECTION_TYPE) ==
S_NON_LAZY_SYMBOL_POINTERS ||
(map->s->flags & SECTION_TYPE) ==
S_LAZY_SYMBOL_POINTERS){
indirect_symtab = (unsigned long *)(cur_obj->obj_addr +
cur_obj->dysymtab->indirectsymoff);
index = indirect_symtab[map->s->reserved1 +
(fine_reloc->input_offset / 4)];
}
else{
fatal("internal error, fine_reloc_output_sectnum() called with "
"an input_offset which maps to a fine_reloc where "
"local_symbol is TRUE but it's not in a S_SYMBOL_STUBS, "
"S_NON_LAZY_SYMBOL_POINTERS, S_LAZY_SYMBOL_POINTERS or "
"S_COALESCED section");
index = 0;
}
nlists = (struct nlist *)(cur_obj->obj_addr +
cur_obj->symtab->symoff);
if(nlists[index].n_sect == NO_SECT)
return(NO_SECT);
section_map = &(cur_obj->section_maps[nlists[index].n_sect - 1]);
return(section_map->output_section->output_sectnum);
}
else if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS &&
fine_reloc->indirect_defined == TRUE &&
(filetype != MH_DYLIB || multi_module_dylib == FALSE)){
merged_symbol = fine_reloc->merged_symbol;
if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR)
merged_symbol = (struct merged_symbol *)
merged_symbol->nlist.n_value;
return(merged_symbol->nlist.n_sect);
}
else{
return(map->output_section->output_sectnum);
}
}
__private_extern__
enum bool
fine_reloc_arm(
struct section_map *map,
unsigned long input_offset)
{
struct fine_reloc *fine_reloc;
struct merged_symbol *merged_symbol;
fine_reloc = fine_reloc_for_input_offset(map, input_offset);
if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS &&
fine_reloc->indirect_defined == TRUE &&
(filetype != MH_DYLIB || multi_module_dylib == FALSE)){
merged_symbol = fine_reloc->merged_symbol;
if(merged_symbol != NULL)
return((merged_symbol->nlist.n_desc & N_ARM_THUMB_DEF)
!= N_ARM_THUMB_DEF);
}
return(FALSE);
}
__private_extern__
enum bool
fine_reloc_thumb(
struct section_map *map,
unsigned long input_offset)
{
struct fine_reloc *fine_reloc;
struct merged_symbol *merged_symbol;
fine_reloc = fine_reloc_for_input_offset(map, input_offset);
if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS &&
fine_reloc->indirect_defined == TRUE &&
(filetype != MH_DYLIB || multi_module_dylib == FALSE)){
merged_symbol = fine_reloc->merged_symbol;
if(merged_symbol != NULL)
return((merged_symbol->nlist.n_desc & N_ARM_THUMB_DEF)
== N_ARM_THUMB_DEF);
}
return(FALSE);
}
__private_extern__
enum bool
fine_reloc_local(
struct section_map *map,
unsigned long input_offset)
{
struct fine_reloc *fine_reloc;
struct merged_symbol *merged_symbol;
fine_reloc = fine_reloc_for_input_offset(map, input_offset);
if((map->s->flags & SECTION_TYPE) == S_SYMBOL_STUBS &&
fine_reloc->indirect_defined == TRUE &&
(filetype != MH_DYLIB || multi_module_dylib == FALSE)){
merged_symbol = fine_reloc->merged_symbol;
if(merged_symbol == NULL)
return(TRUE);
}
return(FALSE);
}
__private_extern__
struct fine_reloc *
fine_reloc_for_input_offset(
struct section_map *map,
unsigned long input_offset)
{
int l = 0;
int u = map->nfine_relocs - 1;
int m;
int r;
if(map->nfine_relocs == 0)
fatal("internal error, fine_reloc_for_input_offset() called with a "
"section_map->nfine_relocs == 0");
l = 0;
m = 0;
u = map->nfine_relocs - 1;
while(l <= u){
m = (l + u) / 2;
if((r = (input_offset - map->fine_relocs[m].input_offset)) == 0)
return(map->fine_relocs + m);
else if (r < 0)
u = m - 1;
else
l = m + 1;
}
if(m == 0 || input_offset > map->fine_relocs[m].input_offset)
return(map->fine_relocs + m);
else
return(map->fine_relocs + (m - 1));
}
#ifdef RLD
__private_extern__
void
clean_objects(void)
{
unsigned long i, j;
struct object_list *object_list, **p;
struct object_file *object_file;
#ifndef SA_RLD
kern_return_t r;
#endif
for(p = &objects; *p; p = &(object_list->next)){
object_list = *p;
for(i = 0; i < object_list->used; i++){
object_file = &(object_list->object_files[i]);
if(object_file->set_num != cur_set)
continue;
if(object_file->ar_hdr == NULL &&
object_file->from_fat_file == FALSE &&
object_file->obj_size != 0 &&
object_file->user_obj_addr == FALSE){
#ifndef SA_RLD
if((r = vm_deallocate(mach_task_self(),
(vm_address_t)object_file->obj_addr,
object_file->obj_size)) != KERN_SUCCESS)
mach_fatal(r, "can't vm_deallocate() memory for "
"mapped file %s",object_file->file_name);
#ifdef RLD_VM_ALLOC_DEBUG
print("rld() vm_deallocate: addr = 0x%0x size = 0x%x\n",
(unsigned int)object_file->obj_addr,
(unsigned int)object_file->obj_size);
#endif
#endif
}
object_file->obj_addr = NULL;
object_file->obj_size = 0;
object_file->user_obj_addr = FALSE;
if(object_file->section_maps != NULL){
for(j = 0; j < object_file->nsection_maps; j++){
object_file->section_maps[j].s =
&(object_file->section_maps[j].output_section->s);
}
}
}
}
}
__private_extern__
void
remove_objects(void)
{
unsigned long i, removed;
struct object_list *object_list, *prev_object_list, *next_object_list;
struct object_file *object_file;
prev_object_list = NULL;
for(object_list = objects;
object_list != NULL;
object_list = object_list->next){
removed = 0;
for(i = 0; i < object_list->used; i++){
object_file = &(object_list->object_files[i]);
if(object_file->set_num == cur_set){
if(cur_set != -1)
free(object_file->file_name);
if(object_file->section_maps != NULL)
free(object_file->section_maps);
if(object_file->undefined_maps != NULL)
free(object_file->undefined_maps);
memset(object_file, '\0', sizeof(struct object_file));
removed++;
}
}
object_list->used -= removed;
nobjects -= removed;
}
for(object_list = objects;
object_list != NULL;
object_list = object_list->next){
if(object_list->used == 0)
break;
prev_object_list = object_list;
}
if(object_list != NULL && object_list->used == 0){
if(object_list == objects)
objects = NULL;
else
prev_object_list->next = NULL;
do {
next_object_list = object_list->next;
free(object_list);
object_list = next_object_list;
}while(object_list != NULL);
}
}
#endif
#ifdef DEBUG
__private_extern__
void
print_object_list(void)
{
unsigned long i, j, k;
struct object_list *object_list, **p;
struct object_file *object_file;
struct fine_reloc *fine_relocs;
print("Object file list\n");
for(p = &objects; *p; p = &(object_list->next)){
object_list = *p;
print(" object_list 0x%x\n", (unsigned int)object_list);
print(" used %lu\n", object_list->used);
print(" next 0x%x\n", (unsigned int)object_list->next);
for(i = 0; i < object_list->used; i++){
object_file = &(object_list->object_files[i]);
print("\tfile_name %s\n", object_file->file_name);
print("\tobj_addr 0x%x\n", (unsigned int)object_file->obj_addr);
print("\tobj_size %lu\n", object_file->obj_size);
print("\tar_hdr 0x%x", (unsigned int)object_file->ar_hdr);
if(object_file->ar_hdr != NULL)
print(" (%.12s)\n", (char *)object_file->ar_hdr);
else
print("\n");
print("\tnsection_maps %lu\n", object_file->nsection_maps);
for(j = 0; j < object_file->nsection_maps; j++){
print("\t (%s,%s)\n",
object_file->section_maps[j].s->segname,
object_file->section_maps[j].s->sectname);
print("\t offset 0x%x\n",
(unsigned int)object_file->section_maps[j].offset);
print("\t fine_relocs 0x%x\n",
(unsigned int)object_file->section_maps[j].fine_relocs);
print("\t nfine_relocs %lu\n",
object_file->section_maps[j].nfine_relocs);
fine_relocs = object_file->section_maps[j].fine_relocs;
for(k = 0;
k < object_file->section_maps[j].nfine_relocs;
k++){
print("\t\t%-6lu %-6lu\n",
fine_relocs[k].input_offset,
fine_relocs[k].output_offset);
}
}
print("\tnundefineds %lu\n", object_file->nundefineds);
for(j = 0; j < object_file->nundefineds; j++){
print("\t (%lu,%s)\n",
object_file->undefined_maps[j].index,
object_file->undefined_maps[j].merged_symbol->nlist.
n_un.n_name);
}
#ifdef RLD
print("\tset_num = %d\n", object_file->set_num);
#endif
}
}
}
__private_extern__
void
print_fine_relocs(
struct fine_reloc *fine_relocs,
unsigned long nfine_relocs,
char *string)
{
unsigned long i;
print("%s\n", string);
for(i = 0; i < nfine_relocs; i++){
print("fine_reloc[%lu]\n", i);
print("\t input_offset 0x%x\n",
(unsigned int)(fine_relocs[i].input_offset));
print("\t output_offset 0x%x\n",
(unsigned int)(fine_relocs[i].output_offset));
print("\t indirect_defined %s\n",
fine_relocs[i].indirect_defined == 1 ? "TRUE" : "FALSE");
print("\t use_contents %s\n",
fine_relocs[i].use_contents == 1 ? "TRUE" : "FALSE");
print("\t local_symbol %s\n",
fine_relocs[i].local_symbol == 1 ? "TRUE" : "FALSE");
print("\t live %s\n",
fine_relocs[i].live == 1 ? "TRUE" : "FALSE");
print("\t refs_marked_live %s\n",
fine_relocs[i].refs_marked_live == 1 ? "TRUE" : "FALSE");
print("\tsearched_for_live_refs %s\n",
fine_relocs[i].searched_for_live_refs == 1 ? "TRUE" :"FALSE");
print("\t merged_symbol 0x08%x %s\n",
(unsigned int)(fine_relocs[i].merged_symbol),
fine_relocs[i].merged_symbol == NULL ? "" :
fine_relocs[i].merged_symbol->nlist.n_un.n_name);
}
}
#endif