home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / cctools / as / write_object.c < prev    next >
C/C++ Source or Header  |  1996-04-18  |  38KB  |  1,220 lines

  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <sys/file.h>
  4. #include <bsd/libc.h>
  5. #include <mach/mach.h>
  6. #include <mach-o/loader.h>
  7. #include <mach-o/reloc.h>
  8. #ifdef I860
  9. #include <mach-o/i860/reloc.h>
  10. #endif
  11. #ifdef M88K
  12. #include <mach-o/m88k/reloc.h>
  13. #endif
  14. #ifdef M98K
  15. #include <mach-o/m98k/reloc.h>
  16. #endif
  17. #ifdef HPPA
  18. #include <mach-o/hppa/reloc.h>
  19. #include "stuff/hppa.h"
  20. #endif
  21. #ifdef SPARC
  22. #include <mach-o/sparc/reloc.h>
  23. #endif
  24. #include "stuff/round.h"
  25. #include "stuff/bytesex.h"
  26. #include "stuff/errors.h"
  27. #include "as.h"
  28. #include "struc-symbol.h"
  29. #include "symbols.h"
  30. #include "frags.h"
  31. #include "fixes.h"
  32. #include "md.h"
  33. #include "sections.h"
  34. #include "messages.h"
  35. #include "xmalloc.h"
  36. #ifdef I860
  37. #define RELOC_SECTDIFF    I860_RELOC_SECTDIFF
  38. #define RELOC_PAIR    I860_RELOC_PAIR
  39. #endif
  40. #ifdef M88K
  41. #define RELOC_SECTDIFF    M88K_RELOC_SECTDIFF
  42. #define RELOC_PAIR    M88K_RELOC_PAIR
  43. #endif
  44. #ifdef M98K
  45. #define RELOC_SECTDIFF    M98K_RELOC_SECTDIFF
  46. #define RELOC_PAIR    M98K_RELOC_PAIR
  47. #endif
  48. #ifdef HPPA
  49. #define RELOC_SECTDIFF    HPPA_RELOC_SECTDIFF
  50. #define RELOC_PAIR    HPPA_RELOC_PAIR
  51. #endif
  52. #ifdef SPARC
  53. #define RELOC_SECTDIFF    SPARC_RELOC_SECTDIFF
  54. #define RELOC_PAIR    SPARC_RELOC_PAIR
  55. #endif
  56. #if defined(M68K) || defined(I386)
  57. #define RELOC_SECTDIFF    GENERIC_RELOC_SECTDIFF
  58. #define RELOC_PAIR    GENERIC_RELOC_PAIR
  59. #endif
  60.  
  61. /*
  62.  * These variables are set by layout_symbols() to organize the symbol table and
  63.  * string table in order the dynamic linker expects.  They are then used in
  64.  * write_object() to put out the symbols and strings in that order.
  65.  * The order of the symbol table is:
  66.  *    local symbols
  67.  *    defined external symbols (sorted by name)
  68.  *    undefined external symbols (sorted by name)
  69.  * The order of the string table is:
  70.  *    strings for external symbols
  71.  *    strings for local symbols
  72.  */
  73. /* index to and number of local symbols */
  74. static unsigned long ilocalsym = 0;
  75. static unsigned long nlocalsym = 0;
  76. /* index to, number of and array of sorted externally defined symbols */
  77. static unsigned long iextdefsym = 0;
  78. static unsigned long nextdefsym = 0;
  79. static symbolS **extdefsyms = NULL;
  80. /* index to, number of and array of sorted undefined symbols */
  81. static unsigned long iundefsym = 0;
  82. static unsigned long nundefsym = 0;
  83. static symbolS **undefsyms = NULL;
  84.  
  85. static unsigned long layout_indirect_symbols(
  86.      void);
  87. static void layout_symbols(
  88.     long *symbol_number,
  89.     long *string_byte_count);
  90. static int qsort_compare(
  91.     const symbolS **sym1,
  92.     const symbolS **sym2);
  93. static unsigned long nrelocs_for_fix(
  94.     struct fix *fixP);
  95. static unsigned long fix_to_relocation_entries(
  96.     struct fix *fixP,
  97.     unsigned long sect_addr,
  98.     struct relocation_info *riP);
  99. #ifdef I860
  100. static void
  101.     I860_tweeks(void);
  102. #endif
  103.  
  104. /*
  105.  * write_object() writes a Mach-O object file from the built up data structures.
  106.  */
  107. void
  108. write_object(
  109. char *out_file_name)
  110. {
  111.     /* The structures for Mach-O relocatables */
  112.     struct mach_header        header;
  113.     struct segment_command    reloc_segment;
  114.     struct symtab_command    symbol_table;
  115.     struct dysymtab_command    dynamic_symbol_table;
  116.     unsigned long        section_type, *indirect_symbols;
  117.     isymbolS            *isymbolP;
  118.     unsigned long        i, j, nsects, nsyms, strsize, nindirectsyms;
  119.  
  120.     /* locals to fill in section struct fields */
  121.     unsigned long offset, zero;
  122.  
  123.     /* The GAS data structures */
  124.     struct frchain *frchainP, *p;
  125.     struct symbol *symbolP;
  126.     struct frag *fragP;
  127.     struct fix *fixP;
  128.  
  129.     unsigned long output_size;
  130.     char *output_addr;
  131.     kern_return_t r;
  132.  
  133.     enum byte_sex host_byte_sex;
  134.     unsigned long reloff, nrelocs;
  135.     long count;
  136.     char *fill_literal;
  137.     long fill_size;
  138.     char *symbol_name;
  139.     int fd;
  140.  
  141. #ifdef I860
  142.     I860_tweeks();
  143. #endif
  144.     i = 0; /* to shut up a compiler "may be used uninitialized" warning */
  145.  
  146.     /*
  147.      * The first group of things to do is to set all the fields in the
  148.      * header structures which includes offsets and determining the final
  149.      * sizes of things.
  150.      */
  151.  
  152.     /* 
  153.      * Fill in the addr and size fields of each section structure and count
  154.      * the number of sections.
  155.      */
  156.     nsects = 0;
  157.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  158.         frchainP->frch_section.addr = frchainP->frch_root->fr_address;
  159.         frchainP->frch_section.size = frchainP->frch_last->fr_address -
  160.                          frchainP->frch_root->fr_address;
  161.         nsects++;
  162.     }
  163.  
  164.     /*
  165.      * Setup the indirect symbol tables by looking up or creating symbol
  166.      * from the indirect symbol names and recording the symbol pointers.
  167.      */
  168.     nindirectsyms = layout_indirect_symbols();
  169.  
  170.     /*
  171.      * Setup the symbol table to include only those symbols that will be in
  172.      * the object file, assign the string table offsets into the symbols
  173.      * and size the string table.
  174.      */
  175.     nsyms = 0;
  176.     strsize = 0;
  177.     layout_symbols(&nsyms, &strsize);
  178.  
  179.     /* fill in the Mach-O header */
  180.     header.magic = MH_MAGIC;
  181.     header.cputype = md_cputype;
  182.     if(archflag_cpusubtype != -1)
  183.         header.cpusubtype = archflag_cpusubtype;
  184.     else
  185.         header.cpusubtype = md_cpusubtype;
  186.  
  187.     header.filetype = MH_OBJECT;
  188.     header.ncmds = 0;
  189.     header.sizeofcmds = 0;
  190.     if(nsects != 0){
  191.         header.ncmds += 1;
  192.         header.sizeofcmds += sizeof(struct segment_command) +
  193.                  nsects * sizeof(struct section);
  194.     }
  195.     if(nsyms != 0){
  196.         header.ncmds += 1;
  197.         header.sizeofcmds += sizeof(struct symtab_command);
  198.         if(flagseen['k']){
  199.         header.ncmds += 1;
  200.         header.sizeofcmds += sizeof(struct dysymtab_command);
  201.         }
  202.     }
  203.     else
  204.         strsize = 0;
  205.     header.flags = 0;
  206.  
  207.     /* fill in the segment command */
  208.     memset(&reloc_segment, '\0', sizeof(struct segment_command));
  209.     reloc_segment.cmd = LC_SEGMENT;
  210.     reloc_segment.cmdsize = sizeof(struct segment_command) +
  211.                 nsects * sizeof(struct section);
  212.     /* leave reloc_segment.segname full of zeros */
  213.     reloc_segment.vmaddr = 0;
  214.     reloc_segment.vmsize = 0;
  215.     reloc_segment.filesize = 0;
  216.     offset = header.sizeofcmds + sizeof(struct mach_header);
  217.     reloc_segment.fileoff = offset;
  218.     reloc_segment.maxprot = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
  219.     reloc_segment.initprot= VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
  220.     reloc_segment.nsects = nsects;
  221.     reloc_segment.flags = 0;
  222.     /*
  223.      * Set the offsets to the contents of the sections (for non-zerofill
  224.      * sections) and set the filesize and vmsize of the segment.  This is
  225.      * complicated by the fact that all the zerofill sections have addresses
  226.      * after the non-zerofill sections and that the alignment of sections
  227.      * produces gaps that are not in any section.  For the vmsize we rely on
  228.      * the fact the the sections start at address 0 so it is just the last
  229.      * zerofill section or the last not-zerofill section.
  230.      */
  231.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  232.         if((frchainP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL)
  233.         continue;
  234.         for(p = frchainP->frch_next; p != NULL; p = p->frch_next)
  235.         if((p->frch_section.flags & SECTION_TYPE) != S_ZEROFILL)
  236.             break;
  237.         if(p != NULL)
  238.         i = p->frch_section.addr - frchainP->frch_section.addr;
  239.         else
  240.         i = frchainP->frch_section.size;
  241.         reloc_segment.filesize += i;
  242.         frchainP->frch_section.offset = offset;
  243.         offset += i;
  244.         reloc_segment.vmsize = frchainP->frch_section.addr +
  245.                    frchainP->frch_section.size;
  246.     }
  247.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  248.         if((frchainP->frch_section.flags & SECTION_TYPE) != S_ZEROFILL)
  249.         continue;
  250.         reloc_segment.vmsize = frchainP->frch_section.addr +
  251.                    frchainP->frch_section.size;
  252.     }
  253.     offset = round(offset, sizeof(long));
  254.  
  255.     /*
  256.      * Count the number of relocation entries for each section.
  257.      */
  258.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  259.         frchainP->frch_section.nreloc = 0;
  260.         for(fixP = frchainP->frch_fix_root; fixP; fixP = fixP->fx_next){
  261.         frchainP->frch_section.nreloc += nrelocs_for_fix(fixP);
  262.         }
  263.     }
  264.  
  265.     /*
  266.      * Fill in the offset to the relocation entries of the sections.
  267.      */
  268.     offset = round(offset, sizeof(long));
  269.     reloff = offset;
  270.     nrelocs = 0;
  271.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  272.         if(frchainP->frch_section.nreloc == 0)
  273.         frchainP->frch_section.reloff = 0;
  274.         else
  275.         frchainP->frch_section.reloff = offset;
  276.         offset += frchainP->frch_section.nreloc *
  277.               sizeof(struct relocation_info);
  278.         nrelocs += frchainP->frch_section.nreloc;
  279.     }
  280.  
  281.     if(flagseen['k']){
  282.         /* fill in the fields of the dysymtab_command */
  283.         dynamic_symbol_table.cmd = LC_DYSYMTAB;
  284.         dynamic_symbol_table.cmdsize = sizeof(struct dysymtab_command);
  285.  
  286.         dynamic_symbol_table.ilocalsym = ilocalsym;
  287.         dynamic_symbol_table.nlocalsym = nlocalsym;
  288.         dynamic_symbol_table.iextdefsym = iextdefsym;
  289.         dynamic_symbol_table.nextdefsym = nextdefsym;
  290.         dynamic_symbol_table.iundefsym = iundefsym;
  291.         dynamic_symbol_table.nundefsym = nundefsym;
  292.  
  293.         if(nindirectsyms == 0){
  294.         dynamic_symbol_table.nindirectsyms = 0;
  295.         dynamic_symbol_table.indirectsymoff = 0;
  296.         }
  297.         else{
  298.         dynamic_symbol_table.nindirectsyms = nindirectsyms;
  299.         dynamic_symbol_table.indirectsymoff = offset;
  300.         offset += nindirectsyms * sizeof(unsigned long);
  301.         }
  302.  
  303.         dynamic_symbol_table.tocoff = 0;
  304.         dynamic_symbol_table.ntoc = 0;
  305.         dynamic_symbol_table.modtaboff = 0;
  306.         dynamic_symbol_table.nmodtab = 0;
  307.         dynamic_symbol_table.extrefsymoff = 0;
  308.         dynamic_symbol_table.nextrefsyms = 0;
  309.         dynamic_symbol_table.extreloff = 0;
  310.         dynamic_symbol_table.nextrel = 0;
  311.         dynamic_symbol_table.locreloff = 0;
  312.         dynamic_symbol_table.nlocrel = 0;
  313.     }
  314.  
  315.     /* fill in the fields of the symtab_command (except the string table) */
  316.     symbol_table.cmd = LC_SYMTAB;
  317.     symbol_table.cmdsize = sizeof(struct symtab_command);
  318.     if(nsyms == 0)
  319.         symbol_table.symoff = 0;
  320.     else
  321.         symbol_table.symoff = offset;
  322.     symbol_table.nsyms = nsyms;
  323.     offset += symbol_table.nsyms * sizeof(struct nlist);
  324.  
  325.     /* fill in the string table fields of the symtab_command */
  326.     if(strsize == 0)
  327.         symbol_table.stroff = 0;
  328.     else
  329.         symbol_table.stroff = offset;
  330.     symbol_table.strsize = round(strsize, sizeof(unsigned long));
  331.     offset += round(strsize, sizeof(unsigned long));
  332.  
  333.     /*
  334.      * The second group of things to do is now with the size of everything
  335.      * known the object file and the offsets set in the various structures
  336.      * the contents of the object file can be created.
  337.      */
  338.  
  339.     /*
  340.      * Create the buffer to copy the parts of the output file into.
  341.      */
  342.     output_size = offset;
  343.     if((r = vm_allocate(task_self(), (vm_address_t *)&output_addr,
  344.                 output_size, TRUE)) != KERN_SUCCESS)
  345.         as_fatal("can't vm_allocate() buffer for output file of size %lu",
  346.              output_size);
  347.  
  348.     /* put the headers in the output file's buffer */
  349.     host_byte_sex = get_host_byte_sex();
  350.     offset = 0;
  351.  
  352.     /* put the mach_header in the buffer */
  353.     memcpy(output_addr + offset, &header, sizeof(struct mach_header));
  354.     if(host_byte_sex != md_target_byte_sex)
  355.         swap_mach_header((struct mach_header *)(output_addr + offset),
  356.                  md_target_byte_sex);
  357.     offset += sizeof(struct mach_header);
  358.  
  359.     /* put the segment_command in the buffer */
  360.     if(nsects != 0){
  361.         memcpy(output_addr + offset, &reloc_segment,
  362.            sizeof(struct segment_command));
  363.         if(host_byte_sex != md_target_byte_sex)
  364.         swap_segment_command((struct segment_command *)
  365.                      (output_addr + offset),
  366.                      md_target_byte_sex);
  367.         offset += sizeof(struct segment_command);
  368.     }
  369.  
  370.     /* put the segment_command's section structures in the buffer */
  371.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  372.         memcpy(output_addr + offset, &(frchainP->frch_section),
  373.            sizeof(struct section));
  374.         if(host_byte_sex != md_target_byte_sex)
  375.         swap_section((struct section *)(output_addr + offset), 1,
  376.                      md_target_byte_sex);
  377.         offset += sizeof(struct section);
  378.     }
  379.  
  380.     /* put the symbol_command in the buffer */
  381.     if(nsyms != 0){
  382.         memcpy(output_addr + offset, &symbol_table,
  383.            sizeof(struct symtab_command));
  384.         if(host_byte_sex != md_target_byte_sex)
  385.         swap_symtab_command((struct symtab_command *)
  386.                      (output_addr + offset),
  387.                      md_target_byte_sex);
  388.         offset += sizeof(struct symtab_command);
  389.     }
  390.  
  391.     if(flagseen['k']){
  392.         /* put the dysymbol_command in the buffer */
  393.         if(nsyms != 0){
  394.         memcpy(output_addr + offset, &dynamic_symbol_table,
  395.                sizeof(struct dysymtab_command));
  396.         if(host_byte_sex != md_target_byte_sex)
  397.             swap_dysymtab_command((struct dysymtab_command *)
  398.                       (output_addr + offset),
  399.                       md_target_byte_sex);
  400.         offset += sizeof(struct dysymtab_command);
  401.         }
  402.     }
  403.  
  404.     /* put the section contents (frags) in the buffer */
  405.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  406.         offset = frchainP->frch_section.offset;
  407.         for(fragP = frchainP->frch_root; fragP; fragP = fragP->fr_next){
  408.         know(fragP->fr_type == rs_fill);
  409.         /* put the fixed part of the frag in the buffer */
  410.         memcpy(output_addr + offset, fragP->fr_literal, fragP->fr_fix);
  411.         offset += fragP->fr_fix;
  412.  
  413.         /* put the variable repeated part of the frag in the buffer */
  414.         fill_literal = fragP->fr_literal + fragP->fr_fix;
  415.         fill_size = fragP->fr_var;
  416.         know(fragP->fr_offset >= 0);
  417.         for(count = fragP->fr_offset; count != 0;  count--){
  418.             memcpy(output_addr + offset, fill_literal, fill_size);
  419.             offset += fill_size;
  420.         }
  421.         }
  422.     }
  423.  
  424.  
  425.     /* put the symbols in the output file's buffer */
  426.     offset = symbol_table.symoff;
  427.     for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next){
  428.         if((symbolP->sy_type & N_EXT) == 0){
  429.         symbol_name = symbolP->sy_nlist.n_un.n_name;
  430.         symbolP->sy_nlist.n_un.n_strx = symbolP->sy_name_offset;
  431.         memcpy(output_addr + offset, (char *)(&symbolP->sy_nlist),
  432.                sizeof(struct nlist));
  433.         symbolP->sy_nlist.n_un.n_name = symbol_name;
  434.         offset += sizeof(struct nlist);
  435.         }
  436.     }
  437.     for(i = 0; i < nextdefsym; i++){
  438.         symbol_name = extdefsyms[i]->sy_nlist.n_un.n_name;
  439.         extdefsyms[i]->sy_nlist.n_un.n_strx = extdefsyms[i]->sy_name_offset;
  440.         memcpy(output_addr + offset, (char *)(&extdefsyms[i]->sy_nlist),
  441.                sizeof(struct nlist));
  442.         extdefsyms[i]->sy_nlist.n_un.n_name = symbol_name;
  443.         offset += sizeof(struct nlist);
  444.     }
  445.     for(j = 0; j < nundefsym; j++){
  446.         symbol_name = undefsyms[j]->sy_nlist.n_un.n_name;
  447.         undefsyms[j]->sy_nlist.n_un.n_strx = undefsyms[j]->sy_name_offset;
  448.         memcpy(output_addr + offset, (char *)(&undefsyms[j]->sy_nlist),
  449.                sizeof(struct nlist));
  450.         undefsyms[j]->sy_nlist.n_un.n_name = symbol_name;
  451.         offset += sizeof(struct nlist);
  452.     }
  453.     if(host_byte_sex != md_target_byte_sex)
  454.         swap_nlist((struct nlist *)(output_addr + symbol_table.symoff),
  455.                symbol_table.nsyms, md_target_byte_sex);
  456.  
  457.     /*
  458.      * Put the relocation entries for each section in the buffer.
  459.      */
  460.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  461.         offset = frchainP->frch_section.reloff;
  462.         for(fixP = frchainP->frch_fix_root; fixP; fixP = fixP->fx_next){
  463.         offset += fix_to_relocation_entries(
  464.                     fixP,
  465.                     frchainP->frch_section.addr,
  466.                     (struct relocation_info *)(output_addr +
  467.                                    offset));
  468.         }
  469.     }
  470.     if(host_byte_sex != md_target_byte_sex)
  471.         swap_relocation_info((struct relocation_info *)
  472.         (output_addr + reloff), nrelocs, md_target_byte_sex);
  473.  
  474.     if(flagseen['k']){
  475.         /* put the indirect symbol table in the buffer */
  476.         offset = dynamic_symbol_table.indirectsymoff;
  477.         for(frchainP = frchain_root;
  478.         frchainP != NULL;
  479.         frchainP = frchainP->frch_next){
  480.         section_type = frchainP->frch_section.flags & SECTION_TYPE;
  481.         if(section_type == S_NON_LAZY_SYMBOL_POINTERS ||
  482.            section_type == S_LAZY_SYMBOL_POINTERS ||
  483.            section_type == S_SYMBOL_STUBS){
  484.             /*
  485.              * For each indirect symbol put out the symbol number.
  486.              */
  487.             for(isymbolP = frchainP->frch_isym_root;
  488.             isymbolP != NULL;
  489.             isymbolP = isymbolP->isy_next){
  490.  
  491.             memcpy(output_addr + offset,
  492.                    (char *)(&isymbolP->isy_symbol->sy_number),
  493.                    sizeof(unsigned long));
  494.             offset += sizeof(unsigned long);
  495.             }
  496.         }
  497.         }
  498.         if(host_byte_sex != md_target_byte_sex){
  499.         indirect_symbols = (unsigned long *)(output_addr +
  500.                     dynamic_symbol_table.indirectsymoff);
  501.         swap_indirect_symbols(indirect_symbols, nindirectsyms, 
  502.                       md_target_byte_sex);
  503.         }
  504.     }
  505.  
  506.     /* put the strings in the output file's buffer */
  507.     offset = symbol_table.stroff;
  508.     if(symbol_table.strsize != 0){
  509.         zero = 0;
  510.         memcpy(output_addr + offset, (char *)&zero, sizeof(char));
  511.         offset += sizeof(char);
  512.     }
  513.     for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next){
  514.         /* Ordinary case: not .stabd. */
  515.         if(symbolP->sy_name != NULL){
  516.         if((symbolP->sy_type & N_EXT) != 0){
  517.             memcpy(output_addr + offset, symbolP->sy_name,
  518.                strlen(symbolP->sy_name) + 1);
  519.             offset += strlen(symbolP->sy_name) + 1;
  520.         }
  521.         }
  522.     }
  523.     for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next){
  524.         /* Ordinary case: not .stabd. */
  525.         if(symbolP->sy_name != NULL){
  526.         if((symbolP->sy_type & N_EXT) == 0){
  527.             memcpy(output_addr + offset, symbolP->sy_name,
  528.                strlen(symbolP->sy_name) + 1);
  529.             offset += strlen(symbolP->sy_name) + 1;
  530.         }
  531.         }
  532.     }
  533.     /*
  534.          * Create the output file.  The unlink() is done to handle the problem
  535.          * when the out_file_name is not writable but the directory allows the
  536.          * file to be removed (since the file may not be there the return code
  537.          * of the unlink() is ignored).
  538.          */
  539.     if(bad_error != 0)
  540.         return;
  541.     (void)unlink(out_file_name);
  542.     if((fd = open(out_file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1)
  543.         as_fatal("can't create output file: %s", out_file_name);
  544.     if(write(fd, output_addr, output_size) != output_size)
  545.         as_fatal("can't write output file");
  546.     if(close(fd) == -1)
  547.         as_fatal("can't close output file");
  548. }
  549.  
  550. /*
  551.  * layout_indirect_symbols() setups the indirect symbol tables by looking up or
  552.  * creating symbol from the indirect symbol names and recording the symbol
  553.  * pointers.  It returns the total count of indirect symbol table entries.
  554.  */
  555. static
  556. unsigned long
  557. layout_indirect_symbols(void)
  558. {
  559.     struct frchain *frchainP;
  560.     unsigned long section_type, total, count, stride;
  561.     isymbolS *isymbolP;
  562.     symbolS *symbolP;
  563.  
  564.     /*
  565.      * Mark symbols that only appear in a lazy section with 
  566.      * REFERENCE_FLAG_UNDEFINED_LAZY.  To do this we first make sure a
  567.      * symbol exists for all non-lazy symbols.  Then we make a pass looking
  568.      * up the lazy symbols and if not there we make the symbol and mark it
  569.      * with REFERENCE_FLAG_UNDEFINED_LAZY.
  570.      */
  571.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  572.         section_type = frchainP->frch_section.flags & SECTION_TYPE;
  573.         if(section_type == S_NON_LAZY_SYMBOL_POINTERS){
  574.         for(isymbolP = frchainP->frch_isym_root;
  575.             isymbolP != NULL;
  576.             isymbolP = isymbolP->isy_next){
  577. /*
  578. (void)symbol_find_or_make(isymbolP->isy_name);
  579. */
  580.             symbolP = symbol_find(isymbolP->isy_name);
  581.             if(symbolP == NULL){
  582.             symbolP = symbol_new(isymbolP->isy_name, N_UNDF, 0, 0,
  583.                          0, &zero_address_frag);
  584.             symbol_table_insert(symbolP);
  585.             }
  586.         }
  587.         }
  588.     }
  589.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  590.         section_type = frchainP->frch_section.flags & SECTION_TYPE;
  591.         if(section_type == S_LAZY_SYMBOL_POINTERS ||
  592.            section_type == S_SYMBOL_STUBS){
  593.         for(isymbolP = frchainP->frch_isym_root;
  594.             isymbolP != NULL;
  595.             isymbolP = isymbolP->isy_next){
  596.  
  597.             symbolP = symbol_find(isymbolP->isy_name);
  598.             if(symbolP == NULL){
  599.             symbolP = symbol_find_or_make(isymbolP->isy_name);
  600.             symbolP->sy_desc |= REFERENCE_FLAG_UNDEFINED_LAZY;
  601.             }
  602.         }
  603.         }
  604.     }
  605.  
  606.     total = 0;
  607.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  608.         section_type = frchainP->frch_section.flags & SECTION_TYPE;
  609.         if(section_type == S_LAZY_SYMBOL_POINTERS ||
  610.            section_type == S_NON_LAZY_SYMBOL_POINTERS ||
  611.            section_type == S_SYMBOL_STUBS){
  612.         count = 0;
  613.         for(isymbolP = frchainP->frch_isym_root;
  614.             isymbolP != NULL;
  615.             isymbolP = isymbolP->isy_next){
  616.  
  617. /*
  618. symbolP = symbol_find_or_make(isymbolP->isy_name);
  619. */
  620.             symbolP = symbol_find(isymbolP->isy_name);
  621.             if(symbolP == NULL){
  622.             symbolP = symbol_new(isymbolP->isy_name, N_UNDF, 0, 0,
  623.                          0, &zero_address_frag);
  624.             symbol_table_insert(symbolP);
  625.             }
  626.             isymbolP->isy_symbol = symbolP;
  627.             count++;
  628.         }
  629.         /*
  630.          * Check for missing indirect symbols.
  631.          */
  632.         if(section_type == S_SYMBOL_STUBS)
  633.             stride = frchainP->frch_section.reserved2;
  634.         else
  635.             stride = sizeof(unsigned long);
  636.         if(frchainP->frch_section.size / stride != count)
  637.             as_warn("missing indirect symbols for section (%s,%s)",
  638.                 frchainP->frch_section.segname,
  639.                 frchainP->frch_section.sectname);
  640.         /*
  641.          * Set the index into the indirect symbol table for this
  642.          * section into the reserved1 field.
  643.          */
  644.         frchainP->frch_section.reserved1 = total;
  645.         total += count;
  646.         }
  647.     }
  648.     return(total);
  649. }
  650.  
  651. /*
  652.  * layout_symbols() removes temporary symbols (symbols that are of the form L1
  653.  * and 1:) if the -L flag is not seen so the symbol table has only the symbols
  654.  * it will have in the output file.  Then each remaining symbol is given a
  655.  * symbol number and a string offset for the symbol name which also sizes the
  656.  * string table.
  657.  * The order of the symbol table is:
  658.  *    local symbols
  659.  *    defined external symbols (sorted by name)
  660.  *    undefined external symbols (sorted by name)
  661.  * The order of the string table is:
  662.  *    strings for external symbols
  663.  *    strings for local symbols
  664.  */
  665. static
  666. void
  667. layout_symbols(
  668. long *symbol_number,
  669. long *string_byte_count)
  670. {
  671.     unsigned long i, j;
  672.     symbolS *symbolP;
  673.     symbolS **symbolPP;
  674.     char *name;
  675.  
  676.     *symbol_number = 0;
  677.     *string_byte_count = sizeof(char);
  678.  
  679.     /*
  680.      * First pass through the symbols remove temporary symbols that are not
  681.      * going to be in the output file.  Also number the local symbols and
  682.      * assign string offset to external symbols.
  683.      */
  684.     symbolPP = &symbol_rootP;
  685.     while((symbolP = *symbolPP)){
  686.         name = symbolP->sy_name;
  687.         /*
  688.          * Deal with temporary symbols.  Temporary symbols start with 'L'
  689.          * but are not stabs.  It is an error if they are undefined.  They
  690.          * are removed if the -L flag is not seen else they are kept.
  691.          */
  692.         if(name != NULL &&
  693.            (symbolP->sy_nlist.n_type & N_STAB) == 0 &&
  694.            name[0] == 'L'){
  695.  
  696.             if((symbolP->sy_nlist.n_type & N_TYPE) == N_UNDF){
  697.             if(name[1] != '\0' && name[2] == '\001'){
  698.             as_bad("Undefined local symbol %c (%cf or %cb)",
  699.                 name[1], name[1], name[1]);
  700.             }
  701.             else{
  702.             as_bad("Undefined local symbol %s", name);
  703.             }
  704.             /* don't keep this symbol */
  705.             *symbolPP = symbolP->sy_next;
  706.         }
  707.             else if(flagseen['L'] || (symbolP->sy_type & N_EXT) != 0){
  708.             if((symbolP->sy_type & N_EXT) == 0){
  709.             nlocalsym++;
  710.             symbolP->sy_number = *symbol_number;
  711.             *symbol_number = *symbol_number + 1;
  712.             }
  713.             else{
  714.             nextdefsym++;
  715.             symbolP->sy_name_offset = *string_byte_count;
  716.             *string_byte_count += strlen(symbolP->sy_name) + 1;
  717.             }
  718.             symbolPP = &(symbolP->sy_next);
  719.         }
  720.         else{
  721.             /* don't keep this symbol */
  722.             *symbolPP = symbolP->sy_next;
  723.         }
  724.         }
  725.         /*
  726.          * All non-temporary symbols will be the symbol table in the output
  727.          * file.
  728.          */
  729.         else{
  730.         /* Any undefined symbols become N_EXT. */
  731.         if(symbolP->sy_type == N_UNDF)
  732.             symbolP->sy_type |= N_EXT;
  733.  
  734.         if((symbolP->sy_type & N_EXT) == 0){
  735.             symbolP->sy_number = *symbol_number;
  736.             *symbol_number = *symbol_number + 1;
  737.             nlocalsym++;
  738.         }
  739.         else{
  740.             if((symbolP->sy_type & N_TYPE) != N_UNDF)
  741.             nextdefsym++;
  742.             else
  743.             nundefsym++;
  744.  
  745.             if(name != NULL){
  746.             /* the ordinary case (symbol has a name) */
  747.             symbolP->sy_name_offset = *string_byte_count;
  748.             *string_byte_count += strlen(symbolP->sy_name) + 1;
  749.             }
  750.             else{
  751.             /* the .stabd case (symbol has no name) */
  752.             symbolP->sy_name_offset = 0;
  753.             }
  754.         }
  755.         symbolPP = &(symbolP->sy_next);
  756.         }
  757.     }
  758.  
  759.     /* Set the indexes for symbol groups into the symbol table */
  760.     ilocalsym = 0;
  761.     iextdefsym = nlocalsym;
  762.     iundefsym = nlocalsym + nextdefsym;
  763.  
  764.     /* allocate arrays for sorting externals by name */
  765.     extdefsyms = xmalloc(nextdefsym * sizeof(symbolS *));
  766.     undefsyms = xmalloc(nundefsym * sizeof(symbolS *));
  767.  
  768.     i = 0;
  769.     j = 0;
  770.     for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next){
  771.         if((symbolP->sy_type & N_EXT) == 0){
  772.         if(symbolP->sy_name != NULL){
  773.             /* the ordinary case (symbol has a name) */
  774.             symbolP->sy_name_offset = *string_byte_count;
  775.             *string_byte_count += strlen(symbolP->sy_name) + 1;
  776.         }
  777.         else{
  778.             /* the .stabd case (symbol has no name) */
  779.             symbolP->sy_name_offset = *string_byte_count;
  780.         }
  781.         }
  782.         else{
  783.         if((symbolP->sy_type & N_TYPE) != N_UNDF)
  784.             extdefsyms[i++] = symbolP;
  785.         else
  786.             undefsyms[j++] = symbolP;
  787.         }
  788.     }
  789.     qsort(extdefsyms, nextdefsym, sizeof(symbolS *),
  790.           (int (*)(const void *, const void *))qsort_compare);
  791.     qsort(undefsyms, nundefsym, sizeof(symbolS *),
  792.           (int (*)(const void *, const void *))qsort_compare);
  793.     for(i = 0; i < nextdefsym; i++){
  794.         extdefsyms[i]->sy_number = *symbol_number;
  795.         *symbol_number = *symbol_number + 1;
  796.     }
  797.     for(j = 0; j < nundefsym; j++){
  798.         undefsyms[j]->sy_number = *symbol_number;
  799.         *symbol_number = *symbol_number + 1;
  800.     }
  801. }
  802.  
  803. /*
  804.  * Function for qsort to sort symbol structs by their name
  805.  */
  806. static
  807. int
  808. qsort_compare(
  809. const symbolS **sym1,
  810. const symbolS **sym2)
  811. {
  812.         return(strcmp((*sym1)->sy_name, (*sym2)->sy_name));
  813. }
  814.  
  815. /*
  816.  * nrelocs_for_fix() returns the number of relocation entries needed for the
  817.  * specified fix structure.
  818.  */
  819. static
  820. unsigned long
  821. nrelocs_for_fix(
  822. struct fix *fixP)
  823. {
  824.     /*
  825.      * If fx_addsy is NULL then this fix needs no relocation entry.
  826.      */
  827.     if(fixP->fx_addsy == NULL)
  828.         return(0);
  829.  
  830.     /*
  831.      * If this fix has a subtract symbol it is a SECTDIFF relocation which
  832.      * takes two relocation entries.
  833.      */
  834.     if(fixP->fx_subsy != NULL)
  835.         return(2);
  836.  
  837.     /*
  838.      * For RISC machines whenever we have a relocation item using the half
  839.      * of an address a second a relocation item describing the other
  840.      * half of the address is used.
  841.      */
  842. #ifdef I860
  843.     if(fixP->fx_r_type == I860_RELOC_HIGH ||
  844.        fixP->fx_r_type == I860_RELOC_HIGHADJ)
  845.         return(2);
  846. #endif
  847. #ifdef M88K
  848.     if(fixP->fx_r_type == M88K_RELOC_HI16 ||
  849.        fixP->fx_r_type == M88K_RELOC_LO16)
  850.         return(2);
  851. #endif
  852. #ifdef M98K
  853.     if(fixP->fx_r_type == M98K_RELOC_HI16 ||
  854.        fixP->fx_r_type == M98K_RELOC_LO16 ||
  855.        fixP->fx_r_type == M98K_RELOC_HA16 ||
  856.        fixP->fx_r_type == M98K_RELOC_LO14)
  857.         return(2);
  858. #endif
  859. #ifdef HPPA
  860.     if(fixP->fx_r_type == HPPA_RELOC_HI21 ||
  861.        fixP->fx_r_type == HPPA_RELOC_LO14 ||
  862.        fixP->fx_r_type == HPPA_RELOC_BR17 ||
  863.        fixP->fx_r_type == HPPA_RELOC_JBSR)
  864.         return(2);
  865. #endif
  866. #ifdef SPARC
  867.     if(fixP->fx_r_type == SPARC_RELOC_HI22 ||
  868.        fixP->fx_r_type == SPARC_RELOC_LO10)
  869.         return(2);
  870. #endif
  871.     return(1);
  872. }
  873.  
  874. /*
  875.  * fix_to_relocation_entries() creates the needed relocation entries for the
  876.  * specified fix structure that is from a section who's address starts at
  877.  * sect_addr.  It returns the number of bytes of relocation_info structs it
  878.  * placed at riP.
  879.  */
  880. static
  881. unsigned long
  882. fix_to_relocation_entries(
  883. struct fix *fixP,
  884. unsigned long sect_addr,
  885. struct relocation_info *riP)
  886. {
  887.     struct symbol *symbolP;
  888.     unsigned long count;
  889.     struct scattered_relocation_info sri;
  890.     unsigned long sectdiff;
  891. #ifdef HPPA
  892.     unsigned long left21, right14;
  893. #endif
  894.  
  895.     /*
  896.      * If fx_addsy is NULL then this fix needs no relocation entry.
  897.      */
  898.     if(fixP->fx_addsy == NULL)
  899.         return(0);
  900.  
  901.     memset(riP, '\0', sizeof(struct relocation_info));
  902.     symbolP = fixP->fx_addsy;
  903.  
  904.     switch(fixP->fx_size){
  905.         case 1:
  906.         riP->r_length = 0;
  907.         break;
  908.         case 2:
  909.         riP->r_length = 1;
  910.         break;
  911.         case 4:
  912.         riP->r_length = 2;
  913.         break;
  914.         default:
  915.         as_fatal("Bad fx_size (0x%x) in fix_to_relocation_info()\n",
  916.              fixP->fx_size);
  917.     }
  918.     riP->r_pcrel = fixP->fx_pcrel;
  919.     riP->r_address = fixP->fx_frag->fr_address + fixP->fx_where -
  920.              sect_addr;
  921.     riP->r_type = fixP->fx_r_type;
  922.     /*
  923.      * For undefined symbols this will be an external relocation entry.
  924.      */
  925.     if((symbolP->sy_type & N_TYPE) == N_UNDF){
  926.         riP->r_extern = 1;
  927.         riP->r_symbolnum = symbolP->sy_number;
  928.     }
  929.     else{
  930.         /*
  931.          * For defined symbols this will be a local relocation entry
  932.          * (possibly a section difference or a scattered relocation entry).
  933.          */
  934.         riP->r_extern = 0;
  935.         riP->r_symbolnum = symbolP->sy_other; /* nsect */
  936.  
  937.         /*
  938.          * If we are allowed to use the new features that are incompatible
  939.          * with 3.2 determine if this is left as a local relocation entry or
  940.          * changed to a SECTDIFF relocation entry.  If this comes from a fix
  941.          * that has a subtract symbol it is a SECTDIFF relocation.  Which is
  942.          * "addsy - subsy + constant" where both symbols are defined in
  943.          * sections.  To encode all this information two scattered
  944.          * relocation entries are used.  The first has the add symbol value
  945.          * and the second has the subtract symbol value.
  946.          */
  947.         if(flagseen['k'] && fixP->fx_subsy != NULL){
  948. #ifdef HPPA
  949.         if(fixP->fx_r_type == HPPA_RELOC_HI21)
  950.             sectdiff = HPPA_RELOC_HI21_SECTDIFF;
  951.         else if(fixP->fx_r_type == HPPA_RELOC_LO14)
  952.             sectdiff = HPPA_RELOC_LO14_SECTDIFF;
  953.         else
  954. #endif
  955. #ifdef SPARC
  956.         if(fixP->fx_r_type == SPARC_RELOC_HI22)
  957.             sectdiff = SPARC_RELOC_HI22_SECTDIFF;
  958.         else if(fixP->fx_r_type == SPARC_RELOC_LO10)
  959.             sectdiff = SPARC_RELOC_LO10_SECTDIFF;
  960.         else
  961. #endif
  962.         {
  963.             if(fixP->fx_r_type != 0)
  964.             as_fatal("incorrect fx_r_type (%u) for fx_subsy != 0 "
  965.                  "in fix_to_relocation_info()",fixP->fx_r_type);
  966.             sectdiff = RELOC_SECTDIFF;
  967.         }
  968.         memset(&sri, '\0',sizeof(struct scattered_relocation_info));
  969.         sri.r_scattered = 1;
  970.         sri.r_length    = riP->r_length;
  971.         sri.r_pcrel     = riP->r_pcrel;
  972.         sri.r_address   = riP->r_address;
  973.         sri.r_type      = sectdiff;
  974.         sri.r_value     = symbolP->sy_value;
  975.         *riP = *((struct relocation_info *)&sri);
  976.         riP++;
  977.  
  978.         sri.r_type      = RELOC_PAIR;
  979.         sri.r_value     = fixP->fx_subsy->sy_value;
  980.         if(sectdiff == RELOC_SECTDIFF)
  981.             sri.r_address = 0;
  982. #ifdef HPPA
  983.         else if(sectdiff == HPPA_RELOC_HI21_SECTDIFF){
  984.             calc_hppa_HILO(symbolP->sy_value - fixP->fx_subsy->sy_value,
  985.                    fixP->fx_offset, &left21, &right14);
  986.             sri.r_address = right14 & 0x3fff;
  987.         }
  988.         else if(sectdiff == HPPA_RELOC_LO14_SECTDIFF){
  989.             calc_hppa_HILO(symbolP->sy_value - fixP->fx_subsy->sy_value,
  990.                    fixP->fx_offset, &left21, &right14);
  991.             sri.r_address = left21 >> 11;
  992.         }
  993. #endif
  994. #ifdef SPARC
  995.         else if(sectdiff == SPARC_RELOC_HI22_SECTDIFF){
  996.             sri.r_address = (symbolP->sy_value - fixP->fx_subsy->sy_value
  997.                      + fixP->fx_offset) & 0x3ff;
  998.         }
  999.         else if(sectdiff == SPARC_RELOC_LO10_SECTDIFF){
  1000.             sri.r_address = ((symbolP->sy_value - fixP->fx_subsy->sy_value
  1001.                      + fixP->fx_offset) >> 10) & 0x3fffff;
  1002.         }
  1003. #endif
  1004.         *riP = *((struct relocation_info *)&sri);
  1005.         return(2 * sizeof(struct relocation_info));
  1006.         }
  1007.         /*
  1008.          * Determine if this is left as a local relocation entry must be
  1009.          * changed to a scattered relocation entry.  These entries allow
  1010.          * the link editor to scatter the contents of a section and a local
  1011.          * relocation can't be used when an offset is added to the symbol's
  1012.          * value (symbol + offset).  This is because the relocation must be
  1013.          * based on the value of the symbol not the value of the expression.
  1014.          * Thus a scattered relocation entry that encodes the address of the
  1015.          * symbol is used when the offset is non-zero.
  1016.          */
  1017. #if !defined(I860)
  1018.         /*
  1019.          * For processors that don't have all references as unique 32 bits
  1020.          * wide references scattered relocation entries are not generated.
  1021.          * This is so that the link editor does not get stuck not being able
  1022.          * to do the relocation if the high half of the reference is shared
  1023.          * by two references to two different symbols.
  1024.          */
  1025.         if(fixP->fx_offset != 0 &&
  1026.            ((symbolP->sy_type & N_TYPE) & ~N_EXT) != N_ABS
  1027. #ifdef M68K
  1028.            /*
  1029.         * Since the m68k's pc relative branch instructions use the
  1030.         * address of the beginning of the displacement (except for
  1031.         * byte) the code in m68k.c when generating fixes adds to the
  1032.         * offset 2 for word and 4 for long displacements.
  1033.         */
  1034.            && !(fixP->fx_pcrel &&
  1035.                 ((fixP->fx_size == 2 && fixP->fx_offset == 2) ||
  1036.                  (fixP->fx_size == 4 && fixP->fx_offset == 4)) )
  1037. #endif /* M68K */
  1038.            ){
  1039.  
  1040.         memset(&sri, '\0',sizeof(struct scattered_relocation_info));
  1041.         sri.r_scattered = 1;
  1042.         sri.r_length    = riP->r_length;
  1043.         sri.r_pcrel     = riP->r_pcrel;
  1044.         sri.r_address   = riP->r_address;
  1045.         sri.r_type      = riP->r_type;
  1046.         sri.r_value     = symbolP->sy_value;
  1047.         *riP = *((struct relocation_info *)&sri);
  1048.         }
  1049. #endif /* !defined(I860) */
  1050.     }
  1051.     count = 1;
  1052.     riP++;
  1053.  
  1054. #if !defined(M68K) && !defined(I386)
  1055.     /*
  1056.      * For RISC machines whenever we have a relocation item using the half
  1057.      * of an address we also emit a relocation item describing the other
  1058.      * half of the address so the linker can reconstruct the address to do
  1059.      * the relocation.
  1060.      */
  1061. #ifdef I860
  1062.     if(fixP->fx_r_type == I860_RELOC_HIGH ||
  1063.        fixP->fx_r_type == I860_RELOC_HIGHADJ)
  1064. #endif
  1065. #ifdef M88K
  1066.     if(fixP->fx_r_type == M88K_RELOC_HI16 ||
  1067.        fixP->fx_r_type == M88K_RELOC_LO16)
  1068. #endif
  1069. #ifdef M98K
  1070.     if(fixP->fx_r_type == M98K_RELOC_HI16 ||
  1071.        fixP->fx_r_type == M98K_RELOC_LO16 ||
  1072.        fixP->fx_r_type == M98K_RELOC_HA16 ||
  1073.        fixP->fx_r_type == M98K_RELOC_LO14)
  1074. #endif
  1075. #ifdef HPPA
  1076.     if(fixP->fx_r_type == HPPA_RELOC_HI21 ||
  1077.        fixP->fx_r_type == HPPA_RELOC_LO14 ||
  1078.        fixP->fx_r_type == HPPA_RELOC_BR17 ||
  1079.        fixP->fx_r_type == HPPA_RELOC_JBSR)
  1080. #endif
  1081. #ifdef SPARC
  1082.     if(fixP->fx_r_type == SPARC_RELOC_HI22 ||
  1083.        fixP->fx_r_type == SPARC_RELOC_LO10)
  1084. #endif
  1085.     {
  1086.         memset(riP, '\0', sizeof(struct relocation_info));
  1087.         switch(fixP->fx_size){
  1088.         case 1:
  1089.             riP->r_length = 0;
  1090.             break;
  1091.         case 2:
  1092.             riP->r_length = 1;
  1093.             break;
  1094.         case 4:
  1095.             riP->r_length = 2;
  1096.             break;
  1097.         default:
  1098.             as_fatal("Bad fx_size (0x%x) in fix_to_relocation_info()\n",
  1099.                  fixP->fx_size);
  1100.         }
  1101.         riP->r_pcrel = fixP->fx_pcrel;
  1102.         /*
  1103.          * We set r_extern to 0, so other apps won't try to use r_symbolnum
  1104.          * as a symbol table indice.  We set all the bits of r_symbolnum so 
  1105.          * it is all but guaranteed to be outside the range we use for non-
  1106.          * external types to denote what section the relocation is in.
  1107.          */
  1108.         riP->r_extern = 0;
  1109.         riP->r_symbolnum = 0x00ffffff;
  1110. #ifdef I860
  1111.         riP->r_type    = I860_RELOC_PAIR;
  1112.         riP->r_address = 0xffff & fixP->fx_value;
  1113. #endif
  1114. #ifdef M88K
  1115.         riP->r_type = M88K_RELOC_PAIR;
  1116.         if(fixP->fx_r_type == M88K_RELOC_HI16)
  1117.         riP->r_address = 0xffff & fixP->fx_value;
  1118.         else if(fixP->fx_r_type == M88K_RELOC_LO16)
  1119.         riP->r_address = 0xffff & (fixP->fx_value >> 16);
  1120. #endif
  1121. #ifdef M98K
  1122.         riP->r_type = M98K_RELOC_PAIR;
  1123.         if(fixP->fx_r_type == M98K_RELOC_HI16 ||
  1124.            fixP->fx_r_type == M98K_RELOC_HA16)
  1125.         riP->r_address = 0xffff & fixP->fx_value;
  1126.         else if(fixP->fx_r_type == M98K_RELOC_LO16 ||
  1127.             fixP->fx_r_type == M98K_RELOC_LO14)
  1128.         riP->r_address = 0xffff & (fixP->fx_value >> 16);
  1129. #endif
  1130. #ifdef HPPA
  1131.         riP->r_type     = HPPA_RELOC_PAIR;
  1132.         calc_hppa_HILO(fixP->fx_value - fixP->fx_offset,
  1133.                fixP->fx_offset, &left21, &right14);
  1134.         if (fixP->fx_r_type == HPPA_RELOC_LO14 ||
  1135.         fixP->fx_r_type == HPPA_RELOC_BR17)
  1136.         riP->r_address = left21 >> 11;
  1137.         else if (fixP->fx_r_type == HPPA_RELOC_HI21)
  1138.         riP->r_address = right14 & 0x3fff;
  1139.         else if (fixP->fx_r_type == HPPA_RELOC_JBSR){
  1140.         if((symbolP->sy_type & N_TYPE) == N_UNDF)
  1141.             riP->r_address = fixP->fx_value & 0xffffff;
  1142.         else
  1143.             riP->r_address = (fixP->fx_value - sect_addr) & 0xffffff;
  1144.         }
  1145. #endif
  1146. #ifdef SPARC
  1147.         riP->r_type     = SPARC_RELOC_PAIR;
  1148.         if (fixP->fx_r_type == SPARC_RELOC_HI22)
  1149.         riP->r_address = fixP->fx_value & 0x3ff;
  1150.         else if (fixP->fx_r_type == SPARC_RELOC_LO10)
  1151.         riP->r_address = (fixP->fx_value >> 10) & 0x3fffff;
  1152. #endif
  1153.         count = 2;
  1154.     }
  1155. #endif /* !defined(M68K) && !defined(I386) */
  1156.     return(count * sizeof(struct relocation_info));
  1157. }
  1158.  
  1159. #ifdef I860
  1160. /*
  1161.  * set_default_section_align() is used to set a default minimum section
  1162.  * alignment if the section exist.
  1163.  */
  1164. static
  1165. void
  1166. set_default_section_align(
  1167. char *segname,
  1168. char *sectname,
  1169. unsigned long align)
  1170. {
  1171.     frchainS *frcP;
  1172.  
  1173.     for(frcP = frchain_root; frcP != NULL; frcP = frcP->frch_next){
  1174.         if(strncmp(frcP->frch_section.segname, segname,
  1175.                sizeof(frcP->frch_section.segname)) == 0 &&
  1176.            strncmp(frcP->frch_section.sectname, sectname,
  1177.                sizeof(frcP->frch_section.sectname)) == 0){
  1178.         if(align > frcP->frch_section.align)
  1179.             frcP->frch_section.align = align;
  1180.         return;
  1181.         }
  1182.     }
  1183. }
  1184.  
  1185. /* 
  1186.  * clear_section_flags() clears the section types for literals from the section
  1187.  * flags field.  This is needed for processors that don't have all references
  1188.  * to sections as unique 32 bits wide references.  In this case the literal
  1189.  * flags are not set.  This is so that the link editor does not merge them and
  1190.  * get stuck not being able to fit the relocated address in the item to be
  1191.  * relocated or if the high half of the reference is shared by two references
  1192.  * to different symbols (which can also stick the link editor).
  1193.  */
  1194. static
  1195. void
  1196. clear_section_flags(void)
  1197. {
  1198.     frchainS *frcP;
  1199.  
  1200.     for(frcP = frchain_root; frcP != NULL; frcP = frcP->frch_next)
  1201.         if(frcP->frch_section.flags != S_ZEROFILL)
  1202.         frcP->frch_section.flags = 0;
  1203. }
  1204.  
  1205. /*
  1206.  * I860_tweeks() preforms the tweeks needed by the I860 processor to get minimum
  1207.  * section alignments and no merging of literals by the link editor.
  1208.  */
  1209. static
  1210. void
  1211. I860_tweeks(void)
  1212. {
  1213.     set_default_section_align("__TEXT", "__text", 5);
  1214.     set_default_section_align("__DATA", "__data", 4);
  1215.     set_default_section_align("__DATA", "__bss",  4);
  1216.  
  1217.     clear_section_flags();
  1218. }
  1219. #endif
  1220.