he `_bfd_link_add_symbols' routine is responsible for reading all the symbols from the object file and passing the correct information to `_bfd_generic_link_add_one_symbol'. The `_bfd_link_add_symbols' routine should not use `bfd_canonicalize_symtab' to read the symbols. The point of providing this routine is to avoid the overhead of converting the symbols into generic `asymbol' structures. `_bfd_generic_link_add_one_symbol' handles the details of combining common symbols, warning about multiple definitions, and so forth. It takes arguments which describe the symbol to add, notably symbol flags, a section, and an offset. The symbol flags include such things as `BSF_WEAK' or `BSF_INDIRECT'. The section is a section in the object file, or something like `bfd_und_section_ptr' for an undefined symbol or `bfd_com_section_ptr' for a common symbol. If the `_bfd_final_link' routine is also going to need to read the symbol information, the `_bfd_link_add_symbols' routine should save it somewhere attached to the object file BFD. However, the information should only be saved if the `keep_memory' field of the `info' argument is TRUE, so that the `-no-keep-memory' linker switch is effective. The a.out function which adds symbols from an object file is `aout_link_add_object_symbols', and most of the interesting work is in `aout_link_add_symbols'. The latter saves pointers to the hash tables entries created by `_bfd_generic_link_add_one_symbol' indexed by symbol number, so that the `_bfd_final_link' routine does not have to call the hash table lookup routine to locate the entry.  File: bfd.info, Node: Adding symbols from an archive, Prev: Adding symbols from an object file, Up: Adding Symbols to the Hash Table 2.17.2.3 Adding symbols from an archive ....................................... When the `_bfd_link_add_symbols' routine is passed an archive, it must look through the symbols defined by the archive and decide which elements of the archive should be included in the link. For each such element it must call the `add_archive_element' linker callback, and it must add the symbols from the object file to the linker hash table. (The callback may in fact indicate that a replacement BFD should be used, in which case the symbols from that BFD should be added to the linker hash table instead.) In most cases the work of looking through the symbols in the archive should be done by the `_bfd_generic_link_add_archive_symbols' function. This function builds a hash table from the archive symbol table and looks through the list of undefined symbols to see which elements should be included. `_bfd_generic_link_add_archive_symbols' is passed a function to call to make the final decision about adding an archive element to the link and to do the actual work of adding the symbols to the linker hash table. The function passed to `_bfd_generic_link_add_archive_symbols' must read the symbols of the archive element and decide whether the archive element should be included in the link. If the element is to be included, the `add_archive_element' linker callback routine must be called with the element as an argument, and the element's symbols must be added to the linker hash table just as though the element had itself been passed to the `_bfd_link_add_symbols' function. The `add_archive_element' callback has the option to indicate that it would like to replace the element archive with a substitute BFD, in which case it is the symbols of that substitute BFD that must be added to the linker hash table instead. When the a.out `_bfd_link_add_symbols' function receives an archive, it calls `_bfd_generic_link_add_archive_symbols' passing `aout_link_check_archive_element' as the function argument. `aout_link_check_archive_element' calls `aout_link_check_ar_symbols'. If the latter decides to add the element (an element is only added if it provides a real, non-common, definition for a previously undefined or common symbol) it calls the `add_archive_element' callback and then `aout_link_check_archive_element' calls `aout_link_add_symbols' to actually add the symbols to the linker hash table - possibly those of a substitute BFD, if the `add_archive_element' callback avails itself of that option. The ECOFF back end is unusual in that it does not normally call `_bfd_generic_link_add_archive_symbols', because ECOFF archives already contain a hash table of symbols. The ECOFF back end searches the archive itself to avoid the overhead of creating a new hash table.  File: bfd.info, Node: Performing the Final Link, Prev: Adding Symbols to the Hash Table, Up: Linker Functions 2.17.3 Performing the final link -------------------------------- When all the input files have been processed, the linker calls the `_bfd_final_link' entry point of the output BFD. This routine is responsible for producing the final output file, which has several aspects. It must relocate the contents of the input sections and copy the data into the output sections. It must build an output symbol table including any local symbols from the input files and the global symbols from the hash table. When producing relocatable output, it must modify the input relocs and write them into the output file. There may also be object format dependent work to be done. The linker will also call the `write_object_contents' entry point when the BFD is closed. The two entry points must work together in order to produce the correct output file. The details of how this works are inevitably dependent upon the specific object file format. The a.out `_bfd_final_link' routine is `NAME(aout,final_link)'. * Menu: * Information provided by the linker:: * Relocating the section contents:: * Writing the symbol table::  File: bfd.info, Node: Information provided by the linker, Next: Relocating the section contents, Prev: Performing the Final Link, Up: Performing the Final Link 2.17.3.1 Information provided by the linker ........................................... Before the linker calls the `_bfd_final_link' entry point, it sets up some data structures for the function to use. The `input_bfds' field of the `bfd_link_info' structure will point to a list of all the input files included in the link. These files are linked through the `link_next' field of the `bfd' structure. Each section in the output file will have a list of `link_order' structures attached to the `map_head.link_order' field (the `link_order' structure is defined in `bfdlink.h'). These structures describe how to create the contents of the output section in terms of the contents of various input sections, fill constants, and, eventually, other types of information. They also describe relocs that must be created by the BFD backend, but do not correspond to any input file; this is used to support -Ur, which builds constructors while generating a relocatable object file.  File: bfd.info, Node: Relocating the section contents, Next: Writing the symbol table, Prev: Information provided by the linker, Up: Performing the Final Link 2.17.3.2 Relocating the section contents ........................................ The `_bfd_final_link' function should look through the `link_order' structures attached to each section of the output file. Each `link_order' structure should either be handled specially, or it should be passed to the function `_bfd_default_link_order' which will do the right thing (`_bfd_default_link_order' is defined in `linker.c'). For efficiency, a `link_order' of type `bfd_indirect_link_order' whose associated section belongs to a BFD of the same format as the output BFD must be handled specially. This type of `link_order' describes part of an output section in terms of a section belonging to one of the input files. The `_bfd_final_link' function should read the contents of the section and any associated relocs, apply the relocs to the section contents, and write out the modified section contents. If performing a relocatable link, the relocs themselves must also be modified and written out. The functions `_bfd_relocate_contents' and `_bfd_final_link_relocate' provide some general support for performing the actual relocations, notably overflow checking. Their arguments include information about the symbol the relocation is against and a `reloc_howto_type' argument which describes the relocation to perform. These functions are defined in `reloc.c'. The a.out function which handles reading, relocating, and writing section contents is `aout_link_input_section'. The actual relocation is done in `aout_link_input_section_std' and `aout_link_input_section_ext'.  File: bfd.info, Node: Writing the symbol table, Prev: Relocating the section contents, Up: Performing the Final Link 2.17.3.3 Writing the symbol table ................................. The `_bfd_final_link' function must gather all the symbols in the input files and write them out. It must also write out all the symbols in the global hash table. This must be controlled by the `strip' and `discard' fields of the `bfd_link_info' structure. The local symbols of the input files will not have been entered into the linker hash table. The `_bfd_final_link' routine must consider each input file and include the symbols in the output file. It may be convenient to do this when looking through the `link_order' structures, or it may be done by stepping through the `input_bfds' list. The `_bfd_final_link' routine must also traverse the global hash table to gather all the externally visible symbols. It is possible that most of the externally visible symbols may be written out when considering the symbols of each input file, but it is still necessary to traverse the hash table since the linker script may have defined some symbols that are not in any of the input files. The `strip' field of the `bfd_link_info' structure controls which symbols are written out. The possible values are listed in `bfdlink.h'. If the value is `strip_some', then the `keep_hash' field of the `bfd_link_info' structure is a hash table of symbols to keep; each symbol should be looked up in this hash table, and only symbols which are present should be included in the output file. If the `strip' field of the `bfd_link_info' structure permits local symbols to be written out, the `discard' field is used to further controls which local symbols are included in the output file. If the value is `discard_l', then all local symbols which begin with a certain prefix are discarded; this is controlled by the `bfd_is_local_label_name' entry point. The a.out backend handles symbols by calling `aout_link_write_symbols' on each input BFD and then traversing the global hash table with the function `aout_link_write_other_symbol'. It builds a string table while writing out the symbols, which is written to the output file at the end of `NAME(aout,final_link)'. 2.17.3.4 `bfd_link_split_section' ................................. *Synopsis* bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec); *Description* Return nonzero if SEC should be split during a reloceatable or final link. #define bfd_link_split_section(abfd, sec) \ BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec)) 2.17.3.5 `bfd_section_already_linked' ..................................... *Synopsis* void bfd_section_already_linked (bfd *abfd, asection *sec, struct bfd_link_info *info); *Description* Check if SEC has been already linked during a reloceatable or final link. #define bfd_section_already_linked(abfd, sec, info) \ BFD_SEND (abfd, _section_already_linked, (abfd, sec, info)) 2.17.3.6 `bfd_generic_define_common_symbol' ........................................... *Synopsis* bfd_boolean bfd_generic_define_common_symbol (bfd *output_bfd, struct bfd_link_info *info, struct bfd_link_hash_entry *h); *Description* Convert common symbol H into a defined symbol. Return TRUE on success and FALSE on failure. #define bfd_define_common_symbol(output_bfd, info, h) \ BFD_SEND (output_bfd, _bfd_define_common_symbol, (output_bfd, info, h)) 2.17.3.7 `bfd_find_version_for_sym ' .................................... *Synopsis* struct bfd_elf_version_tree * bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs, const char *sym_name, bfd_boolean *hide); *Description* Search an elf version script tree for symbol versioning info and export / don't-export status for a given symbol. Return non-NULL on success and NULL on failure; also sets the output `hide' boolean parameter.  File: bfd.info, Node: Hash Tables, Prev: Linker Functions, Up: BFD front end 2.18 Hash Tables ================ BFD provides a simple set of hash table functions. Routines are provided to initialize a hash table, to free a hash table, to look up a string in a hash table and optionally create an entry for it, and to traverse a hash table. There is currently no routine to delete an string from a hash table. The basic hash table does not permit any data to be stored with a string. However, a hash table is designed to present a base class from which other types of hash tables may be derived. These derived types may store additional information with the string. Hash tables were implemented in this way, rather than simply providing a data pointer in a hash table entry, because they were designed for use by the linker back ends. The linker may create thousands of hash table entries, and the overhead of allocating private data and storing and following pointers becomes noticeable. The basic hash table code is in `hash.c'. * Menu: * Creating and Freeing a Hash Table:: * Looking Up or Entering a String:: * Traversing a Hash Table:: * Deriving a New Hash Table Type::  File: bfd.info, Node: Creating and Freeing a Hash Table, Next: Looking Up or Entering a String, Prev: Hash Tables, Up: Hash Tables 2.18.1 Creating and freeing a hash table ---------------------------------------- To create a hash table, create an instance of a `struct bfd_hash_table' (defined in `bfd.h') and call `bfd_hash_table_init' (if you know approximately how many entries you will need, the function `bfd_hash_table_init_n', which takes a SIZE argument, may be used). `bfd_hash_table_init' returns `FALSE' if some sort of error occurs. The function `bfd_hash_table_init' take as an argument a function to use to create new entries. For a basic hash table, use the function `bfd_hash_newfunc'. *Note Deriving a New Hash Table Type::, for why you would want to use a different value for this argument. `bfd_hash_table_init' will create an objalloc which will be used to allocate new entries. You may allocate memory on this objalloc using `bfd_hash_allocate'. Use `bfd_hash_table_free' to free up all the memory that has been allocated for a hash table. This will not free up the `struct bfd_hash_table' itself, which you must provide. Use `bfd_hash_set_default_size' to set the default size of hash table to use.  File: bfd.info, Node: Looking Up or Entering a String, Next: Traversing a Hash Table, Prev: Creating and Freeing a Hash Table, Up: Hash Tables 2.18.2 Looking up or entering a string -------------------------------------- The function `bfd_hash_lookup' is used both to look up a string in the hash table and to create a new entry. If the CREATE argument is `FALSE', `bfd_hash_lookup' will look up a string. If the string is found, it will returns a pointer to a `struct bfd_hash_entry'. If the string is not found in the table `bfd_hash_lookup' will return `NULL'. You should not modify any of the fields in the returns `struct bfd_hash_entry'. If the CREATE argument is `TRUE', the string will be entered into the hash table if it is not already there. Either way a pointer to a `struct bfd_hash_entry' will be returned, either to the existing structure or to a newly created one. In this case, a `NULL' return means that an error occurred. If the CREATE argument is `TRUE', and a new entry is created, the COPY argument is used to decide whether to copy the string onto the hash table objalloc or not. If COPY is passed as `FALSE', you must be careful not to deallocate or modify the string as long as the hash table exists.  File: bfd.info, Node: Traversing a Hash Table, Next: Deriving a New Hash Table Type, Prev: Looking Up or Entering a String, Up: Hash Tables 2.18.3 Traversing a hash table ------------------------------ The function `bfd_hash_traverse' may be used to traverse a hash table, calling a function on each element. The traversal is done in a random order. `bfd_hash_traverse' takes as arguments a function and a generic `void *' pointer. The function is called with a hash table entry (a `struct bfd_hash_entry *') and the generic pointer passed to `bfd_hash_traverse'. The function must return a `boolean' value, which indicates whether to continue traversing the hash table. If the function returns `FALSE', `bfd_hash_traverse' will stop the traversal and return immediately.  File: bfd.info, Node: Deriving a New Hash Table Type, Prev: Traversing a Hash Table, Up: Hash Tables 2.18.4 Deriving a new hash table type ------------------------------------- Many uses of hash tables want to store additional information which each entry in the hash table. Some also find it convenient to store additional information with the hash table itself. This may be done using a derived hash table. Since C is not an object oriented language, creating a derived hash table requires sticking together some boilerplate routines with a few differences specific to the type of hash table you want to create. An example of a derived hash table is the linker hash table. The structures for this are defined in `bfdlink.h'. The functions are in `linker.c'. You may also derive a hash table from an already derived hash table. For example, the a.out linker backend code uses a hash table derived from the linker hash table. * Menu: * Define the Derived Structures:: * Write the Derived Creation Routine:: * Write Other Derived Routines::  File: bfd.info, Node: Define the Derived Structures, Next: Write the Derived Creation Routine, Prev: Deriving a New Hash Table Type, Up: Deriving a New Hash Table Type 2.18.4.1 Define the derived structures ...................................... You must define a structure for an entry in the hash table, and a structure for the hash table itself. The first field in the structure for an entry in the hash table must be of the type used for an entry in the hash table you are deriving from. If you are deriving from a basic hash table this is `struct bfd_hash_entry', which is defined in `bfd.h'. The first field in the structure for the hash table itself must be of the type of the hash table you are deriving from itself. If you are deriving from a basic hash table, this is `struct bfd_hash_table'. For example, the linker hash table defines `struct bfd_link_hash_entry' (in `bfdlink.h'). The first field, `root', is of type `struct bfd_hash_entry'. Similarly, the first field in `struct bfd_link_hash_table', `table', is of type `struct bfd_hash_table'.  File: bfd.info, Node: Write the Derived Creation Routine, Next: Write Other Derived Routines, Prev: Define the Derived Structures, Up: Deriving a New Hash Table Type 2.18.4.2 Write the derived creation routine ........................................... You must write a routine which will create and initialize an entry in the hash table. This routine is passed as the function argument to `bfd_hash_table_init'. In order to permit other hash tables to be derived from the hash table you are creating, this routine must be written in a standard way. The first argument to the creation routine is a pointer to a hash table entry. This may be `NULL', in which case the routine should allocate the right amount of space. Otherwise the space has already been allocated by a hash table type derived from this one. After allocating space, the creation routine must call the creation routine of the hash table type it is derived from, passing in a pointer to the space it just allocated. This will initialize any fields used by the base hash table. Finally the creation routine must initialize any local fields for the new hash table type. Here is a boilerplate example of a creation routine. FUNCTION_NAME is the name of the routine. ENTRY_TYPE is the type of an entry in the hash table you are creating. BASE_NEWFUNC is the name of the creation routine of the hash table type your hash table is derived from. struct bfd_hash_entry * FUNCTION_NAME (struct bfd_hash_entry *entry, struct bfd_hash_table *table, const char *string) { struct ENTRY_TYPE *ret = (ENTRY_TYPE *) entry; /* Allocate the structure if it has not already been allocated by a derived class. */ if (ret == NULL) { ret = bfd_hash_allocate (table, sizeof (* ret)); if (ret == NULL) return NULL; } /* Call the allocation method of the base class. */ ret = ((ENTRY_TYPE *) BASE_NEWFUNC ((struct bfd_hash_entry *) ret, table, string)); /* Initialize the local fields here. */ return (struct bfd_hash_entry *) ret; } *Description* The creation routine for the linker hash table, which is in `linker.c', looks just like this example. FUNCTION_NAME is `_bfd_link_hash_newfunc'. ENTRY_TYPE is `struct bfd_link_hash_entry'. BASE_NEWFUNC is `bfd_hash_newfunc', the creation routine for a basic hash table. `_bfd_link_hash_newfunc' also initializes the local fields in a linker hash table entry: `type', `written' and `next'.  File: bfd.info, Node: Write Other Derived Routines, Prev: Write the Derived Creation Routine, Up: Deriving a New Hash Table Type 2.18.4.3 Write other derived routines ..................................... You will want to write other routines for your new hash table, as well. You will want an initialization routine which calls the initialization routine of the hash table you are deriving from and initializes any other local fields. For the linker hash table, this is `_bfd_link_hash_table_init' in `linker.c'. You will want a lookup routine which calls the lookup routine of the hash table you are deriving from and casts the result. The linker hash table uses `bfd_link_hash_lookup' in `linker.c' (this actually takes an additional argument which it uses to decide how to return the looked up value). You may want a traversal routine. This should just call the traversal routine of the hash table you are deriving from with appropriate casts. The linker hash table uses `bfd_link_hash_traverse' in `linker.c'. These routines may simply be defined as macros. For example, the a.out backend linker hash table, which is derived from the linker hash table, uses macros for the lookup and traversal routines. These are `aout_link_hash_lookup' and `aout_link_hash_traverse' in aoutx.h.  File: bfd.info, Node: BFD back ends, Next: GNU Free Documentation License, Prev: BFD front end, Up: Top 3 BFD back ends *************** * Menu: * What to Put Where:: * aout :: a.out backends * coff :: coff backends * elf :: elf backends * mmo :: mmo backend  File: bfd.info, Node: What to Put Where, Next: aout, Prev: BFD back ends, Up: BFD back ends 3.1 What to Put Where ===================== All of BFD lives in one directory.  File: bfd.info, Node: aout, Next: coff, Prev: What to Put Where, Up: BFD back ends 3.2 a.out backends ================== *Description* BFD supports a number of different flavours of a.out format, though the major differences are only the sizes of the structures on disk, and the shape of the relocation information. The support is split into a basic support file `aoutx.h' and other files which derive functions from the base. One derivation file is `aoutf1.h' (for a.out flavour 1), and adds to the basic a.out functions support for sun3, sun4, 386 and 29k a.out files, to create a target jump vector for a specific target. This information is further split out into more specific files for each machine, including `sunos.c' for sun3 and sun4, `newsos3.c' for the Sony NEWS, and `demo64.c' for a demonstration of a 64 bit a.out format. The base file `aoutx.h' defines general mechanisms for reading and writing records to and from disk and various other methods which BFD requires. It is included by `aout32.c' and `aout64.c' to form the names `aout_32_swap_exec_header_in', `aout_64_swap_exec_header_in', etc. As an example, this is what goes on to make the back end for a sun4, from `aout32.c': #define ARCH_SIZE 32 #include "aoutx.h" Which exports names: ... aout_32_canonicalize_reloc aout_32_find_nearest_line aout_32_get_lineno aout_32_get_reloc_upper_bound ... from `sunos.c': #define TARGET_NAME "a.out-sunos-big" #define VECNAME sunos_big_vec #include "aoutf1.h" requires all the names from `aout32.c', and produces the jump vector sunos_big_vec The file `host-aout.c' is a special case. It is for a large set of hosts that use "more or less standard" a.out files, and for which cross-debugging is not interesting. It uses the standard 32-bit a.out support routines, but determines the file offsets and addresses of the text, data, and BSS sections, the machine architecture and machine type, and the entry point address, in a host-dependent manner. Once these values have been determined, generic code is used to handle the object file. When porting it to run on a new system, you must supply: HOST_PAGE_SIZE HOST_SEGMENT_SIZE HOST_MACHINE_ARCH (optional) HOST_MACHINE_MACHINE (optional) HOST_TEXT_START_ADDR HOST_STACK_END_ADDR in the file `../include/sys/h-XXX.h' (for your host). These values, plus the structures and macros defined in `a.out.h' on your host system, will produce a BFD target that will access ordinary a.out files on your host. To configure a new machine to use `host-aout.c', specify: TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec TDEPFILES= host-aout.o trad-core.o in the `config/XXX.mt' file, and modify `configure.in' to use the `XXX.mt' file (by setting "`bfd_target=XXX'") when your configuration is selected. 3.2.1 Relocations ----------------- *Description* The file `aoutx.h' provides for both the _standard_ and _extended_ forms of a.out relocation records. The standard records contain only an address, a symbol index, and a type field. The extended records (used on 29ks and sparcs) also have a full integer for an addend. 3.2.2 Internal entry points --------------------------- *Description* `aoutx.h' exports several routines for accessing the contents of an a.out file, which are gathered and exported in turn by various format specific files (eg sunos.c). 3.2.2.1 `aout_SIZE_swap_exec_header_in' ....................................... *Synopsis* void aout_SIZE_swap_exec_header_in, (bfd *abfd, struct external_exec *bytes, struct internal_exec *execp); *Description* Swap the information in an executable header RAW_BYTES taken from a raw byte stream memory image into the internal exec header structure EXECP. 3.2.2.2 `aout_SIZE_swap_exec_header_out' ........................................ *Synopsis* void aout_SIZE_swap_exec_header_out (bfd *abfd, struct internal_exec *execp, struct external_exec *raw_bytes); *Description* Swap the information in an internal exec header structure EXECP into the buffer RAW_BYTES ready for writing to disk. 3.2.2.3 `aout_SIZE_some_aout_object_p' ...................................... *Synopsis* const bfd_target *aout_SIZE_some_aout_object_p (bfd *abfd, struct internal_exec *execp, const bfd_target *(*callback_to_real_object_p) (bfd *)); *Description* Some a.out variant thinks that the file open in ABFD checking is an a.out file. Do some more checking, and set up for access if it really is. Call back to the calling environment's "finish up" function just before returning, to handle any last-minute setup. 3.2.2.4 `aout_SIZE_mkobject' ............................ *Synopsis* bfd_boolean aout_SIZE_mkobject, (bfd *abfd); *Description* Initialize BFD ABFD for use with a.out files. 3.2.2.5 `aout_SIZE_machine_type' ................................ *Synopsis* enum machine_type aout_SIZE_machine_type (enum bfd_architecture arch, unsigned long machine, bfd_boolean *unknown); *Description* Keep track of machine architecture and machine type for a.out's. Return the `machine_type' for a particular architecture and machine, or `M_UNKNOWN' if that exact architecture and machine can't be represented in a.out format. If the architecture is understood, machine type 0 (default) is always understood. 3.2.2.6 `aout_SIZE_set_arch_mach' ................................. *Synopsis* bfd_boolean aout_SIZE_set_arch_mach, (bfd *, enum bfd_architecture arch, unsigned long machine); *Description* Set the architecture and the machine of the BFD ABFD to the values ARCH and MACHINE. Verify that ABFD's format can support the architecture required. 3.2.2.7 `aout_SIZE_new_section_hook' .................................... *Synopsis* bfd_boolean aout_SIZE_new_section_hook, (bfd *abfd, asection *newsect); *Description* Called by the BFD in response to a `bfd_make_section' request.  File: bfd.info, Node: coff, Next: elf, Prev: aout, Up: BFD back ends 3.3 coff backends ================= BFD supports a number of different flavours of coff format. The major differences between formats are the sizes and alignments of fields in structures on disk, and the occasional extra field. Coff in all its varieties is implemented with a few common files and a number of implementation specific files. For example, The 88k bcs coff format is implemented in the file `coff-m88k.c'. This file `#include's `coff/m88k.h' which defines the external structure of the coff format for the 88k, and `coff/internal.h' which defines the internal structure. `coff-m88k.c' also defines the relocations used by the 88k format *Note Relocations::. The Intel i960 processor version of coff is implemented in `coff-i960.c'. This file has the same structure as `coff-m88k.c', except that it includes `coff/i960.h' rather than `coff-m88k.h'. 3.3.1 Porting to a new version of coff -------------------------------------- The recommended method is to select from the existing implementations the version of coff which is most like the one you want to use. For example, we'll say that i386 coff is the one you select, and that your coff flavour is called foo. Copy `i386coff.c' to `foocoff.c', copy `../include/coff/i386.h' to `../include/coff/foo.h', and add the lines to `targets.c' and `Makefile.in' so that your new back end is used. Alter the shapes of the structures in `../include/coff/foo.h' so that they match what you need. You will probably also have to add `#ifdef's to the code in `coff/internal.h' and `coffcode.h' if your version of coff is too wild. You can verify that your new BFD backend works quite simply by building `objdump' from the `binutils' directory, and making sure that its version of what's going on and your host system's idea (assuming it has the pretty standard coff dump utility, usually called `att-dump' or just `dump') are the same. Then clean up your code, and send what you've done to Cygnus. Then your stuff will be in the next release, and you won't have to keep integrating it. 3.3.2 How the coff backend works -------------------------------- 3.3.2.1 File layout ................... The Coff backend is split into generic routines that are applicable to any Coff target and routines that are specific to a particular target. The target-specific routines are further split into ones which are basically the same for all Coff targets except that they use the external symbol format or use different values for certain constants. The generic routines are in `coffgen.c'. These routines work for any Coff target. They use some hooks into the target specific code; the hooks are in a `bfd_coff_backend_data' structure, one of which exists for each target. The essentially similar target-specific routines are in `coffcode.h'. This header file includes executable C code. The various Coff targets first include the appropriate Coff header file, make any special defines that are needed, and then include `coffcode.h'. Some of the Coff targets then also have additional routines in the target source file itself. For example, `coff-i960.c' includes `coff/internal.h' and `coff/i960.h'. It then defines a few constants, such as `I960', and includes `coffcode.h'. Since the i960 has complex relocation types, `coff-i960.c' also includes some code to manipulate the i960 relocs. This code is not in `coffcode.h' because it would not be used by any other target. 3.3.2.2 Coff long section names ............................... In the standard Coff object format, section names are limited to the eight bytes available in the `s_name' field of the `SCNHDR' section header structure. The format requires the field to be NUL-padded, but not necessarily NUL-terminated, so the longest section names permitted are a full eight characters. The Microsoft PE variants of the Coff object file format add an extension to support the use of long section names. This extension is defined in section 4 of the Microsoft PE/COFF specification (rev 8.1). If a section name is too long to fit into the section header's `s_name' field, it is instead placed into the string table, and the `s_name' field is filled with a slash ("/") followed by the ASCII decimal representation of the offset of the full name relative to the string table base. Note that this implies that the extension can only be used in object files, as executables do not contain a string table. The standard specifies that long section names from objects emitted into executable images are to be truncated. However, as a GNU extension, BFD can generate executable images that contain a string table and long section names. This would appear to be technically valid, as the standard only says that Coff debugging information is deprecated, not forbidden, and in practice it works, although some tools that parse PE files expecting the MS standard format may become confused; `PEview' is one known example. The functionality is supported in BFD by code implemented under the control of the macro `COFF_LONG_SECTION_NAMES'. If not defined, the format does not support long section names in any way. If defined, it is used to initialise a flag, `_bfd_coff_long_section_names', and a hook function pointer, `_bfd_coff_set_long_section_names', in the Coff backend data structure. The flag controls the generation of long section names in output BFDs at runtime; if it is false, as it will be by default when generating an executable image, long section names are truncated; if true, the long section names extension is employed. The hook points to a function that allows the value of the flag to be altered at runtime, on formats that support long section names at all; on other formats it points to a stub that returns an error indication. With input BFDs, the flag is set according to whether any long section names are detected while reading the section headers. For a completely new BFD, the flag is set to the default for the target format. This information can be used by a client of the BFD library when deciding what output format to generate, and means that a BFD that is opened for read and subsequently converted to a writeable BFD and modified in-place will retain whatever format it had on input. If `COFF_LONG_SECTION_NAMES' is simply defined (blank), or is defined to the value "1", then long section names are enabled by default; if it is defined to the value zero, they are disabled by default (but still accepted in input BFDs). The header `coffcode.h' defines a macro, `COFF_DEFAULT_LONG_SECTION_NAMES', which is used in the backends to initialise the backend data structure fields appropriately; see the comments for further detail. 3.3.2.3 Bit twiddling ..................... Each flavour of coff supported in BFD has its own header file describing the external layout of the structures. There is also an internal description of the coff layout, in `coff/internal.h'. A major function of the coff backend is swapping the bytes and twiddling the bits to translate the external form of the structures into the normal internal form. This is all performed in the `bfd_swap'_thing_direction routines. Some elements are different sizes between different versions of coff; it is the duty of the coff version specific include file to override the definitions of various packing routines in `coffcode.h'. E.g., the size of line number entry in coff is sometimes 16 bits, and sometimes 32 bits. `#define'ing `PUT_LNSZ_LNNO' and `GET_LNSZ_LNNO' will select the correct one. No doubt, some day someone will find a version of coff which has a varying field size not catered to at the moment. To port BFD, that person will have to add more `#defines'. Three of the bit twiddling routines are exported to `gdb'; `coff_swap_aux_in', `coff_swap_sym_in' and `coff_swap_lineno_in'. `GDB' reads the symbol table on its own, but uses BFD to fix things up. More of the bit twiddlers are exported for `gas'; `coff_swap_aux_out', `coff_swap_sym_out', `coff_swap_lineno_out', `coff_swap_reloc_out', `coff_swap_filehdr_out', `coff_swap_aouthdr_out', `coff_swap_scnhdr_out'. `Gas' currently keeps track of all the symbol table and reloc drudgery itself, thereby saving the internal BFD overhead, but uses BFD to swap things on the way out, making cross ports much safer. Doing so also allows BFD (and thus the linker) to use the same header files as `gas', which makes one avenue to disaster disappear. 3.3.2.4 Symbol reading ...................... The simple canonical form for symbols used by BFD is not rich enough to keep all the information available in a coff symbol table. The back end gets around this problem by keeping the original symbol table around, "behind the scenes". When a symbol table is requested (through a call to `bfd_canonicalize_symtab'), a request gets through to `coff_get_normalized_symtab'. This reads the symbol table from the coff file and swaps all the structures inside into the internal form. It also fixes up all the pointers in the table (represented in the file by offsets from the first symbol in the table) into physical pointers to elements in the new internal table. This involves some work since the meanings of fields change depending upon context: a field that is a pointer to another structure in the symbol table at one moment may be the size in bytes of a structure at the next. Another pass is made over the table. All symbols which mark file names (`C_FILE' symbols) are modified so that the internal string points to the value in the auxent (the real filename) rather than the normal text associated with the symbol (`".file"'). At this time the symbol names are moved around. Coff stores all symbols less than nine characters long physically within the symbol table; longer strings are kept at the end of the file in the string table. This pass moves all strings into memory and replaces them with pointers to the strings. The symbol table is massaged once again, this time to create the canonical table used by the BFD application. Each symbol is inspected in turn, and a decision made (using the `sclass' field) about the various flags to set in the `asymbol'. *Note Symbols::. The generated canonical table shares strings with the hidden internal symbol table. Any linenumbers are read from the coff file too, and attached to the symbols which own the functions the linenumbers belong to. 3.3.2.5 Symbol writing ...................... Writing a symbol to a coff file which didn't come from a coff file will lose any debugging information. The `asymbol' structure remembers the BFD from which the symbol was taken, and on output the back end makes sure that the same destination target as source target is present. When the symbols have come from a coff file then all the debugging information is preserved. Symbol tables are provided for writing to the back end in a vector of pointers to pointers. This allows applications like the linker to accumulate and output large symbol tables without having to do too much byte copying. This function runs through the provided symbol table and patches each symbol marked as a file place holder (`C_FILE') to point to the next file place holder in the list. It also marks each `offset' field in the list with the offset from the first symbol of the current symbol. Another function of this procedure is to turn the canonical value form of BFD into the form used by coff. Internally, BFD expects symbol values to be offsets from a section base; so a symbol physically at 0x120, but in a section starting at 0x100, would have the value 0x20. Coff expects symbols to contain their final value, so symbols have their values changed at this point to reflect their sum with their owning section. This transformation uses the `output_section' field of the `asymbol''s `asection' *Note Sections::. * `coff_mangle_symbols' This routine runs though the provided symbol table and uses the offsets generated by the previous pass and the pointers generated when the symbol table was read in to create the structured hierarchy required by coff. It changes each pointer to a symbol into the index into the symbol table of the asymbol. * `coff_write_symbols' This routine runs through the symbol table and patches up the symbols from their internal form into the coff way, calls the bit twiddlers, and writes out the table to the file. 3.3.2.6 `coff_symbol_type' .......................... *Description* The hidden information for an `asymbol' is described in a `combined_entry_type': typedef struct coff_ptr_struct { /* Remembers the offset from the first symbol in the file for this symbol. Generated by coff_renumber_symbols. */ unsigned int offset; /* Should the value of this symbol be renumbered. Used for XCOFF C_BSTAT symbols. Set by coff_slurp_symbol_table. */ unsigned int fix_value : 1; /* Should the tag field of this symbol be renumbered. Created by coff_pointerize_aux. */ unsigned int fix_tag : 1; /* Should the endidx field of this symbol be renumbered. Created by coff_pointerize_aux. */ unsigned int fix_end : 1; /* Should the x_csect.x_scnlen field be renumbered. Created by coff_pointerize_aux. */ unsigned int fix_scnlen : 1; /* Fix up an XCOFF C_BINCL/C_EINCL symbol. The value is the index into the line number entries. Set by coff_slurp_symbol_table. */ unsigned int fix_line : 1; /* The container for the symbol structure as read and translated from the file. */ union { union internal_auxent auxent; struct internal_syment syment; } u; } combined_entry_type; /* Each canonical asymbol really looks like this: */ typedef struct coff_symbol_struct { /* The actual symbol which the rest of BFD works with */ asymbol symbol; /* A pointer to the hidden information for this symbol */ combined_entry_type *native; /* A pointer to the linenumber information for this symbol */ struct lineno_cache_entry *lineno; /* Have the line numbers been relocated yet ? */ bfd_boolean done_lineno; } coff_symbol_type; 3.3.2.7 `bfd_coff_backend_data' ............................... /* COFF symbol classifications. */ enum coff_symbol_classification { /* Global symbol. */ COFF_SYMBOL_GLOBAL, /* Common symbol. */ COFF_SYMBOL_COMMON, /* Undefined symbol. */ COFF_SYMBOL_UNDEFINED, /* Local symbol. */ COFF_SYMBOL_LOCAL, /* PE section symbol. */ COFF_SYMBOL_PE_SECTION }; Special entry points for gdb to swap in coff symbol table parts: typedef struct { void (*_bfd_coff_swap_aux_in) (bfd *, void *, int, int, int, int, void *); void (*_bfd_coff_swap_sym_in) (bfd *, void *, void *); void (*_bfd_coff_swap_lineno_in) (bfd *, void *, void *); unsigned int (*_bfd_coff_swap_aux_out) (bfd *, void *, int, int, int, int, void *); unsigned int (*_bfd_coff_swap_sym_out) (bfd *, void *, void *); unsigned int (*_bfd_coff_swap_lineno_out) (bfd *, void *, void *); unsigned int (*_bfd_coff_swap_reloc_out) (bfd *, void *, void *); unsigned int (*_bfd_coff_swap_filehdr_out) (bfd *, void *, void *); unsigned int (*_bfd_coff_swap_aouthdr_out) (bfd *, void *, void *); unsigned int (*_bfd_coff_swap_scnhdr_out) (bfd *, void *, void *); unsigned int _bfd_filhsz; unsigned int _bfd_aoutsz; unsigned int _bfd_scnhsz; unsigned int _bfd_symesz; unsigned int _bfd_auxesz; unsigned int _bfd_relsz; unsigned int _bfd_linesz; unsigned int _bfd_filnmlen; bfd_boolean _bfd_coff_long_filenames; bfd_boolean _bfd_coff_long_section_names; bfd_boolean (*_bfd_coff_set_long_section_names) (bfd *, int); unsigned int _bfd_coff_default_section_alignment_power; bfd_boolean _bfd_coff_force_symnames_in_strings; unsigned int _bfd_coff_debug_string_prefix_length; void (*_bfd_coff_swap_filehdr_in) (bfd *, void *, void *); void (*_bfd_coff_swap_aouthdr_in) (bfd *, void *, void *); void (*_bfd_coff_swap_scnhdr_in) (bfd *, void *, void *); void (*_bfd_coff_swap_reloc_in) (bfd *abfd, void *, void *); bfd_boolean (*_bfd_coff_bad_format_hook) (bfd *, void *); bfd_boolean (*_bfd_coff_set_arch_mach_hook) (bfd *, void *); void * (*_bfd_coff_mkobject_hook) (bfd *, void *, void *); bfd_boolean (*_bfd_styp_to_sec_flags_hook) (bfd *, void *, const char *, asection *, flagword *); void (*_bfd_set_alignment_hook) (bfd *, asection *, void *); bfd_boolean (*_bfd_coff_slurp_symbol_table) (bfd *); bfd_boolean (*_bfd_coff_symname_in_debug) (bfd *, struct internal_syment *); bfd_boolean (*_bfd_coff_pointerize_aux_hook) (bfd *, combined_entry_type *, combined_entry_type *, unsigned int, combined_entry_type *); bfd_boolean (*_bfd_coff_print_aux) (bfd *, FILE *, combined_entry_type *, combined_entry_type *, combined_entry_type *, unsigned int); void (*_bfd_coff_reloc16_extra_cases) (bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *, bfd_byte *, unsigned int *, unsigned int *); int (*_bfd_coff_reloc16_estimate) (bfd *, asection *, arelent *, unsigned int, struct bfd_link_info *); enum coff_symbol_classification (*_bfd_coff_classify_symbol) (bfd *, struct internal_syment *); bfd_boolean (*_bfd_coff_compute_section_file_positions) (bfd *); bfd_boolean (*_bfd_coff_start_final_link) (bfd *, struct bfd_link_info *); bfd_boolean (*_bfd_coff_relocate_section) (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, struct internal_reloc *, struct internal_syment *, asection **); reloc_howto_type *(*_bfd_coff_rtype_to_howto) (bfd *, asection *, struct internal_reloc *, struct coff_link_hash_entry *, struct internal_syment *, bfd_vma *); bfd_boolean (*_bfd_coff_adjust_symndx) (bfd *, struct bfd_link_info *, bfd *, asection *, struct internal_reloc *, bfd_boolean *); bfd_boolean (*_bfd_coff_link_add_one_symbol) (struct bfd_link_info *, bfd *, const char *, flagword, asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean, struct bfd_link_hash_entry **); bfd_boolean (*_bfd_coff_link_output_has_begun) (bfd *, struct coff_final_link_info *); bfd_boolean (*_bfd_coff_final_link_postscript) (bfd *, struct coff_final_link_info *); bfd_boolean (*_bfd_coff_print_pdata) (bfd *, void *); } bfd_coff_backend_data; #define coff_backend_info(abfd) \ ((bfd_coff_backend_data *) (abfd)->xvec->backend_data) #define bfd_coff_swap_aux_in(a,e,t,c,ind,num,i) \ ((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,ind,num,i)) #define bfd_coff_swap_sym_in(a,e,i) \ ((coff_backend_info (a)->_bfd_coff_swap_sym_in) (a,e,i)) #define bfd_coff_swap_lineno_in(a,e,i) \ ((coff_backend_info ( a)->_bfd_coff_swap_lineno_in) (a,e,i)) #define bfd_coff_swap_reloc_out(abfd, i, o) \ ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_out) (abfd, i, o)) #define bfd_coff_swap_lineno_out(abfd, i, o) \ ((coff_backend_info (abfd)->_bfd_coff_swap_lineno_out) (abfd, i, o)) #define bfd_coff_swap_aux_out(a,i,t,c,ind,num,o) \ ((coff_backend_info (a)->_bfd_coff_swap_aux_out) (a,i,t,c,ind,num,o)) #define bfd_coff_swap_sym_out(abfd, i,o) \ ((coff_backend_info (abfd)->_bfd_coff_swap_sym_out) (abfd, i, o)) #define bfd_coff_swap_scnhdr_out(abfd, i,o) \ ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_out) (abfd, i, o)) #define bfd_coff_swap_filehdr_out(abfd, i,o) \ ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_out) (abfd, i, o)) #define bfd_coff_swap_aouthdr_out(abfd, i,o) \ ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_out) (abfd, i, o)) #define bfd_coff_filhsz(abfd) (coff_backend_info (abfd)->_bfd_filhsz) #define bfd_coff_aoutsz(abfd) (coff_backend_info (abfd)->_bfd_aoutsz) #define bfd_coff_scnhsz(abfd) (coff_backend_info (abfd)->_bfd_scnhsz) #define bfd_coff_symesz(abfd) (coff_backend_info (abfd)->_bfd_symesz) #define bfd_coff_auxesz(abfd) (coff_backend_info (abfd)->_bfd_auxesz) #define bfd_coff_relsz(abfd) (coff_backend_info (abfd)->_bfd_relsz) #define bfd_coff_linesz(abfd) (coff_backend_info (abfd)->_bfd_linesz) #define bfd_coff_filnmlen(abfd) (coff_backend_info (abfd)->_bfd_filnmlen) #define bfd_coff_long_filenames(abfd) \ (coff_backend_info (abfd)->_bfd_coff_long_filenames) #define bfd_coff_long_section_names(abfd) \ (coff_backend_info (abfd)->_bfd_coff_long_section_names) #define bfd_coff_set_long_section_names(abfd, enable) \ ((coff_backend_info (abfd)->_bfd_coff_set_long_section_names) (abfd, enable)) #define bfd_coff_default_section_alignment_power(abfd) \ (coff_backend_info (abfd)->_bfd_coff_default_section_alignment_power) #define bfd_coff_swap_filehdr_in(abfd, i,o) \ ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o)) #define bfd_coff_swap_aouthdr_in(abfd, i,o) \ ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_in) (abfd, i, o)) #define bfd_coff_swap_scnhdr_in(abfd, i,o) \ ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_in) (abfd, i, o)) #define bfd_coff_swap_reloc_in(abfd, i, o) \ ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_in) (abfd, i, o)) #define bfd_coff_bad_format_hook(abfd, filehdr) \ ((coff_backend_info (abfd)->_bfd_coff_bad_format_hook) (abfd, filehdr)) #define bfd_coff_set_arch_mach_hook(abfd, filehdr)\ ((coff_backend_info (abfd)->_bfd_coff_set_arch_mach_hook) (abfd, filehdr)) #define bfd_coff_mkobject_hook(abfd, filehdr, aouthdr)\ ((coff_backend_info (abfd)->_bfd_coff_mkobject_hook)\ (abfd, filehdr, aouthdr)) #define bfd_coff_styp_to_sec_flags_hook(abfd, scnhdr, name, section, flags_ptr)\ ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook)\ (abfd, scnhdr, name, section, flags_ptr)) #define bfd_coff_set_alignment_hook(abfd, sec, scnhdr)\ ((coff_backend_info (abfd)->_bfd_set_alignment_hook) (abfd, sec, scnhdr)) #define bfd_coff_slurp_symbol_table(abfd)\ ((coff_backend_info (abfd)->_bfd_coff_slurp_symbol_table) (abfd)) #define bfd_coff_symname_in_debug(abfd, sym)\ ((coff_backend_info (abfd)->_bfd_coff_symname_in_debug) (abfd, sym)) #define bfd_coff_force_symnames_in_strings(abfd)\ (coff_backend_info (abfd)->_bfd_coff_force_symnames_in_strings) #define bfd_coff_debug_string_prefix_length(abfd)\ (coff_backend_info (abfd)->_bfd_coff_debug_string_prefix_length) #define bfd_coff_print_aux(abfd, file, base, symbol, aux, indaux)\ ((coff_backend_info (abfd)->_bfd_coff_print_aux)\ (abfd, file, base, symbol, aux, indaux)) #define bfd_coff_reloc16_extra_cases(abfd, link_info, link_order,\ reloc, data, src_ptr, dst_ptr)\ ((coff_backend_info (abfd)->_bfd_coff_reloc16_extra_cases)\ (abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)) #define bfd_coff_reloc16_estimate(abfd, section, reloc, shrink, link_info)\ ((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\ (abfd, section, reloc, shrink, link_info)) #define bfd_coff_classify_symbol(abfd, sym)\ ((coff_backend_info (abfd)->_bfd_coff_classify_symbol)\ (abfd, sym)) #define bfd_coff_compute_section_file_positions(abfd)\ ((coff_backend_info (abfd)->_bfd_coff_compute_section_file_positions)\ (abfd)) #define bfd_coff_start_final_link(obfd, info)\ ((coff_backend_info (obfd)->_bfd_coff_start_final_link)\ (obfd, info)) #define bfd_coff_relocate_section(obfd,info,ibfd,o,con,rel,isyms,secs)\ ((coff_backend_info (ibfd)->_bfd_coff_relocate_section)\ (obfd, info, ibfd, o, con, rel, isyms, secs)) #define bfd_coff_rtype_to_howto(abfd, sec, rel, h, sym, addendp)\ ((coff_backend_info (abfd)->_bfd_coff_rtype_to_howto)\ (abfd, sec, rel, h, sym, addendp)) #define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\ ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\ (obfd, info, ibfd, sec, rel, adjustedp)) #define bfd_coff_link_add_one_symbol(info, abfd, name, flags, section,\ value, string, cp, coll, hashp)\ ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\ (info, abfd, name, flags, section, value, string, cp, coll, hashp)) #define bfd_coff_link_output_has_begun(a,p) \ ((coff_backend_info (a)->_bfd_coff_link_output_has_begun) (a, p)) #define bfd_coff_final_link_postscript(a,p) \ ((coff_backend_info (a)->_bfd_coff_final_link_postscript) (a, p)) #define bfd_coff_have_print_pdata(a) \ (coff_backend_info (a)->_bfd_coff_print_pdata) #define bfd_coff_print_pdata(a,p) \ ((coff_backend_info (a)->_bfd_coff_print_pdata) (a, p)) /* Macro: Returns true if the bfd is a PE executable as opposed to a PE object file. */ #define bfd_pei_p(abfd) \ (CONST_STRNEQ ((abfd)->xvec->name, "pei-")) 3.3.2.8 Writing relocations ........................... To write relocations, the back end steps though the canonical relocation table and create an `internal_reloc'. The symbol index to use is removed from the `offset' field in the symbol table supplied. The address comes directly from the sum of the section base address and the relocation offset; the type is dug directly from the howto field. Then the `internal_reloc' is swapped into the shape of an `external_reloc' and written out to disk. 3.3.2.9 Reading linenumbers ........................... Creating the linenumber table is done by reading in the entire coff linenumber table, and creating another table for internal use. A coff linenumber table is structured so that each function is marked as having a line number of 0. Each line within the function is an offset from the first line in the function. The base of the line number information for the table is stored in the symbol associated with the function. Note: The PE format uses line number 0 for a flag indicating a new source file. The information is copied from the external to the internal table, and each symbol which marks a function is marked by pointing its... How does this work ? 3.3.2.10 Reading relocations ............................ Coff relocations are easily transformed into the internal BFD form (`arelent'). Reading a coff relocation table is done in the following stages: * Read the entire coff relocation table into memory. * Process each relocation in turn; first swap it from the external to the internal form. * Turn the symbol referenced in the relocation's symbol index into a pointer into the canonical symbol table. This table is the same as the one returned by a call to `bfd_canonicalize_symtab'. The back end will call that routine and save the result if a canonicalization hasn't been done. * The reloc index is turned into a pointer to a howto structure, in a back end specific way. For instance, the 386 and 960 use the `r_type' to directly produce an index into a howto table vector; the 88k subtracts a number from the `r_type' field and creates an addend field.  File: bfd.info, Node: elf, Next: mmo, Prev: coff, Up: BFD back ends 3.4 ELF backends ================ BFD support for ELF formats is being worked on. Currently, the best supported back ends are for sparc and i386 (running svr4 or Solaris 2). Documentation of the internals of the support code still needs to be written. The code is changing quickly enough that we haven't bothered yet.  File: bfd.info, Node: mmo, Prev: elf, Up: BFD back ends 3.5 mmo backend =============== The mmo object format is used exclusively together with Professor Donald E. Knuth's educational 64-bit processor MMIX. The simulator `mmix' which is available at `http://www-cs-faculty.stanford.edu/~knuth/programs/mmix.tar.gz' understands this format. That package also includes a combined assembler and linker called `mmixal'. The mmo format has no advantages feature-wise compared to e.g. ELF. It is a simple non-relocatable object format with no support for archives or debugging information, except for symbol value information and line numbers (which is not yet implemented in BFD). See `http://www-cs-faculty.stanford.edu/~knuth/mmix.html' for more information about MMIX. The ELF format is used for intermediate object files in the BFD implementation. * Menu: * File layout:: * Symbol-table:: * mmo section mapping::  File: bfd.info, Node: File layout, Next: Symbol-table, Prev: mmo, Up: mmo 3.5.1 File layout ----------------- The mmo file contents is not partitioned into named sections as with e.g. ELF. Memory areas is formed by specifying the location of the data that follows. Only the memory area `0x0000...00' to `0x01ff...ff' is executable, so it is used for code (and constants) and the area `0x2000...00' to `0x20ff...ff' is used for writable data. *Note mmo section mapping::. There is provision for specifying "special data" of 65536 different types. We use type 80 (decimal), arbitrarily chosen the same as the ELF `e_machine' number for MMIX, filling it with section information normally found in ELF objects. *Note mmo section mapping::. Contents is entered as 32-bit words, xor:ed over previous contents, always zero-initialized. A word that starts with the byte `0x98' forms a command called a `lopcode', where the next byte distinguished between the thirteen lopcodes. The two remaining bytes, called the `Y' and `Z' fields, or the `YZ' field (a 16-bit big-endian number), are used for various purposes different for each lopcode. As documented in `http://www-cs-faculty.stanford.edu/~knuth/mmixal-intro.ps.gz', the lopcodes are: `lop_quote' 0x98000001. The next word is contents, regardless of whether it starts with 0x98 or not. `lop_loc' 0x9801YYZZ, where `Z' is 1 or 2. This is a location directive, setting the location for the next data to the next 32-bit word (for Z = 1) or 64-bit word (for Z = 2), plus Y * 2^56. Normally `Y' is 0 for the text segment and 2 for the data segment. `lop_skip' 0x9802YYZZ. Increase the current location by `YZ' bytes. `lop_fixo' 0x9803YYZZ, where `Z' is 1 or 2. Store the current location as 64 bits into the location pointed to by the next 32-bit (Z = 1) or 64-bit (Z = 2) word, plus Y * 2^56. `lop_fixr' 0x9804YYZZ. `YZ' is stored into the current location plus 2 - 4 * YZ. `lop_fixrx' 0x980500ZZ. `Z' is 16 or 24. A value `L' derived from the following 32-bit word are used in a manner similar to `YZ' in lop_fixr: it is xor:ed into the current location minus 4 * L. The first byte of the word is 0 or 1. If it is 1, then L = (LOWEST 24 BITS OF WORD) - 2^Z, if 0, then L = (LOWEST 24 BITS OF WORD). `lop_file' 0x9806YYZZ. `Y' is the file number, `Z' is count of 32-bit words. Set the file number to `Y' and the line counter to 0. The next Z * 4 bytes contain the file name, padded with zeros if the count is not a multiple of four. The same `Y' may occur multiple times, but `Z' must be 0 for all but the first occurrence. `lop_line' 0x9807YYZZ. `YZ' is the line number. Together with lop_file, it forms the source location for the next 32-bit word. Note that for each non-lopcode 32-bit word, line numbers are assumed incremented by one. `lop_spec' 0x9808YYZZ. `YZ' is the type number. Data until the next lopcode other than lop_quote forms special data of type `YZ'. *Note mmo section mapping::. Other types than 80, (or type 80 with a content that does not parse) is stored in sections named `.MMIX.spec_data.N' where N is the `YZ'-type. The flags for such a sections say not to allocate or load the data. The vma is 0. Contents of multiple occurrences of special data N is concatenated to the data of the previous lop_spec Ns. The location in data or code at which the lop_spec occurred is lost. `lop_pre' 0x980901ZZ. The first lopcode in a file. The `Z' field forms the length of header information in 32-bit words, where the first word tells the time in seconds since `00:00:00 GMT Jan 1 1970'. `lop_post' 0x980a00ZZ. Z > 32. This lopcode follows after all content-generating lopcodes in a program. The `Z' field denotes the value of `rG' at the beginning of the program. The following 256 - Z big-endian 64-bit words are loaded into global registers `$G' ... `$255'. `lop_stab' 0x980b0000. The next-to-last lopcode in a program. Must follow immediately after the lop_post lopcode and its data. After this lopcode follows all symbols in a compressed format (*note Symbol-table::). `lop_end' 0x980cYYZZ. The last lopcode in a program. It must follow the lop_stab lopcode and its data. The `YZ' field contains the number of 32-bit words of symbol table information after the preceding lop_stab lopcode. Note that the lopcode "fixups"; `lop_fixr', `lop_fixrx' and `lop_fixo' are not generated by BFD, but are handled. They are generated by `mmixal'. This trivial one-label, one-instruction file: :Main TRAP 1,2,3 can be represented this way in mmo: 0x98090101 - lop_pre, one 32-bit word with timestamp. 0x98010002 - lop_loc, text segment, using a 64-bit address. Note that mmixal does not emit this for the file above. 0x00000000 - Address, high 32 bits. 0x00000000 - Address, low 32 bits. 0x98060002 - lop_file, 2 32-bit words for file-name. 0x74657374 - "test" 0x2e730000 - ".s\0\0" 0x98070001 - lop_line, line 1. 0x00010203 - TRAP 1,2,3 0x980a00ff - lop_post, setting $255 to 0. 0x00000000 0x00000000 0x980b0000 - lop_stab for ":Main" = 0, serial 1. 0x203a4040 *Note Symbol-table::. 0x10404020 0x4d206120 0x69016e00 0x81000000 0x980c0005 - lop_end; symbol table contained five 32-bit words.  File: bfd.info, Node: Symbol-table, Next: mmo section mapping, Prev: File