1 1.1 christos /* srconv.c -- Sysroff conversion program 2 1.10 christos Copyright (C) 1994-2025 Free Software Foundation, Inc. 3 1.1 christos 4 1.1 christos This file is part of GNU Binutils. 5 1.1 christos 6 1.1 christos This program is free software; you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3 of the License, or 9 1.1 christos (at your option) any later version. 10 1.1 christos 11 1.1 christos This program is distributed in the hope that it will be useful, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 christos GNU General Public License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with this program; if not, write to the Free Software 18 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 19 1.1 christos 02110-1301, USA. */ 20 1.1 christos 21 1.1 christos /* Written by Steve Chamberlain (sac (at) cygnus.com) 22 1.1 christos 23 1.1 christos This program can be used to convert a coff object file 24 1.1 christos into a Hitachi OM/LM (Sysroff) format. 25 1.1 christos 26 1.1 christos All debugging information is preserved */ 27 1.1 christos 28 1.1 christos #include "sysdep.h" 29 1.1 christos #include "bfd.h" 30 1.1 christos #include "bucomm.h" 31 1.1 christos #include "sysroff.h" 32 1.1 christos #include "coffgrok.h" 33 1.1 christos #include "libiberty.h" 34 1.1 christos #include "filenames.h" 35 1.1 christos #include "getopt.h" 36 1.1 christos 37 1.1 christos #include "coff/internal.h" 38 1.1 christos #include "../bfd/libcoff.h" 39 1.1 christos 40 1.1 christos /*#define FOOP1 1 */ 41 1.1 christos 42 1.1 christos static int addrsize; 43 1.1 christos static char *toolname; 44 1.1 christos static char **rnames; 45 1.1 christos 46 1.1 christos static void walk_tree_symbol 47 1.1 christos (struct coff_sfile *, struct coff_section *, struct coff_symbol *, int); 48 1.1 christos static void walk_tree_scope 49 1.1 christos (struct coff_section *, struct coff_sfile *, struct coff_scope *, int, int); 50 1.1 christos static int find_base (struct coff_sfile *, struct coff_section *); 51 1.1 christos static void wr_globals (struct coff_ofile *, struct coff_sfile *, int); 52 1.1 christos 53 1.1 christos static FILE *file; 54 1.1 christos static bfd *abfd; 55 1.1 christos static int debug = 0; 56 1.1 christos static int quick = 0; 57 1.1 christos static int noprescan = 0; 58 1.1 christos static struct coff_ofile *tree; 59 1.1 christos /* Obsolete ?? 60 1.1 christos static int absolute_p; 61 1.1 christos */ 62 1.1 christos 63 1.1 christos static int segmented_p; 64 1.1 christos static int code; 65 1.1 christos 66 1.1 christos static int ids1[20000]; 67 1.1 christos static int ids2[20000]; 68 1.1 christos 69 1.1 christos static int base1 = 0x18; 70 1.1 christos static int base2 = 0x2018; 71 1.1 christos 72 1.1 christos static int 73 1.1 christos get_member_id (int x) 74 1.1 christos { 75 1.1 christos if (ids2[x]) 76 1.1 christos return ids2[x]; 77 1.1 christos 78 1.1 christos ids2[x] = base2++; 79 1.1 christos return ids2[x]; 80 1.1 christos } 81 1.1 christos 82 1.1 christos static int 83 1.1 christos get_ordinary_id (int x) 84 1.1 christos { 85 1.1 christos if (ids1[x]) 86 1.1 christos return ids1[x]; 87 1.1 christos 88 1.1 christos ids1[x] = base1++; 89 1.1 christos return ids1[x]; 90 1.1 christos } 91 1.1 christos static char * 92 1.1 christos section_translate (char *n) 93 1.1 christos { 94 1.1 christos if (strcmp (n, ".text") == 0) 95 1.1 christos return "P"; 96 1.1 christos if (strcmp (n, ".data") == 0) 97 1.1 christos return "D"; 98 1.1 christos if (strcmp (n, ".bss") == 0) 99 1.1 christos return "B"; 100 1.1 christos return n; 101 1.1 christos } 102 1.1 christos 103 1.1 christos #define DATE "940201073000"; /* Just a time on my birthday */ 104 1.1 christos 105 1.1 christos static char * 106 1.1 christos strip_suffix (const char *name) 107 1.1 christos { 108 1.1 christos int i; 109 1.1 christos char *res; 110 1.1 christos 111 1.1 christos for (i = 0; name[i] != 0 && name[i] != '.'; i++) 112 1.1 christos ; 113 1.1 christos res = (char *) xmalloc (i + 1); 114 1.1 christos memcpy (res, name, i); 115 1.1 christos res[i] = 0; 116 1.1 christos return res; 117 1.1 christos } 118 1.1 christos 119 1.1 christos /* IT LEN stuff CS */ 120 1.1 christos static void 121 1.1 christos checksum (FILE *ffile, unsigned char *ptr, int size, int ccode) 122 1.1 christos { 123 1.1 christos int j; 124 1.1 christos int last; 125 1.1 christos int sum = 0; 126 1.1 christos int bytes = size / 8; 127 1.1 christos 128 1.1 christos last = !(ccode & 0xff00); 129 1.1 christos if (size & 0x7) 130 1.3 christos fatal (_("Checksum failure")); 131 1.3 christos 132 1.1 christos ptr[0] = ccode | (last ? 0x80 : 0); 133 1.1 christos ptr[1] = bytes + 1; 134 1.1 christos 135 1.1 christos for (j = 0; j < bytes; j++) 136 1.1 christos sum += ptr[j]; 137 1.1 christos 138 1.1 christos /* Glue on a checksum too. */ 139 1.1 christos ptr[bytes] = ~sum; 140 1.1 christos if (fwrite (ptr, bytes + 1, 1, ffile) != 1) 141 1.1 christos /* FIXME: Return error status. */ 142 1.3 christos fatal (_("Failed to write checksum")); 143 1.1 christos } 144 1.1 christos 145 1.1 christos 146 1.1 christos static void 147 1.1 christos writeINT (int n, unsigned char *ptr, int *idx, int size, FILE *ffile) 148 1.1 christos { 149 1.1 christos int byte = *idx / 8; 150 1.1 christos 151 1.1 christos if (size == -2) 152 1.1 christos size = addrsize; 153 1.1 christos else if (size == -1) 154 1.1 christos size = 0; 155 1.1 christos 156 1.1 christos if (byte > 240) 157 1.1 christos { 158 1.1 christos /* Lets write out that record and do another one. */ 159 1.1 christos checksum (ffile, ptr, *idx, code | 0x1000); 160 1.1 christos *idx = 16; 161 1.1 christos byte = *idx / 8; 162 1.1 christos } 163 1.1 christos 164 1.1 christos switch (size) 165 1.1 christos { 166 1.1 christos case 0: 167 1.1 christos break; 168 1.1 christos case 1: 169 1.1 christos ptr[byte] = n; 170 1.1 christos break; 171 1.1 christos case 2: 172 1.1 christos ptr[byte + 0] = n >> 8; 173 1.1 christos ptr[byte + 1] = n; 174 1.1 christos break; 175 1.1 christos case 4: 176 1.1 christos ptr[byte + 0] = n >> 24; 177 1.1 christos ptr[byte + 1] = n >> 16; 178 1.1 christos ptr[byte + 2] = n >> 8; 179 1.1 christos ptr[byte + 3] = n >> 0; 180 1.1 christos break; 181 1.1 christos default: 182 1.3 christos fatal (_("Unsupported integer write size: %d"), size); 183 1.1 christos } 184 1.1 christos *idx += size * 8; 185 1.1 christos } 186 1.1 christos 187 1.1 christos static void 188 1.1 christos writeBITS (int val, unsigned char *ptr, int *idx, int size) 189 1.1 christos { 190 1.1 christos int byte = *idx / 8; 191 1.1 christos int bit = *idx % 8; 192 1.1 christos int old; 193 1.1 christos 194 1.1 christos *idx += size; 195 1.1 christos 196 1.1 christos old = ptr[byte]; 197 1.1 christos /* Turn off all about to change bits. */ 198 1.1 christos old &= ~((~0 >> (8 - bit - size)) & ((1 << size) - 1)); 199 1.1 christos /* Turn on the bits we want. */ 200 1.1 christos old |= (val & ((1 << size) - 1)) << (8 - bit - size); 201 1.1 christos ptr[byte] = old; 202 1.1 christos } 203 1.1 christos 204 1.1 christos static void 205 1.1 christos writeBARRAY (barray data, unsigned char *ptr, int *idx, 206 1.1 christos int size ATTRIBUTE_UNUSED, FILE *ffile) 207 1.1 christos { 208 1.1 christos int i; 209 1.1 christos 210 1.1 christos writeINT (data.len, ptr, idx, 1, ffile); 211 1.1 christos for (i = 0; i < data.len; i++) 212 1.1 christos writeINT (data.data[i], ptr, idx, 1, ffile); 213 1.1 christos } 214 1.1 christos 215 1.1 christos static void 216 1.1 christos writeCHARS (char *string, unsigned char *ptr, int *idx, int size, FILE *ffile) 217 1.1 christos { 218 1.1 christos int i = *idx / 8; 219 1.1 christos 220 1.1 christos if (i > 240) 221 1.1 christos { 222 1.1 christos /* Lets write out that record and do another one. */ 223 1.1 christos checksum (ffile, ptr, *idx, code | 0x1000); 224 1.1 christos *idx = 16; 225 1.1 christos i = *idx / 8; 226 1.1 christos } 227 1.1 christos 228 1.1 christos if (size == 0) 229 1.1 christos { 230 1.1 christos /* Variable length string. */ 231 1.1 christos size = strlen (string); 232 1.1 christos ptr[i++] = size; 233 1.1 christos } 234 1.1 christos 235 1.1 christos /* BUG WAITING TO HAPPEN. */ 236 1.1 christos memcpy (ptr + i, string, size); 237 1.1 christos i += size; 238 1.1 christos *idx = i * 8; 239 1.1 christos } 240 1.1 christos 241 1.1 christos #define SYSROFF_SWAP_OUT 242 1.1 christos #include "sysroff.c" 243 1.1 christos 244 1.1 christos static char *rname_sh[] = 245 1.1 christos { 246 1.1 christos "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15" 247 1.1 christos }; 248 1.1 christos 249 1.1 christos static char *rname_h8300[] = 250 1.1 christos { 251 1.1 christos "ER0", "ER1", "ER2", "ER3", "ER4", "ER5", "ER6", "ER7", "PC", "CCR" 252 1.1 christos }; 253 1.1 christos 254 1.1 christos static void 255 1.1 christos wr_tr (void) 256 1.1 christos { 257 1.1 christos /* The TR block is not normal - it doesn't have any contents. */ 258 1.1 christos 259 1.1 christos static char b[] = 260 1.1 christos { 261 1.1 christos 0xff, /* IT */ 262 1.1 christos 0x03, /* RL */ 263 1.1 christos 0xfd, /* CS */ 264 1.1 christos }; 265 1.1 christos 266 1.1 christos if (fwrite (b, sizeof (b), 1, file) != 1) 267 1.1 christos /* FIXME: Return error status. */ 268 1.3 christos fatal (_("Failed to write TR block")); 269 1.1 christos } 270 1.1 christos 271 1.1 christos static void 272 1.1 christos wr_un (struct coff_ofile *ptr, struct coff_sfile *sfile, int first, 273 1.1 christos int nsecs ATTRIBUTE_UNUSED) 274 1.1 christos { 275 1.1 christos struct IT_un un; 276 1.1 christos struct coff_symbol *s; 277 1.1 christos 278 1.1 christos un.spare1 = 0; 279 1.1 christos 280 1.1 christos if (bfd_get_file_flags (abfd) & EXEC_P) 281 1.1 christos un.format = FORMAT_LM; 282 1.1 christos else 283 1.1 christos un.format = FORMAT_OM; 284 1.1 christos un.spare1 = 0; 285 1.1 christos 286 1.1 christos /* Don't count the abs section. */ 287 1.1 christos un.nsections = ptr->nsections - 1; 288 1.1 christos 289 1.1 christos un.nextdefs = 0; 290 1.1 christos un.nextrefs = 0; 291 1.1 christos /* Count all the undefined and defined variables with global scope. */ 292 1.1 christos 293 1.1 christos if (first) 294 1.1 christos { 295 1.1 christos for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list) 296 1.1 christos { 297 1.1 christos if (s->visible->type == coff_vis_ext_def 298 1.1 christos || s->visible->type == coff_vis_common) 299 1.1 christos un.nextdefs++; 300 1.1 christos 301 1.1 christos if (s->visible->type == coff_vis_ext_ref) 302 1.1 christos un.nextrefs++; 303 1.1 christos } 304 1.1 christos } 305 1.1 christos un.tool = toolname; 306 1.1 christos un.tcd = DATE; 307 1.1 christos un.linker = "L_GX00"; 308 1.1 christos un.lcd = DATE; 309 1.1 christos un.name = sfile->name; 310 1.1 christos sysroff_swap_un_out (file, &un); 311 1.1 christos } 312 1.1 christos 313 1.1 christos static void 314 1.1 christos wr_hd (struct coff_ofile *p) 315 1.1 christos { 316 1.1 christos struct IT_hd hd; 317 1.1 christos 318 1.1 christos hd.spare1 = 0; 319 1.8 christos hd.spare2 = 0; 320 1.1 christos if (bfd_get_file_flags (abfd) & EXEC_P) 321 1.1 christos hd.mt = MTYPE_ABS_LM; 322 1.1 christos else 323 1.1 christos hd.mt = MTYPE_OMS_OR_LMS; 324 1.1 christos 325 1.1 christos hd.cd = DATE; 326 1.1 christos 327 1.1 christos hd.nu = p->nsources; /* Always one unit */ 328 1.1 christos hd.code = 0; /* Always ASCII */ 329 1.1 christos hd.ver = "0200"; /* Version 2.00 */ 330 1.1 christos 331 1.1 christos switch (bfd_get_arch (abfd)) 332 1.1 christos { 333 1.1 christos case bfd_arch_h8300: 334 1.1 christos hd.au = 8; 335 1.1 christos hd.si = 0; 336 1.1 christos hd.spcsz = 32; 337 1.1 christos hd.segsz = 0; 338 1.1 christos hd.segsh = 0; 339 1.1 christos switch (bfd_get_mach (abfd)) 340 1.1 christos { 341 1.1 christos case bfd_mach_h8300: 342 1.1 christos hd.cpu = "H8300"; 343 1.1 christos hd.afl = 2; 344 1.1 christos addrsize = 2; 345 1.1 christos toolname = "C_H8/300"; 346 1.1 christos break; 347 1.1 christos case bfd_mach_h8300h: 348 1.1 christos hd.cpu = "H8300H"; 349 1.1 christos hd.afl = 4; 350 1.1 christos addrsize = 4; 351 1.1 christos toolname = "C_H8/300H"; 352 1.1 christos break; 353 1.1 christos case bfd_mach_h8300s: 354 1.1 christos hd.cpu = "H8300S"; 355 1.1 christos hd.afl = 4; 356 1.1 christos addrsize = 4; 357 1.1 christos toolname = "C_H8/300S"; 358 1.1 christos break; 359 1.1 christos default: 360 1.3 christos fatal (_("Unrecognized H8300 sub-architecture: %ld"), 361 1.3 christos bfd_get_mach (abfd)); 362 1.1 christos } 363 1.1 christos rnames = rname_h8300; 364 1.1 christos break; 365 1.1 christos case bfd_arch_sh: 366 1.1 christos hd.au = 8; 367 1.1 christos hd.si = 0; 368 1.1 christos hd.afl = 4; 369 1.1 christos hd.spcsz = 32; 370 1.1 christos hd.segsz = 0; 371 1.1 christos hd.segsh = 0; 372 1.1 christos hd.cpu = "SH"; 373 1.1 christos addrsize = 4; 374 1.1 christos toolname = "C_SH"; 375 1.1 christos rnames = rname_sh; 376 1.1 christos break; 377 1.1 christos default: 378 1.3 christos fatal (_("Unsupported architecture: %d"), bfd_get_arch (abfd)); 379 1.1 christos } 380 1.1 christos 381 1.1 christos if (! (bfd_get_file_flags(abfd) & EXEC_P)) 382 1.1 christos { 383 1.1 christos hd.ep = 0; 384 1.1 christos } 385 1.1 christos else 386 1.1 christos { 387 1.1 christos hd.ep = 1; 388 1.1 christos hd.uan = 0; 389 1.1 christos hd.sa = 0; 390 1.1 christos hd.sad = 0; 391 1.1 christos hd.address = bfd_get_start_address (abfd); 392 1.1 christos } 393 1.1 christos 394 1.1 christos hd.os = ""; 395 1.1 christos hd.sys = ""; 396 1.1 christos hd.mn = strip_suffix (bfd_get_filename (abfd)); 397 1.1 christos 398 1.1 christos sysroff_swap_hd_out (file, &hd); 399 1.1 christos } 400 1.1 christos 401 1.1 christos 402 1.1 christos static void 403 1.1 christos wr_sh (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_section *sec) 404 1.1 christos { 405 1.1 christos struct IT_sh sh; 406 1.1 christos sh.unit = 0; 407 1.1 christos sh.section = sec->number; 408 1.1 christos #ifdef FOOP1 409 1.1 christos sh.section = 0; 410 1.1 christos #endif 411 1.1 christos sysroff_swap_sh_out (file, &sh); 412 1.1 christos } 413 1.1 christos 414 1.1 christos 415 1.1 christos static void 416 1.1 christos wr_ob (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_section *section) 417 1.1 christos { 418 1.1 christos bfd_size_type i; 419 1.1 christos int first = 1; 420 1.1 christos unsigned char stuff[200]; 421 1.1 christos 422 1.1 christos i = 0; 423 1.7 christos while (i < bfd_section_size (section->bfd_section)) 424 1.1 christos { 425 1.1 christos struct IT_ob ob; 426 1.1 christos int todo = 200; /* Copy in 200 byte lumps. */ 427 1.1 christos 428 1.1 christos ob.spare = 0; 429 1.7 christos if (i + todo > bfd_section_size (section->bfd_section)) 430 1.7 christos todo = bfd_section_size (section->bfd_section) - i; 431 1.1 christos 432 1.1 christos if (first) 433 1.1 christos { 434 1.1 christos ob.saf = 1; 435 1.1 christos if (bfd_get_file_flags (abfd) & EXEC_P) 436 1.1 christos ob.address = section->address; 437 1.1 christos else 438 1.1 christos ob.address = 0; 439 1.1 christos 440 1.1 christos first = 0; 441 1.1 christos } 442 1.1 christos else 443 1.1 christos { 444 1.1 christos ob.saf = 0; 445 1.1 christos } 446 1.1 christos 447 1.1 christos ob.cpf = 0; /* Never compress. */ 448 1.1 christos ob.data.len = todo; 449 1.1 christos bfd_get_section_contents (abfd, section->bfd_section, stuff, i, todo); 450 1.1 christos ob.data.data = stuff; 451 1.1 christos sysroff_swap_ob_out (file, &ob /*, i + todo < section->size */ ); 452 1.1 christos i += todo; 453 1.1 christos } 454 1.1 christos 455 1.1 christos /* Now fill the rest with blanks. */ 456 1.1 christos while (i < (bfd_size_type) section->size) 457 1.1 christos { 458 1.1 christos struct IT_ob ob; 459 1.1 christos int todo = 200; /* Copy in 200 byte lumps. */ 460 1.1 christos 461 1.1 christos ob.spare = 0; 462 1.1 christos if (i + todo > (bfd_size_type) section->size) 463 1.1 christos todo = section->size - i; 464 1.1 christos ob.saf = 0; 465 1.1 christos 466 1.1 christos ob.cpf = 0; /* Never compress. */ 467 1.1 christos ob.data.len = todo; 468 1.1 christos memset (stuff, 0, todo); 469 1.1 christos ob.data.data = stuff; 470 1.1 christos sysroff_swap_ob_out (file, &ob); 471 1.1 christos i += todo; 472 1.1 christos } 473 1.1 christos /* Now fill the rest with blanks. */ 474 1.1 christos } 475 1.1 christos 476 1.1 christos static void 477 1.1 christos wr_rl (struct coff_ofile *ptr ATTRIBUTE_UNUSED, struct coff_section *sec) 478 1.1 christos { 479 1.1 christos int nr = sec->nrelocs; 480 1.1 christos int i; 481 1.1 christos 482 1.1 christos for (i = 0; i < nr; i++) 483 1.1 christos { 484 1.1 christos struct coff_reloc *r = sec->relocs + i; 485 1.1 christos struct coff_symbol *ref; 486 1.1 christos struct IT_rl rl; 487 1.1 christos 488 1.1 christos rl.apol = 0; 489 1.1 christos rl.boundary = 0; 490 1.1 christos rl.segment = 1; 491 1.1 christos rl.sign = 0; 492 1.1 christos rl.check = 0; 493 1.1 christos rl.addr = r->offset; 494 1.1 christos rl.bitloc = 0; 495 1.1 christos rl.flen = 32; /* SH Specific. */ 496 1.1 christos 497 1.1 christos /* What sort of reloc ? Look in the section to find out. */ 498 1.1 christos ref = r->symbol; 499 1.1 christos if (ref->visible->type == coff_vis_ext_ref) 500 1.1 christos { 501 1.1 christos rl.bcount = 4; /* Always 4 for us. */ 502 1.1 christos rl.op = OP_EXT_REF; 503 1.1 christos rl.symn = ref->er_number; 504 1.1 christos } 505 1.1 christos else if (ref->visible->type == coff_vis_common) 506 1.1 christos { 507 1.1 christos rl.bcount = 11; /* Always 11 for us. */ 508 1.1 christos rl.op = OP_SEC_REF; 509 1.1 christos rl.secn = ref->where->section->number; 510 1.1 christos rl.copcode_is_3 = 3; 511 1.1 christos rl.alength_is_4 = 4; 512 1.1 christos rl.addend = ref->where->offset - ref->where->section->address; 513 1.1 christos rl.aopcode_is_0x20 = 0x20; 514 1.1 christos } 515 1.1 christos else 516 1.1 christos { 517 1.1 christos rl.bcount = 11; /* Always 11 for us. */ 518 1.1 christos rl.op = OP_SEC_REF; 519 1.1 christos rl.secn = ref->where->section->number; 520 1.1 christos rl.copcode_is_3 = 3; 521 1.1 christos rl.alength_is_4 = 4; 522 1.1 christos rl.addend = -ref->where->section->address; 523 1.1 christos rl.aopcode_is_0x20 = 0x20; 524 1.1 christos } 525 1.1 christos 526 1.1 christos rl.end = 0xff; 527 1.1 christos 528 1.1 christos if ( rl.op == OP_SEC_REF 529 1.1 christos || rl.op == OP_EXT_REF) 530 1.1 christos sysroff_swap_rl_out (file, &rl); 531 1.1 christos } 532 1.1 christos } 533 1.1 christos 534 1.1 christos static void 535 1.1 christos wr_object_body (struct coff_ofile *p) 536 1.1 christos { 537 1.1 christos int i; 538 1.1 christos 539 1.1 christos for (i = 1; i < p->nsections; i++) 540 1.1 christos { 541 1.1 christos wr_sh (p, p->sections + i); 542 1.1 christos wr_ob (p, p->sections + i); 543 1.1 christos wr_rl (p, p->sections + i); 544 1.1 christos } 545 1.1 christos } 546 1.1 christos 547 1.1 christos static void 548 1.1 christos wr_dps_start (struct coff_sfile *sfile, 549 1.1 christos struct coff_section *section ATTRIBUTE_UNUSED, 550 1.1 christos struct coff_scope *scope, int type, int nest) 551 1.1 christos { 552 1.1 christos struct IT_dps dps; 553 1.1 christos 554 1.1 christos dps.end = 0; 555 1.1 christos dps.opt = 0; 556 1.1 christos dps.type = type; 557 1.1 christos 558 1.1 christos if (scope->sec) 559 1.1 christos { 560 1.1 christos dps.san = scope->sec->number; 561 1.1 christos dps.address = scope->offset - find_base (sfile, scope->sec); 562 1.1 christos dps.block_size = scope->size; 563 1.1 christos 564 1.1 christos if (debug) 565 1.1 christos { 566 1.1 christos printf ("DPS %s %d %x\n", 567 1.1 christos sfile->name, 568 1.1 christos nest, 569 1.1 christos dps.address); 570 1.1 christos } 571 1.1 christos } 572 1.1 christos else 573 1.1 christos { 574 1.1 christos dps.san = 0; 575 1.1 christos dps.address = 0; 576 1.1 christos dps.block_size = 0; 577 1.1 christos } 578 1.1 christos 579 1.1 christos dps.nesting = nest; 580 1.1 christos dps.neg = 0x1001; 581 1.1 christos sysroff_swap_dps_out (file, &dps); 582 1.1 christos } 583 1.1 christos 584 1.1 christos static void 585 1.1 christos wr_dps_end (struct coff_section *section ATTRIBUTE_UNUSED, 586 1.1 christos struct coff_scope *scope ATTRIBUTE_UNUSED, int type) 587 1.1 christos { 588 1.1 christos struct IT_dps dps; 589 1.1 christos 590 1.1 christos dps.end = 1; 591 1.1 christos dps.type = type; 592 1.1 christos sysroff_swap_dps_out (file, &dps); 593 1.1 christos } 594 1.1 christos 595 1.1 christos static int * 596 1.1 christos nints (int x) 597 1.1 christos { 598 1.10 christos return (int *) (xcalloc (x, sizeof (int))); 599 1.1 christos } 600 1.1 christos 601 1.1 christos static void 602 1.1 christos walk_tree_type_1 (struct coff_sfile *sfile, struct coff_symbol *symbol, 603 1.1 christos struct coff_type *type, int nest) 604 1.1 christos { 605 1.1 christos switch (type->type) 606 1.1 christos { 607 1.1 christos case coff_secdef_type: 608 1.1 christos case coff_basic_type: 609 1.1 christos { 610 1.1 christos struct IT_dbt dbt; 611 1.1 christos 612 1.1 christos switch (type->u.basic) 613 1.1 christos { 614 1.1 christos case T_NULL: 615 1.1 christos case T_VOID: 616 1.1 christos dbt.btype = BTYPE_VOID; 617 1.1 christos dbt.sign = BTYPE_UNSPEC; 618 1.1 christos dbt.fptype = FPTYPE_NOTSPEC; 619 1.1 christos break; 620 1.1 christos 621 1.1 christos case T_CHAR: 622 1.1 christos dbt.btype = BTYPE_CHAR; 623 1.1 christos dbt.sign = BTYPE_UNSPEC; 624 1.1 christos dbt.fptype = FPTYPE_NOTSPEC; 625 1.1 christos break; 626 1.1 christos 627 1.1 christos case T_SHORT: 628 1.1 christos case T_INT: 629 1.1 christos case T_LONG: 630 1.1 christos dbt.btype = BTYPE_INT; 631 1.1 christos dbt.sign = SIGN_SIGNED; 632 1.1 christos dbt.fptype = FPTYPE_NOTSPEC; 633 1.1 christos break; 634 1.1 christos 635 1.1 christos case T_FLOAT: 636 1.1 christos dbt.btype = BTYPE_FLOAT; 637 1.1 christos dbt.fptype = FPTYPE_SINGLE; 638 1.1 christos break; 639 1.1 christos 640 1.1 christos case T_DOUBLE: 641 1.1 christos dbt.btype = BTYPE_FLOAT; 642 1.1 christos dbt.fptype = FPTYPE_DOUBLE; 643 1.1 christos break; 644 1.1 christos 645 1.1 christos case T_LNGDBL: 646 1.1 christos dbt.btype = BTYPE_FLOAT; 647 1.1 christos dbt.fptype = FPTYPE_EXTENDED; 648 1.1 christos break; 649 1.1 christos 650 1.1 christos case T_UCHAR: 651 1.1 christos dbt.btype = BTYPE_CHAR; 652 1.1 christos dbt.sign = SIGN_UNSIGNED; 653 1.1 christos dbt.fptype = FPTYPE_NOTSPEC; 654 1.1 christos break; 655 1.1 christos 656 1.1 christos case T_USHORT: 657 1.1 christos case T_UINT: 658 1.1 christos case T_ULONG: 659 1.1 christos dbt.btype = BTYPE_INT; 660 1.1 christos dbt.sign = SIGN_UNSIGNED; 661 1.1 christos dbt.fptype = FPTYPE_NOTSPEC; 662 1.1 christos break; 663 1.1 christos } 664 1.1 christos 665 1.1 christos dbt.bitsize = type->size; 666 1.1 christos dbt.neg = 0x1001; 667 1.1 christos sysroff_swap_dbt_out (file, &dbt); 668 1.1 christos break; 669 1.1 christos } 670 1.1 christos 671 1.1 christos case coff_pointer_type: 672 1.1 christos { 673 1.1 christos struct IT_dpt dpt; 674 1.1 christos 675 1.1 christos dpt.dunno = 0; 676 1.1 christos walk_tree_type_1 (sfile, symbol, type->u.pointer.points_to, nest + 1); 677 1.1 christos dpt.neg = 0x1001; 678 1.1 christos sysroff_swap_dpt_out (file, &dpt); 679 1.1 christos break; 680 1.1 christos } 681 1.1 christos 682 1.1 christos case coff_function_type: 683 1.1 christos { 684 1.1 christos struct IT_dfp dfp; 685 1.1 christos struct coff_symbol *param; 686 1.1 christos 687 1.1 christos dfp.end = 0; 688 1.1 christos dfp.spare = 0; 689 1.1 christos dfp.nparams = type->u.function.parameters->nvars; 690 1.1 christos dfp.neg = 0x1001; 691 1.1 christos 692 1.1 christos walk_tree_type_1 (sfile, symbol, type->u.function.function_returns, nest + 1); 693 1.1 christos 694 1.1 christos sysroff_swap_dfp_out (file, &dfp); 695 1.1 christos 696 1.1 christos for (param = type->u.function.parameters->vars_head; 697 1.1 christos param; 698 1.1 christos param = param->next) 699 1.1 christos walk_tree_symbol (sfile, 0, param, nest); 700 1.1 christos 701 1.1 christos dfp.end = 1; 702 1.1 christos sysroff_swap_dfp_out (file, &dfp); 703 1.1 christos break; 704 1.1 christos } 705 1.1 christos 706 1.1 christos case coff_structdef_type: 707 1.1 christos { 708 1.1 christos struct IT_dbt dbt; 709 1.1 christos struct IT_dds dds; 710 1.1 christos struct coff_symbol *member; 711 1.1 christos 712 1.1 christos dds.spare = 0; 713 1.1 christos dbt.btype = BTYPE_STRUCT; 714 1.1 christos dbt.bitsize = type->size; 715 1.1 christos dbt.sign = SIGN_UNSPEC; 716 1.1 christos dbt.fptype = FPTYPE_NOTSPEC; 717 1.1 christos dbt.sid = get_member_id (type->u.astructdef.idx); 718 1.1 christos dbt.neg = 0x1001; 719 1.1 christos sysroff_swap_dbt_out (file, &dbt); 720 1.1 christos dds.end = 0; 721 1.1 christos dds.neg = 0x1001; 722 1.1 christos sysroff_swap_dds_out (file, &dds); 723 1.1 christos 724 1.1 christos for (member = type->u.astructdef.elements->vars_head; 725 1.1 christos member; 726 1.1 christos member = member->next) 727 1.1 christos walk_tree_symbol (sfile, 0, member, nest + 1); 728 1.1 christos 729 1.1 christos dds.end = 1; 730 1.1 christos sysroff_swap_dds_out (file, &dds); 731 1.1 christos 732 1.1 christos } 733 1.1 christos break; 734 1.1 christos 735 1.1 christos case coff_structref_type: 736 1.1 christos { 737 1.1 christos struct IT_dbt dbt; 738 1.1 christos 739 1.1 christos dbt.btype = BTYPE_TAG; 740 1.1 christos dbt.bitsize = type->size; 741 1.1 christos dbt.sign = SIGN_UNSPEC; 742 1.1 christos dbt.fptype = FPTYPE_NOTSPEC; 743 1.1 christos 744 1.1 christos if (type->u.astructref.ref) 745 1.1 christos dbt.sid = get_member_id (type->u.astructref.ref->number); 746 1.1 christos else 747 1.1 christos dbt.sid = 0; 748 1.1 christos 749 1.1 christos dbt.neg = 0x1001; 750 1.1 christos sysroff_swap_dbt_out (file, &dbt); 751 1.1 christos } 752 1.1 christos break; 753 1.1 christos 754 1.1 christos case coff_array_type: 755 1.1 christos { 756 1.1 christos struct IT_dar dar; 757 1.1 christos int j; 758 1.1 christos int dims = 1; /* Only output one dimension at a time. */ 759 1.1 christos 760 1.1 christos dar.dims = dims; 761 1.1 christos dar.variable = nints (dims); 762 1.1 christos dar.subtype = nints (dims); 763 1.1 christos dar.spare = nints (dims); 764 1.1 christos dar.max_variable = nints (dims); 765 1.1 christos dar.maxspare = nints (dims); 766 1.1 christos dar.max = nints (dims); 767 1.1 christos dar.min_variable = nints (dims); 768 1.1 christos dar.min = nints (dims); 769 1.1 christos dar.minspare = nints (dims); 770 1.1 christos dar.neg = 0x1001; 771 1.1 christos dar.length = type->size / type->u.array.dim; 772 1.1 christos 773 1.1 christos for (j = 0; j < dims; j++) 774 1.1 christos { 775 1.1 christos dar.variable[j] = VARIABLE_FIXED; 776 1.1 christos dar.subtype[j] = SUB_INTEGER; 777 1.1 christos dar.spare[j] = 0; 778 1.1 christos dar.max_variable[j] = 0; 779 1.1 christos dar.max[j] = type->u.array.dim; 780 1.1 christos dar.min_variable[j] = 0; 781 1.1 christos dar.min[j] = 1; /* Why isn't this 0 ? */ 782 1.1 christos } 783 1.1 christos walk_tree_type_1 (sfile, symbol, type->u.array.array_of, nest + 1); 784 1.1 christos sysroff_swap_dar_out (file, &dar); 785 1.1 christos } 786 1.1 christos break; 787 1.1 christos 788 1.1 christos case coff_enumdef_type: 789 1.1 christos { 790 1.1 christos struct IT_dbt dbt; 791 1.1 christos struct IT_den den; 792 1.1 christos struct coff_symbol *member; 793 1.1 christos 794 1.1 christos dbt.btype = BTYPE_ENUM; 795 1.1 christos dbt.bitsize = type->size; 796 1.1 christos dbt.sign = SIGN_UNSPEC; 797 1.1 christos dbt.fptype = FPTYPE_NOTSPEC; 798 1.1 christos dbt.sid = get_member_id (type->u.aenumdef.idx); 799 1.1 christos dbt.neg = 0x1001; 800 1.1 christos sysroff_swap_dbt_out (file, &dbt); 801 1.1 christos 802 1.1 christos den.end = 0; 803 1.1 christos den.neg = 0x1001; 804 1.1 christos den.spare = 0; 805 1.1 christos sysroff_swap_den_out (file, &den); 806 1.1 christos 807 1.1 christos for (member = type->u.aenumdef.elements->vars_head; 808 1.1 christos member; 809 1.1 christos member = member->next) 810 1.1 christos walk_tree_symbol (sfile, 0, member, nest + 1); 811 1.1 christos 812 1.1 christos den.end = 1; 813 1.1 christos sysroff_swap_den_out (file, &den); 814 1.1 christos } 815 1.1 christos break; 816 1.1 christos 817 1.1 christos case coff_enumref_type: 818 1.1 christos { 819 1.1 christos struct IT_dbt dbt; 820 1.1 christos 821 1.1 christos dbt.btype = BTYPE_TAG; 822 1.1 christos dbt.bitsize = type->size; 823 1.1 christos dbt.sign = SIGN_UNSPEC; 824 1.1 christos dbt.fptype = FPTYPE_NOTSPEC; 825 1.1 christos dbt.sid = get_member_id (type->u.aenumref.ref->number); 826 1.1 christos dbt.neg = 0x1001; 827 1.1 christos sysroff_swap_dbt_out (file, &dbt); 828 1.1 christos } 829 1.1 christos break; 830 1.1 christos 831 1.1 christos default: 832 1.3 christos fatal (_("Unrecognised type: %d"), type->type); 833 1.1 christos } 834 1.1 christos } 835 1.1 christos 836 1.1 christos /* Obsolete ? 837 1.1 christos static void 838 1.1 christos dty_start () 839 1.1 christos { 840 1.1 christos struct IT_dty dty; 841 1.1 christos dty.end = 0; 842 1.1 christos dty.neg = 0x1001; 843 1.1 christos dty.spare = 0; 844 1.1 christos sysroff_swap_dty_out (file, &dty); 845 1.1 christos } 846 1.1 christos 847 1.1 christos static void 848 1.1 christos dty_stop () 849 1.1 christos { 850 1.1 christos struct IT_dty dty; 851 1.1 christos dty.end = 0; 852 1.1 christos dty.neg = 0x1001; 853 1.1 christos dty.end = 1; 854 1.1 christos sysroff_swap_dty_out (file, &dty); 855 1.1 christos } 856 1.1 christos 857 1.1 christos 858 1.1 christos static void 859 1.1 christos dump_tree_structure (sfile, symbol, type, nest) 860 1.1 christos struct coff_sfile *sfile; 861 1.1 christos struct coff_symbol *symbol; 862 1.1 christos struct coff_type *type; 863 1.1 christos int nest; 864 1.1 christos { 865 1.1 christos if (symbol->type->type == coff_function_type) 866 1.1 christos { 867 1.1 christos 868 1.1 christos 869 1.1 christos } 870 1.1 christos 871 1.1 christos } 872 1.1 christos */ 873 1.1 christos 874 1.1 christos static void 875 1.1 christos walk_tree_type (struct coff_sfile *sfile, struct coff_symbol *symbol, 876 1.1 christos struct coff_type *type, int nest) 877 1.1 christos { 878 1.6 christos struct IT_dty dty; 879 1.6 christos 880 1.6 christos dty.spare = 0; 881 1.6 christos dty.end = 0; 882 1.6 christos dty.neg = 0x1001; 883 1.6 christos 884 1.1 christos if (symbol->type->type == coff_function_type) 885 1.1 christos { 886 1.1 christos sysroff_swap_dty_out (file, &dty); 887 1.1 christos walk_tree_type_1 (sfile, symbol, type, nest); 888 1.1 christos dty.end = 1; 889 1.1 christos sysroff_swap_dty_out (file, &dty); 890 1.1 christos 891 1.1 christos wr_dps_start (sfile, 892 1.1 christos symbol->where->section, 893 1.1 christos symbol->type->u.function.code, 894 1.1 christos BLOCK_TYPE_FUNCTION, nest); 895 1.1 christos wr_dps_start (sfile, symbol->where->section, 896 1.1 christos symbol->type->u.function.code, 897 1.1 christos BLOCK_TYPE_BLOCK, nest); 898 1.1 christos walk_tree_scope (symbol->where->section, 899 1.1 christos sfile, 900 1.1 christos symbol->type->u.function.code, 901 1.1 christos nest + 1, BLOCK_TYPE_BLOCK); 902 1.1 christos 903 1.1 christos wr_dps_end (symbol->where->section, 904 1.1 christos symbol->type->u.function.code, 905 1.1 christos BLOCK_TYPE_BLOCK); 906 1.1 christos wr_dps_end (symbol->where->section, 907 1.1 christos symbol->type->u.function.code, BLOCK_TYPE_FUNCTION); 908 1.1 christos } 909 1.1 christos else 910 1.1 christos { 911 1.1 christos sysroff_swap_dty_out (file, &dty); 912 1.1 christos walk_tree_type_1 (sfile, symbol, type, nest); 913 1.1 christos dty.end = 1; 914 1.1 christos sysroff_swap_dty_out (file, &dty); 915 1.1 christos } 916 1.1 christos } 917 1.1 christos 918 1.1 christos static void 919 1.1 christos walk_tree_symbol (struct coff_sfile *sfile, struct coff_section *section ATTRIBUTE_UNUSED, struct coff_symbol *symbol, int nest) 920 1.1 christos { 921 1.1 christos struct IT_dsy dsy; 922 1.1 christos 923 1.1 christos memset (&dsy, 0, sizeof(dsy)); 924 1.1 christos dsy.nesting = nest; 925 1.1 christos 926 1.1 christos switch (symbol->type->type) 927 1.1 christos { 928 1.1 christos case coff_function_type: 929 1.1 christos dsy.type = STYPE_FUNC; 930 1.1 christos dsy.assign = 1; 931 1.1 christos break; 932 1.1 christos 933 1.1 christos case coff_structref_type: 934 1.1 christos case coff_pointer_type: 935 1.1 christos case coff_array_type: 936 1.1 christos case coff_basic_type: 937 1.1 christos case coff_enumref_type: 938 1.1 christos dsy.type = STYPE_VAR; 939 1.1 christos dsy.assign = 1; 940 1.1 christos break; 941 1.1 christos 942 1.1 christos case coff_enumdef_type: 943 1.1 christos dsy.type = STYPE_TAG; 944 1.1 christos dsy.assign = 0; 945 1.1 christos dsy.magic = 2; 946 1.1 christos break; 947 1.1 christos 948 1.1 christos case coff_structdef_type: 949 1.1 christos dsy.type = STYPE_TAG; 950 1.1 christos dsy.assign = 0; 951 1.1 christos dsy.magic = symbol->type->u.astructdef.isstruct ? 0 : 1; 952 1.1 christos break; 953 1.1 christos 954 1.1 christos case coff_secdef_type: 955 1.1 christos return; 956 1.1 christos 957 1.1 christos default: 958 1.3 christos fatal (_("Unrecognised coff symbol type: %d"), symbol->type->type); 959 1.1 christos } 960 1.1 christos 961 1.1 christos if (symbol->where->where == coff_where_member_of_struct) 962 1.1 christos { 963 1.1 christos dsy.assign = 0; 964 1.1 christos dsy.type = STYPE_MEMBER; 965 1.1 christos } 966 1.1 christos 967 1.1 christos if (symbol->where->where == coff_where_member_of_enum) 968 1.1 christos { 969 1.1 christos dsy.type = STYPE_ENUM; 970 1.1 christos dsy.assign = 0; 971 1.1 christos dsy.evallen = 4; 972 1.1 christos dsy.evalue = symbol->where->offset; 973 1.1 christos } 974 1.1 christos 975 1.1 christos if (symbol->type->type == coff_structdef_type 976 1.1 christos || symbol->where->where == coff_where_entag 977 1.1 christos || symbol->where->where == coff_where_strtag) 978 1.1 christos { 979 1.1 christos dsy.snumber = get_member_id (symbol->number); 980 1.1 christos } 981 1.1 christos else 982 1.1 christos { 983 1.1 christos dsy.snumber = get_ordinary_id (symbol->number); 984 1.1 christos } 985 1.1 christos 986 1.1 christos dsy.sname = symbol->name[0] == '_' ? symbol->name + 1 : symbol->name; 987 1.1 christos 988 1.1 christos switch (symbol->visible->type) 989 1.1 christos { 990 1.1 christos case coff_vis_common: 991 1.1 christos case coff_vis_ext_def: 992 1.1 christos dsy.ainfo = AINFO_STATIC_EXT_DEF; 993 1.1 christos break; 994 1.1 christos 995 1.1 christos case coff_vis_ext_ref: 996 1.1 christos dsy.ainfo = AINFO_STATIC_EXT_REF; 997 1.1 christos break; 998 1.1 christos 999 1.1 christos case coff_vis_int_def: 1000 1.1 christos dsy.ainfo = AINFO_STATIC_INT; 1001 1.1 christos break; 1002 1.1 christos 1003 1.1 christos case coff_vis_auto: 1004 1.1 christos case coff_vis_autoparam: 1005 1.1 christos dsy.ainfo = AINFO_AUTO; 1006 1.1 christos break; 1007 1.1 christos 1008 1.1 christos case coff_vis_register: 1009 1.1 christos case coff_vis_regparam: 1010 1.1 christos dsy.ainfo = AINFO_REG; 1011 1.1 christos break; 1012 1.1 christos break; 1013 1.1 christos 1014 1.1 christos case coff_vis_tag: 1015 1.1 christos case coff_vis_member_of_struct: 1016 1.1 christos case coff_vis_member_of_enum: 1017 1.1 christos break; 1018 1.1 christos 1019 1.1 christos default: 1020 1.3 christos fatal (_("Unrecognised coff symbol visibility: %d"), symbol->visible->type); 1021 1.1 christos } 1022 1.1 christos 1023 1.1 christos dsy.dlength = symbol->type->size; 1024 1.1 christos 1025 1.1 christos switch (symbol->where->where) 1026 1.1 christos { 1027 1.1 christos case coff_where_memory: 1028 1.1 christos 1029 1.1 christos dsy.section = symbol->where->section->number; 1030 1.1 christos #ifdef FOOP 1031 1.1 christos dsy.section = 0; 1032 1.1 christos #endif 1033 1.1 christos break; 1034 1.1 christos 1035 1.1 christos case coff_where_member_of_struct: 1036 1.1 christos case coff_where_member_of_enum: 1037 1.1 christos case coff_where_stack: 1038 1.1 christos case coff_where_register: 1039 1.1 christos case coff_where_unknown: 1040 1.1 christos case coff_where_strtag: 1041 1.1 christos case coff_where_entag: 1042 1.1 christos case coff_where_typedef: 1043 1.1 christos break; 1044 1.1 christos 1045 1.1 christos default: 1046 1.3 christos fatal (_("Unrecognised coff symbol location: %d"), symbol->where->where); 1047 1.1 christos } 1048 1.1 christos 1049 1.1 christos switch (symbol->where->where) 1050 1.1 christos { 1051 1.1 christos case coff_where_memory: 1052 1.1 christos dsy.address = symbol->where->offset - find_base (sfile, symbol->where->section); 1053 1.1 christos break; 1054 1.1 christos 1055 1.1 christos case coff_where_stack: 1056 1.1 christos dsy.address = symbol->where->offset; 1057 1.1 christos break; 1058 1.1 christos 1059 1.1 christos case coff_where_member_of_struct: 1060 1.1 christos if (symbol->where->bitsize) 1061 1.1 christos { 1062 1.1 christos int bits = (symbol->where->offset * 8 + symbol->where->bitoffset); 1063 1.1 christos dsy.bitunit = 1; 1064 1.1 christos dsy.field_len = symbol->where->bitsize; 1065 1.1 christos dsy.field_off = (bits / 32) * 4; 1066 1.1 christos dsy.field_bitoff = bits % 32; 1067 1.1 christos } 1068 1.1 christos else 1069 1.1 christos { 1070 1.1 christos dsy.bitunit = 0; 1071 1.1 christos 1072 1.1 christos dsy.field_len = symbol->type->size; 1073 1.1 christos dsy.field_off = symbol->where->offset; 1074 1.1 christos } 1075 1.1 christos break; 1076 1.1 christos 1077 1.1 christos case coff_where_member_of_enum: 1078 1.1 christos /* dsy.bitunit = 0; 1079 1.1 christos dsy.field_len = symbol->type->size; 1080 1.1 christos dsy.field_off = symbol->where->offset; */ 1081 1.1 christos break; 1082 1.1 christos 1083 1.1 christos case coff_where_register: 1084 1.1 christos case coff_where_unknown: 1085 1.1 christos case coff_where_strtag: 1086 1.1 christos case coff_where_entag: 1087 1.1 christos case coff_where_typedef: 1088 1.1 christos break; 1089 1.1 christos 1090 1.1 christos default: 1091 1.3 christos fatal (_("Unrecognised coff symbol location: %d"), symbol->where->where); 1092 1.1 christos } 1093 1.1 christos 1094 1.1 christos if (symbol->where->where == coff_where_register) 1095 1.1 christos dsy.reg = rnames[symbol->where->offset]; 1096 1.1 christos 1097 1.1 christos switch (symbol->visible->type) 1098 1.1 christos { 1099 1.1 christos case coff_vis_common: 1100 1.1 christos /* We do this 'cause common C symbols are treated as extdefs. */ 1101 1.1 christos case coff_vis_ext_def: 1102 1.1 christos case coff_vis_ext_ref: 1103 1.1 christos dsy.ename = symbol->name; 1104 1.1 christos break; 1105 1.1 christos 1106 1.1 christos case coff_vis_regparam: 1107 1.1 christos case coff_vis_autoparam: 1108 1.1 christos dsy.type = STYPE_PARAMETER; 1109 1.1 christos break; 1110 1.1 christos 1111 1.1 christos case coff_vis_int_def: 1112 1.1 christos case coff_vis_auto: 1113 1.1 christos case coff_vis_register: 1114 1.1 christos case coff_vis_tag: 1115 1.1 christos case coff_vis_member_of_struct: 1116 1.1 christos case coff_vis_member_of_enum: 1117 1.1 christos break; 1118 1.1 christos 1119 1.1 christos default: 1120 1.3 christos fatal (_("Unrecognised coff symbol visibility: %d"), symbol->visible->type); 1121 1.1 christos } 1122 1.1 christos 1123 1.1 christos dsy.sfn = 0; 1124 1.1 christos dsy.sln = 2; 1125 1.1 christos dsy.neg = 0x1001; 1126 1.1 christos 1127 1.1 christos sysroff_swap_dsy_out (file, &dsy); 1128 1.1 christos 1129 1.1 christos walk_tree_type (sfile, symbol, symbol->type, nest); 1130 1.1 christos } 1131 1.1 christos 1132 1.1 christos static void 1133 1.1 christos walk_tree_scope (struct coff_section *section, struct coff_sfile *sfile, struct coff_scope *scope, int nest, int type) 1134 1.1 christos { 1135 1.1 christos struct coff_symbol *vars; 1136 1.1 christos struct coff_scope *child; 1137 1.1 christos 1138 1.1 christos if (scope->vars_head 1139 1.1 christos || (scope->list_head && scope->list_head->vars_head)) 1140 1.1 christos { 1141 1.1 christos wr_dps_start (sfile, section, scope, type, nest); 1142 1.1 christos 1143 1.1 christos if (nest == 0) 1144 1.1 christos wr_globals (tree, sfile, nest + 1); 1145 1.1 christos 1146 1.1 christos for (vars = scope->vars_head; vars; vars = vars->next) 1147 1.1 christos walk_tree_symbol (sfile, section, vars, nest); 1148 1.1 christos 1149 1.1 christos for (child = scope->list_head; child; child = child->next) 1150 1.1 christos walk_tree_scope (section, sfile, child, nest + 1, BLOCK_TYPE_BLOCK); 1151 1.1 christos 1152 1.1 christos wr_dps_end (section, scope, type); 1153 1.1 christos } 1154 1.1 christos } 1155 1.1 christos 1156 1.1 christos static void 1157 1.1 christos walk_tree_sfile (struct coff_section *section, struct coff_sfile *sfile) 1158 1.1 christos { 1159 1.1 christos walk_tree_scope (section, sfile, sfile->scope, 0, BLOCK_TYPE_COMPUNIT); 1160 1.1 christos } 1161 1.1 christos 1162 1.1 christos static void 1163 1.1 christos wr_program_structure (struct coff_ofile *p, struct coff_sfile *sfile) 1164 1.1 christos { 1165 1.3 christos if (p->nsections < 4) 1166 1.3 christos return; 1167 1.1 christos walk_tree_sfile (p->sections + 4, sfile); 1168 1.1 christos } 1169 1.1 christos 1170 1.1 christos static void 1171 1.1 christos wr_du (struct coff_ofile *p, struct coff_sfile *sfile, int n) 1172 1.1 christos { 1173 1.1 christos struct IT_du du; 1174 1.1 christos int lim; 1175 1.1 christos int i; 1176 1.1 christos int j; 1177 1.1 christos unsigned int *lowest = (unsigned *) nints (p->nsections); 1178 1.1 christos unsigned int *highest = (unsigned *) nints (p->nsections); 1179 1.1 christos 1180 1.1 christos du.format = bfd_get_file_flags (abfd) & EXEC_P ? 0 : 1; 1181 1.1 christos du.optimized = 0; 1182 1.1 christos du.stackfrmt = 0; 1183 1.1 christos du.spare = 0; 1184 1.1 christos du.unit = n; 1185 1.1 christos du.sections = p->nsections - 1; 1186 1.10 christos du.san = (int *) xcalloc (du.sections, sizeof (int)); 1187 1.1 christos du.address = nints (du.sections); 1188 1.1 christos du.length = nints (du.sections); 1189 1.1 christos 1190 1.1 christos for (i = 0; i < du.sections; i++) 1191 1.1 christos { 1192 1.1 christos lowest[i] = ~0; 1193 1.1 christos highest[i] = 0; 1194 1.1 christos } 1195 1.1 christos 1196 1.1 christos lim = du.sections; 1197 1.1 christos for (j = 0; j < lim; j++) 1198 1.1 christos { 1199 1.1 christos int src = j; 1200 1.1 christos int dst = j; 1201 1.1 christos 1202 1.1 christos du.san[dst] = dst; 1203 1.1 christos 1204 1.1 christos if (sfile->section[src].init) 1205 1.1 christos { 1206 1.1 christos du.length[dst] 1207 1.1 christos = sfile->section[src].high - sfile->section[src].low + 1; 1208 1.1 christos du.address[dst] 1209 1.1 christos = sfile->section[src].low; 1210 1.1 christos } 1211 1.1 christos else 1212 1.1 christos { 1213 1.1 christos du.length[dst] = 0; 1214 1.1 christos du.address[dst] = 0; 1215 1.1 christos } 1216 1.1 christos 1217 1.1 christos if (debug) 1218 1.1 christos { 1219 1.1 christos if (sfile->section[src].parent) 1220 1.1 christos { 1221 1.1 christos printf (" section %6s 0x%08x..0x%08x\n", 1222 1.1 christos sfile->section[src].parent->name, 1223 1.1 christos du.address[dst], 1224 1.1 christos du.address[dst] + du.length[dst] - 1); 1225 1.1 christos } 1226 1.1 christos } 1227 1.1 christos 1228 1.1 christos du.sections = dst + 1; 1229 1.1 christos } 1230 1.1 christos 1231 1.1 christos du.tool = "c_gcc"; 1232 1.1 christos du.date = DATE; 1233 1.1 christos 1234 1.1 christos sysroff_swap_du_out (file, &du); 1235 1.1 christos } 1236 1.1 christos 1237 1.1 christos static void 1238 1.1 christos wr_dus (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_sfile *sfile) 1239 1.1 christos { 1240 1.1 christos struct IT_dus dus; 1241 1.1 christos 1242 1.1 christos dus.efn = 0x1001; 1243 1.1 christos dus.ns = 1; /* p->nsources; sac 14 jul 94 */ 1244 1.1 christos dus.drb = nints (dus.ns); 1245 1.10 christos dus.fname = (char **) xcalloc (dus.ns, sizeof (char *)); 1246 1.1 christos dus.spare = nints (dus.ns); 1247 1.1 christos dus.ndir = 0; 1248 1.1 christos /* Find the filenames. */ 1249 1.1 christos dus.drb[0] = 0; 1250 1.1 christos dus.fname[0] = sfile->name; 1251 1.1 christos 1252 1.1 christos sysroff_swap_dus_out (file, &dus); 1253 1.1 christos 1254 1.1 christos } 1255 1.1 christos 1256 1.1 christos /* Find the offset of the .text section for this sfile in the 1257 1.1 christos .text section for the output file. */ 1258 1.1 christos 1259 1.1 christos static int 1260 1.1 christos find_base (struct coff_sfile *sfile, struct coff_section *section) 1261 1.1 christos { 1262 1.1 christos return sfile->section[section->number].low; 1263 1.1 christos } 1264 1.1 christos 1265 1.1 christos static void 1266 1.1 christos wr_dln (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_sfile *sfile, 1267 1.1 christos int n ATTRIBUTE_UNUSED) 1268 1.1 christos { 1269 1.1 christos /* Count up all the linenumbers */ 1270 1.1 christos 1271 1.1 christos struct coff_symbol *sy; 1272 1.1 christos int lc = 0; 1273 1.1 christos struct IT_dln dln; 1274 1.1 christos 1275 1.1 christos int idx; 1276 1.1 christos 1277 1.1 christos for (sy = sfile->scope->vars_head; 1278 1.1 christos sy; 1279 1.1 christos sy = sy->next) 1280 1.1 christos { 1281 1.1 christos struct coff_type *t = sy->type; 1282 1.1 christos if (t->type == coff_function_type) 1283 1.1 christos { 1284 1.1 christos struct coff_line *l = t->u.function.lines; 1285 1.1 christos if (l) 1286 1.1 christos lc += l->nlines; 1287 1.1 christos } 1288 1.1 christos } 1289 1.1 christos 1290 1.1 christos dln.sfn = nints (lc); 1291 1.1 christos dln.sln = nints (lc); 1292 1.1 christos dln.cc = nints (lc); 1293 1.1 christos dln.section = nints (lc); 1294 1.1 christos 1295 1.1 christos dln.from_address = nints (lc); 1296 1.1 christos dln.to_address = nints (lc); 1297 1.1 christos 1298 1.1 christos 1299 1.1 christos dln.neg = 0x1001; 1300 1.1 christos 1301 1.1 christos dln.nln = lc; 1302 1.1 christos 1303 1.1 christos /* Run through once more and fill up the structure */ 1304 1.1 christos idx = 0; 1305 1.1 christos for (sy = sfile->scope->vars_head; 1306 1.1 christos sy; 1307 1.1 christos sy = sy->next) 1308 1.1 christos { 1309 1.1 christos if (sy->type->type == coff_function_type) 1310 1.1 christos { 1311 1.1 christos int i; 1312 1.1 christos struct coff_line *l = sy->type->u.function.lines; 1313 1.1 christos if (l) 1314 1.1 christos { 1315 1.1 christos int base = find_base (sfile, sy->where->section); 1316 1.1 christos for (i = 0; i < l->nlines; i++) 1317 1.1 christos { 1318 1.1 christos dln.section[idx] = sy->where->section->number; 1319 1.1 christos dln.sfn[idx] = 0; 1320 1.1 christos dln.sln[idx] = l->lines[i]; 1321 1.1 christos dln.from_address[idx] = 1322 1.1 christos l->addresses[i] + sy->where->section->address - base; 1323 1.1 christos dln.cc[idx] = 0; 1324 1.1 christos if (idx) 1325 1.1 christos dln.to_address[idx - 1] = dln.from_address[idx]; 1326 1.1 christos idx++; 1327 1.1 christos 1328 1.1 christos } 1329 1.1 christos dln.to_address[idx - 1] = dln.from_address[idx - 1] + 2; 1330 1.1 christos } 1331 1.1 christos } 1332 1.1 christos } 1333 1.1 christos if (lc) 1334 1.1 christos sysroff_swap_dln_out (file, &dln); 1335 1.1 christos } 1336 1.1 christos 1337 1.1 christos /* Write the global symbols out to the debug info. */ 1338 1.1 christos 1339 1.1 christos static void 1340 1.1 christos wr_globals (struct coff_ofile *p, struct coff_sfile *sfile, 1341 1.1 christos int n ATTRIBUTE_UNUSED) 1342 1.1 christos { 1343 1.1 christos struct coff_symbol *sy; 1344 1.1 christos 1345 1.1 christos for (sy = p->symbol_list_head; 1346 1.1 christos sy; 1347 1.1 christos sy = sy->next_in_ofile_list) 1348 1.1 christos { 1349 1.1 christos if (sy->visible->type == coff_vis_ext_def 1350 1.1 christos || sy->visible->type == coff_vis_ext_ref) 1351 1.1 christos { 1352 1.1 christos /* Only write out symbols if they belong to 1353 1.1 christos the current source file. */ 1354 1.1 christos if (sy->sfile == sfile) 1355 1.1 christos walk_tree_symbol (sfile, 0, sy, 0); 1356 1.1 christos } 1357 1.1 christos } 1358 1.1 christos } 1359 1.1 christos 1360 1.1 christos static void 1361 1.1 christos wr_debug (struct coff_ofile *p) 1362 1.1 christos { 1363 1.1 christos struct coff_sfile *sfile; 1364 1.1 christos int n = 0; 1365 1.1 christos 1366 1.1 christos for (sfile = p->source_head; 1367 1.1 christos sfile; 1368 1.1 christos sfile = sfile->next) 1369 1.1 christos { 1370 1.1 christos if (debug) 1371 1.1 christos printf ("%s\n", sfile->name); 1372 1.1 christos 1373 1.1 christos wr_du (p, sfile, n); 1374 1.1 christos wr_dus (p, sfile); 1375 1.1 christos wr_program_structure (p, sfile); 1376 1.1 christos wr_dln (p, sfile, n); 1377 1.1 christos n++; 1378 1.1 christos } 1379 1.1 christos } 1380 1.1 christos 1381 1.1 christos static void 1382 1.1 christos wr_cs (void) 1383 1.1 christos { 1384 1.1 christos /* It seems that the CS struct is not normal - the size is wrong 1385 1.1 christos heres one I prepared earlier. */ 1386 1.1 christos static char b[] = 1387 1.1 christos { 1388 1.1 christos 0x80, /* IT */ 1389 1.1 christos 0x21, /* RL */ 1390 1.1 christos 0x00, /* number of chars in variable length part */ 1391 1.1 christos 0x80, /* hd */ 1392 1.1 christos 0x00, /* hs */ 1393 1.1 christos 0x80, /* un */ 1394 1.1 christos 0x00, /* us */ 1395 1.1 christos 0x80, /* sc */ 1396 1.1 christos 0x00, /* ss */ 1397 1.1 christos 0x80, /* er */ 1398 1.1 christos 0x80, /* ed */ 1399 1.1 christos 0x80, /* sh */ 1400 1.1 christos 0x80, /* ob */ 1401 1.1 christos 0x80, /* rl */ 1402 1.1 christos 0x80, /* du */ 1403 1.1 christos 0x80, /* dps */ 1404 1.1 christos 0x80, /* dsy */ 1405 1.1 christos 0x80, /* dty */ 1406 1.1 christos 0x80, /* dln */ 1407 1.1 christos 0x80, /* dso */ 1408 1.1 christos 0x80, /* dus */ 1409 1.1 christos 0x00, /* dss */ 1410 1.1 christos 0x80, /* dbt */ 1411 1.1 christos 0x00, /* dpp */ 1412 1.1 christos 0x80, /* dfp */ 1413 1.1 christos 0x80, /* den */ 1414 1.1 christos 0x80, /* dds */ 1415 1.1 christos 0x80, /* dar */ 1416 1.1 christos 0x80, /* dpt */ 1417 1.1 christos 0x00, /* dul */ 1418 1.1 christos 0x00, /* dse */ 1419 1.1 christos 0x00, /* dot */ 1420 1.1 christos 0xDE /* CS */ 1421 1.1 christos }; 1422 1.1 christos 1423 1.1 christos if (fwrite (b, sizeof (b), 1, file) != 1) 1424 1.1 christos /* FIXME: Return error status. */ 1425 1.3 christos fatal (_("Failed to write CS struct")); 1426 1.1 christos } 1427 1.1 christos 1428 1.1 christos /* Write out the SC records for a unit. Create an SC 1429 1.1 christos for all the sections which appear in the output file, even 1430 1.1 christos if there isn't an equivalent one on the input. */ 1431 1.1 christos 1432 1.1 christos static int 1433 1.1 christos wr_sc (struct coff_ofile *ptr, struct coff_sfile *sfile) 1434 1.1 christos { 1435 1.1 christos int i; 1436 1.1 christos int scount = 0; 1437 1.1 christos /* First work out the total number of sections. */ 1438 1.1 christos int total_sec = ptr->nsections; 1439 1.1 christos struct myinfo 1440 1.1 christos { 1441 1.1 christos struct coff_section *sec; 1442 1.1 christos struct coff_symbol *symbol; 1443 1.1 christos }; 1444 1.1 christos struct coff_symbol *symbol; 1445 1.1 christos struct myinfo *info 1446 1.1 christos = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo)); 1447 1.1 christos 1448 1.1 christos 1449 1.1 christos for (i = 0; i < total_sec; i++) 1450 1.1 christos { 1451 1.1 christos info[i].sec = ptr->sections + i; 1452 1.1 christos info[i].symbol = 0; 1453 1.1 christos } 1454 1.1 christos 1455 1.1 christos for (symbol = sfile->scope->vars_head; 1456 1.1 christos symbol; 1457 1.1 christos symbol = symbol->next) 1458 1.1 christos { 1459 1.1 christos 1460 1.1 christos if (symbol->type->type == coff_secdef_type) 1461 1.1 christos { 1462 1.1 christos for (i = 0; i < total_sec; i++) 1463 1.1 christos { 1464 1.1 christos if (symbol->where->section == info[i].sec) 1465 1.1 christos { 1466 1.1 christos info[i].symbol = symbol; 1467 1.1 christos break; 1468 1.1 christos } 1469 1.1 christos } 1470 1.1 christos } 1471 1.1 christos } 1472 1.1 christos 1473 1.1 christos /* Now output all the section info, and fake up some stuff for sections 1474 1.1 christos we don't have. */ 1475 1.1 christos for (i = 1; i < total_sec; i++) 1476 1.1 christos { 1477 1.1 christos struct IT_sc sc; 1478 1.1 christos char *name; 1479 1.1 christos 1480 1.1 christos symbol = info[i].symbol; 1481 1.1 christos sc.spare = 0; 1482 1.1 christos sc.spare1 = 0; 1483 1.1 christos 1484 1.1 christos if (!symbol) 1485 1.1 christos { 1486 1.1 christos /* Don't have a symbol set aside for this section, which means 1487 1.1 christos that nothing in this file does anything for the section. */ 1488 1.1 christos sc.format = !(bfd_get_file_flags (abfd) & EXEC_P); 1489 1.1 christos sc.addr = 0; 1490 1.1 christos sc.length = 0; 1491 1.1 christos name = info[i].sec->name; 1492 1.1 christos } 1493 1.1 christos else 1494 1.1 christos { 1495 1.1 christos if (bfd_get_file_flags (abfd) & EXEC_P) 1496 1.1 christos { 1497 1.1 christos sc.format = 0; 1498 1.1 christos sc.addr = symbol->where->offset; 1499 1.1 christos } 1500 1.1 christos else 1501 1.1 christos { 1502 1.1 christos sc.format = 1; 1503 1.1 christos sc.addr = 0; 1504 1.1 christos } 1505 1.1 christos sc.length = symbol->type->size; 1506 1.1 christos name = symbol->name; 1507 1.1 christos } 1508 1.1 christos 1509 1.1 christos sc.align = 4; 1510 1.1 christos sc.concat = CONCAT_SIMPLE; 1511 1.1 christos sc.read = 3; 1512 1.1 christos sc.write = 3; 1513 1.1 christos sc.exec = 3; 1514 1.1 christos sc.init = 3; 1515 1.1 christos sc.mode = 3; 1516 1.1 christos sc.spare = 0; 1517 1.1 christos sc.segadd = 0; 1518 1.1 christos sc.spare1 = 0; /* If not zero, then it doesn't work. */ 1519 1.1 christos sc.name = section_translate (name); 1520 1.1 christos 1521 1.1 christos if (strlen (sc.name) == 1) 1522 1.1 christos { 1523 1.1 christos switch (sc.name[0]) 1524 1.1 christos { 1525 1.1 christos case 'D': 1526 1.1 christos case 'B': 1527 1.1 christos sc.contents = CONTENTS_DATA; 1528 1.1 christos break; 1529 1.1 christos 1530 1.1 christos default: 1531 1.1 christos sc.contents = CONTENTS_CODE; 1532 1.1 christos } 1533 1.1 christos } 1534 1.1 christos else 1535 1.1 christos { 1536 1.1 christos sc.contents = CONTENTS_CODE; 1537 1.1 christos } 1538 1.1 christos 1539 1.1 christos sysroff_swap_sc_out (file, &sc); 1540 1.1 christos scount++; 1541 1.1 christos } 1542 1.3 christos free (info); 1543 1.1 christos return scount; 1544 1.1 christos } 1545 1.1 christos 1546 1.1 christos /* Write out the ER records for a unit. */ 1547 1.1 christos 1548 1.1 christos static void 1549 1.1 christos wr_er (struct coff_ofile *ptr, struct coff_sfile *sfile ATTRIBUTE_UNUSED, 1550 1.1 christos int first) 1551 1.1 christos { 1552 1.1 christos int idx = 0; 1553 1.1 christos struct coff_symbol *sym; 1554 1.1 christos 1555 1.1 christos if (first) 1556 1.1 christos { 1557 1.1 christos for (sym = ptr->symbol_list_head; sym; sym = sym->next_in_ofile_list) 1558 1.1 christos { 1559 1.1 christos if (sym->visible->type == coff_vis_ext_ref) 1560 1.1 christos { 1561 1.1 christos struct IT_er er; 1562 1.1 christos 1563 1.1 christos er.spare = 0; 1564 1.1 christos er.type = ER_NOTSPEC; 1565 1.1 christos er.name = sym->name; 1566 1.1 christos sysroff_swap_er_out (file, &er); 1567 1.1 christos sym->er_number = idx++; 1568 1.1 christos } 1569 1.1 christos } 1570 1.1 christos } 1571 1.1 christos } 1572 1.1 christos 1573 1.1 christos /* Write out the ED records for a unit. */ 1574 1.1 christos 1575 1.1 christos static void 1576 1.1 christos wr_ed (struct coff_ofile *ptr, struct coff_sfile *sfile ATTRIBUTE_UNUSED, 1577 1.1 christos int first) 1578 1.1 christos { 1579 1.1 christos struct coff_symbol *s; 1580 1.1 christos 1581 1.1 christos if (first) 1582 1.1 christos { 1583 1.1 christos for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list) 1584 1.1 christos { 1585 1.1 christos if (s->visible->type == coff_vis_ext_def 1586 1.1 christos || s->visible->type == coff_vis_common) 1587 1.1 christos { 1588 1.1 christos struct IT_ed ed; 1589 1.1 christos 1590 1.1 christos ed.section = s->where->section->number; 1591 1.1 christos ed.spare = 0; 1592 1.1 christos 1593 1.1 christos if (s->where->section->data) 1594 1.1 christos { 1595 1.1 christos ed.type = ED_TYPE_DATA; 1596 1.1 christos } 1597 1.1 christos else if (s->where->section->code & SEC_CODE) 1598 1.1 christos { 1599 1.1 christos ed.type = ED_TYPE_ENTRY; 1600 1.1 christos } 1601 1.1 christos else 1602 1.1 christos { 1603 1.1 christos ed.type = ED_TYPE_NOTSPEC; 1604 1.1 christos ed.type = ED_TYPE_DATA; 1605 1.1 christos } 1606 1.1 christos 1607 1.1 christos ed.address = s->where->offset - s->where->section->address; 1608 1.1 christos ed.name = s->name; 1609 1.1 christos sysroff_swap_ed_out (file, &ed); 1610 1.1 christos } 1611 1.1 christos } 1612 1.1 christos } 1613 1.1 christos } 1614 1.1 christos 1615 1.1 christos static void 1616 1.1 christos wr_unit_info (struct coff_ofile *ptr) 1617 1.1 christos { 1618 1.1 christos struct coff_sfile *sfile; 1619 1.1 christos int first = 1; 1620 1.1 christos 1621 1.1 christos for (sfile = ptr->source_head; 1622 1.1 christos sfile; 1623 1.1 christos sfile = sfile->next) 1624 1.1 christos { 1625 1.1 christos long p1; 1626 1.1 christos long p2; 1627 1.1 christos int nsecs; 1628 1.1 christos 1629 1.1 christos p1 = ftell (file); 1630 1.1 christos wr_un (ptr, sfile, first, 0); 1631 1.1 christos nsecs = wr_sc (ptr, sfile); 1632 1.1 christos p2 = ftell (file); 1633 1.1 christos fseek (file, p1, SEEK_SET); 1634 1.1 christos wr_un (ptr, sfile, first, nsecs); 1635 1.1 christos fseek (file, p2, SEEK_SET); 1636 1.1 christos wr_er (ptr, sfile, first); 1637 1.1 christos wr_ed (ptr, sfile, first); 1638 1.1 christos first = 0; 1639 1.1 christos } 1640 1.1 christos } 1641 1.1 christos 1642 1.1 christos static void 1643 1.1 christos wr_module (struct coff_ofile *p) 1644 1.1 christos { 1645 1.1 christos wr_cs (); 1646 1.1 christos wr_hd (p); 1647 1.1 christos wr_unit_info (p); 1648 1.1 christos wr_object_body (p); 1649 1.1 christos wr_debug (p); 1650 1.1 christos wr_tr (); 1651 1.1 christos } 1652 1.1 christos 1653 1.1 christos static int 1654 1.1 christos align (int x) 1655 1.1 christos { 1656 1.1 christos return (x + 3) & ~3; 1657 1.1 christos } 1658 1.1 christos 1659 1.1 christos /* Find all the common variables and turn them into 1660 1.1 christos ordinary defs - dunno why, but thats what hitachi does with 'em. */ 1661 1.1 christos 1662 1.1 christos static void 1663 1.1 christos prescan (struct coff_ofile *otree) 1664 1.1 christos { 1665 1.1 christos struct coff_symbol *s; 1666 1.1 christos struct coff_section *common_section; 1667 1.1 christos 1668 1.3 christos if (otree->nsections < 3) 1669 1.3 christos return; 1670 1.3 christos 1671 1.1 christos /* Find the common section - always section 3. */ 1672 1.1 christos common_section = otree->sections + 3; 1673 1.1 christos 1674 1.1 christos for (s = otree->symbol_list_head; 1675 1.1 christos s; 1676 1.1 christos s = s->next_in_ofile_list) 1677 1.1 christos { 1678 1.1 christos if (s->visible->type == coff_vis_common) 1679 1.1 christos { 1680 1.1 christos struct coff_where *w = s->where; 1681 1.1 christos /* s->visible->type = coff_vis_ext_def; leave it as common */ 1682 1.1 christos common_section->size = align (common_section->size); 1683 1.1 christos w->offset = common_section->size + common_section->address; 1684 1.1 christos w->section = common_section; 1685 1.1 christos common_section->size += s->type->size; 1686 1.1 christos common_section->size = align (common_section->size); 1687 1.1 christos } 1688 1.1 christos } 1689 1.1 christos } 1690 1.1 christos 1691 1.6 christos ATTRIBUTE_NORETURN static void 1692 1.1 christos show_usage (FILE *ffile, int status) 1693 1.1 christos { 1694 1.1 christos fprintf (ffile, _("Usage: %s [option(s)] in-file [out-file]\n"), program_name); 1695 1.1 christos fprintf (ffile, _("Convert a COFF object file into a SYSROFF object file\n")); 1696 1.1 christos fprintf (ffile, _(" The options are:\n\ 1697 1.1 christos -q --quick (Obsolete - ignored)\n\ 1698 1.1 christos -n --noprescan Do not perform a scan to convert commons into defs\n\ 1699 1.1 christos -d --debug Display information about what is being done\n\ 1700 1.1 christos @<file> Read options from <file>\n\ 1701 1.1 christos -h --help Display this information\n\ 1702 1.1 christos -v --version Print the program's version number\n")); 1703 1.1 christos 1704 1.1 christos if (REPORT_BUGS_TO[0] && status == 0) 1705 1.1 christos fprintf (ffile, _("Report bugs to %s\n"), REPORT_BUGS_TO); 1706 1.1 christos exit (status); 1707 1.1 christos } 1708 1.1 christos 1709 1.1 christos int 1710 1.1 christos main (int ac, char **av) 1711 1.1 christos { 1712 1.1 christos int opt; 1713 1.1 christos static struct option long_options[] = 1714 1.1 christos { 1715 1.1 christos {"debug", no_argument, 0, 'd'}, 1716 1.1 christos {"quick", no_argument, 0, 'q'}, 1717 1.1 christos {"noprescan", no_argument, 0, 'n'}, 1718 1.1 christos {"help", no_argument, 0, 'h'}, 1719 1.1 christos {"version", no_argument, 0, 'V'}, 1720 1.1 christos {NULL, no_argument, 0, 0} 1721 1.1 christos }; 1722 1.1 christos char **matching; 1723 1.1 christos char *input_file; 1724 1.1 christos char *output_file; 1725 1.1 christos 1726 1.8 christos #ifdef HAVE_LC_MESSAGES 1727 1.1 christos setlocale (LC_MESSAGES, ""); 1728 1.1 christos #endif 1729 1.1 christos setlocale (LC_CTYPE, ""); 1730 1.1 christos bindtextdomain (PACKAGE, LOCALEDIR); 1731 1.1 christos textdomain (PACKAGE); 1732 1.1 christos 1733 1.1 christos program_name = av[0]; 1734 1.1 christos xmalloc_set_program_name (program_name); 1735 1.3 christos bfd_set_error_program_name (program_name); 1736 1.1 christos 1737 1.1 christos expandargv (&ac, &av); 1738 1.1 christos 1739 1.1 christos while ((opt = getopt_long (ac, av, "dHhVvqn", long_options, 1740 1.1 christos (int *) NULL)) 1741 1.1 christos != EOF) 1742 1.1 christos { 1743 1.1 christos switch (opt) 1744 1.1 christos { 1745 1.1 christos case 'q': 1746 1.1 christos quick = 1; 1747 1.1 christos break; 1748 1.1 christos case 'n': 1749 1.1 christos noprescan = 1; 1750 1.1 christos break; 1751 1.1 christos case 'd': 1752 1.1 christos debug = 1; 1753 1.1 christos break; 1754 1.1 christos case 'H': 1755 1.1 christos case 'h': 1756 1.1 christos show_usage (stdout, 0); 1757 1.1 christos /*NOTREACHED */ 1758 1.1 christos case 'v': 1759 1.1 christos case 'V': 1760 1.1 christos print_version ("srconv"); 1761 1.1 christos exit (0); 1762 1.1 christos /*NOTREACHED */ 1763 1.1 christos case 0: 1764 1.1 christos break; 1765 1.1 christos default: 1766 1.1 christos show_usage (stderr, 1); 1767 1.1 christos /*NOTREACHED */ 1768 1.1 christos } 1769 1.1 christos } 1770 1.1 christos 1771 1.1 christos /* The input and output files may be named on the command line. */ 1772 1.1 christos output_file = NULL; 1773 1.1 christos if (optind < ac) 1774 1.1 christos { 1775 1.1 christos input_file = av[optind]; 1776 1.1 christos ++optind; 1777 1.1 christos if (optind < ac) 1778 1.1 christos { 1779 1.1 christos output_file = av[optind]; 1780 1.1 christos ++optind; 1781 1.1 christos if (optind < ac) 1782 1.1 christos show_usage (stderr, 1); 1783 1.1 christos if (filename_cmp (input_file, output_file) == 0) 1784 1.1 christos { 1785 1.1 christos fatal (_("input and output files must be different")); 1786 1.1 christos } 1787 1.1 christos } 1788 1.1 christos } 1789 1.1 christos else 1790 1.1 christos input_file = 0; 1791 1.1 christos 1792 1.1 christos if (!input_file) 1793 1.1 christos { 1794 1.1 christos fatal (_("no input file specified")); 1795 1.1 christos } 1796 1.1 christos 1797 1.1 christos if (!output_file) 1798 1.1 christos { 1799 1.1 christos /* Take a .o off the input file and stick on a .obj. If 1800 1.1 christos it doesn't end in .o, then stick a .obj on anyway */ 1801 1.1 christos 1802 1.1 christos int len = strlen (input_file); 1803 1.1 christos 1804 1.1 christos output_file = xmalloc (len + 5); 1805 1.1 christos strcpy (output_file, input_file); 1806 1.1 christos 1807 1.1 christos if (len > 3 1808 1.1 christos && output_file[len - 2] == '.' 1809 1.1 christos && output_file[len - 1] == 'o') 1810 1.1 christos { 1811 1.1 christos output_file[len] = 'b'; 1812 1.1 christos output_file[len + 1] = 'j'; 1813 1.1 christos output_file[len + 2] = 0; 1814 1.1 christos } 1815 1.1 christos else 1816 1.1 christos { 1817 1.1 christos strcat (output_file, ".obj"); 1818 1.1 christos } 1819 1.1 christos } 1820 1.1 christos 1821 1.1 christos abfd = bfd_openr (input_file, 0); 1822 1.1 christos 1823 1.1 christos if (!abfd) 1824 1.1 christos bfd_fatal (input_file); 1825 1.1 christos 1826 1.1 christos if (!bfd_check_format_matches (abfd, bfd_object, &matching)) 1827 1.1 christos { 1828 1.1 christos bfd_nonfatal (input_file); 1829 1.1 christos 1830 1.1 christos if (bfd_get_error () == bfd_error_file_ambiguously_recognized) 1831 1.8 christos list_matching_formats (matching); 1832 1.1 christos exit (1); 1833 1.1 christos } 1834 1.1 christos 1835 1.1 christos file = fopen (output_file, FOPEN_WB); 1836 1.1 christos 1837 1.1 christos if (!file) 1838 1.1 christos fatal (_("unable to open output file %s"), output_file); 1839 1.1 christos 1840 1.1 christos if (debug) 1841 1.1 christos printf ("ids %d %d\n", base1, base2); 1842 1.1 christos 1843 1.1 christos tree = coff_grok (abfd); 1844 1.3 christos if (tree) 1845 1.3 christos { 1846 1.3 christos if (!noprescan) 1847 1.3 christos prescan (tree); 1848 1.1 christos 1849 1.3 christos wr_module (tree); 1850 1.3 christos } 1851 1.1 christos return 0; 1852 1.1 christos } 1853