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]

Re: Porting Binutils: Relocation entries fail to emit


Maxim Blinov <maxim.a.blinov@gmail.com> writes:
> 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. 

Bit late, so you might have already solved this, sorry, but: a more
direct way of testing those functions would be a gas file like:

       .2byte  myvar

This will still go through the assembler's md_apply_fix and tc_gen_reloc
routines before reaching bfd, but you should be able to start with a
boilerplate implementation of those two routines.

If your functions are being called for that test case but not
for your original one then the problem is likely to be in the assember
rather than bfd.  E.g. the assembly of the "load" instruction might be
not creating a fixup against "myvar".

Thanks,
Richard


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