This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Porting Binutils: Relocation entries fail to emit


Hi all,

I am currently trying to port Binutils to my own architecture. I've 
figured out most of it, but the assembler refuses to emit relocation entries.
I've tried to copy examples and understand them as far as possible, but
evidently I am missing a key piece of knowledge.

Specifically, my architecture features a single, 16 bit general-purpose 
register. It may be loaded as follows:

Acc = p
Acc = *p
Acc = **p

Where Acc is the register, and p is the opcode argument. I want to be able to 
write the following gas code to emit such instructions, and control the actual 
location of the value being loaded:

.global _entry
.extern myvar

.section .text

_start:
	load myvar /* Acc = *p, where myvar = p */

By my understanding, the assembler must emit a relocation entry for the symbol 
in the output object file. The implementation files that give the assembler 
insight on how to do this, as I understand, are those located in the bfd/ 
directory, where the `HOWTO` macros tell the assembler `how to` add the relo-
-cation. As such, I have attempted to provide a minimal implementation to
what was apparently neccesary (from what I understand, generic functions
are used in absence of machine specific ones). The code goes as follows:

P.s. My target name is `logisimna16`

>>> bfd/elf32-logisimna16.c:

#include "sysdep.h"
#include "bfd.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "libiberty.h"
#include "elf-bfd.h"
#include "elf/logisimna16.h"

struct logisimna16_reloc_map
{
	bfd_reloc_code_real_type bfd_reloc_val;
	unsigned int logisimna16_reloc_val;
};

static const struct logisimna16_reloc_map
	logisimna16_reloc_map[R_LOGISIMNA16_MAX] =
{
	{BFD_RELOC_NONE, R_LOGISIMNA16_NONE},
	{BFD_RELOC_16, R_LOGISIMNA16_NUM16},
	{BFD_RELOC_16, R_LOGISIMNA16_IMM16}
};


static reloc_howto_type logisimna16_elf_howto_table[] = {
	HOWTO(R_LOGISIMNA16_NONE,
		0,
		0,
		0,
		FALSE,
		0,
		complain_overflow_dont,
		bfd_elf_generic_reloc,
		"R_LOGISIMNA16_NONE",
		0,
		0,
		0,
		FALSE),

	HOWTO(R_LOGISIMNA16_NUM16,
		0,
		2,
		16,
		FALSE,
		0,
		complain_overflow_bitfield,
		bfd_elf_generic_reloc,
		"R_LOGISIMNA16_NUM16",
		FALSE,
		0x0,
		0xFFFF,
		FALSE),
	
	HOWTO(R_LOGISIMNA16_IMM16,
		0,
		2,
		16,
		FALSE,
		0,
		complain_overflow_bitfield,
		bfd_elf_generic_reloc,
		"R_LOGISIMNA16_IMM16",
		FALSE,
		0x0,
		0xFFFF,
		FALSE)
};

/* ELF-specific function implementations */

static reloc_howto_type* logisimna16_reloc_type_lookup(bfd* abfd,
	bfd_reloc_code_real_type code)
{
	unsigned int i;
	
	for(i = ARRAY_SIZE(logisimna16_reloc_map); i--;) {
		if(logisimna16_reloc_map[i].bfd_reloc_val == code) {
			return &logisimna16_elf_howto_table[
				logisimna16_reloc_map[i].logisimna16_reloc_val];
		}
	}
	
	_bfd_error_handler ("Unsupported LOGISIMNA16 relocation type: 0x%x\n", code);
	return NULL;
}

static reloc_howto_type* logisimna16_reloc_name_lookup (
	bfd* abfd ATTRIBUTE_UNUSED, const char* r_name)
{
	unsigned int i;

	for (i = 0; ARRAY_SIZE (logisimna16_elf_howto_table); i++) {
		if (logisimna16_elf_howto_table[i].name != NULL
		  && strcasecmp (logisimna16_elf_howto_table[i].name, r_name) == 0)
		{
			return logisimna16_elf_howto_table + i;
		}
	}

	return NULL;
}

static void elf_logisimna16_info_to_howto(
	bfd* abfd ATTRIBUTE_UNUSED, arelent* cache_ptr,
	Elf_Internal_Rela* dst)
{
	unsigned int r_type;

	r_type = ELF32_R_TYPE (dst->r_info);

	if (r_type >= (unsigned int) R_LOGISIMNA16_MAX) {
		_bfd_error_handler (_("%B: invalid LOGISIMNA16 reloc number: %d"), abfd, r_type);
		r_type = 0;
	}

	cache_ptr->howto = &logisimna16_elf_howto_table[r_type];
}

/* ELF-specific function bindings */

#define ELF_ARCH							bfd_arch_logisimna16
#define ELF_MACHINE_CODE					EM_LOGISIMNA16
//#define ELF_MACHINE_ALT1
#define ELF_MAXPAGESIZE						0x1

#define TARGET_LITTLE_SYM					logisimna16_elf32_vec
#define TARGET_LITTLE_NAME					"elf32-logisimna16"

#define elf_info_to_howto					\
					elf_logisimna16_info_to_howto
#define elf_info_to_howto_rel		NULL
#define elf_symbol_leading_char		'_'

#define elf_backend_can_gc_sections 1

#define bfd_elf32_bfd_reloc_type_lookup  \
					logisimna16_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup  \
					logisimna16_reloc_name_lookup
/*

#define elf_backend_relocate_section \
#define elf_backend_gc_mark_hook  \
#define .. etc, all elf_backend funcs and defines are left undefined to be
	set to the fallback funcs.
*/

>>> EOF

>>> bfd/cpu-logisimna16.c:

const bfd_arch_info_type bfd_logisimna16_arch = {
	16,
	16,
	8,
	bfd_arch_logisimna16,
	bfd_mach_logisimna16,
	"logisimna16",
	"logisimna16",
	1,
	TRUE,
	bfd_default_compatible,
	bfd_default_scan,
	bfd_arch_default_fill,
	0
};

>>> EOF

>>> include/elf/logisimna16.h

#ifndef ELF_LOGISIMNA16_H
#define ELF_LOGISIMNA16_H

#include "elf/reloc-macros.h"

/* Creating indices for reloc_map_index array.  */
START_RELOC_NUMBERS(elf_logisimna16_reloc_type)
  RELOC_NUMBER (R_LOGISIMNA16_NONE,           0)
  RELOC_NUMBER (R_LOGISIMNA16_NUM16,          1)
  RELOC_NUMBER (R_LOGISIMNA16_IMM16,          2)
END_RELOC_NUMBERS(R_LOGISIMNA16_MAX)
        
#endif /* _ELF_LOGISIMNA16_H */

>>> EOF

The lookup functions in elf32-logisimna16 were taken from the cr16
implementation, with the `cr16` name replaced with my own.

I am unsure as to the mechanism by which relocation entries are produced. I
figured that given the HOWTO's, the assembler would do everything else for me.
However, running this code in GDB showed that none of the functions in
elf32-logisimna16.c were called at any point during compilation, or when the
assembler called write_object_file(), despite the evident presence of 
external/unresolved symbols.

I would be very grateful if someone more knowledgeable could shed some light
onto my situation. 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]