view objgrep/dumpmatch.c @ 220:2cc7a17c3859

pirelli/rfcal: new understanding
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 16 Nov 2017 04:19:58 +0000
parents 77cd647375e5
children
line wrap: on
line source

/*
 * objgrep: output on matches
 */

#include <sys/types.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "intstruct.h"
#include "coffconst.h"
#include "globals.h"

extern unsigned get_u16(), get_u32();

dump_symtab_on_match()
{
	unsigned n;
	struct internal_syment *sym;

	printf("\nThis source section's symbols:\n\n");
	for (n = 0; n < nsymtab; n++) {
		sym = symtab[n];
		if (!sym)
			continue;
		if (sym->section != grep_section)
			continue;
		switch (sym->class) {
		case C_EXT:
			printf("%s = %08X\n", sym->name,
				sym->value + match_offset);
			continue;
		case C_STAT:
			printf("%s:%s = %08X\n", objfilename, sym->name,
				sym->value + match_offset);
			continue;
		}
	}
}

static unsigned
arm_branch_reloc(location)
	unsigned location;
{
	unsigned word, dest;

	word = get_u32(binfilemap + location);
	dest = (word & 0x00FFFFFF) << 2;
	if (dest & 0x02000000)
		dest |= 0xFC000000;
	dest += location + 8;
	return(dest);
}

static unsigned
thumb_bl_reloc(location)
	unsigned location;
{
	unsigned ins1, ins2;
	unsigned dest;

	ins1 = get_u16(binfilemap + location);
	ins2 = get_u16(binfilemap + location + 2);
	dest = ((ins1 & 0x7FF) << 12) | ((ins2 & 0x7FF) << 1);
	if (dest & 0x00400000)
		dest |= 0xFF800000;
	dest += location + 4;
	return(dest);
}

process_relocs_on_match()
{
	unsigned n, value;
	struct internal_reloc *rel;

	for (n = 0, rel = relocs; n < grep_section->nreloc; n++, rel++) {
		switch (rel->type) {
		case RTYPE_LONG:
			value = get_u32(binfilemap + match_offset +
					rel->location);
			break;
		case RTYPE_ARM_B:
			value = arm_branch_reloc(match_offset + rel->location);
			break;
		case RTYPE_THUMB_BL:
			value = thumb_bl_reloc(match_offset + rel->location);
			break;
		default:
			fprintf(stderr,
			"BUG in dump_relocs_on_match(): bad reloc type\n");
			abort();
		}
		value -= rel->addend;
		rel->symvalue = value;
		if (rel->secbase) {
			if (!rel->secbase->recov_flag) {
				rel->secbase->recov_flag = 1;
				rel->secbase->recov_addr = value;
			} else if (rel->secbase->recov_addr != value)
			    printf("Multiple addresses for %s:%s: %08X, %08X\n",
				objfilename, rel->secbase->name,
				rel->secbase->recov_addr, value);
		}
	}
}

dump_ext_relocs_on_match()
{
	unsigned n;
	struct internal_reloc *rel;

	printf("\nExternals deduced from relocs:\n\n");
	for (n = 0, rel = relocs; n < grep_section->nreloc; n++, rel++)
		if (rel->extsym)
			printf("%s = %08X\n", rel->extsym->name, rel->symvalue);
}

dump_reloc_symtab_on_match()
{
	unsigned n;
	struct internal_syment *sym;

	printf("\nThis module's symbols deduced from section relocs:\n\n");
	for (n = 0; n < nsymtab; n++) {
		sym = symtab[n];
		if (!sym || !sym->section)
			continue;
		if (!sym->section->recov_flag)
			continue;
		switch (sym->class) {
		case C_EXT:
			printf("%s = %08X\n", sym->name,
				sym->value + sym->section->recov_addr);
			continue;
		case C_STAT:
			printf("%s:%s = %08X\n", objfilename, sym->name,
				sym->value + sym->section->recov_addr);
			continue;
		}
	}
}