160526Sobrien/* BFD back-end definitions used by all FreeBSD targets.
2218822Sdim   Copyright 1990, 1991, 1992, 1996, 1997, 2000, 2001, 2002, 2005, 2007
378835Sobrien   Free Software Foundation, Inc.
433965Sjdp
5218822Sdim   This file is part of BFD, the Binary File Descriptor library.
633965Sjdp
7218822Sdim   This program is free software; you can redistribute it and/or modify
8218822Sdim   it under the terms of the GNU General Public License as published by
9218822Sdim   the Free Software Foundation; either version 2 of the License, or
10218822Sdim   (at your option) any later version.
1133965Sjdp
12218822Sdim   This program is distributed in the hope that it will be useful,
13218822Sdim   but WITHOUT ANY WARRANTY; without even the implied warranty of
14218822Sdim   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15218822Sdim   GNU General Public License for more details.
1633965Sjdp
17218822Sdim   You should have received a copy of the GNU General Public License
18218822Sdim   along with this program; if not, write to the Free Software
19218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
20218822Sdim   USA.  */
2133965Sjdp
2260526Sobrien/* $FreeBSD$ */
2360526Sobrien
2433973Sjdp/* FreeBSD QMAGIC files have the header in the text. */
2533973Sjdp#define	N_HEADER_IN_TEXT(x)	1
2633973Sjdp#define MY_text_includes_header 1
2733965Sjdp
2833973Sjdp#define TEXT_START_ADDR		(TARGET_PAGE_SIZE + 0x20)
2933965Sjdp
3033973Sjdp/*
3133973Sjdp * FreeBSD uses a weird mix of byte orderings for its a_info field.
3233973Sjdp * Its assembler emits NetBSD style object files, with a big-endian
3333973Sjdp * a_info.  Its linker seems to accept either byte ordering, but
3433973Sjdp * emits a little-endian a_info.
3533973Sjdp *
3633973Sjdp * Here, we accept either byte ordering, but always produce
3733973Sjdp * little-endian.
3833973Sjdp *
3933973Sjdp * FIXME - Probably we should always produce the _native_ byte
4033973Sjdp * ordering.  I.e., it should be in the architecture-specific
4160526Sobrien * file, not here.  But in reality, there is no chance
4233973Sjdp * that FreeBSD will ever use a.out in a new port.
4333973Sjdp */
4433965Sjdp
4533965Sjdp#define N_MACHTYPE(exec) \
4633965Sjdp	((enum machine_type) \
4733973Sjdp	 ((freebsd_swap_magic(&(exec).a_info) >> 16) & 0x3ff))
4833965Sjdp#define N_FLAGS(exec) \
4933973Sjdp	((enum machine_type) \
5033973Sjdp	 ((freebsd_swap_magic(&(exec).a_info) >> 26) & 0x3f))
5133965Sjdp
5233965Sjdp#define N_SET_INFO(exec, magic, type, flags) \
5333965Sjdp	((exec).a_info = ((magic) & 0xffff) \
5433965Sjdp	 | (((int)(type) & 0x3ff) << 16) \
5533965Sjdp	 | (((flags) & 0x3f) << 26))
5633965Sjdp#define N_SET_MACHTYPE(exec, machtype) \
5733965Sjdp	((exec).a_info = \
58218822Sdim         ((exec).a_info & 0xfb00ffff) | ((((int) (machtype)) & 0x3ff) << 16))
5933965Sjdp#define N_SET_FLAGS(exec, flags) \
6033965Sjdp	((exec).a_info = \
6133965Sjdp	 ((exec).a_info & 0x03ffffff) | ((flags & 0x03f) << 26))
6233965Sjdp
63218822Sdim#include "sysdep.h"
6433965Sjdp#include "bfd.h"
6533965Sjdp#include "libbfd.h"
6633965Sjdp#include "libaout.h"
6733965Sjdp
6833973Sjdp#define SWAP_MAGIC(ext)			(freebsd_swap_magic(ext))
6933965Sjdp
70218822Sdim#define MY_bfd_final_link MY (bfd_final_link)
71218822Sdim#define MY_write_object_contents MY (write_object_contents)
72218822Sdimstatic bfd_boolean MY (bfd_final_link) (bfd *, struct bfd_link_info *);
73218822Sdimstatic bfd_boolean MY (write_object_contents) (bfd *);
74218822Sdimstatic long freebsd_swap_magic (void *);
7533965Sjdp
7633965Sjdp#include "aout-target.h"
7733965Sjdp
78130566Sobrienstatic bfd_boolean
79218822SdimMY (bfd_final_link) (bfd *abfd, struct bfd_link_info *info)
8033973Sjdp{
8133973Sjdp  obj_aout_subformat (abfd) = q_magic_format;
8233973Sjdp  return NAME(aout,final_link) (abfd, info, MY_final_link_callback);
8333973Sjdp}
8433973Sjdp
8533973Sjdp/* Swap a magic number.  We accept either endian, whichever looks valid. */
8633973Sjdp
8733973Sjdpstatic long
88218822Sdimfreebsd_swap_magic (void *ext)
8933973Sjdp{
9033973Sjdp  long linfo = bfd_getl32(ext);
9133973Sjdp  long binfo = bfd_getb32(ext);
9233973Sjdp  int lmagic = linfo & 0xffff;
9333973Sjdp  int bmagic = binfo & 0xffff;
9433973Sjdp  int lmagic_ok = lmagic == OMAGIC || lmagic == NMAGIC ||
9533973Sjdp    lmagic == ZMAGIC || lmagic == QMAGIC;
9633973Sjdp  int bmagic_ok = bmagic == OMAGIC || bmagic == NMAGIC ||
9733973Sjdp    bmagic == ZMAGIC || bmagic == QMAGIC;
9833973Sjdp
9933973Sjdp  return bmagic_ok && !lmagic_ok ? binfo : linfo;
10033973Sjdp}
10133973Sjdp
10233965Sjdp/* Write an object file.
10333965Sjdp   Section contents have already been written.  We write the
10433965Sjdp   file header, symbols, and relocation.  */
10533965Sjdp
106130566Sobrienstatic bfd_boolean
107218822SdimMY (write_object_contents) (bfd *abfd)
10833965Sjdp{
10933965Sjdp  struct external_exec exec_bytes;
11033965Sjdp  struct internal_exec *execp = exec_hdr (abfd);
11133965Sjdp
11233965Sjdp  obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
11333965Sjdp
11433965Sjdp  /* Magic number, maestro, please!  */
115218822Sdim  switch (bfd_get_arch(abfd))
116218822Sdim    {
117218822Sdim    case bfd_arch_m68k:
118218822Sdim      if (strcmp (abfd->xvec->name, "a.out-m68k4k-netbsd") == 0)
119218822Sdim	N_SET_MACHTYPE (*execp, M_68K4K_NETBSD);
120218822Sdim      else
121218822Sdim	N_SET_MACHTYPE (*execp, M_68K_NETBSD);
122218822Sdim      break;
123218822Sdim    case bfd_arch_sparc:
124218822Sdim      N_SET_MACHTYPE (*execp, M_SPARC_NETBSD);
125218822Sdim      break;
126218822Sdim    case bfd_arch_i386:
127218822Sdim      N_SET_MACHTYPE (*execp, M_386_NETBSD);
128218822Sdim      break;
129218822Sdim    case bfd_arch_ns32k:
130218822Sdim      N_SET_MACHTYPE (*execp, M_532_NETBSD);
131218822Sdim      break;
132218822Sdim    default:
133218822Sdim      N_SET_MACHTYPE (*execp, M_UNKNOWN);
134218822Sdim      break;
135218822Sdim    }
13633965Sjdp
13733965Sjdp  WRITE_HEADERS(abfd, execp);
13833965Sjdp
139130566Sobrien  return TRUE;
14033965Sjdp}
141