.gitignore: update to ignore all make created files
[keystone-rtos/ibl.git] / src / interp / coff / cload.c
1 /*
2  *
3  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 
4  * 
5  * 
6  *  Redistribution and use in source and binary forms, with or without 
7  *  modification, are permitted provided that the following conditions 
8  *  are met:
9  *
10  *    Redistributions of source code must retain the above copyright 
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  *    Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the 
15  *    documentation and/or other materials provided with the   
16  *    distribution.
17  *
18  *    Neither the name of Texas Instruments Incorporated nor the names of
19  *    its contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
23  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
24  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
26  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
27  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
28  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
31  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
32  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34 */
38 /***************************************************************************
39 * FILENAME: cload.c
40 * VERSION:  2.6  5/2/96  13:11:03
41 * SCCS ID:  "@(#)cload.c        2.6  5/2/96"
42 ***************************************************************************/
43 /******************************************************************************/
44 /* CLOAD.C  - Generic COFF Loader                      Version 6.00 4/96      */
45 /******************************************************************************/
46 /*                                                                            */
47 /*  This module contains functions to read in and load a COFF object file.    */
48 /*  The following routines are defined here:                                  */
49 /*                                                                            */
50 /*    cload()           - Main driver for COFF loader.                        */
51 /*    cload_headers()   - Read in the various headers of the COFF file.       */
52 /*    cload_data()      - Read in the raw data and load it into memory.       */
53 /*    cload_sect_data() - Read, relocate, and write out one section.          */
54 /*    cload_cinit()     - Process one buffer of C initialization records.     */
55 /*    cload_symbols()   - Read in the symbol table.                           */
56 /*    cload_strings()   - Read in the string table.                           */
57 /*    str_free()        - Free a string table.                                */
58 /*    sym_read()        - Read and relocate a symbol and its aux entry.       */
59 /*    sym_name()        - Return a pointer to the name of a symbol.           */
60 /*    sym_add_name()    - Add a symbol name to the string table.              */
61 /*    reloc_add()       - Add a symbol to the relocation symbol table.        */
62 /*    relocate()        - Perform a single relocation.                        */
63 /*    reloc_read()      - Read in and swap one relocation entry.              */
64 /*    reloc_size()      - Return the field size of a relocation type.         */
65 /*    reloc_offset()    - Return the field offset of a relocation type.       */
66 /*    reloc_stop()      - Return the number of bits to read for a reloc type. */
67 /*    sym_reloc_amount()- Return relocation amount for a relocation entry.    */
68 /*    unpack()          - Extract a relocation field from object bytes.       */
69 /*    repack()          - Encode a relocated field into object bytes.         */
70 /*    cload_lineno()    - Read in & swap line number entries.                 */
71 /*    swap4byte()       - Swap the order of bytes in a int.                  */
72 /*    swap2byte()       - Swap the order of bytes in a short.                 */
73 /*                                                                            */
74 /*  The loader calls the following external functions to perform application  */
75 /*  specific tasks:                                                           */
76 /*                                                                            */
77 /*   set_reloc_amount() - Define relocation amounts for each section.         */
78 /*   mem_write()        - Load a buffer of data into memory.                  */
79 /*   lookup_sym()       - Look up a symbol in an external symbol table.       */
80 /*   load_syms()        - Build the symbol table for the application.         */
81 /*   load_msg()         - Write diagnostic messages during loading.           */
82 /*                                                                            */
83 /******************************************************************************/
84 #include "header.h"
85 #include "coff_trg.h"
86 #if ((FILE_BASED) && !defined(FILE))
87 #include <stdio.h>
88 #endif
89 /*----------------------------------------------------------------------------*/
90 /* CONSTANTS, MACROS, VARIABLES, AND STRUCTURES FOR THE LOADER.               */
91 /*----------------------------------------------------------------------------*/
92 #define TRUE 1
93 #define FALSE 0
94 #define WORDSZ sizeof(T_DATA)           /* SIZE OF DATA UNITS IN OBJ FILE     */
96 #ifdef TMS320C60
97    extern int target_coff (unsigned short flags);
98 #endif
100 /*----------------------------------------------------------------------------*/
101 /* APPLICATION VARIABLES                                                      */
102 /*----------------------------------------------------------------------------*/
103 #if (FILE_BASED)
104 FILE   *fin;                                                    /* INPUT FILE                         */
105 #else
106 extern unsigned char gRxBuffer[0x400040];
107 #endif
108                             
109 int     need_data    = TRUE;            /* APPLICATION NEEDS RAW DATA         */
110 int     need_symbols = FALSE;           /* APPLICATION NEEDS SYMBOL TABLE     */
111 int     clear_bss    = FALSE;           /* CLEAR BSS SECTION                  */
114 /*----------------------------------------------------------------------------*/
115 /* FILL VALUES TO BE USED BY LOADERS                                          */
116 /*----------------------------------------------------------------------------*/
117 #if defined(OTIS)
118 extern int fill_bss;
119 extern int fill_bss_value;
120 #else
121 #define fill_bss 0
122 #define fill_bss_value 0
123 #endif
125 /*----------------------------------------------------------------------------*/
126 /* LOADER VARIABLES                                                           */
127 /*----------------------------------------------------------------------------*/
128 FILHDR  file_hdr;                       /* FILE HEADER STRUCTURE              */
129 int     coff_version;                   /* COFF VERSION USED IN FILE          */
130 AOUTHDR o_filehdr;                      /* OPTIONAL (A.OUT) FILE HEADER       */
131 T_ADDR  entry_point;                    /* ENTRY POINT OF MODULE              */
132 T_ADDR *reloc_amount = NULL;            /* AMOUNT OF RELOCATION PER SECTION   */
133 char   *sect_hdrs = NULL;               /* ARRAY OF SECTION HEADERS           */
134 char   *o_sect_hdrs = NULL;             /* ARRAY OF OLD COFF SECTION HEADERS  */
135 int     n_sections;                     /* NUMBER OF SECTIONS IN THE FILE     */
136 int     big_e_target;                   /* TARGET DATA IN BIG-ENDIAN FORMAT   */
137 int     byte_swapped;                   /* BYTE ORDERING OPPOSITE OF HOST     */
138 int     curr_sect;                      /* SECTION NUMBER CURRENTLY LOADING   */
139 int     load_err;                       /* ERROR CODE RETURNED IF LOADER FAILS*/
140 struct strtab *str_head = NULL;         /* LIST OF STRING TABLE BUFFERS       */
142 static T_SIZE  init_size = 0;           /* CURRENT SIZE OF C INITIALIZATION   */
143 static int     need_reloc;              /* RELOCATION REQUIRED                */
145 #if TMS320C60
146 int big_e_config = TRG_DEF_BIG_E;       /* ENDIANNESS CONFIGURATION           */
147 #else
148 int big_e_config = DONTCARE;            /* ENDIANNESS CONFIGURATION           */
149 #endif
151 /*----------------------------------------------------------------------------*/
152 /* THIS STRUCTURE IS USED TO STORE THE RELOCATION AMOUNTS FOR SYMBOLS.        */
153 /* EACH RELOCATABLE SYMBOL HAS A CORRESPONDING ENTRY IN THIS TABLE.           */
154 /* THE TABLE IS SORTED BY SYMBOL INDEX; LOOKUP USES A BINARY SEARCH.          */
155 /*----------------------------------------------------------------------------*/
156 typedef struct
158    int rt_index;                       /* INDEX OF SYMBOL IN SYMBOL TABLE    */
159    int rt_disp;                        /* AMOUNT OF RELOCATION               */
160 } RELOC_TAB;
162 /*----------------------------------------------------------------------------*/
163 /* THE RELOCATION SYMBOL TABLE IS ALLOCATED DYNAMICALLY, AND REALLOCATED      */
164 /* AS MORE SPACE IS NEEDED.                                                   */
165 /*----------------------------------------------------------------------------*/
166 #define RELOC_TAB_START 128             /* STARTING SIZE OF TABLE             */
167 #define RELOC_GROW_SIZE 128             /* REALLOC AMOUNT FOR TABLE           */
169 static RELOC_TAB *reloc_tab = NULL;     /* RELOCATION SYMBOL TABLE            */
171 static int        reloc_tab_size;       /* CURRENT ALLOCATED AMOUNT           */
172 static int        reloc_sym_index;      /* CURRENT SIZE OF TABLE              */
174 /*----------------------------------------------------------------------------*/
175 /* RUN-TIME RELOCATION (AS OPPOSED TO LOAD-TIME) RELOCATION IS DETERMINED     */
176 /* AS FOLLOWS:  IF THE SECTION'S RUNTIME ADDRESS == LOADTIME ADDRESS, USE     */
177 /* LOADTIME RELOCATION.  OTHERWISE, ASSUME LOADTIME RELOC ONLY (RUNTIME RELOC */
178 /* == 0).                                                                     */
179 /*----------------------------------------------------------------------------*/
180 #define RUN_RELOC_AMOUNT(i) ((SECT_HDR(i)->s_paddr == SECT_HDR(i)->s_vaddr) ?  \
181                                     reloc_amount[i] : 0)
183 /*----------------------------------------------------------------------------*/
184 /* DEFINE A STRUCTURE FOR STRING TABLE BUFFERS.  THESE BUFFERS ARE STORED     */
185 /* AS A LINKED LIST OF MEMORY PACKETS, EACH CONTAINING UP TO 64K OF THE       */
186 /* STRING TABLE.                                                              */
187 /*----------------------------------------------------------------------------*/
188 typedef struct strtab
190    unsigned int  size;                 /* SIZE OF THIS PACKET                */
191    unsigned int  offset;               /* STARTING OFFSET OF THIS PACKET     */
192    unsigned int  index;                /* AMOUNT CURRENTLY FILLED            */
193    struct strtab *next;                 /* NEXT BUFFER                        */
194    char           buf[1];               /* STRING DATA (EXPAND AS ALLOCATED)  */
195 } STRTAB;
197 #define MAX_STRING_ALLOC (unsigned int)(0xffff-sizeof(STRTAB)+1)
198                                        /* MAX STRING BUFFER: 64K (SMALL HOSTS)*/
199 #define MIN_STRING_ALLOC 0x0400        /* MIN STRING BUFFER: 1K               */
201 unsigned int unpack();
203 #define reloc_read(x)   TRUE
205 /* extern void mem_copy(unsigned char* dst, unsigned char* src, int nbytes); - defined in osal.h */
206 /******************************************************************************/
207 /*                                                                            */
208 /* CLOAD() - Main driver for COFF loader.                                     */
209 /*                                                                            */
210 /******************************************************************************/
211 int cload()
213    int result;
215    load_err = 0;
217    result   = cload_headers() && (need_reloc == FALSE) && cload_data();
219    if (reloc_tab) free(reloc_tab);
220    reloc_tab = NULL;
222    if(result == TRUE)
223        return 0;
224    else
225        return -1;
228 \f
229 /******************************************************************************/
230 /*                                                                            */
231 /* CLOAD_HEADERS() - Read in the various headers of the COFF file.            */
232 /*                                                                            */
233 /******************************************************************************/
234 int cload_headers()
236    int i;
238    byte_swapped = FALSE;
239    need_reloc   = FALSE;
240 #if FILE_BASED
241    if (fseek(fin, 0L, 0) != 0 || !fread(&file_hdr, FILHSZ, 1, fin)) 
242       { load_err = E_FILE; return FALSE; }
243 #else
244         mem_copy((void*)&file_hdr, gRxBuffer, FILHSZ);
245 #endif
247    /*-------------------------------------------------------------------------*/
248    /* MAKE SURE THIS IS REALLY A COFF FILE. CHECK FOR SWAPPED FILES.          */
249    /* DETERMINE BYTE ORDERING OF OBJECT DATA.                                 */
250    /*-------------------------------------------------------------------------*/
251    if (!ISCOFF(file_hdr.f_magic))
252    {
253        swap2byte(&file_hdr.f_magic);
255        if (!ISCOFF(file_hdr.f_magic)) { load_err = E_MAGIC; return FALSE; }
257        byte_swapped = TRUE;
259        swap2byte(&file_hdr.f_nscns);  swap4byte(&file_hdr.f_timdat);
260        swap4byte(&file_hdr.f_symptr); swap4byte(&file_hdr.f_nsyms);
261        swap2byte(&file_hdr.f_opthdr); swap2byte(&file_hdr.f_flags);
262 #if COFF_VERSION_1 || COFF_VERSION_2
263        swap2byte(&file_hdr.f_target_id); 
264 #endif
265    }
267    /*-------------------------------------------------------------------------*/
268    /* DETERMINE THE ENDIANNESS OF THE COFF FILE, AND ENSURE THE ENDIANNESS OF */
269    /* THE FILE IS THE SAME AS THE TARGET, IF THERE IS A TARGET.               */
270    /*-------------------------------------------------------------------------*/
271    big_e_target = ((file_hdr.f_flags & F_BIG) != 0);
272    if (big_e_config != DONTCARE && big_e_target != big_e_config) 
273       { load_err = E_ENDIAN; return FALSE; }
275    /*-------------------------------------------------------------------------*/
276    /* DETERMINE VERSION OF COFF BEING USED, CHECK TARGET ID IF NEEDED.        */
277    /*-------------------------------------------------------------------------*/
278    if (ISCOFF_1(file_hdr.f_magic) || ISCOFF_2(file_hdr.f_magic))
279    {
280        if (!ISMAGIC(file_hdr.f_target_id)) { load_err = E_MAGIC; return FALSE; }
281        coff_version = file_hdr.f_magic;
282    } 
283    else coff_version = COFF_MAGIC_0;
285 #ifdef TMS320C60
286    /*-------------------------------------------------------------------------*/
287    /* DETERMINE WHETHER THE RIGHT COFF IS BEING LOADED                        */
288    /*-------------------------------------------------------------------------*/
289    if ( !target_coff( file_hdr.f_flags) )
290        { load_err = E_FILE; return FALSE; }
291 #endif
292  
293    /*-------------------------------------------------------------------------*/
294    /* READ IN OPTIONAL HEADER, IF THERE IS ONE, AND SWAP IF NEEDED.           */
295    /*-------------------------------------------------------------------------*/
296    if (file_hdr.f_opthdr == AOUTSZ)
297    {
298 #if FILE_BASED          
299       fseek(fin, (int)FILHSZ_IN(coff_version), 0); 
300       if (fread(&o_filehdr, file_hdr.f_opthdr, 1, fin) != 1) 
301          { load_err = E_FILE; return FALSE; }
302 #else
303         mem_copy((void*)&o_filehdr, &gRxBuffer[(int)FILHSZ_IN(coff_version)], file_hdr.f_opthdr);
304 #endif   
306       if (byte_swapped)
307       {
308           swap2byte(&o_filehdr.magic);      swap2byte(&o_filehdr.vstamp);
309           swap4byte(&o_filehdr.tsize);      swap4byte(&o_filehdr.dsize);
310           swap4byte(&o_filehdr.bsize);      swap4byte(&o_filehdr.entrypt);
311           swap4byte(&o_filehdr.text_start); swap4byte(&o_filehdr.data_start);
312       }
313       entry_point = o_filehdr.entrypt;
314    }
316    /*-------------------------------------------------------------------------*/
317    /* Read in string table so that we can see long section names, if needed.  */
318    /* This used tobe read right before the symbol table was read, but now the */
319    /* section headers use "flexname" method to specify section names and so   */
320    /* might need access to a string table entry.                              */
321    /*-------------------------------------------------------------------------*/
322    //if (!cload_strings()) return FALSE;
324    /*-------------------------------------------------------------------------*/
325    /* READ IN SECTION HEADERS.                                                */
326    /*-------------------------------------------------------------------------*/
327    if (sect_hdrs)   { free(sect_hdrs);     sect_hdrs = NULL; }
328    if (o_sect_hdrs) { free(o_sect_hdrs); o_sect_hdrs = NULL; }
330    if (!(sect_hdrs = (char *)malloc((n_sections = file_hdr.f_nscns) * SCNHSZ)))
331       { load_err = E_ALLOC;  return FALSE; }
332       
333 #if FILE_BASED
334    fseek(fin, (int)FILHSZ_IN(coff_version) + file_hdr.f_opthdr, 0); 
335 #endif
336    /*-------------------------------------------------------------------------*/
337    /* Depending on which version of COFF we are reading, set up the section   */
338    /* headers or s copy that we can translate into the new version.           */
339    /*-------------------------------------------------------------------------*/
340    if (ISCOFF_2(coff_version))
341    {
342 #if FILE_BASED
343       if (fread(sect_hdrs,SCNHSZ_IN(coff_version),n_sections,fin) != n_sections)
344          { load_err = E_FILE;   return FALSE; }
345 #else
346         mem_copy((void*)sect_hdrs, &gRxBuffer[(int)FILHSZ_IN(coff_version) + file_hdr.f_opthdr], SCNHSZ_IN(coff_version)*n_sections );
347 #endif
348    }
349    else
350    {
351       if (!(o_sect_hdrs = (char *)malloc(n_sections * SCNHSZ_IN(coff_version))))
352          { load_err = E_ALLOC;  return FALSE; }
353 #if FILE_BASED
354       if (fread(o_sect_hdrs,SCNHSZ_IN(coff_version),n_sections,fin)!=n_sections)
355          { load_err = E_FILE;   return FALSE; }
356 #else
357         mem_copy((void*)o_sect_hdrs, &gRxBuffer[(int)FILHSZ_IN(coff_version) + file_hdr.f_opthdr], SCNHSZ_IN(coff_version)*n_sections );
358 #endif
359    }
361    if (reloc_amount) free(reloc_amount);
363         if (!(reloc_amount = (T_ADDR*)malloc(n_sections * sizeof(T_ADDR))))
364         { 
365         load_err = E_ALLOC;  
366         return FALSE; 
367         }
369    /*-------------------------------------------------------------------------*/
370    /* SWAP SECTION HEADERS IF REQUIRED.                                       */
371    /*-------------------------------------------------------------------------*/
372    for (i = 0; i < n_sections; i++)
373    {
374        SCNHDR   *sptr = SECT_HDR(i);
375        O_SCNHDR *tptr = O_SECT_HDR(i);
377        if (byte_swapped)
378        {
379           /*-----------------------------------------------------------------*/
380           /* Swap sections according to native COFF version.                 */
381           /*-----------------------------------------------------------------*/
382           if (ISCOFF_2(coff_version))
383           {
384              if (sptr->s_zeroes == 0L) swap4byte(&sptr->s_offset);
385              swap4byte(&sptr->s_paddr);  
386              swap4byte(&sptr->s_vaddr);
387              swap4byte(&sptr->s_size);   
388              swap4byte(&sptr->s_scnptr);
389              swap4byte(&sptr->s_relptr); 
390              swap4byte(&sptr->s_lnnoptr);
391              swap4byte(&sptr->s_nreloc); 
392              swap4byte(&sptr->s_nlnno);
393              swap4byte(&sptr->s_flags);  
394              /* s_mwidth   - single byte */
395              /* s_reserved - single byte */
396              swap2byte(&sptr->s_page);
397           }
398           else
399           {
400              swap4byte(&tptr->os_paddr);  
401              swap4byte(&tptr->os_vaddr);
402              swap4byte(&tptr->os_size);   
403              swap4byte(&tptr->os_scnptr);
404              swap4byte(&tptr->os_relptr); 
405              swap4byte(&tptr->os_lnnoptr);
406              swap2byte(&tptr->os_nreloc); 
407              swap2byte(&tptr->os_nlnno);
408              swap2byte(&tptr->os_flags);
409              /* os_reserved - one byte */
410              /* os_page     - one byte */
411           }
412        }
414        /*---------------------------------------------------------------------*/
415        /* Old COFF version section headers are now ready to be transferred.   */
416        /*---------------------------------------------------------------------*/
417        if (!ISCOFF_2(coff_version))
418        {
419           strn_copy(sptr->s_name, tptr->os_name, SYMNMLEN);
420           sptr->s_paddr   = tptr->os_paddr;
421           sptr->s_vaddr   = tptr->os_vaddr;
422           sptr->s_size    = tptr->os_size;
423           sptr->s_scnptr  = tptr->os_scnptr;
424           sptr->s_relptr  = tptr->os_relptr;
425           sptr->s_lnnoptr = tptr->os_lnnoptr;
426           sptr->s_nreloc  = tptr->os_nreloc;
427           sptr->s_nlnno   = tptr->os_nlnno;
428           sptr->s_flags   = tptr->os_flags;
429           sptr->s_page    = tptr->os_page;
430        }
432        reloc_amount[i] = 0;
434 #if 0    // not to search the string table
435       /*---------------------------------------------------------------------*/
436       /* Fix up section name if it is a pointer into the string table.       */
437       /*---------------------------------------------------------------------*/
438       if (sptr->s_zeroes == 0L)
439       {
440          STRTAB *packet = str_head;
442          if (packet == NULL) 
443          {
444              return -1;
445          }
447          if (str_head->offset > sptr->s_offset)
448          {
449              return -1;
450          }
452          while (sptr->s_offset < (int)packet->offset) packet = packet->next;
453          sptr->s_nptr = packet->buf + (sptr->s_offset - packet->offset);
454       }
455 #endif
456    } // for ends
459    /*-------------------------------------------------------------------------*/
460    /* CALL AN EXTERNAL ROUTINE TO DETERMINE THE RELOCATION AMOUNTS FOR        */
461    /* EACH SECTION.                                                           */
462    /*-------------------------------------------------------------------------*/
463    if (!set_reloc_amount()) { load_err = E_SETRELOC; return FALSE; }
464    for (i = 0; i < n_sections; i++) need_reloc |= (reloc_amount[i] != 0);
465    if (!need_data) need_reloc = FALSE;
467    if (need_reloc && (file_hdr.f_flags & F_RELFLG)) 
468       { load_err = E_RELOC; return FALSE; }
470    return TRUE;
473 \f
474 /******************************************************************************/
475 /*                                                                            */
476 /* CLOAD_DATA() - Read in the raw data and load it into memory.               */
477 /*                                                                            */
478 /******************************************************************************/
479 int cload_data()
481    int ok = TRUE;
483    if (!need_data) return TRUE;
485    /*-------------------------------------------------------------------------*/
486    /* LOOP THROUGH THE SECTIONS AND LOAD THEM ONE AT A TIME.                  */
487    /*-------------------------------------------------------------------------*/
488    for (curr_sect = 0; curr_sect < n_sections && ok; curr_sect++)
489    {
490       SCNHDR *sptr = SECT_HDR(curr_sect);                        
491       char   *sname = (sptr->s_zeroes == 0L) ? 
492                                 sptr->s_nptr : SNAMECPY(sptr->s_name);
494       /*----------------------------------------------------------------------*/
495       /* IF THIS IS THE TEXT SECTION, RELOCATE THE ENTRY POINT.               */
496       /*----------------------------------------------------------------------*/
497       if ((sptr->s_flags & STYP_TEXT) && !str_comp(sname, ".text"))
498          entry_point += RUN_RELOC_AMOUNT(curr_sect);
500       /*----------------------------------------------------------------------*/
501       /* IGNORE EMPTY SECTIONS OR SECTIONS WHOSE FLAGS INDICATE THE           */
502       /* SECTION IS NOT TO BE LOADED.  IF THE CLEAR_BSS FLAG IS SET, BSS      */
503       /* IS "LOADED" EVEN THOUGH IT HAS NO DATA, AND DEFER THE CINIT          */
504       /* SECTION UNTIL LATER TO ENSURE BSS IS LOADED FIRST.                   */
505       /*----------------------------------------------------------------------*/
506       if ((sptr->s_scnptr || ((clear_bss || fill_bss) && IS_BSS(sptr)))   &&
507           (sptr->s_size)                                              &&
508           !(sptr->s_flags & (STYP_DSECT | STYP_COPY | STYP_NOLOAD)))
509           ok &= cload_sect_data(sptr);
510    }
512   /*-------------------------------------------------------------------------*/
513   /* WE DEFERRED CINIT, LOAD IT/THEM NOW.                                    */
514   /*-------------------------------------------------------------------------*/
515   for (curr_sect = 0; curr_sect < n_sections && ok; curr_sect++)
516   {
517      SCNHDR *sptr = SECT_HDR(curr_sect);
518      char   *sname = (sptr->s_zeroes == 0L) ? 
519                                sptr->s_nptr : SNAMECPY(sptr->s_name);
520      
521      if (IS_CINIT(sptr))
522      {
523                 ok &= cload_sect_data(sptr);
524      }
525   }
527    return ok;
530 \f
531 /******************************************************************************/
532 /*                                                                            */
533 /* CLOAD_SECT_DATA() - Read, relocate, and write out the data for one section.*/
534 /*                                                                            */
535 /******************************************************************************/
536 int cload_sect_data(SCNHDR *sptr)
538    T_ADDR        addr    = sptr->s_vaddr; /* CURRENT ADDRESS IN SECTION       */
539    unsigned int nbytes;                  /* BYTE COUNT WITHIN SECTION        */
540    int           packet_size = 0;         /* SIZE OF CURRENT DATA BUFFER      */
541    int           excess  = 0;             /* BYTES LEFT FROM PREVIOUS BUFFER  */
542    unsigned int  n_reloc = 0;             /* COUNTER FOR RELOCATION ENTRIES   */
543    RELOC         reloc;                   /* RELOCATION ENTRY                 */
544    int           relsz   = RELSZ_IN(coff_version); 
545    unsigned char *packet = NULL;          /* LOAD BUFFER                      */
546    unsigned int section_length = (unsigned int)LOCTOBYTE(sptr->s_size);
547    unsigned int buffer_size    = LOADBUFSIZE;
549 #if defined (UNBUFFERED) && UNBUFFERED
550    /*-------------------------------------------------------------------------*/
551    /* IF UNBUFFERED, THEN SET SIZE TO SECTION LENGTH ROUNDED UP TO MULTIPLE   */
552    /* 32 BYTES.  WE MAINTAIN A MINIMIUM OF LOADBUFSIZE IN THE EVENT SOMEONE   */
553    /* CONTINUES TO USE THAT MACRO AS A SIZE LIMIT.                            */
554    /*-------------------------------------------------------------------------*/
555    buffer_size = MAX(buffer_size, (section_length + 32) & ~31ul); 
556 #endif
558    /*-------------------------------------------------------------------------*/
559    /* ENSURE LOADBUFSIZE IS A MULTIPLE OF 2                                   */
560    /*-------------------------------------------------------------------------*/
561    if (LOADBUFSIZE % 2) 
562    {
563        return -1;
564    }
566    /*-------------------------------------------------------------------------*/
567    /* READ THE FIRST RELOCATION ENTRY, IF THERE ARE ANY.                      */
568    /* IF THIS IS A BSS SECTION, CLEAR THE LOAD BUFFER.                        */
569    /*-------------------------------------------------------------------------*/
570 #if FILE_BASED   
571    if (need_reloc && sptr->s_nreloc &&
572        (fseek(fin, sptr->s_relptr, 0) != 0 || !reloc_read(&reloc)))
573       { load_err = E_FILE; return FALSE; }
574 #else
575         // need_reloc is not used....
576         if (need_reloc && sptr->s_nreloc && !reloc_read(&reloc, sptr->s_relptr))
577       { load_err = E_FILE; return FALSE; }
578 #endif
579    /*-------------------------------------------------------------------------*/
580    /* ALLOCATE THE PACKET BUFFER                                              */
581    /*-------------------------------------------------------------------------*/
582    packet = (unsigned char *) malloc(buffer_size);
583    if (!packet) { load_err = E_ALLOC; return FALSE; }
585 #ifdef OTIS
586    if (IS_BSS(sptr))
587    {
588       TRG_MVAL filval = fill_bss_value;
590       free (packet);
592       if (!mem_fill(filval, LOCTOBYTE(sptr->s_size), addr, sptr->s_page))
593          { load_err = E_MEMWRITE; return FALSE; }
594       return TRUE;
595    }
596 #else
597    /*-------------------------------------------------------------------------*/
598    /* Always want to clear memory for cases where memsize is not a multiple   */
599    /* of the data size being written out.  If we do not clear the array, the  */
600    /* last byte or so can be corrupted with data from the last buffer read.   */
601    /*-------------------------------------------------------------------------*/
602    for (nbytes = 0; nbytes < buffer_size; ++nbytes) packet[nbytes] = 0;
603 #endif
604        
605    /*-------------------------------------------------------------------------*/
606    /* COPY ALL THE DATA IN THE SECTION.                                       */
607    /*-------------------------------------------------------------------------*/
609    for (nbytes = 0; nbytes < section_length; nbytes += packet_size)
610    {
611       int j;
613       /*----------------------------------------------------------------------*/
614       /* READ IN A BUFFER OF DATA.  IF THE PREVIOUS RELOCATION SPANNED        */
615       /* ACROSS THE END OF THE LAST BUFFER, COPY THE LEFTOVER BYTES INTO      */
616       /* THE BEGINNING OF THE NEW BUFFER.                                     */
617       /*----------------------------------------------------------------------*/
618       for (j = 0; j < excess; ++j) packet[j] = packet[packet_size + j];
620       packet_size = (int)MIN(LOCTOBYTE(sptr->s_size) - nbytes, buffer_size);
622       if (sptr->s_scnptr)
623 #if FILE_BASED   
624           if ((fseek(fin, sptr->s_scnptr + (int)(nbytes + excess), 0) != 0) ||
625               (fread(packet + excess, packet_size - excess, 1, fin) != 1))
626            { 
627               load_err = E_FILE; 
628               free (packet);
629               return FALSE; 
630           }
631 #else
632         mem_copy((void*)(packet + excess), (void*)&gRxBuffer[sptr->s_scnptr + (int)(nbytes + excess)], packet_size - excess);
633 #endif
636       excess = 0;
638       /*----------------------------------------------------------------------*/
639       /* Clear out end of packet in case we write padding.                    */
640       /*----------------------------------------------------------------------*/
641       if (excess + packet_size < buffer_size)
642           for(j = excess + packet_size; j < buffer_size; j++)
643               packet[j] = 0;
645       /*----------------------------------------------------------------------*/
646       /* READ AND PROCESS ALL THE RELOCATION ENTRIES THAT AFFECT DATA         */
647       /* CURRENTLY IN THE BUFFER.                                             */
648       /*----------------------------------------------------------------------*/
649       if (need_reloc)
650          while (n_reloc < sptr->s_nreloc && 
651                 (T_ADDR)reloc.r_vaddr < addr + BYTETOLOC(packet_size))
652          {
653             int i       = (int)LOCTOBYTE(reloc.r_vaddr - addr);   /* BYTE NDX */
654             int fieldsz = reloc_size(reloc.r_type);               /* IN BITS  */
655             int wordsz  = MAX(fieldsz, reloc_stop(reloc.r_type)); /* IN BITS  */
657             /*----------------------------------------------------------------*/
658             /* IF THIS RELOCATION SPANS PAST THE END OF THE BUFFER,           */
659             /* SET 'EXCESS' TO THE NUMBER OF REMAINING BYTES AND FLUSH THE    */
660             /* BUFFER.  AT THE NEXT FILL, THESE BYTES WILL BE COPIED FROM     */
661             /* THE END OF THE BUFFER TO THE BEGINNING AND THEN RELOCATED.     */
662             /*----------------------------------------------------------------*/
663             if (i + (wordsz >> 3) > packet_size)
664             { 
665                i          -= i % LOADWORDSIZE;   /* DON'T BREAK WITHIN A WORD */
666                excess      = packet_size - i; 
667                packet_size = i;
668                break;
669             }
671             /*----------------------------------------------------------------*/
672             /* PERFORM THE RELOCATION AND READ IN THE NEXT RELOCATION ENTRY.  */
673             /*----------------------------------------------------------------*/
674 #if 0
675             if (!relocate(&reloc, packet + i, curr_sect)) 
676                 { free (packet); return FALSE; }
677 #endif
679 #if FILE_BASED  
680             if (n_reloc++ < sptr->s_nreloc                                    &&
681                (fseek(fin, sptr->s_relptr + ((int)n_reloc * relsz), 0) != 0  ||
682                  !reloc_read(&reloc)))
683 #else
684                 if (n_reloc++ < sptr->s_nreloc && !reloc_read(&reloc, sptr->s_relptr + ((int)n_reloc * relsz)));
685 #endif           
686                { load_err = E_FILE; free (packet); return FALSE; }
687          }
689       /*----------------------------------------------------------------------*/
690       /* WRITE OUT THE RELOCATED DATA TO THE TARGET DEVICE.  IF THIS IS A     */
691       /* CINIT SECTION, CALL A SPECIAL FUNCTION TO HANDLE IT.                 */
692       /*----------------------------------------------------------------------*/
693       if (!(IS_CINIT(sptr) ?
694               cload_cinit(packet, &packet_size, &excess) :
695               (int) mem_write(packet, packet_size, addr + reloc_amount[curr_sect], 
696                                                             sptr->s_page)))
697          { load_err = E_MEMWRITE; free (packet); return FALSE; }
699       /*----------------------------------------------------------------------*/
700       /* KEEP TRACK OF THE ADDRESS WITHIN THE SECTION.                        */
701       /*----------------------------------------------------------------------*/
702       addr += BYTETOLOC(packet_size);
704    }
706    free (packet);
707    return TRUE;
710 \f
711 /******************************************************************************/
712 /*                                                                            */
713 /* CLOAD_CINIT() - Process one buffer of C initialization records.            */
714 /*                                                                            */
715 /******************************************************************************/
716 int cload_cinit(unsigned char *packet, int *packet_size, int *excess)
718    int           i;                      /* BYTE COUNTER                      */
719    int           init_packet_size;       /* SIZE OF CURRENT INITIALIZATION    */
720    static T_ADDR init_addr;              /* ADDRESS OF CURRENT INITIALIZATION */
721    int           bss_page = 0;           /* BSS SECTION PAGE NUMBER           */
722  
723    /*-------------------------------------------------------------------------*/
724    /* FIND THE BSS SECTION ASSOCIATED WITH THE THE CINIT SECTION CURRENTLY    */
725    /* BEING LOADED.                                                           */
726    /*-------------------------------------------------------------------------*/
727    for (i = 0; i < n_sections; ++i)
728       if (IS_BSS(SECT_HDR(i))) 
729           { bss_page = SECT_HDR(i)->s_page; break; }
731    /*-------------------------------------------------------------------------*/
732    /*  PROCESS ALL THE INITIALIZATION RECORDS IN THE BUFFER.                  */
733    /*-------------------------------------------------------------------------*/
734    for (i = 0; i < *packet_size; i += init_packet_size)
735    {
736       /*----------------------------------------------------------------------*/
737       /* IF STARTING A NEW INITIALIZATION, READ THE SIZE AND ADDRESS FROM     */
738       /* THE TABLE.                                                           */
739       /*----------------------------------------------------------------------*/
740       if (init_size == 0)
741       {
742          T_SIZE temp;
743          int    align;
745          /*-------------------------------------------------------------------*/
746          /* POSITION THE BYTE INDEX ON THE NEXT INIT RECORD.                  */
747          /*-------------------------------------------------------------------*/
748          if (align = (i % INIT_ALIGN)) i += (INIT_ALIGN - align);
750          /*-------------------------------------------------------------------*/
751          /* IF THE SIZE AND ADDRESS ARE NOT FULLY CONTAINED IN THIS BUFFER,   */
752          /* STOP HERE.  SET THE 'EXCESS' COUNTER TO THE NUMBER OF UNPROCESSED */
753          /* BYTES - THESE WILL BE COPIED TO THE HEAD OF THE NEXT BUFFER.      */
754          /*-------------------------------------------------------------------*/
755          if ((int)(i + sizeof(T_SIZE)) > *packet_size)
756             { *excess += *packet_size - i;  *packet_size = i;  break; }
758          /*-------------------------------------------------------------------*/
759          /* IF THE NEXT SIZE FIELD IS ZERO, BREAK.                            */
760          /*-------------------------------------------------------------------*/
761          temp = unpack(packet + i, sizeof(T_SIZE)*8, sizeof(T_SIZE)*8, 0);
762          if (temp == 0) break;
764          /*-------------------------------------------------------------------*/
765          /* READ THE ADDRESS FIELD ,IF IT'S ALL HERE.                         */
766          /*-------------------------------------------------------------------*/
767          if ((int)(i + sizeof(T_SIZE) + sizeof(T_IADDR)) > *packet_size)
768              { *excess += *packet_size - i;  *packet_size = i;  break; }
770          i         += sizeof(T_SIZE);
771          init_size  = temp;
772          init_addr  = unpack(packet+i,sizeof(T_IADDR)*8,sizeof(T_IADDR)*8,0);
773          i         += sizeof(T_IADDR);
774       }
776       /*----------------------------------------------------------------------*/
777       /* WRITE OUT THE CURRENT PACKET, UP TO THE END OF THE BUFFER.           */
778       /*----------------------------------------------------------------------*/
779       if (init_packet_size = MIN(*packet_size-i, (int)(init_size * INIT_WSIZE)))
780       {
781         
782          if (!mem_write(packet + i, init_packet_size, init_addr, bss_page))
783             return FALSE;
785          init_addr += BYTETOLOC(init_packet_size);
786          init_size -= init_packet_size / INIT_WSIZE;
787       }
788    }
789    return TRUE;
792 #if 0
793 /******************************************************************************/
794 /*                                                                            */
795 /* CLOAD_SYMBOLS() - Read in the symbol table.                                */
796 /*                                                                            */
797 /******************************************************************************/
798 int cload_symbols()
800    SYMENT sym;
801    AUXENT aux;
802    int first, next;
804    if (file_hdr.f_nsyms == 0 || (!need_symbols && !need_reloc)) return TRUE;
806    /*------------------------------------------------------------------------*/
807    /* ALLOCATE THE RELOCATION SYMBOL TABLE.                                  */
808    /*------------------------------------------------------------------------*/
809    if (need_reloc)
810    {
811       reloc_sym_index = 0;
812       reloc_tab_size  = MIN(RELOC_TAB_START, (int)file_hdr.f_nsyms);
814       if (!(reloc_tab = (RELOC_TAB *)malloc(reloc_tab_size*sizeof(RELOC_TAB))))
815           { load_err = E_ALLOC; return FALSE; }
816    }
818    /*------------------------------------------------------------------------*/
819    /* IF THE APPLICATION NEEDS THE SYMBOL TABLE, LET IT READ IT IN.          */
820    /* PASS NEED_RELOC TO THE APPLICATION SO THAT IT CAN CALL RELOC_ADD().    */
821    /*------------------------------------------------------------------------*/
822    if (need_symbols) 
823    {
824       if (load_syms(need_reloc)) return TRUE;
825       else { load_err = E_SYM; return FALSE; }
826    }
828    /*------------------------------------------------------------------------*/
829    /*  READ THE SYMBOL TABLE AND BUILD THE RELOCATION SYMBOL TABLE           */
830    /*  FOR SYMBOLS THAT CAN BE USED IN RELCOATION, STORE THEM IN A           */
831    /*  SPECIAL SYMBOL TABLE THAT CAN BE SEARCHED QUICKLY DURING              */
832    /*  RELOCATION.                                                           */
833    /*------------------------------------------------------------------------*/
834    for (first = 0; first < file_hdr.f_nsyms; first = next)
835    {
836        if (!(next = sym_read(first, &sym, &aux))) 
837           { load_err = E_FILE; return FALSE; }
839        if (sym.n_sclass == C_EXT     || sym.n_sclass == C_EXTREF  ||
840            sym.n_sclass == C_STAT    || sym.n_sclass == C_LABEL   ||
841            sym.n_sclass == C_SYSTEM  || sym.n_sclass == C_BLOCK   || 
842            sym.n_sclass == C_FCN     || sym.n_sclass == C_STATLAB || 
843            sym.n_sclass == C_EXTLAB) 
844           if (!reloc_add(first, &sym)) return FALSE;
845    }
846    return TRUE;
850 /******************************************************************************/
851 /*                                                                            */
852 /* CLOAD_STRINGS() - Read in the string table.                                */
853 /*                                                                            */
854 /******************************************************************************/
855 int cload_strings()
857    unsigned int str_size;              /* SIZE OF STRING TABLE              */
858    unsigned int bufsize;               /* SIZE OF CURRENT BUFFER            */
859    unsigned int ntoread;                /* AMOUNT TO READ FROM FILE          */
860    int excess;                          /* AMOUNT LEFT OVER FROM LAST BUFFER */
861    STRTAB *packet;                      /* STRING TABLE BUFFER PACKET        */
862    unsigned int i = 0;
864    /*----------------------------------------------------------------------*/
865    /* Do not load if not loading/saving the symbol tables.                 */
866    /* This is because the string table is an extension of the symbol table */
867    /* and if you free and rebuild it, the symbol table's str_head will be  */
868    /* incorrect.                                                           */
869    /*----------------------------------------------------------------------*/
870    if (!need_symbols) return TRUE;
872    /*------------------------------------------------------------------------*/
873    /* FREE ANY PREVIOUS STRING BUFFERS                                       */
874    /*------------------------------------------------------------------------*/
875    str_free(str_head); str_head = NULL;
877    /*------------------------------------------------------------------------*/
878    /* SEEK TO THE END OF THE SYMBOL TABLE AND READ IN THE SIZE OF THE STRING */
879    /* TABLE.                                                                 */
880    /*------------------------------------------------------------------------*/
881 #if FILE_BASED
882    if ((file_hdr.f_nsyms == 0) ||
883            fseek(fin, file_hdr.f_symptr + (file_hdr.f_nsyms * SYMESZ), 0) != 0 ||
884        fread(&str_size, sizeof(int), 1, fin) != 1)
885        return TRUE;
886 #else
887    mem_copy(&str_size, &gRxBuffer[file_hdr.f_symptr + (file_hdr.f_nsyms * SYMESZ)], sizeof(int));       
888    if ((file_hdr.f_nsyms == 0))
889        return TRUE; 
890 #endif
891    if (byte_swapped) swap4byte(&str_size);
893    /*------------------------------------------------------------------------*/
894    /* THE STRING TABLE IS READ IN AS A LINKED LIST OF BUFFERS.  TO           */
895    /* PREVENT NAMES FROM BEING SPLIT ACROSS MULTIPLE BUFFERS, ANY PARTIAL    */
896    /* NAME AT THE END OF A BUFFER IS COPIED INTO THE BEGINNING OF THE        */
897    /* NEXT BUFFER.  THE VARIABLE 'EXCESS' KEEPS TRACK OF HOW MUCH NEEDS      */
898    /* TO BE COPIED FROM THE PREVIOUS BUFFER.                                 */
899    /*------------------------------------------------------------------------*/
900    str_size -= 4;                       /* SUBTRACT OFF 4 BYTES ALREADY READ */
901    excess    = 0;                       /* INITIALIZE LAST-BUFFER OVERFLOW   */
904    /*------------------------------------------------------------------------*/
905    /* READ STRING BUFFERS UNTIL THE WHOLE STRING TABLE IS READ.              */
906    /*------------------------------------------------------------------------*/
907    while (str_size)
908    {
909       /*---------------------------------------------------------------------*/
910       /* ALLOCATE A NEW BUFFER.  ON 16-BIT MACHINES, RESTRICT THE            */
911       /* BUFFER SIZE TO THE MAXIMUM THAT CAN BE ALLOCATED AT ONCE.           */
912       /*---------------------------------------------------------------------*/
913       bufsize = str_size + excess;
915       if (sizeof(int) < 4  && bufsize > MAX_STRING_ALLOC)
916          bufsize = MAX_STRING_ALLOC;
918       if (!(packet = (struct strtab *)malloc(sizeof(STRTAB) + 
919                                              (unsigned int)bufsize - 1)))
920          { load_err = E_ALLOC; return FALSE; }
922       /*---------------------------------------------------------------------*/
923       /* COPY ANY PARTIAL STRING FROM THE LAST BUFFER INTO THIS ONE.         */
924       /* THEN FILL THE REST OF THE BUFFER BY READING FROM THE FILE.          */
925       /*---------------------------------------------------------------------*/
926       if (excess)
927          strn_copy(packet->buf, str_head->buf + str_head->size, excess);
929       ntoread = (unsigned int)(bufsize - excess);
930 #if FILE_BASED
931       if (fread(packet->buf + excess, ntoread, 1, fin) != 1) 
932          { load_err = E_FILE; return FALSE; }
933 #else
934         mem_copy(packet->buf + excess, &gRxBuffer[file_hdr.f_symptr + (file_hdr.f_nsyms * SYMESZ) +sizeof(int)+ i++*ntoread], ntoread);
935 #endif   
936       str_size -= ntoread;
938       /*---------------------------------------------------------------------*/
939       /* IF THE BUFFER ENDS IN A PARTIAL STRING (DOESN'T END IN NULL),       */
940       /* KEEP TRACK OF HOW MANY CHARACTERS ARE IN THE PARTIAL STRING         */
941       /* SO THEY CAN BE COPIED INTO THE NEXT BUFFER.                         */
942       /*---------------------------------------------------------------------*/
943       for (excess = 0; packet->buf[bufsize - 1]; --bufsize, ++excess) ;
945       /*---------------------------------------------------------------------*/
946       /* LINK THE NEW BUFFER INTO THE HEAD OF THE LIST.                      */
947       /*---------------------------------------------------------------------*/
948       packet->size   = 
949       packet->index  = bufsize;
950       packet->next   = str_head;
951       packet->offset = str_head ? (str_head->offset + str_head->size) : 4;
952       str_head       = packet;
953    }
954    return TRUE;
957 \f
958 /******************************************************************************/
959 /*                                                                            */
960 /* STR_FREE() - Free the list of string table buffers.                        */
961 /*                                                                            */
962 /******************************************************************************/
963 void str_free(STRTAB *head)
965    STRTAB *this_one, *next;
966    for (this_one = head; this_one; this_one = next)
967    {
968       next = this_one->next;
969       free(this_one);
970    }
975 /******************************************************************************/
976 /*                                                                            */
977 /* SYM_READ() - Read and relocate a symbol and its aux entry.  Return the     */
978 /*              index of the next symbol.                                     */
979 /*                                                                            */
980 /******************************************************************************/
981 int sym_read(int index, SYMENT *sym, AUXENT *aux)
983     /*------------------------------------------------------------------------*/
984     /* READ IN A SYMBOL AND ITS AUX ENTRY.                                    */
985     /*------------------------------------------------------------------------*/
986 #if FILE_BASED
987     if (fseek(fin, file_hdr.f_symptr + (index * SYMESZ), 0) != 0 ||
988         fread(sym, SYMESZ, 1, fin) != 1                                ||
989         (sym->n_numaux && fread(aux, SYMESZ, 1, fin) != 1)) 
990       { load_err = E_FILE; return FALSE; }
991 #else
992         mem_copy((void*)sym, (void*)&gRxBuffer[file_hdr.f_symptr + (index * SYMESZ)], SYMESZ); 
993     if (sym->n_numaux) 
994     { 
995         mem_copy((void*)aux, (void*)&gRxBuffer[file_hdr.f_symptr + ( (index+1) * SYMESZ)], SYMESZ);
996         load_err = E_FILE; 
997         return FALSE; 
998     }
999 #endif
1000     if (byte_swapped)
1001     {
1002         /*--------------------------------------------------------------------*/
1003         /* SWAP THE SYMBOL TABLE ENTRY.                                       */
1004         /*--------------------------------------------------------------------*/
1005         if (sym->n_zeroes == 0) swap4byte(&sym->n_offset);
1006         swap4byte(&sym->n_value);
1007         swap2byte(&sym->n_scnum);
1008         swap2byte(&sym->n_type);
1010         /*--------------------------------------------------------------------*/
1011         /* SWAP THE AUX ENTRY, BASED ON THE STORAGE CLASS.                    */
1012         /*--------------------------------------------------------------------*/
1013         if (sym->n_numaux) switch(sym->n_sclass)
1014         {
1015           case C_FILE    : break;
1017           case C_STRTAG  :
1018           case C_UNTAG   :
1019           case C_ENTAG   : swap4byte(&aux->x_tag.x_fsize);
1020                            swap4byte(&aux->x_tag.x_endndx);
1021                            break;
1023           case C_FCN     : if (!str_comp(sym->n_name, ".bf"))
1024                            {
1025                                swap2byte(&aux->x_block.x_lcnt);
1026                                swap4byte(&aux->x_block.x_regmask); 
1027                                swap4byte(&aux->x_block.x_framesize);
1028                            }
1029                                 
1030           case C_BLOCK   : swap2byte(&aux->x_block.x_lnno);
1031                            swap4byte(&aux->x_block.x_endndx);
1032                            break;
1034           case C_EOS     : swap4byte(&aux->x_eos.x_fsize);
1035                            swap4byte(&aux->x_eos.x_tagndx);
1036                            break;
1038           default        : /*-------------------------------------------------*/
1039                            /* HANDLE FUNCTION DEFINITION SYMBOL               */
1040                            /*-------------------------------------------------*/
1041                            if (((sym->n_type >> 4) & 3) == DCT_FCN)
1042                            {
1043                                swap4byte(&aux->x_func.x_tagndx);
1044                                swap4byte(&aux->x_func.x_fsize);
1045                                swap4byte(&aux->x_func.x_lnnoptr);
1046                                swap4byte(&aux->x_func.x_endndx);
1047                            }
1049                            /*-------------------------------------------------*/
1050                            /* HANDLE ARRAYS.                                  */
1051                            /*-------------------------------------------------*/
1052                            else if (((sym->n_type >> 4) & 3) == DCT_ARY)
1053                            {
1054                                swap4byte(&aux->x_array.x_tagndx);
1055                                swap4byte(&aux->x_array.x_fsize);
1056                                swap2byte(&aux->x_array.x_dimen[0]);
1057                                swap2byte(&aux->x_array.x_dimen[1]);
1058                                swap2byte(&aux->x_array.x_dimen[2]);
1059                                swap2byte(&aux->x_array.x_dimen[3]);
1060                            }
1062                            /*-------------------------------------------------*/
1063                            /* HANDLE SECTION DEFINITIONS                      */
1064                            /*-------------------------------------------------*/
1065                            else if (sym->n_type == 0)
1066                            {
1067                                swap4byte(&aux->x_scn.x_scnlen);
1068                                swap2byte(&aux->x_scn.x_nreloc);
1069                                swap2byte(&aux->x_scn.x_nlinno);
1070                            }
1072                            /*-------------------------------------------------*/
1073                            /* HANDLE MISC SYMBOL RECORD                       */
1074                            /*-------------------------------------------------*/
1075                            else
1076                            {
1077                                swap4byte(&aux->x_sym.x_fsize);
1078                                swap4byte(&aux->x_sym.x_tagndx);
1079                            }
1080         }
1081     }
1083     /*------------------------------------------------------------------------*/
1084     /* RELOCATE THE SYMBOL, BASED ON ITS STORAGE CLASS.                       */
1085     /*------------------------------------------------------------------------*/
1086     switch(sym->n_sclass)
1087     {
1088        case C_SYSTEM  :
1089        case C_EXT     :
1090        case C_EXTREF  :
1091        case C_STAT    :
1092        case C_LABEL   :
1093        case C_BLOCK   :
1094        case C_FCN     : 
1095        case C_STATLAB :
1096        case C_EXTLAB  :
1097           /*------------------------------------------------------------------*/
1098           /* IF THE SYMBOL IS UNDEFINED, CALL AN APPLICATION ROUTINE TO LOOK  */
1099           /* IT UP IN AN EXTERNAL SYMBOL TABLE.  IF THE SYMBOL IS DEFINED,    */
1100           /* RELOCATE IT ACCORDING TO THE SECTION IT IS DEFINED IN.           */
1101           /*------------------------------------------------------------------*/
1102           if (sym->n_scnum == 0) 
1103              lookup_sym((short)index, sym, aux);
1104           else if (sym->n_scnum > 0) 
1105           {
1106              if (sym->n_sclass == C_STATLAB || sym->n_sclass == C_EXTLAB)
1107                   sym->n_value += reloc_amount[sym->n_scnum - 1];
1108              else sym->n_value += RUN_RELOC_AMOUNT(sym->n_scnum - 1);
1109           }
1110     }
1112     return (index + sym->n_numaux + 1);
1115 \f
1116 /******************************************************************************/
1117 /*                                                                            */
1118 /* SYM_NAME() - Return a pointer to the name of a symbol in either the symbol */
1119 /*              entry or the string table.                                    */
1120 /*                                                                            */
1121 /******************************************************************************/
1122 char *sym_name(SYMENT *symptr)
1124     static char temp[9];
1126     if (symptr->n_zeroes == 0)
1127     {
1128        STRTAB *packet = str_head;
1130        /*---------------------------------------------------------------------*/
1131        /* Return the empty string if this symbol has no name (offset == 0)    */
1132        /*---------------------------------------------------------------------*/
1133        if (symptr->n_offset < 4) /* Anything below 4 isn't valid */
1134        {
1135           temp[0] = 0;
1136           return temp;
1137        }
1139        /*---------------------------------------------------------------------*/
1140        /* Otherwise, return the string in the string table.                   */
1141        /*---------------------------------------------------------------------*/
1142        while (packet && symptr->n_offset < (int)packet->offset)
1143           packet = packet->next;
1145        /*---------------------------------------------------------------------*/
1146        /* Return the empty string if packet NULL (invalid offset)             */
1147        /*---------------------------------------------------------------------*/
1148        if (!packet)
1149        {
1150           temp[0] = 0;
1151           return temp;
1152        }
1154        return packet->buf + (symptr->n_offset - packet->offset);
1155     }
1156     
1157     strn_copy(temp, symptr->n_name, 8);
1158     temp[8] = 0;
1159     return temp;
1163 /******************************************************************************/
1164 /*                                                                            */
1165 /* SYM_ADD_NAME() - Given a symbol table entry, return a pointer to the       */
1166 /*                  symbol's name in the string table.  Add the name to the   */
1167 /*                  table if it's not already there.                          */
1168 /*                                                                            */
1169 /******************************************************************************/
1170 char *sym_add_name(SYMENT *symptr)
1172     char *dest;
1173     char *result;
1174     int i;
1176     /*------------------------------------------------------------------------*/
1177     /* IF THE SYMBOL'S NAME WAS IN THE COFF STRING TABLE, LOOK THROUGH THE    */
1178     /* LIST OF STRING TABLE BUFFERS UNTIL FINDING THE ONE THE NAME IS IN,     */
1179     /* AND SIMPLY POINT INTO THE BUFFER.                                      */
1180     /*------------------------------------------------------------------------*/
1181     if (symptr->n_zeroes == 0)
1182        return sym_name(symptr);
1184     /*------------------------------------------------------------------------*/
1185     /* OTHERWISE ADD THE STRING TO THE STRING TABLE.                          */
1186     /* ALLOCATE AND LINK IN A NEW PACKET IF NECESSARY.  NEW PACKETS ARE       */
1187     /* LINKED TO THE HEAD OF THE LIST TO EASE ADDING NEW SYMBOLS.             */
1188     /*------------------------------------------------------------------------*/
1189     if (!str_head || str_head->index + SYMNMLEN + 1 > str_head->size)
1190     {
1191        STRTAB *packet;
1193        if (!(packet = (STRTAB *)malloc(sizeof(STRTAB) + MIN_STRING_ALLOC - 1)))
1194           { load_err = E_ALLOC; return NULL; }
1196        packet->size   = MIN_STRING_ALLOC;
1197        packet->index  = 0;
1198        packet->next   = str_head;
1199        packet->offset = str_head ? (str_head->offset + str_head->size) : 4;
1200        str_head       = packet;
1201     }
1203     /*------------------------------------------------------------------------*/
1204     /* COPY THE NAME INTO THE STRING TABLE.                                   */
1205     /*------------------------------------------------------------------------*/
1206     result = dest = str_head->buf + str_head->index; 
1207     for (i = 0; *dest++ = symptr->n_name[i++]; )
1208        if (i == SYMNMLEN) { *dest++ = '\0'; ++i; break; }
1210     symptr->n_zeroes = 0;
1211     symptr->n_offset = str_head->offset + str_head->index;
1212     str_head->index += i;
1213     return result;
1215 #endif
1217 #if 0
1218 /******************************************************************************/
1219 /*                                                                            */
1220 /* RELOC_ADD() - Add an entry to the relocation symbol table.  This table     */
1221 /*               stores relocation information for each relocatable symbol.   */
1222 /*                                                                            */
1223 /******************************************************************************/
1224 int reloc_add(int index, SYMENT *sym)
1226    int disp;                            /* RELOCATION AMOUNT FOR THIS SYMBOL */
1228    if (!need_reloc) return TRUE;
1230    /*-------------------------------------------------------------------------*/
1231    /* USE THE SYMBOL VALUE TO CALCULATE THE RELOCATION AMOUNT:                */
1232    /* 1) IF THE SYMBOL WAS UNDEFINED (DEFINED IN SECTION 0), USE THE          */
1233    /*    SYMBOL'S VALUE.                                                      */
1234    /* 2) IF THE SYMBOL HAS A POSITIVE SECTION NUMBER, USE THE RELOCATION      */
1235    /*    AMOUNT FOR THE SECTION IN WHICH THE SYMBOL IS DEFINED.               */
1236    /* 3) OTHERWISE, THE SYMBOL IS ABSOLUTE, SO THE RELOCATION AMOUNT IS 0.    */
1237    /*-------------------------------------------------------------------------*/
1238    if (sym->n_scnum == 0)
1239       disp = sym->n_value;
1240    else if (sym->n_scnum > 0)
1241    {
1242       if (sym->n_sclass == C_STATLAB || sym->n_sclass == C_EXTLAB)
1243            disp = reloc_amount[sym->n_scnum - 1];
1244       else disp = RUN_RELOC_AMOUNT(sym->n_scnum - 1);
1245    }
1246    else disp = 0;
1248    /*-------------------------------------------------------------------------*/
1249    /* IF THERE IS A NON-ZERO RELOCATION AMOUNT, ADD THE SYMBOL TO THE TABLE.  */
1250    /*-------------------------------------------------------------------------*/
1251    if (disp == 0) return TRUE;
1253    if (reloc_sym_index >= reloc_tab_size)
1254    {
1255       reloc_tab_size += RELOC_GROW_SIZE;
1256       reloc_tab = (RELOC_TAB *)realloc((char *)reloc_tab, 
1257                                        reloc_tab_size*sizeof(RELOC_TAB));
1259       if (!reloc_tab) { load_err = E_ALLOC; return FALSE; }
1260    }
1261    reloc_tab[reloc_sym_index  ].rt_index = index;
1262    reloc_tab[reloc_sym_index++].rt_disp  = disp;
1264    return TRUE;
1269 /******************************************************************************/
1270 /*                                                                            */
1271 /* RELOCATE() - Perform a single relocation by patching the raw data.         */
1272 /*                                                                            */
1273 /******************************************************************************/
1274 int relocate(RELOC *rp, unsigned char *data, int s)
1276 /*   RELOC         *rp;                    RELOCATION ENTRY                   */
1277 /*   unsigned char *data;                  DATA BUFFER                        */
1278 /*   int            s;                     INDEX OF CURRENT SECTION           */
1279    int fieldsz = reloc_size(rp->r_type);     /* SIZE OF ACTUAL PATCH VALUE    */
1280    int offset  = reloc_offset(rp->r_type);   /* OFFSET OF ACTUAL PATCH VALUE  */
1281    int wordsz  = MAX(fieldsz, reloc_stop(rp->r_type)); /* SIZE CONTAINING FLD */
1282    int objval;                              /* FIELD TO BE PATCHED           */
1283    int reloc_amt;                           /* AMOUNT OF RELOCATION          */
1285    int pp_shift_cnt = 0;
1286    int pp_local     = FALSE;
1288    if (rp->r_type == R_ABS) return TRUE;          /* NOTHING TO DO   */
1290    /*-------------------------------------------------------------------------*/
1291    /* DETERMINE THE RELOCATION AMOUNT FROM THE RELOCATION SYMBOL TABLE.       */
1292    /*-------------------------------------------------------------------------*/
1293    reloc_amt = (rp->r_symndx == -1) ? RUN_RELOC_AMOUNT(s) 
1294                                     : sym_reloc_amount(rp);
1296    /*-------------------------------------------------------------------------*/
1297    /* EXTRACT THE RELOCATABLE FIELD FROM THE OBJECT DATA.                     */
1298    /*-------------------------------------------------------------------------*/
1299    objval = unpack(data, fieldsz, wordsz, offset + BIT_OFFSET(rp->r_vaddr));
1301    /*-------------------------------------------------------------------------*/
1302    /* MODIFY THE FIELD BASED ON THE RELOCATION TYPE.                          */
1303    /*-------------------------------------------------------------------------*/
1304    switch (rp->r_type)
1305    {
1306       /*----------------------------------------------------------------------*/
1307       /* NORMAL RELOCATIONS: ADD IN THE RELOCATION AMOUNT.                    */
1308       /*----------------------------------------------------------------------*/
1309       case R_RELBYTE:
1310       case R_RELWORD:
1311       case R_REL24:
1312       case R_RELLONG:
1313       case R_DIR32:
1314       case R_PARTLS16:
1315          objval += reloc_amt;
1316          break;
1318       /*--------------------------------------------------------------------*/
1319       /* ADD IN THE RELOCATION AMOUNT, BUT MAKE SURE WE'RE STILL IN THE     */
1320       /* 370'S REGISTER FILE.                                               */
1321       /*--------------------------------------------------------------------*/
1322       case R_RRNREG:
1323       case R_RRRELREG:
1324          if (rp->r_type == R_RRNREG)
1325             objval = ((char)objval + reloc_amt);
1326          else objval += reloc_amt;
1327  
1328          if (objval & ((-1L >> 8*fieldsz) << 8*fieldsz))
1329          {
1330             /* ERROR */
1331          }
1332  
1333          break;
1334  
1335       /*--------------------------------------------------------------------*/
1336       /* PP UNSCALED 15-BIT OFFSET RELOCATION.                              */
1337       /*--------------------------------------------------------------------*/
1338       case R_PP15    :
1339       case R_PPL15   :
1340       case R_PPN15   :
1341       case R_PPLN15  :
1342          {
1343             int  bit;
1344             char *sname = (SECT_HDR(s)->s_zeroes == 0L) ?
1345                           SECT_HDR(s)->s_nptr : SNAMECPY(SECT_HDR(s)->s_name);
1347             pp_local = (rp->r_type == R_PPL15) || (rp->r_type == R_PPLN15);
1349             /*--------------------------------------------------------------*/
1350             /* IF NEGATIVE RELOC TYPE, THEN TREAT CONST OFFSET AS A NEGATIVE*/
1351             /*--------------------------------------------------------------*/
1352             if (rp->r_type == R_PPN15 || rp->r_type == R_PPLN15)
1353             {
1354                 objval      = -objval;
1355                 rp->r_type -= 010;           /* CHANGE TYPE TO NON NEG.     */
1356             }
1358             objval += reloc_amt;
1360             /*--------------------------------------------------------------*/
1361             /* IF THE ADDRESS STILL FALLS WITHIN AN APPROPRIATE RANGE       */
1362             /*--------------------------------------------------------------*/
1363             if ((objval >= 0x00000000 && objval <= 0x00007fff) || 
1364                 (objval >= 0x01000000 && objval <= 0x010007ff) )
1365                 break;
1367             /*--------------------------------------------------------------*/
1368             /* IF THE ADDRESS FALLS OUTSIDE AN APPROPRIATE RANGE, BUT CAN   */
1369             /* BE SCALED BY SIZE TO GET BACK INTO RANGE, THEN READ THE UPPER*/
1370             /* BIT OF THE SIZE FIELD.  IF IT IS A 1, THEN WE CAN SCALE THIS */
1371             /* OFFSET BY 4, IF IT IS 0, THEN WE CAN SCALE THIS OFFSET BY 2. */ 
1372             /*--------------------------------------------------------------*/
1373             bit = unpack(data, 1, 64, pp_local ? 30 : 8);
1374  
1375             /*--------------------------------------------------------------*/
1376             /* DETERMINE IF THE OFFSET IS ALIGNED FOR SCALING.  IF SO,      */
1377             /* THEN PACK THE SCALED OFFSET INTO INSTRUCTION, CHANGE THE     */
1378             /* RELOC TYPE TO SCALED, AND TURN ON SCALE BIT IN INSTRUCT.     */
1379             /*--------------------------------------------------------------*/
1380             if (!(objval & ((2<<bit)-1)) && 
1381                  (objval >>= (bit+1)) >= 0 && objval <= 0x7fff)
1382             {
1383                 rp->r_type = pp_local ? (bit ? R_PPL15W : R_PPL15H) : 
1384                                         (bit ? R_PP15W : R_PP15H);
1385                 repack(1, data, 1, 64, pp_local ? 28 : 6);
1386                 break;
1387             }
1388             
1389             /*--------------------------------------------------------------*/
1390             /* ERROR, THE OFFSET WILL NOT FIT SCALED OR UNSCALED.           */
1391             /*--------------------------------------------------------------*/
1392             
1393             load_err = E_RELOCENT;
1394             return FALSE;
1395          }
1397       /*--------------------------------------------------------------------*/
1398       /* PP SCALED 15-BIT OFFSET RELOCATION. FOR R_PP15W THE RELOC_AMT IS   */
1399       /* DIVIDED BY 4.  FOR R_PP15H THE RELOC_AMT IS DIVIDED BY 2.          */ 
1400       /*--------------------------------------------------------------------*/
1401       case R_PP15W   :
1402       case R_PPL15W  :
1403       case R_PPN15W  :
1404       case R_PPLN15W :  pp_shift_cnt++;   /* FALL THROUGH */
1406       case R_PP15H   :
1407       case R_PPL15H  :
1408       case R_PPN15H  :
1409       case R_PPLN15H :  pp_shift_cnt++;   /* FALL THROUGH */
1410          {
1411             int obj_addr_x;
1412             char *sname = (SECT_HDR(s)->s_zeroes == 0) ? 
1413                           SECT_HDR(s)->s_nptr : SNAMECPY(SECT_HDR(s)->s_name);
1415             /*--------------------------------------------------------------*/
1416             /* NOTE THAT THIS IS DEPENDENT ON THE NUMBERING OF THESE RELOC  */
1417             /* VALUES.                                                      */
1418             /*--------------------------------------------------------------*/
1419             pp_local = (rp->r_type & 4);
1421             /*--------------------------------------------------------------*/
1422             /* IF NEGATIVE RELOC TYPE, THEN TREAT CONST OFFSET AS NEGATIVE  */
1423             /*--------------------------------------------------------------*/
1424             if (rp->r_type >= R_PPN15) 
1425             {
1426                 objval      = -objval;
1427                 rp->r_type -= 010;           /* CHANGE TYPE TO NON NEG.     */
1428             }
1430             obj_addr_x = (objval << pp_shift_cnt) + reloc_amt;
1432             /*--------------------------------------------------------------*/
1433             /* LINK TIME ADDRESS VIOLATES THE SCALING FACTOR WE ARE USING   */
1434             /* FOR THIS OPERAND. UNSCALE THE VALUE IF IT WILL FIT IN 15 BITS*/
1435             /* BY CHANGING RELOC TYPE TO UNSCALED, AND CHANGING SCALE BIT   */
1436             /* IN THE INSTRUCTION.                                          */
1437             /*--------------------------------------------------------------*/
1438             if (pp_shift_cnt && (reloc_amt & ((1<<pp_shift_cnt)-1)))
1439             {
1440                 objval     = obj_addr_x;
1441                 rp->r_type = (pp_local ? R_PPL15 : R_PP15);
1442                 repack(0, data, 1, 64, pp_local ? 28 : 6);
1443             }
1444             else objval = obj_addr_x >> pp_shift_cnt;
1446             /*--------------------------------------------------------------*/
1447             /* IF THE ADDRESS STILL FALLS WITHIN AN APPROPRIATE RANGE       */
1448             /*--------------------------------------------------------------*/
1449             if ((objval     >= 0x00000000  && objval     <= 0x00007fff) || 
1450                 (obj_addr_x >= 0x01000000  && obj_addr_x <= 0x010007ff) )
1451                 break;
1453             /*--------------------------------------------------------------*/
1454             /* ERROR, THE OFFSET WILL NOT FIT SCALED OR UNSCALED.           */
1455             /*--------------------------------------------------------------*/
1456             
1457             load_err = E_RELOCENT;
1458             return FALSE;
1459          }
1461       /*--------------------------------------------------------------------*/
1462       /* PP 16-bit byte offset relocation. For R_PP16B the lower 15-bits    */
1463       /* are handled just like R_PP15, and the upper bit is placed in the   */
1464       /* scale indicator bit of the field.                                  */
1465       /*--------------------------------------------------------------------*/
1466       case R_PP16B   :
1467       case R_PPL16B  :
1468       case R_PPN16B  :
1469       case R_PPLN16B :
1470          {
1471             char *sname = (SECT_HDR(s)->s_zeroes == 0) ? 
1472                           SECT_HDR(s)->s_nptr : SNAMECPY(SECT_HDR(s)->s_name);
1474             pp_local = (rp->r_type == R_PPL16B) || (rp->r_type == R_PPLN16B);
1476             /*--------------------------------------------------------------*/
1477             /* READ THE SCALE BIT (16th BIT) AND CREATE 16 BIT CONSTANT OFF */
1478             /*--------------------------------------------------------------*/
1479             objval |= (unpack(data, 1, 64, pp_local ? 28 : 6) << 15);
1481             /*--------------------------------------------------------------*/
1482             /* IF NEGATIVE RELOC TYPE, THEN TREAT CONST OFFSET AS NEGATIVE  */
1483             /*--------------------------------------------------------------*/
1484             if (rp->r_type == R_PPN16B || rp->r_type == R_PPLN16B)
1485             {
1486                objval      = - objval;
1487                rp->r_type -= 010; /* CHANGE THE TYPE TO A NON NEG TYPE.     */
1488             }
1490             objval += reloc_amt;
1492             /*--------------------------------------------------------------*/
1493             /* IF THE ADDRESS STILL FALLS WITHIN AN APPROPRIATE RANGE       */
1494             /*--------------------------------------------------------------*/
1495             if ((objval >= 0x00000000 && objval <= 0x0000ffff) || 
1496                 (objval >= 0x01000000 && objval <= 0x010007ff) )
1497             {
1498                /*-----------------------------------------------------------*/
1499                /* RELOCATE THE 16TH BIT OF THE ADDRESS.                     */
1500                /*-----------------------------------------------------------*/
1501                repack(((objval&0x8000) >> 15), data, 1, 64, pp_local ? 28 : 6);
1502                break;
1503             }
1505             /*--------------------------------------------------------------*/
1506             /* ADDRESS IS OUT OF RANGE.                                     */
1507             /*--------------------------------------------------------------*/
1508             
1509             load_err = E_RELOCENT;
1510             return FALSE;
1511          }
1513       /*--------------------------------------------------------------------*/
1514       /* PP BASE ADDRESS RELOCATION.  BIT 0 IS 0 IF IN DATA RAM, 1 IF IN    */
1515       /* PARAMETER RAM.  THIS CODE ASSUMES THAT WE DO NOT RELOCATE FROM     */
1516       /* PRAM TO DRAM OR FROM DRAM TO PRAM AT LOAD TIME.                    */
1517       /*--------------------------------------------------------------------*/
1518       case R_PPLBASE: pp_local = TRUE;
1519       case R_PPBASE:
1520          {
1521            /*---------------------------------------------------------------*/
1522            /* IF WAS DRAM AND RELOC_AMT IS GREAT ENOUGH TO MOVE INTO PRAM,  */
1523            /* CHANGE TO PRAM                                                */
1524            /*---------------------------------------------------------------*/
1525            if (!objval && reloc_amt > (int)(0x01000000 - 0xC000)) objval = 1;
1527            /*---------------------------------------------------------------*/
1528            /* IF WAS PRAM AND RELOC_AMT IS NEGATIVE AND CAN MOVE INTO DRAM, */
1529            /* CHANGE TO DRAM                                                */
1530            /*---------------------------------------------------------------*/
1531            else if (objval && (-reloc_amt) > (int)(0x01000000 - 0xC000))
1532                objval = 0;
1534            break;
1535          }
1537       /*----------------------------------------------------------------------*/
1538       /* 34010 ONE'S COMPLEMENT RELOCATION.  SUBTRACT INSTEAD OF ADD.         */
1539       /*----------------------------------------------------------------------*/
1540       case R_OCRLONG:
1541          objval -= reloc_amt;
1542          break;
1544       /*----------------------------------------------------------------------*/
1545       /* 34020 WORD-SWAPPED RELOCATION.  SWAP BEFORE RELOCATING.              */
1546       /*----------------------------------------------------------------------*/
1547       case R_GSPOPR32:
1548       case R_OCBD32:
1549           objval  = ((objval >> 16) & 0xFFFF) | (objval << 16); 
1550           objval += (rp->r_type == R_GSPOPR32) ? reloc_amt : -reloc_amt; 
1551           objval  = ((objval >> 16) & 0xFFFF) | (objval << 16);
1552           break; 
1554       /*----------------------------------------------------------------------*/
1555       /* PC-RELATIVE RELOCATIONS.  IN THIS CASE THE RELOCATION AMOUNT         */
1556       /* IS ADJUSTED BY THE PC DIFFERENCE.   IF THIS IS AN INTERNAL           */
1557       /* RELOCATION TO THE CURRENT SECTION, NO ADJUSTMENT IS NEEDED.          */
1558       /*----------------------------------------------------------------------*/
1559       case R_PCRBYTE:
1560       case R_PCRWORD:
1561       case R_GSPPCR16:
1562       case R_GSPPCA16:
1563       case R_PCRLONG:
1564       case R_PCR24:
1565       case R_ANKPCR16:
1566       case R_ANKPCR8:
1567          {
1568             int           shift = 8 * (4 - fieldsz);
1569             unsigned int pcdif = RUN_RELOC_AMOUNT(s);
1571             /*----------------------------------------------------------------*/
1572             /* HANDLE SPECIAL CASES OF JUMPING FROM ABSOLUTE SECTIONS (SPECIAL*/
1573             /* RELOC TYPE) OR TO ABSOLUTE DESTINATION (SYMNDX == -1).  IN     */
1574             /* EITHER CASE, SET THE APPROPRIATE RELOCATION AMOUNT TO 0.       */
1575             /*----------------------------------------------------------------*/
1576             if( rp->r_symndx == -1 )      reloc_amt = 0;
1577             if( rp->r_type == R_GSPPCA16) pcdif = 0;
1579             /*----------------------------------------------------------------*/
1580             /* Handle ankoor's offset where upper 14 (PCR8) and upper 6(PCR16)*/
1581             /* bits of 22 bit address is held in r_disp field of reloc entry  */
1582             /*----------------------------------------------------------------*/
1583             if(rp->r_type == R_ANKPCR8 || rp->r_type == R_ANKPCR16)
1584             {
1585                 shift = 10;
1586                 objval |= rp->r_disp << ((rp->r_type == R_ANKPCR8) ? 8 : 16);
1587             }
1589             reloc_amt -= pcdif;
1591             if (rp->r_type == R_GSPPCR16 || rp->r_type == R_GSPPCA16)
1592                reloc_amt >>= 4;                              /* BITS TO WORDS */
1594             objval  = (int)(objval << shift) >> shift;      /* SIGN EXTEND   */
1595             objval += reloc_amt;
1596             break;
1597          }
1599       /*--------------------------------------------------------------------*/
1600       /* Ankoor page-addressing.  Calculate address from the 22-bit         */
1601       /* value in the relocation field plus the relocation amount. Shift    */
1602       /* out the lower 16 bits.                                             */
1603       /*--------------------------------------------------------------------*/
1604       case R_PARTMS6:
1605           objval = (objval & 0xC0) |
1606                    (((rp->r_disp += reloc_amt) >> 16) & 0x3F);
1607           break;
1609       /*----------------------------------------------------------------------*/
1610       /* 320C30 PAGE-ADDRESSING RELOCATION.  CALCULATE THE ADDRESS FROM       */
1611       /* THE 8-BIT PAGE VALUE IN THE FIELD, THE 16-BIT OFFSET IN THE RELOC    */
1612       /* ENTRY, AND THE RELOCATION AMOUNT.  THEN, STORE THE 8-BIT PAGE        */
1613       /* VALUE OF THE RESULT BACK IN THE FIELD.                               */
1614       /*----------------------------------------------------------------------*/
1615       case R_PARTMS8:
1616           objval = (int)((objval << 16) + rp->r_disp + reloc_amt) >> 16;
1617           break;
1619       /*----------------------------------------------------------------------*/
1620       /* DSP(320) PAGE-ADDRESSING.  CALCULATE ADDRESS FROM THE 16-BIT         */
1621       /* VALUE IN THE RELOCATION FIELD PLUS THE RELOCATION AMOUNT.  OR THE    */
1622       /* TOP 9 BITS OF THIS RESULT INTO THE RELOCATION FIELD.                 */
1623       /*----------------------------------------------------------------------*/
1624       case R_PARTMS9:
1625           objval = (objval & 0xFE00) | 
1626                    (((int)(rp->r_disp + reloc_amt) >> 7) & 0x1FF);
1627           break;
1629       /*----------------------------------------------------------------------*/
1630       /* DSP(320) PAGE-ADDRESSING.  CALCULATE ADDRESS AS ABOVE, AND OR THE    */
1631       /* 7-BIT DISPLACEMENT INTO THE FIELD.                                   */
1632       /*----------------------------------------------------------------------*/
1633       case R_PARTLS7:
1634           objval = (objval & 0x80) | ((rp->r_disp + reloc_amt) & 0x7F);
1635           break;
1637       /*--------------------------------------------------------------------*/
1638       /* Ankoor page-addressing.  Calculate address from the 22-bit         */
1639       /* value in the relocation field plus the relocation amount. Mask off */
1640       /* bits [21:16] and [5:0] to extract a data page within a 64K page    */
1641       /*--------------------------------------------------------------------*/
1642       case R_PARTMID10:
1643           objval = (objval & 0xFC00) |
1644                    (((rp->r_disp += reloc_amt) >> 6) & 0x3FF);
1645           break;
1647       /*--------------------------------------------------------------------*/
1648       /* RR(370) MSB RELOCATION.  CALCULATE ADDRESS FROM THE 16-BIT VALUE   */
1649       /* IN THE RELOCATION ENTRY PLUS THE RELOCATION AMOUNT.  PATCH THE     */
1650       /* MSB OF THE RESULT INTO THE RELOCATION FIELD.                       */
1651       /*--------------------------------------------------------------------*/
1652       case R_HIWORD:
1653           objval += (rp->r_disp += (unsigned short)reloc_amt) >> 8;
1654           break;
1656       /*--------------------------------------------------------------------*/
1657       /* C8+ High byte of 24-bit address.  Calculate address from 24-bit    */
1658       /* value in the relocation entry plus the relocation amount.  Patch   */
1659       /* the MSB of the result into the relocation field.                   */
1660       /*--------------------------------------------------------------------*/
1661       case R_C8PHIBYTE:
1662           objval = (int)((objval << 16) + rp->r_disp + reloc_amt) >> 16;
1663           break;
1665       /*--------------------------------------------------------------------*/
1666       /* C8+ Middle byte of 24-bit address.  Calculate address from 24-bit  */
1667       /* value in the relocation entry plus the relocation amount.  Patch   */
1668       /* the middle byte of the result into the relocation field.           */
1669       /*--------------------------------------------------------------------*/
1670       case R_C8PMIDBYTE:
1671           objval = (int)((objval << 16) + rp->r_disp + reloc_amt) >> 8;
1672           break;
1674       /*--------------------------------------------------------------------*/
1675       /* C8+ Vector Address.  Calculate address from 24-bit value in the    */
1676       /* relocation entry plus the relocation amount.  MSB must be 0xFF     */
1677       /* since interrupt and trap handlers must be programmed in the top-   */
1678       /* most segment of memory.  Patch bottom 16-bits of the result into   */
1679       /* the relocation field.                                              */
1680       /*--------------------------------------------------------------------*/
1681       case R_C8PVECADR:
1682           objval += reloc_amt;
1683           if ((objval & 0xFF0000) != 0xFF0000)
1684           {
1685              /* ERROR */
1686           }
1687           objval &= 0xFFFF;
1688           break;
1690       /*----------------------------------------------------------------------*/
1691       /* C8+ 24-bit Address.  The byte ordering for 24-bit addresses on the   */
1692       /* C8+ is reversed (low, middle, high).  Needs to be unordered, add     */
1693       /* in reloc_amt, then re-ordered.                                       */
1694       /*----------------------------------------------------------------------*/
1695       case R_C8PADR24:
1696           objval = ((objval>>16) | (objval&0xff00) | ((objval&0xff)<<16));
1697           objval += reloc_amt;
1698           objval = ((objval>>16) | (objval&0xff00) | ((objval&0xff)<<16));
1699           break;
1701       /*----------------------------------------------------------------------*/
1702       /* DSP(320) 13-BIT CONSTANT.  RELOCATE ONLY THE LOWER 13 BITS OF THE    */
1703       /* FIELD.                                                               */
1704       /*----------------------------------------------------------------------*/
1705       case R_REL13:
1706           objval = (objval & 0xE000) | ((objval + reloc_amt) & 0x1FFF);
1707           break;
1709       /*--------------------------------------------------------------------*/
1710       /* ANKOOR 22-bit extended address.  Calculate address by masking      */
1711       /* off the opcode and OR in the lower 16-bit constant + the           */
1712       /* amount.                                                            */
1713       /*--------------------------------------------------------------------*/
1714       case R_REL22:
1715          {
1716             unsigned int obj_hi = unpack(data  , 16, 16, 0);
1717             unsigned int obj_lo = unpack(data+2, 16, 16, 0);
1719             /*--------------------------------------------------------------*/
1720             /* BUILD THE OFFSET TO BE RELOCATED.                            */
1721             /*--------------------------------------------------------------*/
1722             objval = ((obj_hi & 0x003F) << 16) | (obj_lo & 0xFFFF);
1724             /*--------------------------------------------------------------*/
1725             /* Calculate displacement                                       */
1726             /*--------------------------------------------------------------*/
1727             objval += reloc_amt;
1729             /*--------------------------------------------------------------*/
1730             /* REPACK THE RELOCATED VALUE BACK IN THE OBJECT VALUE.         */
1731             /*--------------------------------------------------------------*/
1732             obj_hi = (obj_hi & 0xFFC0) | ((objval & 0x3F0000) >> 16);
1733             obj_lo = objval & 0xFFFF;
1734             repack(obj_hi, data  , 16, 16, 0);
1735             repack(obj_lo, data+2, 16, 16, 0);
1737             return TRUE;
1738          }
1740       /*--------------------------------------------------------------------*/
1741       /* DSP, LEAD 23-bit extended address.  Calculate address by masking   */
1742       /* off the opcode and OR in the lower 16-bit constant + the           */
1743       /* amount.                                                            */
1744       /*--------------------------------------------------------------------*/
1745       case R_REL23:
1746          {
1747             unsigned int obj_hi = unpack(data  , 16, 16, 0);
1748             unsigned int obj_lo = unpack(data+2, 16, 16, 0);
1750             /*--------------------------------------------------------------*/
1751             /* BUILD THE OFFSET TO BE RELOCATED.                            */
1752             /*--------------------------------------------------------------*/
1753             objval = ((obj_hi & 0x007F) << 16) | (obj_lo & 0xFFFF);
1755             /*--------------------------------------------------------------*/
1756             /* Calculate displacement                                       */
1757             /*--------------------------------------------------------------*/
1758             objval += reloc_amt;
1760             /*--------------------------------------------------------------*/
1761             /* REPACK THE RELOCATED VALUE BACK IN THE OBJECT VALUE.         */
1762             /*--------------------------------------------------------------*/
1763             obj_hi = (obj_hi & 0xFF80) | ((objval & 0x7F0000) >> 16);
1764             obj_lo = objval & 0xFFFF;
1765             repack(obj_hi, data  , 16, 16, 0);
1766             repack(obj_lo, data+2, 16, 16, 0);
1768             return TRUE;
1769          }
1772       /*----------------------------------------------------------------------*/
1773       /* PRISM (370/16) code label relocation.  Convert word address to byte  */
1774       /* address, add in relocation, convert back to word address.            */
1775       /*----------------------------------------------------------------------*/
1776       case R_LABCOD:
1777           objval = ((objval << 1) + reloc_amt) >> 1;
1778           break;
1779    }
1781    /*-------------------------------------------------------------------------*/
1782    /* PACK THE RELOCATED FIELD BACK INTO THE OBJECT DATA.                     */
1783    /*-------------------------------------------------------------------------*/
1784    repack(objval, data, fieldsz, wordsz, offset + BIT_OFFSET(rp->r_vaddr));
1785    return TRUE;
1786
1789 /******************************************************************************/
1790 /*                                                                            */
1791 /* RELOC_READ() - Read a single relocation entry.                             */
1792 /*                                                                            */
1793 /******************************************************************************/
1794 #if FILE_BASED
1795 int reloc_read(RELOC *rptr)
1796 #else
1797 int reloc_read(RELOC *rptr, unsigned int offset)
1798 #endif
1800 #if COFF_VERSION_1 || COFF_VERSION_2
1801    /*------------------------------------------------------------------------*/
1802    /* THE FOLLOWING UNION IS USED TO READ IN VERSION 0 OR 1 RELOC ENTRIES    */
1803    /*------------------------------------------------------------------------*/
1804    /* THE FORMAT OF RELOCATION ENTRIES CHANGED BETWEEN COFF VERSIONS 0 AND 1.*/
1805    /* VERSION 0 HAS A 16 BIT SYMBOL INDEX, WHILE VERSION 1 HAS A 32 BIT INDX.*/
1806    /*------------------------------------------------------------------------*/
1807    union { RELOC new_c; RELOC_OLD old; } input_entry;
1808 #if FILE_BASED
1809    if (fread(&input_entry, RELSZ_IN(coff_version), 1, fin) != 1)
1810       { load_err = E_FILE; return FALSE; }
1811 #else
1812         mem_copy((void*)&input_entry, (void*)&gRxBuffer[offset], RELSZ_IN(coff_version));
1813 #endif
1814    /*------------------------------------------------------------------------*/
1815    /* IF LOADING A VERSION 0 FILE, TRANSLATE ENTRY TO VERSION 1 FORMAT.      */
1816    /* (THIS COULD BE SIMPLER - ALL THE SWAPS EXCEPT FOR THE SYMBOL INDEX     */
1817    /* COULD BE DONE AFTER THE TRANSLATION - BUT THIS SEEMS TO BE CLEARER)    */
1818    /*------------------------------------------------------------------------*/
1819    if (ISCOFF_0(coff_version))
1820    {
1821       if (byte_swapped)
1822       {
1823          swap4byte(&input_entry.old.r_vaddr);
1824          swap2byte(&input_entry.old.r_type);
1826          /* if a field reloc, fields are chars, so don't swap */
1827          if (!isfldrel(input_entry.old.r_type))
1828          {
1829              swap2byte(&input_entry.old.r_symndx);
1830              swap2byte(&input_entry.old.r_disp);
1831          }
1832       }
1834       rptr->r_vaddr  = input_entry.old.r_vaddr;
1835       rptr->r_symndx = input_entry.old.r_symndx;
1836       rptr->r_disp   = input_entry.old.r_disp;
1837       rptr->r_type   = input_entry.old.r_type;
1838    }
1839    else
1840    {
1841       *rptr = input_entry.new_c;
1843       if (byte_swapped)
1844       {
1845          swap4byte(&rptr->r_vaddr); 
1846          swap2byte(&rptr->r_type);
1848          /* Again, if a field reloc, fields are chars, so don't swap */
1849          if (!isfldrel(rptr->r_type))
1850          {
1851              swap4byte(&rptr->r_symndx);
1852              swap2byte(&rptr->r_disp);  
1853          }
1854       }
1855    }
1857 #else
1858    /*-------------------------------------------------------------------------*/
1859    /* READ IN AND BYTE SWAP AN VERSION 0 RELOC ENTRY                          */
1860    /*-------------------------------------------------------------------------*/
1861    if (fread(rptr, RELSZ, 1, fin) != 1) { load_err = E_FILE; return FALSE; }
1863    if (byte_swapped)
1864    {
1865       swap4byte(&rptr->r_vaddr);
1866       swap2byte(&rptr->r_type);  
1868       /* If a field reloc, fields are chars, so don't swap */
1869       if (!isfldrel(rptr->r_type))
1870       {
1871           swap2byte(&rptr->r_symndx);
1872           swap2byte(&rptr->r_disp);
1873       }
1874    }
1875 #endif
1877    return TRUE;
1881 #endif
1882 /*************************************************************************/
1883 /*                                                                       */
1884 /*   RELOC_SIZE()-                                                       */
1885 /*      Return the field size of a relocation type.                      */
1886 /*                                                                       */
1887 /*************************************************************************/
1889 int reloc_size(int type)
1891    switch (type)
1892    {
1893        case R_PPBASE:
1894        case R_PPLBASE:      return 1;
1896        case R_HIWORD:
1897        case R_C8PHIBYTE:
1898        case R_C8PMIDBYTE:
1899        case R_RELBYTE:
1900        case R_PCRBYTE:
1901        case R_RRNREG:
1902        case R_RRRELREG:
1903        case R_ANKPCR8:
1904        case R_PARTLS6:
1905        case R_PARTMS6:
1906        case R_PARTLS7:      return 8;
1908        case R_PP15:
1909        case R_PP15W:
1910        case R_PP15H:
1911        case R_PP16B:
1912        case R_PPN15:
1913        case R_PPN15W:
1914        case R_PPN15H:
1915        case R_PPN16B:
1916        case R_PPL15:
1917        case R_PPL15W:
1918        case R_PPL15H:
1919        case R_PPL16B:
1920        case R_PPLN15:
1921        case R_PPLN15W:
1922        case R_PPLN15H:
1923        case R_PPLN16B:      return 15;
1925        case R_LABCOD:
1926        case R_RELWORD:
1927        case R_PCRWORD:
1928        case R_ANKPCR16:
1929        case R_GSPPCR16:
1930        case R_GSPPCA16:
1931        case R_PARTLS16:
1932        case R_PARTMS8:
1933        case R_PARTMS9:
1934        case R_PARTMID10:
1935        case R_PARTMS16:
1936        case R_REL22:
1937        case R_REL13:        
1938        case R_C8PVECADR:    return 16;
1940        case R_REL24:
1941        case R_PCR24:
1942        case R_PCR24W:
1943       case R_C8PADR24:      return 24;
1945        case R_MPPCR:
1946        case R_GSPOPR32:
1947        case R_RELLONG:
1948        case R_PCRLONG:
1949        case R_OCBD32:
1950        case R_OCRLONG:
1951        case R_DIR32:        return 32;
1953        default:             return 0;
1954    }
1958 /*************************************************************************/
1959 /*                                                                       */
1960 /*   RELOC_OFFSET()-                                                     */
1961 /*      Return the offset of a relocation type field.  The value of      */
1962 /*      offset should be the bit offset of the LSB of the field in       */
1963 /*      little-endian mode.                                              */
1964 /*                                                                       */
1965 /*************************************************************************/
1967 int reloc_offset(int type)
1969    switch (type)
1970    {
1971        case R_PP15    :
1972        case R_PP15W   :
1973        case R_PP15H   :
1974        case R_PP16B   :
1975        case R_PPN15   :
1976        case R_PPN15W  :
1977        case R_PPN15H  :
1978        case R_PPN16B  :
1979        case R_PPLBASE :     return 22;
1981        case R_PPL15   :
1982        case R_PPL15W  :
1983        case R_PPL15H  :
1984        case R_PPL16B  :
1985        case R_PPLN15  :
1986        case R_PPLN15W :
1987        case R_PPLN15H :
1988        case R_PPLN16B :
1989        case R_PPBASE  :     return 0;
1991        default        :     return 0;
1992    }
1996 /*************************************************************************/
1997 /*                                                                       */
1998 /*   RELOC_STOP() -                                                      */
1999 /*      Return the number of bits to read for a relocation type.         */
2000 /*                                                                       */
2001 /*************************************************************************/
2003 int reloc_stop(int type)
2005    switch (type)
2006    {
2007        case R_PPBASE  :
2008        case R_PPLBASE :
2010        case R_PP15    :
2011        case R_PP15W   :
2012        case R_PP15H   :
2013        case R_PP16B   :
2015        case R_PPL15   :
2016        case R_PPL15W  :
2017        case R_PPL15H  :
2018        case R_PPL16B  :
2020        case R_PPN15   :
2021        case R_PPN15W  :
2022        case R_PPN15H  :
2023        case R_PPN16B  :
2025        case R_PPLN15  :
2026        case R_PPLN15W :
2027        case R_PPLN15H :
2028        case R_PPLN16B :   return 64;
2030        default       :    return WORDSZ * 8;
2031    }
2035 #if 0
2036 /******************************************************************************/
2037 /*                                                                            */
2038 /* SYM_RELOC_AMOUNT() - Determine the amount of relocation for a particular   */
2039 /*                      relocation entry.  Search the relocation symbol table */
2040 /*                      for the referenced symbol, and return the amount from */
2041 /*                      the table.                                            */
2042 /*                                                                            */
2043 /******************************************************************************/
2044 int sym_reloc_amount(RELOC *rp)
2046    int index = rp->r_symndx;
2048    int i = 0,
2049        j = reloc_sym_index - 1;
2051    /*-------------------------------------------------------------------------*/
2052    /* THIS IS A SIMPLE BINARY SEARCH (THE RELOC TABLE IS ALWAYS SORTED).      */
2053    /*-------------------------------------------------------------------------*/
2054    while (i <= j)
2055    {
2056       int m = (i + j) / 2;
2057       if      (reloc_tab[m].rt_index < index) i = m + 1;
2058       else if (reloc_tab[m].rt_index > index) j = m - 1;
2059       else return reloc_tab[m].rt_disp;                              /* FOUND */
2060    }
2062    /*-------------------------------------------------------------------------*/
2063    /* IF NOT FOUND, SYMBOL WAS NOT RELOCATED.                                 */
2064    /*-------------------------------------------------------------------------*/
2065    return 0;
2068 #endif
2070 /******************************************************************************/
2071 /*                                                                            */
2072 /*  UNPACK() - Extract a relocation field from object bytes and convert into  */
2073 /*             a int so it can be relocated.                                 */
2074 /*                                                                            */
2075 /******************************************************************************/
2076 unsigned int unpack(unsigned char *data, int fieldsz, int wordsz, int bit_offset)
2078    register int  i;
2079    unsigned int objval;
2080    int           start;                       /* MS byte with reloc data      */
2081    int           stop;                        /* LS byte with reloc data      */
2082    int           r  = bit_offset & 7;         /* num unused LS bits in stop   */
2083    int           l  = 8 - r;                  /* num used   MS bits in stop   */
2084    int           tr = ((bit_offset+fieldsz-1) & 7)+1; /* # LS bits in strt*/
2085    int           tl = 8 - tr;                 /* num unused MS bits in start  */
2087    start = (big_e_target ? (wordsz-fieldsz-bit_offset) : 
2088                            (bit_offset+fieldsz-1)) >>3;
2089    stop  = (big_e_target ? (wordsz-bit_offset-1) : bit_offset) >>3;
2091    if (start == stop) return (data[stop] >> r) & ((0x1 << fieldsz) - 0x1);
2093    objval = (unsigned)((data[start] << tl) & 0xFF) >> tl;
2094    
2095    if (big_e_target) 
2096          for (i=start+1; i<stop; ++i) objval = (objval << 8) | data[i];
2097    else  for (i=start-1; i>stop; --i) objval = (objval << 8) | data[i];
2098    
2099    return (objval << l) | (data[stop] >> r);
2104 /******************************************************************************/
2105 /*                                                                            */
2106 /* REPACK() - Encode a binary relocated field back into the object data.      */
2107 /*                                                                            */
2108 /******************************************************************************/
2109 void repack(unsigned int objval, unsigned char *data, int fieldsz,
2110             int  wordsz, int bit_offset)
2112    register int  i;
2113    int           start;                      /* MS byte with reloc data       */
2114    int           stop;                       /* LS byte with reloc data       */
2115    int           r     = bit_offset & 7;     /* num unused LS bits in stop    */
2116    int           l     = 8 - r;              /* num used   MS bits in stop    */
2117    int           tr    = ((bit_offset+fieldsz-1) & 7)+1; /* # LS bits in strt */
2118    unsigned int mask  = (1ul << fieldsz) - 1ul;
2120    if (fieldsz < sizeof(objval)) objval &= mask;
2121    
2122    start = (big_e_target ? (wordsz-fieldsz-bit_offset) : 
2123                            (bit_offset+fieldsz-1)) >>3;
2124    stop  = (big_e_target ? (wordsz-bit_offset-1) : bit_offset) >>3;
2126    if (start == stop)
2127    {
2128        data[stop] &= ~(mask << r);
2129        data[stop] |= (objval << r); 
2130        return;
2131    }
2133    data[start] &= ~((1<<tr)-1);
2134    data[stop]  &=  ((1<< r)-1);
2135    data[stop]  |= (objval << r); 
2136    objval     >>= l;
2138    if (big_e_target) 
2139         for (i = stop - 1; i > start; objval >>= 8) data[i--] = objval;
2140    else for (i = stop + 1; i < start; objval >>= 8) data[i++] = objval;
2141    
2142    data[start] |= objval; 
2146 /******************************************************************************/
2147 /*                                                                            */
2148 /* CLOAD_LINENO() - Read in, swap, and relocate line number entries.  This    */
2149 /*                  function is not called directly by the loader, but by the */
2150 /*                  application when it needs to read in line number entries. */
2151 /*                                                                            */
2152 /******************************************************************************/
2153 int cload_lineno(int filptr, int count, LINENO *lptr, int scnum) 
2155 /*   int    filptr;                      WHERE TO READ FROM                  */
2156 /*   int     count;                       HOW MANY TO READ                    */
2157 /*   LINENO *lptr;                        WHERE TO PUT THEM                   */
2158 /*   int     scnum;                       SECTION NUMBER OF THESE ENTRIES     */
2160     int i;
2162     /*------------------------------------------------------------------------*/
2163     /* READ IN THE REQUESTED NUMBER OF LINE NUMBER ENTRIES AS A BLOCK.        */
2164     /*------------------------------------------------------------------------*/
2165 #if FILE_BASED
2166     if (fseek(fin, filptr, 0) != 0) { load_err = E_FILE; return FALSE; }
2167     for (i = 0; i < count; i++)
2168         if (fread(lptr + i, 1, LINESZ, fin) != LINESZ) 
2169                                     { load_err = E_FILE; return FALSE; }
2170 #else
2171         for (i = 0; i < count; i++)
2172         mem_copy((void*)(lptr+i), (void*)&gRxBuffer[filptr + i*LINESZ], LINESZ);
2173 #endif
2174     /*------------------------------------------------------------------------*/
2175     /* SWAP AND RELOCATE EACH ENTRY, AS NECESSARY.                            */
2176     /*------------------------------------------------------------------------*/
2177     if (byte_swapped || RUN_RELOC_AMOUNT(scnum - 1))
2178        for (i = 0; i < count; i++, lptr++)
2179        {
2180           if (byte_swapped)
2181           {
2182               swap2byte(&lptr->l_lnno);
2183               swap4byte(&lptr->l_addr.l_paddr);
2184           }
2186           if (lptr->l_lnno != 0) 
2187              lptr->l_addr.l_paddr += RUN_RELOC_AMOUNT(scnum - 1);
2188        }
2189     
2190     return TRUE;
2194 /******************************************************************************/
2195 /*                                                                            */
2196 /*  SWAP4BYTE() - Swap the order of bytes in a int.                          */
2197 /*                                                                            */
2198 /******************************************************************************/
2199 void swap4byte(void *addr)
2201    unsigned int *value = (unsigned int *)addr;
2202    unsigned int temp1, temp2, temp3, temp4;
2204    temp1 = (*value)       & 0xFF;
2205    temp2 = (*value >> 8)  & 0xFF;
2206    temp3 = (*value >> 16) & 0xFF;
2207    temp4 = (*value >> 24) & 0xFF;
2209    *value = (temp1 << 24) | (temp2 << 16) | (temp3 << 8) | temp4;
2213 /******************************************************************************/
2214 /*                                                                            */
2215 /*  SWAP2BYTE() - Swap the order of bytes in a short.                         */
2216 /*                                                                            */
2217 /******************************************************************************/
2218 void swap2byte(void *addr)
2220    unsigned short *value = (unsigned short *)addr;
2221    unsigned short temp1,temp2;
2223    temp1 = temp2 = *value;
2224    *value = ((temp2 & 0xFF) << 8) | ((temp1 >> 8) & 0xFF);