# This shell script emits a C file. -*- C -*- # It does some substitutions. cat >e${EMULATION_NAME}.c <children); for (j = 0; init[j].ptr; j++) { long val = init[j].value; lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val))); if (init[j].size == sizeof(short)) *(short *)init[j].ptr = val; else if (init[j].size == sizeof(int)) *(int *)init[j].ptr = val; else if (init[j].size == sizeof(long)) *(long *)init[j].ptr = val; else abort(); } /* Restore the pointer. */ stat_ptr = save; if (pe.FileAlignment > pe.SectionAlignment) { einfo ("%P: warning, file alignment > section alignment.\n"); } } static void gld_${EMULATION_NAME}_after_open() { /* Pass the wacky PE command line options into the output bfd */ struct internal_extra_pe_aouthdr *i; if (!coff_data(output_bfd)->pe) { einfo ("%F%P: PE operations on non PE file.\n"); } pe_data(output_bfd)->pe_opthdr = pe; pe_data(output_bfd)->dll = init[DLLOFF].value; } /* Callback function for qsort in sort_sections. */ static int sfunc (a, b) void *a; void *b; { lang_statement_union_type **ra = a; lang_statement_union_type **rb = b; return strcmp ((*ra)->input_section.ifile->filename, (*rb)->input_section.ifile->filename); } /* Sort the input sections of archives into filename order. */ static void sort_sections (s) lang_statement_union_type *s; { for (; s ; s = s->next) switch (s->header.type) { case lang_output_section_statement_enum: sort_sections (s->output_section_statement.children.head); break; case lang_wild_statement_enum: { lang_statement_union_type **p = &s->wild_statement.children.head; /* Sort any children in the same archive. Run through all the children of this wild statement, when an input_section in an archive is found, scan forward to find all input_sections which are in the same archive. Sort them by their filename and then re-thread the pointer chain. */ while (*p) { lang_statement_union_type *start = *p; if (start->header.type != lang_input_section_enum || !start->input_section.ifile->the_bfd->my_archive) p = &(start->header.next); else { lang_statement_union_type **vec; lang_statement_union_type *end; lang_statement_union_type *np; int count; int i; for (end = start, count = 0; end && end->header.type == lang_input_section_enum && (end->input_section.ifile->the_bfd->my_archive == start->input_section.ifile->the_bfd->my_archive); end = end->next) count++; np = end; vec = (lang_statement_union_type **) alloca (count * sizeof (lang_statement_union_type *)); for (end = start, i = 0; i < count; i++, end = end->next) vec[i] = end; qsort (vec, count, sizeof (vec[0]), sfunc); /* Fill in the next pointers again. */ *p = vec[0]; for (i = 0; i < count - 1; i++) vec[i]->header.next = vec[i + 1]; vec[i]->header.next = np; p = &(vec[i]->header.next); } } } break; default: break; } } static void gld_${EMULATION_NAME}_before_allocation() { extern lang_statement_list_type *stat_ptr; #ifdef TARGET_IS_ppcpe /* Here we rummage through the found bfds to collect toc information */ { LANG_FOR_EACH_INPUT_STATEMENT (is) { ppc_process_before_allocation(is->the_bfd, &link_info); } } /* We have seen it all. Allocate it, and carry on */ ppc_allocate_toc_section (&link_info); #endif sort_sections (*stat_ptr); } static char * gld_${EMULATION_NAME}_get_script(isfile) int *isfile; EOF # Scripts compiled in. # sed commands to quote an ld script as a C string. sc="-f ${srcdir}/emultempl/stringify.sed" cat >>e${EMULATION_NAME}.c <> e${EMULATION_NAME}.c echo ' ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c echo ' ; else return' >> e${EMULATION_NAME}.c sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c echo '; }' >> e${EMULATION_NAME}.c cat >>e${EMULATION_NAME}.c <